"""
A script to get a feed full of links (like Delicious bookmarks) and post
batches of them to a single entry on LJ. It accumulates links until there are
MAX_PENDING of them or until the last LJ entry it made was MAX_TIME ago.
The information which it needs between runs is written to PICKLE_FILE.
"""
# $Id: lj-minifeed.py,v 1.5 2009/10/07 22:41:58 paul Exp $
import xml.dom.minidom
import md5
import sys
import pickle
import feedparser
import codecs
import xmlrpclib
import pickle
import datetime
import time
PICKLE_FILE = "minifeed.data"
MAX_PENDING = 10 # post if we have this many items pending
MAX_TIME = 60 * 60 * 24 * 4 # or if we have something pending and it's been this long
POST_HEADING = "
" # HTML at the begining of the body of the post. You'll want to change this
# Cheapo object persistence via pickle. This is the the object we
# save and restore. The defaults are only used if we can't find the
# pickle file.
class State:
def __init__(self):
self.seen_guids = []
self.feed_url = "http://feeds.delicious.com/v2/rss/pw201?count=15"
self.etag = None
self.modified = None
self.pending = []
self.last_time = 0
self.tag_dict = {}
def update_lj_args(lj, args, username, password):
challenge = lj.LJ.XMLRPC.getchallenge()
std = {
'version': 1, # so LJ assumes we're using UTF-8.
'auth_method': 'challenge',
'auth_challenge': challenge['challenge'],
'auth_response': md5.new(challenge['challenge'] + md5.new(password).hexdigest()).hexdigest(),
'username': username,
}
args.update(std)
def post_to_lj(body, title, tags, username, password):
# Faff to comply with LJ's bots policy
class CustomTransport(xmlrpclib.Transport):
user_agent = "http://www.noctua.org.uk/paul/software/lj-minifeed.html; pw201 AT livejournal.com, running on behalf of lj user " + username
lj = xmlrpclib.ServerProxy("http://www.livejournal.com/interface/xmlrpc", CustomTransport())
args = {}
update_lj_args(lj, args, username, password)
# I don't want to create new tags on LJ for every tag I use on delicious
# but I do want to use the LJ tags if they already existed. So we check the
# delicious tags against the LJ ones. I use a "-" for a space on delicious,
# spaces are allowed in tags on LJ.
lj_tags = [t['name'] for t in lj.LJ.XMLRPC.getusertags(args)['tags']]
munged_tags = [t.replace('-', ' ') for t in tags]
post_tags = "link blog," + ",".join([t for t in munged_tags if t in lj_tags])
now = datetime.datetime.now()
args = {
"event" : body,
"subject" : title,
"year" : now.year,
"mon" : now.month,
"day" : now.day,
"hour": now.hour,
"min" : now.minute,
"props": {"taglist": post_tags}
}
update_lj_args(lj, args, username, password)
return lj.LJ.XMLRPC.postevent(args)
def get_html(item):
"""
Generate HTML summary for an entry in the feed
"""
html = u'