zs

Zeitungsschau rss to email converter
git clone git://r-36.net/zs
Log | Files | Refs | LICENSE

commit 3c5f83c92d5f06694af51f996986c7fe0f9f9544
parent 05d5993acdbe7f3d6de29e18d5f0349e935cf2a8
Author: Christoph Lohmann <20h@r-36.net>
Date:   Wed, 12 Mar 2014 22:55:50 +0100

Add final features before alpha.

	* "del" instead of "delete"
	* add "dryrun"
	* use pickle instead of shelve
	* make email handling easier
	* add useful output when "run" is invoked

Diffstat:
feeddb.py | 43++++++++++++++++++++++++++++++-------------
feedemail.py | 10+++++-----
zs.py | 50++++++++++++++++++++++++++++++++++++--------------
3 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/feeddb.py b/feeddb.py @@ -5,7 +5,7 @@ # by 20h # -import shelve +import pickle import os import os.path import fcntl @@ -16,16 +16,25 @@ class feeddb(object): lockf = None feeds = {} cfg = {} + dbpath = "" + lpath = "" def __init__(self, path="~/.zs/feed.db", email=None): - dbpath = os.path.expanduser(path) - path = os.path.abspath(os.path.dirname(dbpath)) + self.dbpath = os.path.expanduser(path) + path = os.path.abspath(os.path.dirname(self.dbpath)) if not os.path.exists(path): os.makedirs(path, 0o750) - lockpath = "%s.lck" % (dbpath) - self.lockf = open(lockpath, "w") + self.lpath = "%s.lck" % (self.dbpath) + self.lockf = open(self.lpath, "w") fcntl.lockf(self.lockf.fileno(), fcntl.LOCK_EX) - self.db = shelve.open(dbpath) + + try: + fd = open(self.dbpath, "rb") + self.db = pickle.load(fd) + fd.close() + except FileNotFoundError: + self.db = {} + if "feeds" in self.db: self.feeds = self.db["feeds"] if "cfg" in self.db: @@ -51,10 +60,13 @@ class feeddb(object): if self.db != None: self.db["feeds"] = self.feeds self.db["cfg"] = self.cfg - self.db.close() + fd = open(self.dbpath, "wb+") + pickle.dump(self.db, fd) + fd.close() if self.lockf != None: fcntl.flock(self.lockf.fileno(), fcntl.LOCK_UN) self.lockf.close() + os.remove(self.lpath) def readfeed(self, uri): if not uri in self.feeds: @@ -100,16 +112,21 @@ class feeddb(object): def unpause(self, uri): self.setfeedval(uri, "pause", False) + def getfeedval(self, uri, key): + feed = self.readfeed(uri) + if feed == None: + return None + return feed[key] + + def ispaused(self, uri): + return self.getfeedval(uri, "pause") + def listfeeds(self): return list(self.feeds.keys()) - def addfeed(self, uri, email=None): + def addfeed(self, uri): if not uri in self.listfeeds(): feed = {} - if email == None: - feed["toemail"] = self.cfg["email"] - else: - feed["toemail"] = email feed["uri"] = uri feed["pause"] = False feed["articles"] = [] @@ -181,7 +198,7 @@ class feeddb(object): article["id"]] if len(a) > 0: for aa in a: - a["unread"] = False + aa["unread"] = False self.writefeed(uri, feed); def resetarticles(self, uri): diff --git a/feedemail.py b/feedemail.py @@ -42,7 +42,7 @@ def send(feed, to, smtphost="localhost", smtpport=None, ssl="False", \ # Append metadata. if "link" in article: - text = "%sLink: %s\n" % (text, article["link"]) + text = "%sURL: %s\n" % (text, article["link"]) if "file" in article: text = "%sEnclosure: %s\n" % (text, article["file"]) @@ -88,11 +88,11 @@ def send(feed, to, smtphost="localhost", smtpport=None, ssl="False", \ else: s.connect(smtphost) - if user != None and password != None: - s.ehlo() - if ssl == False: - s.starttls() + s.ehlo() + if ssl == False: + s.starttls() s.ehlo() + if user != None and password != None: s.login(user, password) s.sendmail(faddr, to, msg.as_string()) diff --git a/zs.py b/zs.py @@ -11,28 +11,44 @@ import feed import feeddb import opml import feedemail +import urllib.error -def run(db, selfeed=None): +def run(db, selfeed=None, dryrun=False): feeduris = db.listfeeds() if feeduris != None and selfeed in feeduris: feeduris = [selfeed] - print("feeduris: %s" % (feeduris)) for feeduri in feeduris: - curfeed = feed.fetch(feeduri) - print("curfeed: %d" % (len(curfeed["articles"]))) + if db.ispaused(feeduri): + print("pause %s" % (feeduri)) + continue + + print("fetch %s" % (feeduri)) + try: + curfeed = feed.fetch(feeduri) + except urllib.error.HTTPError as err: + if err.code == 404: + print("404 -> pause %s" % (feeduri)) + db.pause(feeduri) + continue + + clen = len(curfeed["articles"]) + if clen == 0: + print("0 articles -> pause %s" % (feeduri)) + db.pause(feeduri) + continue + db.mergefeed(feeduri, curfeed) ufeed = db.unreadarticles(feeduri) - print("unread: %d" % (len(ufeed["articles"]))) - - if "toemail" in ufeed: - toemail = ufeed["toemail"] - else: - toemail = db.cfg["email"] - feedemail.send(ufeed, toemail, db.cfg["smtphost"], \ - db.cfg["smtpport"], db.cfg["smtpssl"], \ - db.cfg["smtpuser"], db.cfg["smtppassword"]) + if len(ufeed["articles"]) > 0: + print("cur %d unread %d" % (clen, \ + len(ufeed["articles"]))) + + if dryrun == False: + feedemail.send(ufeed, db.cfg["email"], db.cfg["smtphost"], \ + db.cfg["smtpport"], db.cfg["smtpssl"], \ + db.cfg["smtpuser"], db.cfg["smtppassword"]) db.setreadarticles(feeduri, ufeed) def usage(app): @@ -54,6 +70,12 @@ def main(args): else: run(db) + elif args[1] == "dryrun": + if len(args) > 2: + run(db, args[2], dryrun=True) + else: + run(db, dryrun=True) + elif args[1] == "cfg": if len(args) < 3: for k in db.cfg: @@ -80,7 +102,7 @@ def main(args): for f in db.listfeeds(): print(f) - elif args[1] == "delete": + elif args[1] == "del": if len(args) < 3: usage(args[0]) db.delfeed(args[1])