#!/usr/bin/env python # # Copyright (C) 2006-2008 Michael G. Noll # Copyright (C) 2008 Mark A. Matienzo # # deliciouscopy is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # deliciouscopy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with deliciouscopy. If not, see . import md5 import os import sys from time import sleep, strftime import feedparser import pydelicious from simplejson import loads as json_load import settings class DeliciousCopy(object): """Class to copy inbox items to public bookmarks, checking for if the poster is in the account's network. Based upon Michael Noll's deliciousmonitor.py: http://www.michael-noll.com/wiki/Del.icio.us_Python_API#deliciousmonitor.py """ def __init__(self, username, password, key, logfile, verbose=False): self.inbox = pydelicious.dlcs_feed('user_inbox', format='rss', username=username, key=key) self.api = pydelicious.DeliciousAPI(username, password) self.posters = json_load(pydelicious.json_network(username)) self.logfile = logfile self.verbose = verbose def check(self): """Check inbox for new items.""" logfh = None if os.access(self.logfile, os.F_OK): if self.verbose: print "[LOG] Log file found. Trying to resume...", try: # read in previous log data for resuming logfh = open(self.logfile, 'r') logfh.readline() logfh.close() if self.verbose: print "OK" except IOError: # most probably, the log file does not exist (yet) if self.verbose: print "failed" else: # log file does not exist, so there isn't any resume data # to read in pass try: if self.verbose: print "[LOG] Open log file for appending...", logfh = open(self.logfile, 'a') if self.verbose: print "done" except IOError: if self.verbose: print "failed" print "[LOG] ERROR: could not open log file for appending" self._cleanup() return # query metadata about each entry from delicious.com for index, entry in enumerate(self.inbox.entries): url = entry.link urlmd5 = md5.new(url).hexdigest() if entry.author in self.posters: if self.verbose: logfh.write("[LOG] %s Processing entry #%s: '%s'\n" % \ (strftime("%Y-%m-%d %H:%M:%S"), index + 1, url)) try: sleep(1) # be nice and wait 1 sec between connects urlinfo = json_load(pydelicious.dlcs_feed('urlinfo', urlmd5=urlmd5)) if urlinfo: urlinfo = urlinfo[0] else: urlinfo = {} title = urlinfo['title'] top_tags = urlinfo['top_tags'] or [] tagstr = 'via:%s ' % entry.author + \ ' '.join([tag.replace(' ','_') for tag in top_tags]) self.api.posts_add(url, title, tags=tagstr.strip()) if self.verbose: logfh.write("[LOG] %s Saved %s\n" % \ (strftime("%Y-%m-%d %H:%M:%S"), url)) except KeyError: pass except pydelicious.DeliciousItemExistsError: if self.verbose: logfh.write("[LOG] %s %s already added\n" % \ (strftime("%Y-%m-%d %H:%M:%S"), url)) except: logfh.write("[LOG] %s ERROR: %s\n" % \ (strftime("%Y-%m-%d %H:%M:%S"), sys.exc_info()[0])) # clean up logfh.close() raise else: logfh.write("[LOG] %s ERROR: %s not in network-aborting %s\n" % :\ (strftime("%Y-%m-%d %H:%M:%S"), entry.author, url)) # clean up logfh.close() if __name__ == "__main__": dc = DeliciousCopy(username=settings.USERNAME, password=settings.PASSWORD, key=settings.KEY, logfile=settings.LOGFILE) dc.check()