From e6472738b5253aa328f8b2a4f4f2a23abc8582c2 Mon Sep 17 00:00:00 2001 From: cedricbonhomme Date: Sun, 15 Apr 2012 18:59:50 +0200 Subject: Reorganization of folders. --- pyAggr3g470r.py | 1271 ------------------------------------------------------- 1 file changed, 1271 deletions(-) delete mode 100755 pyAggr3g470r.py (limited to 'pyAggr3g470r.py') diff --git a/pyAggr3g470r.py b/pyAggr3g470r.py deleted file mode 100755 index 1284ea3e..00000000 --- a/pyAggr3g470r.py +++ /dev/null @@ -1,1271 +0,0 @@ -#! /usr/bin/env python -#-*- coding: utf-8 -*- - -# pyAggr3g470r - A Web based news aggregator. -# Copyright (C) 2010-2012 Cédric Bonhomme - http://cedricbonhomme.org/ -# -# For more information : http://bitbucket.org/cedricbonhomme/pyaggr3g470r/ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see - -__author__ = "Cedric Bonhomme" -__version__ = "$Revision: 3.1 $" -__date__ = "$Date: 2010/01/29 $" -__revision__ = "$Date: 2012/03/09 $" -__copyright__ = "Copyright (c) Cedric Bonhomme" -__license__ = "GPLv3" - -# -# This file contains the "Root" class which describes -# all pages of pyAggr3g470r. These pages are: -# - main page; -# - management; -# - history; -# - favorites; -# - notifications; -# - unread; -# - feed summary. -# - -import os -import re -import time -import cherrypy -import calendar - -from collections import Counter -import datetime - -import utils -import export -import mongodb -import feedgetter -from qrcode.pyqrnative.PyQRNative import QRCode, QRErrorCorrectLevel, CodeOverflowException -from qrcode import qr - - -def error_page_404(status, message, traceback, version): - """ - Display an error if the page does not exist. - """ - html = htmlheader() - html += htmlnav - html += "

Error %s - This page does not exist." % status - html += "\n
\n" + htmlfooter - return html - -def handle_error(): - """ - Handle different type of errors. - """ - html = htmlheader() - html += htmlnav - html += "

Sorry, an error occured" - html += "\n
\n" + htmlfooter - cherrypy.response.status = 500 - cherrypy.response.body = [html] - -def htmlheader(nb_unread_articles=""): - """ - Return the header of the HTML page with the number of unread articles - in the 'title' HTML tag.. - """ - return '\n' + \ - '' + \ - '\n\t'+ nb_unread_articles +'pyAggr3g470r - News aggregator\n' + \ - '\t' + \ - '\n\t\n' + \ - '\n\t\n' + \ - '\n' - -htmlfooter = '

This software is under GPLv3 license. You are welcome to copy, modify or' + \ - ' redistribute the source code according to the' + \ - ' GPLv3 license.

\n' + \ - '\n' - -htmlnav = '\n

pyAggr3g470r - News aggregator

\n' + \ - 'pyAggr3g470r (source code)' - - -class Root: - """ - Root class. - All pages of pyAggr3g470r are described in this class. - """ - def __init__(self): - """ - """ - self.mongo = mongodb.Articles(utils.MONGODB_ADDRESS, utils.MONGODB_PORT) - - def index(self): - """ - Main page containing the list of feeds and articles. - """ - feeds = self.mongo.get_all_collections() - nb_unread_articles = self.mongo.nb_unread_articles() - nb_favorites = self.mongo.nb_favorites() - nb_mail_notifications = self.mongo.nb_mail_notifications() - - # if there are unread articles, display the number in the tab of the browser - html = htmlheader((nb_unread_articles and \ - ['(' + str(nb_unread_articles) +') '] or \ - [""])[0]) - html += htmlnav - html += self.create_right_menu() - html += """
\n""" - - if feeds: - html += '\n' - html += '\n' - html += '      \n' - - html += """\n""" % \ - (nb_favorites,) - - html += """\n""" % \ - (nb_mail_notifications,) - - html += '      ' - if nb_unread_articles != 0: - html += '\n' - html += """\n""" % \ - (nb_unread_articles,) - html += '\n' - - - # The main page display all the feeds. - for feed in feeds: - html += """

%s -

\n""" % \ - (feed["feed_id"], feed["feed_link"], feed["feed_title"], \ - feed["feed_link"], feed["feed_image"]) - - # The main page display only 10 articles by feeds. - for article in self.mongo.get_articles_from_collection(feed["feed_id"])[:10]: - if article["article_readed"] == False: - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - # display a heart for faved articles - if article["article_like"] == True: - like = """ """ - else: - like = "" - - # Descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content.split(' ')[:55]) - else: - description = "No description." - # Title of the article - article_title = article["article_title"] - if len(article_title) >= 110: - article_title = article_title[:110] + " ..." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s%s%s""" % \ - (feed["feed_id"], article["article_id"], not_read_begin, \ - article_title, not_read_end, description) + like + "
\n" - html += "
\n" - - # some options for the current feed - html += """All articles   """ % (feed["feed_id"],) - html += """Feed summary   """ % (feed["feed_id"],) - if self.mongo.nb_unread_articles(feed["feed_id"]) != 0: - html += """  Mark all as read""" % (feed["feed_id"],) - html += """     Unread article(s) (%s)""" % (feed["feed_id"], self.mongo.nb_unread_articles(feed["feed_id"])) - if feed["mail"] == "0": - html += """
\nStay tuned""" % (feed["feed_id"],) - else: - html += """
\nStop staying tuned""" % (feed["feed_id"],) - html += """

Top

""" - html += "
\n" - html += htmlfooter - return html - - index.exposed = True - - - def create_right_menu(self): - """ - Create the right menu. - """ - html = """
\n""" - html += """
\n""" - html += "
\n" - # insert the list of feeds in the menu - html += self.create_list_of_feeds() - html += "
\n" - - return html - - def create_list_of_feeds(self): - """ - Create the list of feeds. - """ - feeds = self.mongo.get_all_collections() - html = """" - - - def management(self, max_nb_articles=5): - """ - Management page. - Allows adding and deleting feeds. Export functions of the MongoDB data base - and display some statistics. - """ - feeds = self.mongo.get_all_collections() - nb_mail_notifications = self.mongo.nb_mail_notifications() - nb_favorites = self.mongo.nb_favorites() - nb_articles = self.mongo.nb_articles() - nb_unread_articles = self.mongo.nb_unread_articles() - - html = htmlheader() - html += htmlnav - html += """
\n""" - html += "

Add Feeds

\n" - # Form: add a feed - html += """
\n
\n""" - - if feeds: - # Form: delete a feed - html += "

Delete Feeds

\n" - html += """
\n""" - - html += """

Active e-mail notifications: %s

\n""" % \ - (nb_mail_notifications,) - html += """

You like %s article(s).

\n""" % \ - (nb_favorites, ) - - html += "
\n" - - # Informations about the data base of articles - html += """

%s article(s) are loaded from the database with - %s unread article(s).
\n""" % \ - (nb_articles, nb_unread_articles) - #html += """Database: %s.\n
Size: %s bytes.
\n""" % \ - #(os.path.abspath(utils.sqlite_base), os.path.getsize(utils.sqlite_base)) - html += 'Advanced statistics.

\n' - - html += """
\n
\n""" - html += """
\n
\n""" - - - html += '
\n' - html += "For each feed only load the " - html += """\n""" % (max_nb_articles) - html += " last articles." - if utils.MAX_NB_ARTICLES == -1: - html += "
All articles are currently loaded.\n" - else: - html += "
For each feed only " + str(utils.MAX_NB_ARTICLES) + " articles are currently loaded. " - html += 'Load all articles.
\n' - html += "
\n" - - # Export functions - html += "

Export articles

\n\n" - html += """
\n\t\n
\n""" - html += "
" - html += htmlfooter - return html - - management.exposed = True - - - def statistics(self, word_size=6): - """ - More advanced statistics. - """ - articles = self.mongo.get_all_articles() - html = htmlheader() - html += htmlnav - html += """
\n""" - - # Some statistics (most frequent word) - if articles: - top_words = utils.top_words(articles, n=50, size=int(word_size)) - html += "

Statistics

\n
\n" - # Tags cloud - html += 'Minimum size of a word:' - html += '
' - html += """""" % (word_size) - html += '
\n' - html += '

Tag cloud

\n' - html += '
' + \ - utils.tag_cloud(top_words) + '
' - html += "
\n" - - html += htmlfooter - return html - - statistics.exposed = True - - - def search(self, query=None): - """ - Simply search for the string 'query' - in the description of the article. - """ - param, _, value = query.partition(':') - wordre = re.compile(r'\b%s\b' % param, re.I) - feed_id = None - if param == "Feed": - feed_id, _, query = value.partition(':') - html = htmlheader() - html += htmlnav - html += """
""" - html += """

Articles containing the string %s


""" % (query,) - - if feed_id is not None: - for article in self.feeds[feed_id].articles.values(): - article_content = utils.clear_string(article.article_description) - if not article_content: - utils.clear_string(article.article_title) - if wordre.findall(article_content) != []: - if article.article_readed == "0": - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - html += article.article_date + " - " + not_read_begin + \ - """%s""" % \ - (feed_id, article.article_id, article.article_title) + \ - not_read_end + """
\n""" - else: - feeds = self.mongo.get_all_collections() - for feed in feeds: - new_feed_section = True - for article in self.mongo.get_articles_from_collection(feed["feed_id"]): - article_content = utils.clear_string(article["article_content"]) - if not article_content: - utils.clear_string(article["article_title"]) - if wordre.findall(article_content) != []: - if new_feed_section is True: - new_feed_section = False - html += """

%s

\n""" % \ - (feed["feed_id"], feed["feed_title"], feed["feed_link"], feed["feed_image"]) - - if article["article_readed"] == False: - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - # display a heart for faved articles - if article["article_like"] == True: - like = """ """ - else: - like = "" - - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s%s%s""" % \ - (feed["feed_id"], article["article_id"], not_read_begin, \ - article["article_title"][:150], not_read_end, description) + like + "
\n" - html += "
" - html += htmlfooter - return html - - search.exposed = True - - - def fetch(self): - """ - Fetch all feeds. - """ - feed_getter = feedgetter.FeedGetter() - feed_getter.retrieve_feed() - return self.index() - - fetch.exposed = True - - - def article(self, param): - """ - Display the article in parameter in a new Web page. - """ - try: - feed_id, article_id = param.split(':') - feed = self.mongo.get_collection(feed_id) - articles = self.mongo.get_articles_from_collection(feed_id) - article = self.mongo.get_article(feed_id, article_id) - except: - return self.error_page("Bad URL. This article do not exists.") - html = htmlheader() - html += htmlnav - html += """
""" - - if article["article_readed"] == False: - # if the current article is not yet readed, update the database - self.mark_as_read("Article:"+article["article_id"]+":"+feed["feed_id"]) - - html += '\n
\n' - # Title of the article - html += """

%s from %s

