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])