""" 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.7 2011/01/11 14:39:13 paul Exp $ import xml.dom.minidom import hashlib import sys import pickle import feedparser import codecs import xmlrpclib import pickle import datetime import time PICKLE_FILE = "minifeed.data" MAX_PENDING = 5 # post if we have this many items pending MAX_TIME = 60 * 60 * 24 * 6 # 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': hashlib.md5(challenge['challenge'] + hashlib.md5(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] munged_tags.extend(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'