Skip to content

Instantly share code, notes, and snippets.

@kolen
Created February 13, 2009 20:09
Show Gist options
  • Save kolen/64075 to your computer and use it in GitHub Desktop.
Save kolen/64075 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Send RSS feed items to email as plaintext converted by lynx
__revision__ = '0.0.1'
import shelve, urllib, smtplib, popen2, os
import cgi
from xml.dom.minidom import parse
from email.MIMEText import MIMEText
import cgitb; cgitb.enable()
email_from = u'RSS Obrygator <[email protected]>'
lynx_cmdline = 'lynx -force_html -image_links -dump -assume_local_charset=utf-8 -display_charset=utf-8 file:///dev/stdin'
class FeedDescr:
def __init__(self, handle, url, email):
self.url = url
self.last_guid = ''
self.title = ''
self.link = ''
self.handle = handle
self.email_to = email
class FeedItem:
def __repr__(self):
return "<FeedItem '%s' '%s'>" %(self.title, self.guid)
class FeedFetcher:
def __init__(self, descr):
self.descr = descr
self.items = []
def fetch(self):
f = urllib.urlopen(self.descr.url)
doc = parse(f)
self.descr.link = self.extractField(doc, 'link')
self.descr.title = self.extractField(doc, 'title')
new_last_guid = None
rssitems = doc.getElementsByTagName('item')
for item in rssitems:
fi = FeedItem()
fi.title = self.extractField(item, 'title')
fi.link = self.extractField(item, 'link')
fi.description = self.extractField(item, 'description')
fi.creator = self.extractField(item, 'dc:creator')
fi.guid = self.extractField(item, 'guid')
if not new_last_guid:
new_last_guid = fi.guid
if not self.descr.last_guid:
self.items.append(fi)
break
if self.descr.last_guid and fi.guid == self.descr.last_guid:
break
self.items.append(fi)
self.descr.last_guid = new_last_guid
def extractField(self, item, field):
try:
attrItems = item.getElementsByTagName(field)
if not attrItems:
return u''
fc = attrItems[0].firstChild
if fc == None:
return u''
return fc.data
except:
return "Unexpected error: %s" % (sys.exc_info()[0])
class FeedSender:
def send(self, fetchedFeed, email):
template = u'''
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
%s
%s
Лента: %s
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Автор: %s
%s
--
Люто и бешено преподнесено Obrygator/%s
'''
html_template = u'''
<html>
<meta http-equiv="Content-type" value="text/html; charset=utf-8" />
<body>
%s
</body>
</html>
'''
for item in fetchedFeed.items:
os.environ['LANG'] = 'en_EN'
fin,fout = popen2.popen2(lynx_cmdline)
fout.write((html_template % (item.description)).encode('utf-8'))
fout.close()
textualDescr = fin.read().decode('utf-8')
mailbody = template % (item.title, item.link,
fetchedFeed.descr.title,
item.creator,
textualDescr,
__revision__)
envelope = MIMEText(mailbody.encode('utf-8'), 'plain', 'utf-8')
envelope['To'] = fetchedFeed.descr.email_to
envelope['From'] = email_from
envelope['Subject'] = "[%s] %s (%s)" % (fetchedFeed.descr.handle,
item.title,
fetchedFeed.descr.title)
envelope.set_charset('utf-8')
smtp = smtplib.SMTP()
smtp.connect()
smtp.sendmail(email_from, [fetchedFeed.descr.email_to.encode('utf-8')], envelope.as_string())
def ctype():
print 'Content-type: text/html\n\n'
feeds = shelve.open('data/feeds', writeback=True)
fs = cgi.FieldStorage()
if fs['mode'].value == 'send':
ctype()
for key in feeds:
feed = feeds[key]
ff = FeedFetcher(feed)
ff.fetch()
fs = FeedSender()
fs.send(ff, feed.email_to)
#store back
feeds[key] = feed
elif fs['mode'].value == 'add':
if fs.has_key('add'):
handle = fs['handle'].value
url = fs['url'].value
email_to = fs['email_to'].value
fd = FeedDescr(handle, url, email_to)
feeds[handle] = fd
ctype()
print "Okay"
else:
ctype()
print "<html><body>"
print '<form method="post">h:<input name="handle" type="text" />'
print 'url:<input name="url" type="text" />'
print 'email:<input name="email_to" type="text" />'
print '<button type="submit">Add</button>'
print '<input type="hidden" name="mode" value="add"/>'
print '<input type="hidden" name="add" value="yes"/>'
print '</form>'
for key in feeds:
print "<b>%s</b> %s %s %s %s<br />" % (key,
feeds[key].title.encode('utf-8'),
feeds[key].url.encode('utf-8'),
feeds[key].email_to.encode('utf-8'),
feeds[key].last_guid.encode('utf-8'))
print "</body></html>"
elif fs['mode'].value == 'remove':
del feeds[fs['handle'].value]
ctype()
else:
ctype()
print 'error in args'
feeds.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment