aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcedricbonhomme <devnull@localhost>2010-03-22 22:36:34 +0100
committercedricbonhomme <devnull@localhost>2010-03-22 22:36:34 +0100
commit3aa4143dee58eb21d224ec69ce232612ddd38ce5 (patch)
tree3cbe18167b4bb73952f6d76ace0965e6cbeeb41f
parentThe database of feeds is monitored with the Python gamin module. (diff)
downloadnewspipe-3aa4143dee58eb21d224ec69ce232612ddd38ce5.tar.gz
newspipe-3aa4143dee58eb21d224ec69ce232612ddd38ce5.tar.bz2
newspipe-3aa4143dee58eb21d224ec69ce232612ddd38ce5.zip
Added: email notification of new articles.
-rwxr-xr-x[-rw-r--r--]COPYING0
-rwxr-xr-x[-rw-r--r--]cfg/pyAggr3g470r.cfg6
-rwxr-xr-x[-rw-r--r--]css/img/blogmarks.pngbin195 -> 195 bytes
-rwxr-xr-x[-rw-r--r--]css/img/delicious.pngbin266 -> 266 bytes
-rwxr-xr-x[-rw-r--r--]css/img/digg.pngbin358 -> 358 bytes
-rwxr-xr-x[-rw-r--r--]css/img/reddit.pngbin525 -> 525 bytes
-rwxr-xr-x[-rw-r--r--]css/img/scoopeo.pngbin295 -> 295 bytes
-rwxr-xr-x[-rw-r--r--]css/style.css0
-rwxr-xr-x[-rw-r--r--]feedgetter.py20
-rwxr-xr-x[-rw-r--r--]pyAggr3g470r.py79
-rwxr-xr-x[-rw-r--r--]tuxdroid.py0
-rwxr-xr-x[-rw-r--r--]utils.py33
-rwxr-xr-x[-rw-r--r--]var/feed.lst0
13 files changed, 105 insertions, 33 deletions
diff --git a/COPYING b/COPYING
index 20d40b6b..20d40b6b 100644..100755
--- a/COPYING
+++ b/COPYING
diff --git a/cfg/pyAggr3g470r.cfg b/cfg/pyAggr3g470r.cfg
index b31a1233..73e4d25f 100644..100755
--- a/cfg/pyAggr3g470r.cfg
+++ b/cfg/pyAggr3g470r.cfg
@@ -1,3 +1,7 @@
[global]
-path = /home/cedric/prog/python/pyaggr3g470r/
+path = /home/cedric/prog/python/projects/pyaggr3g470r/
sqlitebase = ./var/feed.db
+[mail]
+mail_from = pyAggr3g470r@mail.com
+mail_to = example@mail.com
+smtp = smtp.orange.fr \ No newline at end of file
diff --git a/css/img/blogmarks.png b/css/img/blogmarks.png
index 2464e5bb..2464e5bb 100644..100755
--- a/css/img/blogmarks.png
+++ b/css/img/blogmarks.png
Binary files differ
diff --git a/css/img/delicious.png b/css/img/delicious.png
index a96f8c00..a96f8c00 100644..100755
--- a/css/img/delicious.png
+++ b/css/img/delicious.png
Binary files differ
diff --git a/css/img/digg.png b/css/img/digg.png
index 097c4600..097c4600 100644..100755
--- a/css/img/digg.png
+++ b/css/img/digg.png
Binary files differ
diff --git a/css/img/reddit.png b/css/img/reddit.png
index 2d615f2a..2d615f2a 100644..100755
--- a/css/img/reddit.png
+++ b/css/img/reddit.png
Binary files differ
diff --git a/css/img/scoopeo.png b/css/img/scoopeo.png
index 052c7dc8..052c7dc8 100644..100755
--- a/css/img/scoopeo.png
+++ b/css/img/scoopeo.png
Binary files differ
diff --git a/css/style.css b/css/style.css
index 67537a82..67537a82 100644..100755
--- a/css/style.css
+++ b/css/style.css
diff --git a/feedgetter.py b/feedgetter.py
index eea8bfbb..68c90aa2 100644..100755
--- a/feedgetter.py
+++ b/feedgetter.py
@@ -16,6 +16,8 @@ import feedparser
from datetime import datetime
+import utils
+
url_finders = [ \
re.compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+)(:[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\),\\\"]"), \
re.compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+)(:[0-9]*)?"), \
@@ -40,7 +42,8 @@ class FeedGetter(object):
self.c = self.conn.cursor()
self.c.execute('''create table if not exists feeds
(feed_title text, feed_site_link text, \
- feed_link text PRIMARY KEY, feed_image_link text)''')
+ feed_link text PRIMARY KEY, feed_image_link text,
+ mail text)''')
self.c.execute('''create table if not exists articles
(article_date text, article_title text, \
article_link text PRIMARY KEY, article_description text, \
@@ -108,12 +111,14 @@ class FeedGetter(object):
except:
feed_image = "/css/img/feed-icon-28x28.png"
try:
- self.c.execute('insert into feeds values (?,?,?,?)', (\
+ self.c.execute('insert into feeds values (?,?,?,?,?)', (\
a_feed.feed.title.encode('utf-8'), \
a_feed.feed.link.encode('utf-8'), \
feed_link, \
- feed_image))
+ feed_image,
+ "0"))
except sqlite3.IntegrityError:
+ # feed already in the base
pass
for article in a_feed['entries']:
try:
@@ -129,7 +134,16 @@ class FeedGetter(object):
description, \
"0", \
feed_link))
+ result = self.c.execute("SELECT mail from feeds WHERE feed_site_link='" + \
+ a_feed.feed.link.encode('utf-8') + "'").fetchall()
+ print result
+ if result[0][0] == "1":
+ print "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ # send the article
+ utils.send_mail(utils.mail_from, utils.mail_to, \
+ a_feed.feed.title.encode('utf-8'), description)
except sqlite3.IntegrityError:
+ # article already in the base
pass
diff --git a/pyAggr3g470r.py b/pyAggr3g470r.py
index ed52f67f..fc5bce84 100644..100755
--- a/pyAggr3g470r.py
+++ b/pyAggr3g470r.py
@@ -12,38 +12,32 @@ import time
import sqlite3
import cherrypy
import threading
-import ConfigParser
from cherrypy.lib.static import serve_file
import utils
import feedgetter
-config = ConfigParser.RawConfigParser()
-config.read("./cfg/pyAggr3g470r.cfg")
-path = config.get('global','path')
-sqlite_base = os.path.abspath(config.get('global', 'sqlitebase'))
-
bindhost = "0.0.0.0"
cherrypy.config.update({ 'server.socket_port': 12556, 'server.socket_host': bindhost})
path = {'/css/style.css': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/style.css'}, \
+ 'tools.staticfile.filename':utils.path+'css/style.css'}, \
'/css/img/feed-icon-28x28.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/feed-icon-28x28.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/feed-icon-28x28.png'}, \
'/css/img/delicious.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/delicious.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/delicious.png'}, \
'/css/img/digg.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/digg.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/digg.png'}, \
'/css/img/reddit.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/reddit.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/reddit.png'}, \
'/css/img/scoopeo.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/scoopeo.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/scoopeo.png'}, \
'/css/img/blogmarks.png': {'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'css/img/blogmarks.png'}, \
+ 'tools.staticfile.filename':utils.path+'css/img/blogmarks.png'}, \
'/var/histogram.png':{'tools.staticfile.on': True, \
- 'tools.staticfile.filename':path+'var/histogram.png'}}
+ 'tools.staticfile.filename':utils.path+'var/histogram.png'}}
htmlheader = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' + \
'<head>' + \
@@ -119,6 +113,10 @@ class Root:
html += "<br />\n"
html += """<a href="/all_articles/%s">All articles</a>""" % (rss_feed_id,)
+ if self.feeds[rss_feed_id][6] == "0":
+ html += """ <a href="/tuned/start:%s">Stay tuned</a>""" % (rss_feed_id,)
+ else:
+ html += """ <a href="/tuned/stop:%s">Stop staying tuned</a>""" % (rss_feed_id,)
html += """ <a href="/mark_as_read/Feed_FromMainPage:%s">Mark all as read</a>""" % (rss_feed_id,)
if self.feeds[rss_feed_id][1] != 0:
html += """ <a href="/unread/%s" title="Unread article(s)"
@@ -155,7 +153,7 @@ class Root:
<a href="/unread/All">%s unread article(s)</a>.<br />""" % \
(self.nb_articles, sum([feed[1] for feed in self.feeds.values()]))
html += """Database: %s.\n<br />Size: %s bytes.</p>\n""" % \
- (os.path.abspath(sqlite_base), os.path.getsize(sqlite_base))
+ (os.path.abspath(utils.sqlite_base), os.path.getsize(utils.sqlite_base))
html += """<form method=get action="/fetch/">\n<input
type="submit" value="Fetch all feeds"></form>\n"""
@@ -525,7 +523,7 @@ class Root:
LOCKER.acquire()
param, _, identifiant = target.partition(':')
try:
- conn = sqlite3.connect(sqlite_base, isolation_level = None)
+ conn = sqlite3.connect(utils.sqlite_base, isolation_level = None)
c = conn.cursor()
# Mark all articles as read.
if param == "All":
@@ -554,6 +552,33 @@ class Root:
mark_as_read.exposed = True
+ def tuned(self, param):
+ """
+ """
+ try:
+ action, feed_id = param.split(':')
+ except:
+ return self.error_page("Bad URL")
+ conn = sqlite3.connect(utils.sqlite_base, isolation_level = None)
+ c = conn.cursor()
+ if action == "start":
+ try:
+ c.execute("UPDATE feeds SET mail=1 WHERE feed_site_link='" +
+ self.feeds[feed_id][5].encode('utf-8') + "'")
+ except:
+ pass
+ else:
+ try:
+ c.execute("UPDATE feeds SET mail=0 WHERE feed_site_link='" +
+ self.feeds[feed_id][5].encode('utf-8') + "'")
+ except:
+ pass
+ conn.commit()
+ c.close()
+
+ tuned.exposed = True
+
+
def update(self, path=None, event = None):
"""
Synchronizes transient objects with the database,
@@ -566,9 +591,9 @@ class Root:
self.top_words = utils.top_words(self.articles, 10)
if "pylab" not in utils.IMPORT_ERROR:
utils.create_histogram(self.top_words)
- print "Base (%s) loaded" % sqlite_base
+ print "Base (%s) loaded" % utils.sqlite_base
else:
- print "Base (%s) empty!" % sqlite_base
+ print "Base (%s) empty!" % utils.sqlite_base
def watch_base(self):
@@ -578,15 +603,15 @@ class Root:
When a change is detected, reload the base.
"""
mon = gamin.WatchMonitor()
- mon.watch_file(sqlite_base, self.update)
+ mon.watch_file(utils.sqlite_base, self.update)
time.sleep(10)
ret = mon.event_pending()
try:
- print "Watching %s" % sqlite_base
+ print "Watching %s" % utils.sqlite_base
while True:
ret = mon.event_pending()
if ret > 0:
- print "The base of feeds (%s) has changed.\nReloading..." % sqlite_base
+ print "The base of feeds (%s) has changed.\nReloading..." % utils.sqlite_base
ret = mon.handle_one_event()
time.sleep(2)
except KeyboardInterrupt:
@@ -603,17 +628,17 @@ class Root:
"""
old_size = 0
try:
- print "Watching %s" % sqlite_base
+ print "Watching %s" % utils.sqlite_base
while True:
time.sleep(5)
# very simple test
- if os.path.getsize(sqlite_base) != old_size:
- print "The base of feeds (%s) has changed.\nReloading..." % sqlite_base
+ if os.path.getsize(utils.sqlite_base) != old_size:
+ print "The base of feeds (%s) has changed.\nReloading..." % utils.sqlite_base
self.update()
- old_size = os.path.getsize(sqlite_base)
+ old_size = os.path.getsize(utils.sqlite_base)
except KeyboardInterrupt:
pass
- print "Stop watching", sqlite_base
+ print "Stop watching", utils.sqlite_base
if __name__ == '__main__':
@@ -626,7 +651,7 @@ if __name__ == '__main__':
thread_watch_base = threading.Thread(None, root.watch_base, None, ())
except:
print "The gamin module is not installed."
- print "The base of feeds will be monitored"
+ print "The base of feeds will be monitored with the simple method."
thread_watch_base = threading.Thread(None, root.watch_base_classic, None, ())
thread_watch_base.setDaemon(True)
thread_watch_base.start()
diff --git a/tuxdroid.py b/tuxdroid.py
index c48fadf2..c48fadf2 100644..100755
--- a/tuxdroid.py
+++ b/tuxdroid.py
diff --git a/utils.py b/utils.py
index 8c6e947d..ef6b3977 100644..100755
--- a/utils.py
+++ b/utils.py
@@ -17,6 +17,9 @@ except:
import sqlite3
import hashlib
+import smtplib
+from email.mime.text import MIMEText
+
from datetime import datetime
from string import punctuation
from collections import defaultdict
@@ -33,6 +36,17 @@ except:
import threading
LOCKER = threading.Lock()
+import os
+import ConfigParser
+config = ConfigParser.RawConfigParser()
+config.read("./cfg/pyAggr3g470r.cfg")
+path = config.get('global','path')
+sqlite_base = os.path.abspath(config.get('global', 'sqlitebase'))
+mail_from = config.get('mail','mail_from')
+mail_to = config.get('mail','mail_to')
+mail_smtp = config.get('mail','smtp')
+
+
def detect_language(text):
"""
Detect the language of a text.
@@ -114,6 +128,21 @@ def create_histogram(words, file_name="./var/histogram.png"):
pylab.savefig(file_name, dpi = 80)
pylab.close()
+def send_mail(mfrom, mto, feed_title, message):
+ """Send the warning via mail
+ """
+ mail = MIMEText(message)
+ mail['From'] = mfrom
+ mail['To'] = mto
+ mail['Subject'] = '[pyAggr3g470r] News from ' + feed_title
+ #email['Text'] = message
+
+ server = smtplib.SMTP(mail_smtp)
+ server.sendmail(mfrom, \
+ mto, \
+ mail.as_string())
+ server.quit()
+
def compare(stringtime1, stringtime2):
"""
Compare two dates in the format 'yyyy-mm-dd hh:mm:ss'.
@@ -157,7 +186,7 @@ def load_feed():
# article_link, article_description, article_readed,
# article_language)
# feeds[feed_id] = (nb_article, nb_article_unreaded, feed_image,
- # feed_title, feed_link, feed_site_link)
+ # feed_title, feed_link, feed_site_link, mail)
articles, feeds = {}, {}
if list_of_feeds != []:
for feed in list_of_feeds:
@@ -198,7 +227,7 @@ def load_feed():
feeds[feed_id] = (len(articles[feed_id]), \
len([article for article in articles[feed_id] \
if article[5]=="0"]), \
- feed[3], feed[0], feed[2], feed[1] \
+ feed[3], feed[0], feed[2], feed[1] , feed[4]\
)
c.close()
LOCKER.release()
diff --git a/var/feed.lst b/var/feed.lst
index 43b89680..43b89680 100644..100755
--- a/var/feed.lst
+++ b/var/feed.lst
bgstack15