Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 134 lines (109 sloc) 4.05 KB
#!/usr/bin/env python
"""E-mails a user's recent Tumblr links to recipients.
I use this to automate the distribution of interesting links to
my geek-buddies mailing list.
- tag your links with a special tag
- run this script with your tumblr blog name, this tag and the recipient(s)
as arguments every hour or so
The script needs write permissions in /var/local to save the ID of the
most recently mailed link. This ID is saved independently per user and tag.
# configuration
SMTP_SERVER = 'localhost'
import urllib
import urlparse
import re
import smtplib
import textwrap
from email.mime.text import MIMEText
import json
except ImportError:
# Python 2.5 and earlier need this package
import simplejson as json
class TumblrToMail:
def __init__(self, user, tag, recipients):
self.user = user
self.tag = tag
self.recipients = recipients
self.db_file = '/var/local/tumblr_mail.latest'
self.db_key = (user, tag)
self.db = eval(open(self.db_file).read(), {}, {})
except (IOError, OSError):
self.db = {}
self.latest = self.db.get(self.db_key, 0)
self.lw = textwrap.TextWrapper(initial_indent='* ', subsequent_indent=' ',
break_long_words=False, break_on_hyphens=False
) = textwrap.TextWrapper(initial_indent=' ', subsequent_indent=' ')
def __del__(self):
if self.latest:
self.db[self.db_key] = self.latest
open(self.db_file, 'w').write(repr(self.db))
def get_links(self):
url = '' % self.user
posts = urllib.urlopen(url).read()
posts = re.sub(r'^.*?(\{.*\});*$', r'\1', posts) # extract the JSON structure
posts = json.loads(posts)
except ValueError:
print posts
return []
return [
p for p in posts['posts']
if int(p['id']) > self.latest and self.tag in p.get('tags', [])
def make_mail(self, link):
url = list(urlparse.urlsplit(link['link-url']))
url[2] = urllib.quote(url[2])
mail = self.lw.fill(u'%s: %s' % (link['link-text'], urlparse.urlunsplit(url)))
desc = link['link-description']
if desc:
mail += '\n\n' +
return mail
def run(self, options):
links = self.get_links()
if not links:
body = ('\n\n'.join(self.make_mail(l) for l in links)).strip() + """
""" % self.user
self.latest = max(int(l['id']) for l in links) if not options.dry_run else None
if not self.recipients and not options.full:
print body
msg = MIMEText(body.encode('utf-8'))
msg['Subject'] = "Interesting links" if len(links) > 1 else links[0]['link-text']
msg['From'] = '%s (%s)' % (SENDER, self.user)
if self.recipients:
msg['To'] = ', '.join(self.recipients)
if options.full:
print msg.as_string()
smtp = smtplib.SMTP(SMTP_SERVER)
smtp.sendmail(SENDER, self.recipients, msg.as_string())
if __name__ == '__main__':
import optparse
parser = optparse.OptionParser("Usage: %prog [options] blog-name tag [recipient ...]",
description="Sends an email generated from tagged link posts.",
epilog="Without recipients, prints the mail body to stdout."
parser.add_option('-d', '--dry-run', action='store_true',
help="don't save which link was sent last"
parser.add_option('-f', '--full', action='store_true',
help="print the full mail with headers to stdout"
options, args = parser.parse_args()
user = args[0]
tag = args[1]
recipients = args[2:]
except IndexError:
parser.error("blog-name and tag are required arguments.")
TumblrToMail(user, tag, recipients).run(options)