\n
\n""" % \ - (article["article_title"], feed_id, feed["feed_title"]) - if article["article_like"] == True: - html += """""" % \ - (feed_id, article["article_id"]) - else: - html += """""" % \ - (feed_id, article["article_id"]) - html += """  """ % \ - (feed_id, article["article_id"]) - html += "

" - - # Description (full content) of the article - description = article["article_content"] - if description: - p = re.compile(r'<') - q = re.compile(r'>') - - description = p.sub('<', description) - description = q.sub('>', description) - - html += description + "\n


" - else: - html += "No description available.\n


" - - # Generation of the QR Code for the current article - try: - os.makedirs("./var/qrcode/") - except OSError: - pass - if not os.path.isfile("./var/qrcode/" + article_id + ".png"): - # QR Code generation - try: - if len(utils.clear_string(description)) > 4296: - raise Exception() - f = qr.QRUrl(url = utils.clear_string(description)) - f.make() - except: - f = qr.QRUrl(url = article["article_link"]) - f.make() - f.save("./var/qrcode/"+article_id+".png") - - # Previous and following articles - articles_list = articles.distinct("article_id") - try: - following = articles[articles_list.index(article_id) - 1] - html += """
\n""" % \ - (feed_id, following["article_id"], following["article_title"]) - except Exception, e: - print e - try: - previous = articles[articles_list.index(article_id) + 1] - except: - previous = articles[0] - finally: - html += """
\n""" % \ - (feed_id, previous["article_id"], previous["article_title"]) - - html += "\n
\n" - - # Footer menu - html += "
\n" - html += """\nPlain text\n""" % (feed_id, article["article_id"]) - html += """ - Export to EPUB\n""" % (feed_id, article["article_id"]) - html += """
\nComplete story\n
\n""" % (article["article_link"],) - - # Share this article: - html += "Share this article:
\n" - # on Diaspora - html += """\n\t - \n""" % \ - (utils.DIASPORA_POD, article["article_link"], article["article_title"], "via pyAggr3g470r") - - # on Identi.ca - html += """\n\n""" % \ - (article["article_title"], article["article_link"]) - - # on Hacker News - html += """\n\n""" % \ - (article["article_link"], article["article_title"]) - - # on Pinboard - html += """\n\n\t\n - """ % \ - (article["article_link"], article["article_title"]) - - # on Digg - html += """\n\n\t\n - """ % \ - (article["article_link"], article["article_title"]) - # on reddit - html += """\n\n\t\n - """ % \ - (article["article_link"], article["article_title"]) - # on Scoopeo - html += """\n\n\t\n - """ % \ - (article["article_link"], article["article_title"]) - # on Blogmarks - html += """\n\n\t\n - """ % \ - (article["article_link"], article["article_title"]) - - # Google +1 button - html += """\n\n""" % \ - (article["article_link"],) - - - # QRCode (for smartphone) - html += """
\n""" % (article_id, article_id) - html += "
\n" + htmlfooter - return html - - article.exposed = True - - - def feed(self, feed_id, word_size=6): - """ - This page gives summary informations about a feed (number of articles, - unread articles, average activity, tag cloud, e-mail notification and - favourite articles for the current feed. - """ - try: - feed = self.mongo.get_collection(feed_id) - articles = self.mongo.get_articles_from_collection(feed_id) - except KeyError: - return self.error_page("This feed do not exists.") - html = htmlheader() - html += htmlnav - html += """
""" - html += "

The feed " + feed["feed_title"] + " contains " + str(self.mongo.nb_articles(feed_id)) + " articles. " - html += "Representing " + str((round(float(self.mongo.nb_articles(feed_id)) / 1000, 4)) * 100) + " % of the total " #hack - html += "(" + str(1000) + ").

" - if articles != []: - html += "

" + (self.mongo.nb_unread_articles(feed_id) == 0 and ["All articles are read"] or [str(self.mongo.nb_unread_articles(feed_id)) + \ - " unread article" + (self.mongo.nb_unread_articles(feed_id) == 1 and [""] or ["s"])[0]])[0] + ".

" - if feed["mail"] == True: - html += """

You are receiving articles from this feed to the address: %s. """ % \ - (utils.mail_to, utils.mail_to) - html += """Stop receiving articles from this feed.

""" % \ - (feed[feed_id], ) - - if articles != []: - last_article = utils.string_to_datetime(str(articles[0]["article_date"])) - first_article = utils.string_to_datetime(str(articles[self.mongo.nb_articles(feed_id)-2]["article_date"])) - delta = last_article - first_article - delta_today = datetime.datetime.fromordinal(datetime.date.today().toordinal()) - last_article - html += "

The last article was posted " + str(abs(delta_today.days)) + " day(s) ago.

" - if delta.days > 0: - html += """

Daily average: %s,""" % (str(round(float(self.mongo.nb_articles(feed_id))/abs(delta.days), 2)),) - html += """ between the %s and the %s.

\n""" % \ - (str(articles[self.mongo.nb_articles(feed_id)-2]["article_date"])[:10], str(articles[0]["article_date"])[:10]) - - html += "

Recent articles

" - for article in articles[:10]: - if article["article_readed"] == False: - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - # display a heart for faved articles - if article["article_like"] == True: - like = """ """ - else: - like = "" - - # Descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - # Title of the article - article_title = article["article_title"] - if len(article_title) >= 110: - article_title = article_title[:110] + " ..." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s%s%s""" % \ - (feed["feed_id"], article["article_id"], not_read_begin, \ - article_title, not_read_end, description) + like + "
\n" - html += "
\n" - html += """All articles   """ % (feed["feed_id"],) - - favs = [article for article in articles if article["article_like"] == True] - if len(favs) != 0: - html += "

Your favorites articles for this feed

" - for article in favs: - if article["like"] == True: - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s
\n""" % \ - (feed["feed_id"], article["article_id"], article["article_title"][:150], description) - - - # This section enables the user to edit informations about - # the current feed: - # - feed logo; - # - feed name; - # - URL of the feed (not the site); - html += "
\n

Edit this feed

\n" - html += '\n\n
' + \ - '' + \ - """
\n""" % \ - (feed["feed_link"],) - html += '\n\n
' + \ - '' + \ - """
\n""" % \ - (feed["feed_link"],) - html += '\n\n
' + \ - '' + \ - """
\n""" % \ - (feed["feed_link"],) - - dic = {} - top_words = utils.top_words(articles = self.mongo.get_articles_from_collection(feed_id), n=50, size=int(word_size)) - html += "

Tag cloud

\n
\n" - # Tags cloud - html += 'Minimum size of a word:' - html += """
""" % (feed["feed_id"],) - html += """""" % (word_size,) - html += '
\n' - html += '
' + \ - utils.tag_cloud(top_words) + '
' - - html += "
" - html += "
" - html += htmlfooter - return html - - feed.exposed = True - - - def articles(self, feed_id): - """ - This page displays all articles of a feed. - """ - try: - feed = self.mongo.get_collection(feed_id) - articles = self.mongo.get_articles_from_collection(feed_id) - except KeyError: - return self.error_page("This feed do not exists.") - html = htmlheader() - html += htmlnav - html += """
\n""" - html += """Mark all articles from this feed as read""" % (feed_id,) - html += """
\n
\n""" % ("Feed:"+feed_id,) - html += "
\n" - html += self.create_list_of_feeds() - html += """
""" - html += """

Articles of the feed %s


""" % (feed["feed_title"],) - - for article in articles: - - if article["article_readed"] == False: - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - if article["article_like"] == True: - like = """ """ - else: - like = "" - - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s%s%s""" % \ - (feed_id, article["article_id"], not_read_begin, \ - article["article_title"][:150], not_read_end, description) + like + "
\n" - - html += """\n

All feeds

""" - html += "
\n" - html += htmlfooter - return html - - articles.exposed = True - - - def unread(self, feed_id=""): - """ - This page displays all unread articles of a feed. - """ - feeds = self.mongo.get_all_collections() - html = htmlheader() - html += htmlnav - html += """
""" - if self.mongo.nb_unread_articles() != 0: - - # List unread articles of all the database - if feed_id == "": - html += "

Unread article(s)

" - html += """\n
\nMark articles as read\n
\n""" - for feed in feeds: - new_feed_section = True - nb_unread = 0 - - # For all unread article of the current feed. - for article in self.mongo.get_articles_from_collection(feed["feed_id"], condition=("article_readed", False)): - nb_unread += 1 - if new_feed_section is True: - new_feed_section = False - html += """

%s

\n""" % \ - (feed["feed_id"], feed["site_link"], feed["feed_title"], feed["feed_link"], feed["feed_image"]) - - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s
\n""" % \ - (feed["feed_id"], article["article_id"], article["article_title"][:150], description) - - if nb_unread == self.mongo.nb_unread_articles(feed["feed_id"]): - html += """
\nMark all articles from this feed as read\n""" % \ - (feed["feed_id"],) - html += """
\nMark articles as read\n""" - - # List unread articles of a feed - else: - try: - feed = self.mongo.get_collection(feed_id) - except: - self.error_page("This feed do not exists.") - html += """

Unread article(s) of the feed %s

-
""" % (feed_id, feed["feed_title"]) - - # For all unread article of the feed. - for article in self.mongo.get_articles_from_collection(feed_id, condition=("article_readed", False)): - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s
\n""" % \ - (feed_id, article["article_id"], article["article_title"][:150], description) - - html += """
\nMark all as read""" % (feed_id,) - # No unread article - else: - html += '

No unread article(s)

\n
\nWhy not check for news?' - html += """\n

All feeds

""" - html += "
\n" - html += htmlfooter - return html - - unread.exposed = True - - - def history(self, query="all", m=""): - """ - This page enables to browse articles chronologically. - """ - feeds = self.mongo.get_all_collections() - html = htmlheader() - html += htmlnav - html += """
\n""" - - # Get the date from the tag cloud - # Format: /history/?query=year:2011-month:06 to get the - # list of articles of June, 2011. - if m != "": - query = """year:%s-month:%s""" % tuple(m.split('-')) - - if query == "all": - html += "

Search with tags cloud

\n" - html += "

Choose a year


\n" - if "year" in query: - the_year = query.split('-')[0].split(':')[1] - if "month" not in query: - html += "

Choose a month for " + the_year + "


\n" - if "month" in query: - the_month = query.split('-')[1].split(':')[1] - html += "

Articles of "+ calendar.month_name[int(the_month)] + \ - ", "+ the_year +".


\n" - - timeline = Counter() - for feed in feeds: - new_feed_section = True - for article in self.mongo.get_articles_from_collection(feed["feed_id"]): - - if query == "all": - timeline[str(article["article_date"]).split(' ')[0].split('-')[0]] += 1 - - elif query[:4] == "year": - - if str(article["article_date"]).split(' ')[0].split('-')[0] == the_year: - timeline[str(article["article_date"]).split(' ')[0].split('-')[1]] += 1 - - if "month" in query: - if str(article["article_date"]).split(' ')[0].split('-')[1] == the_month: - if article["article_readed"] == False: - # not readed articles are in bold - not_read_begin, not_read_end = "", "" - else: - not_read_begin, not_read_end = "", "" - - if article["article_like"] == True: - like = """ """ - else: - like = "" - # Descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - # Title of the article - article_title = article["article_title"] - if len(article_title) >= 110: - article_title = article_title[:110] + " ..." - - if new_feed_section is True: - new_feed_section = False - html += """

%s

\n""" % \ - (feed["feed_id"], feed["feed_link"], feed["feed_title"], feed["feed_link"], feed["feed_image"]) - - html += article["article_date"].strftime("%a %d (%H:%M:%S) ") + \ - """%s%s%s%s""" % \ - (feed["feed_id"], article["article_id"], not_read_begin, \ - article_title, not_read_end, description) + like + "
\n" - if query == "all": - query_string = "year" - elif "year" in query: - query_string = "year:" + the_year + "-month" - if "month" not in query: - html += '
' + \ - utils.tag_cloud([(elem, timeline[elem]) for elem in timeline.keys()], query_string) + '
' - html += '

Search with a month+year picker

\n' - html += '
\n\t\n\t\n
' - html += '
' - html += htmlfooter - return html - - history.exposed = True - - - def plain_text(self, target): - """ - Display an article in plain text (without HTML tags). - """ - try: - feed_id, article_id = target.split(':') - feed = self.mongo.get_collection(feed_id) - article = self.mongo.get_article(feed_id, article_id) - except: - return self.error_page("Bad URL. This article do not exists.") - html = htmlheader() - html += htmlnav - html += """
""" - html += """

%s from %s

\n
\n"""% \ - (article["article_title"], feed_id, feed["feed_title"]) - description = utils.clear_string(article["article_content"]) - if description: - html += description - else: - html += "No description available." - html += "\n
\n" + htmlfooter - return html - - plain_text.exposed = True - - - def error_page(self, message): - """ - Display a message (bad feed id, bad article id, etc.) - """ - html = htmlheader() - html += htmlnav - html += """
""" - html += """%s""" % message - html += "\n
\n" + htmlfooter - return html - - error_page.exposed = True - - - def mark_as_read(self, target=""): - """ - Mark one (or more) article(s) as read by setting the value of the field - 'article_readed' of the MongoDB database to 'True'. - """ - param, _, identifiant = target.partition(':') - - # Mark all articles as read. - if param == "": - self.mongo.mark_as_read(True, None, None) - # Mark all articles from a feed as read. - elif param == "Feed" or param == "Feed_FromMainPage": - self.mongo.mark_as_read(True, identifiant, None) - # Mark an article as read. - elif param == "Article": - self.mongo.mark_as_read(True, identifiant.split(':')[1], identifiant.split(':')[0]) - if param == "" or param == "Feed_FromMainPage": - return self.index() - elif param == "Feed": - return self.articles(identifiant) - - mark_as_read.exposed = True - - - def notifications(self): - """ - List all active e-mail notifications. - """ - html = htmlheader() - html += htmlnav - html += """
""" - feeds = self.mongo.get_all_collections(condition=("mail",True)) - if feeds != []: - html += "

You are receiving e-mails for the following feeds:

\n" - for feed in feeds: - html += """\t%s - Stop
\n""" % \ - (feed["feed_id"], feed["feed_title"], feed["feed_id"]) - else: - html += "

No active notifications.

\n" - html += """

Notifications are sent to: %s

""" % \ - (utils.mail_to, utils.mail_to) - html += "\n
\n" + htmlfooter - return html - - notifications.exposed = True - - - def mail_notification(self, param): - """ - Enable or disable to notifications of news for a feed. - """ - try: - action, feed_id = param.split(':') - feed = self.feeds[feed_id] - except: - return self.error_page("Bad URL. This feed do not exists.") - - return self.index() - - mail_notification.exposed = True - - - def like(self, param): - """ - Mark or unmark an article as favorites. - """ - try: - like, feed_id, article_id = param.split(':') - articles = self.mongo.get_article(feed_id, article_id) - except: - return self.error_page("Bad URL. This article do not exists.") - self.mongo.like_article("1"==like, feed_id, article_id) - return self.article(feed_id+":"+article_id) - - like.exposed = True - - - def favorites(self): - """ - List of favorites articles - """ - feeds = self.mongo.get_all_collections() - html = htmlheader() - html += htmlnav - html += """
""" - html += "

Your favorites articles

" - for feed in feeds: - new_feed_section = True - for article in self.mongo.get_articles_from_collection(feed["feed_id"]): - if article["article_like"] == True: - if new_feed_section is True: - new_feed_section = False - html += """

%s

\n""" % \ - (feed["feed_id"], feed["feed_link"], feed["feed_title"], feed["feed_link"], feed["feed_image"]) - - # descrition for the CSS ToolTips - article_content = utils.clear_string(article["article_content"]) - if article_content: - description = " ".join(article_content[:500].split(' ')[:-1]) - else: - description = "No description." - - # a description line per article (date, title of the article and - # CSS description tooltips on mouse over) - html += article["article_date"].ctime() + " - " + \ - """%s%s
\n""" % \ - (feed["feed_id"], article["article_id"], article["article_title"][:150], description) - html += "
\n" - html += htmlfooter - return html - - favorites.exposed = True - - - def add_feed(self, url): - """ - Add a new feed with the URL of a page. - """ - html = htmlheader() - html += htmlnav - html += """
""" - # search the feed in the HTML page with BeautifulSoup - feed_url = utils.search_feed(url) - if feed_url is None: - return self.error_page("Impossible to find a feed at this URL.") - # if a feed exists - else: - result = utils.add_feed(feed_url) - # if the feed is not in the file feed.lst - if result is False: - html += "

You are already following this feed!

" - else: - html += """

Feed added. You can now fetch your feeds.

""" - html += """\n
\nBack to the management page.
\n""" - html += "
\n" - html += htmlfooter - return html - - add_feed.exposed = True - - - def remove_feed(self, feed_id): - """ - Remove a feed from the file feed.lst and from the MongoDB database. - """ - html = htmlheader() - html += htmlnav - html += """
""" - - feed = self.mongo.get_collection(feed_id) - self.mongo.delete_feed(feed_id) - utils.remove_feed(feed["feed_link"]) - - html += """

All articles from the feed %s are now removed from the base.


""" % \ - (feed["feed_title"],) - html += """Back to the management page.
\n""" - html += "
\n" - html += htmlfooter - return html - - remove_feed.exposed = True - - - def change_feed_url(self, new_feed_url, old_feed_url): - """ - Enables to change the URL of a feed already present in the database. - """ - html = htmlheader() - html += htmlnav - html += """
""" - utils.change_feed_url(old_feed_url, new_feed_url) - html += "

The URL of the feed has been changed.

" - html += "
\n" - html += htmlfooter - return html - - change_feed_url.exposed = True - - def change_feed_name(self, feed_url, new_feed_name): - """ - Enables to change the name of a feed. - """ - html = htmlheader() - html += htmlnav - html += """
""" - utils.change_feed_name(feed_url, new_feed_name) - html += "

The name of the feed has been changed.

" - html += "
\n" - html += htmlfooter - return html - - change_feed_name.exposed = True - - def change_feed_logo(self, feed_url, new_feed_logo): - """ - Enables to change the name of a feed. - """ - html = htmlheader() - html += htmlnav - html += """
""" - utils.change_feed_logo(feed_url, new_feed_logo) - html += "

The logo of the feed has been changed.

" - html += "
\n" - html += htmlfooter - return html - - change_feed_logo.exposed = True - - - def set_max_articles(self, max_nb_articles=1): - """ - Enables to set the maximum of articles to be loaded per feed from - the data base. - """ - if max_nb_articles < -1 or max_nb_articles == 0: - max_nb_articles = 1 - utils.MAX_NB_ARTICLES = int(max_nb_articles) - return self.management() - - set_max_articles.exposed = True - - - def delete_article(self, param): - """ - Delete an article. - """ - try: - feed_id, article_id = param.split(':') - self.mongo.delete_article(feed_id, article_id) - except: - return self.error_page("Bad URL. This article do not exists.") - - return self.index() - - delete_article.exposed = True - - - def drop_base(self): - """ - Delete all articles. - """ - utils.drop_base() - return self.management() - - drop_base.exposed = True - - - def export(self, export_method): - """ - Export articles currently loaded from the MongoDB database with - the appropriate function of the 'export' module. - """ - try: - getattr(export, export_method)(self.feeds) - except Exception, e: - return self.error_page(e) - return self.management() - - export.exposed = True - - - def epub(self, param): - """ - Export an article to EPUB. - """ - try: - from epub import ez_epub - except Exception, e: - return self.error_page(e) - try: - feed_id, article_id = param.split(':') - except: - return self.error_page("Bad URL.") - try: - feed = self.feeds[feed_id] - article = feed.articles[article_id] - except: - self.error_page("This article do not exists.") - try: - folder = utils.path + "/var/export/epub/" - os.makedirs(folder) - except OSError: - # directories already exists (not a problem) - pass - section = ez_epub.Section() - section.title = article.article_title.decode('utf-8') - section.paragraphs = [utils.clear_string(article.article_description).decode('utf-8')] - ez_epub.makeBook(article.article_title.decode('utf-8'), [feed.feed_title.decode('utf-8')], [section], \ - os.path.normpath(folder) + "article.epub", lang='en-US', cover=None) - return self.article(param) - - epub.exposed = True - - -if __name__ == '__main__': - # Point of entry in execution mode - print "Launching pyAggr3g470r..." - - root = Root() - root.favicon_ico = cherrypy.tools.staticfile.handler(filename=os.path.join(utils.path + "/img/favicon.png")) - cherrypy.config.update({ 'server.socket_port': 12556, 'server.socket_host': "0.0.0.0"}) - cherrypy.config.update({'error_page.404': error_page_404}) - _cp_config = {'request.error_response': handle_error} - - cherrypy.quickstart(root, "/" ,config=utils.path + "/cfg/cherrypy.cfg") \ No newline at end of file -- cgit