From 1aa54d2c79180519b84cdf8b7c6071718de0e648 Mon Sep 17 00:00:00 2001 From: Lindsey Smith Date: Fri, 1 Oct 2010 12:00:00 +0000 Subject: [PATCH] Bump to version 2.68. --- CHANGELOG | 5 +++ rss2email.py | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d9cf7ba..3ca50ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v2.68 (2010-10-01) + * Added ability to pause/resume checking of individual feeds through pause and unpause commands + * Added ability to import and export OPML feed lists through importopml and exportopml commands + + v2.67 (2010-09-21) * Fixed entries that include an id which is blank (i.e., an empty string) were being resent * Fixed some entries not being sent by email because they had bad From headers diff --git a/rss2email.py b/rss2email.py index 00fdbd7..f23f788 100755 --- a/rss2email.py +++ b/rss2email.py @@ -10,8 +10,12 @@ Usage: list reset delete n + pause n + unpause n + opmlexport + opmlimport filename """ -__version__ = "2.67" +__version__ = "2.68" __author__ = "Lindsey Smith (lindsey@allthingsrss.com)" __copyright__ = "(C) 2004 Aaron Swartz. GNU GPL 2 or 3." ___contributors__ = ["Dean Jackson", "Brian Lalor", "Joey Hess", @@ -437,6 +441,7 @@ def getEmail(feed, entry): class Feed: def __init__(self, url, to): self.url, self.etag, self.modified, self.seen = url, None, None, {} + self.active = True self.to = to def load(lock=1): @@ -461,7 +466,11 @@ def load(lock=1): feeds = pickle.load(feedfileObject) if unix: fcntl.flock(feedfileObject.fileno(), locktype) - + if feeds: + for feed in feeds[1:]: + if not hasattr(feed, 'active'): + feed.active = True + return feeds, feedfileObject def unlock(feeds, feedfileObject): @@ -513,6 +522,8 @@ def run(num=None): for f in ifeeds: try: feednum += 1 + if not f.active: continue + if VERBOSE: print >>warn, 'I: Processing [%d] "%s"' % (feednum, f.url) r = {} try: @@ -633,7 +644,7 @@ def run(num=None): from_addr = getEmail(r.feed, entry) - name = h2t.unescape(getName(r, entry)) + name = h2t.unescape(getName(r, entry)) fromhdr = formataddr((name, from_addr,)) tohdr = (f.to or default_to) subjecthdr = title @@ -745,11 +756,53 @@ def list(): print "default email:", default_to else: ifeeds = feeds; i = 0 for f in ifeeds: - print `i`+':', f.url, '('+(f.to or ('default: '+default_to))+')' + active = '[*]' if f.active else '[ ]' + print `i`+':',active, f.url, '('+(f.to or ('default: '+default_to))+')' if not (f.to or default_to): print " W: Please define a default address with 'r2e email emailaddress'" i+= 1 +def opmlexport(): + import xml.sax.saxutils + feeds, feedfileObject = load(lock=0) + + if feeds: + print '\n\n\nrss2email OPML export\n\n' + for f in feeds[1:]: + url = xml.sax.saxutils.escape(f.url) + print '' % (url, url) + print '\n' + +def opmlimport(importfile): + importfileObject = None + print 'Importing feeds from', importfile + if not os.path.exists(importfile): + print 'OPML import file "%s" does not exist.' % feedfile + try: + importfileObject = open(importfile, 'r') + except IOError, e: + print "OPML import file could not be opened: %s" % e + sys.exit(1) + try: + import xml.dom.minidom + dom = xml.dom.minidom.parse(importfileObject) + newfeeds = dom.getElementsByTagName('outline') + except: + print 'E: Unable to parse OPML file' + sys.exit(1) + + feeds, feedfileObject = load(lock=1) + + import xml.sax.saxutils + + for f in newfeeds: + if f.hasAttribute('xmlUrl'): + feedurl = f.getAttribute('xmlUrl') + print 'Adding %s' % xml.sax.saxutils.unescape(feedurl) + feeds.append(Feed(feedurl, None)) + + unlock(feeds, feedfileObject) + def delete(n): feeds, feedfileObject = load() if (n == 0) and (feeds and isstr(feeds[0])): @@ -763,6 +816,18 @@ def delete(n): print >>warn, "W: feed IDs have changed, list before deleting again" unlock(feeds, feedfileObject) +def toggleactive(n, active): + feeds, feedfileObject = load() + if (n == 0) and (feeds and isstr(feeds[0])): + print >>warn, "W: ID has to be equal to or higher than 1" + elif n >= len(feeds): + print >>warn, "W: no such feed" + else: + action = 'Unpausing' if active else 'Pausing' + print >>warn, "%s feed %s" % (action, feeds[n].url) + feeds[n].active = active + unlock(feeds, feedfileObject) + def reset(): feeds, feedfileObject = load() if feeds and isstr(feeds[0]): @@ -821,8 +886,24 @@ if __name__ == '__main__': else: raise InputError, "Action '%s' requires a number as its argument" % action + elif action in ("pause", "unpause"): + if not args: + raise InputError, "Action '%s' requires an argument" % action + elif args[0].isdigit(): + active = (action == "unpause") + toggleactive(int(args[0]), active) + else: + raise InputError, "Action '%s' requires a number as its argument" % action + elif action == "reset": reset() + elif action == "opmlexport": opmlexport() + + elif action == "opmlimport": + if not args: + raise InputError, "OPML import '%s' requires a filename argument" % action + opmlimport(args[0]) + else: raise InputError, "Invalid action" -- 2.26.2