Add final features before alpha. - zs - Zeitungsschau rss to email converter
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 3c5f83c92d5f06694af51f996986c7fe0f9f9544
 (DIR) parent 05d5993acdbe7f3d6de29e18d5f0349e935cf2a8
 (HTM) 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(-)
       ---
 (DIR) 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):
 (DIR) 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())
 (DIR) 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])