From d6b34ceb21951d97fd978e66d03459749d6dea6e Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Wed, 25 Feb 2015 23:18:55 +0100 Subject: Removed the functionality for the email notifications of new articles. No real added value. --- README.rst | 4 +--- conf.py | 2 -- conf/conf.cfg-sample | 1 - ...b750a389c22_remove_email_notification_column.py | 22 ++++++++++++++++++++++ pyaggr3g470r/export.py | 1 - pyaggr3g470r/forms.py | 1 - pyaggr3g470r/models.py | 1 - pyaggr3g470r/notifications.py | 11 ----------- pyaggr3g470r/rest.py | 6 ------ pyaggr3g470r/templates/edit_feed.html | 5 ----- pyaggr3g470r/utils.py | 7 +++---- pyaggr3g470r/views.py | 3 +-- 12 files changed, 27 insertions(+), 37 deletions(-) create mode 100644 migrations/versions/1b750a389c22_remove_email_notification_column.py diff --git a/README.rst b/README.rst index 2fea7d11..2dd4db27 100644 --- a/README.rst +++ b/README.rst @@ -6,8 +6,7 @@ Presentation ============ `pyAggr3g470r `_ is a -web-based news aggregator. It can be deployed on Heroku or on a -traditional server. +web-based news aggregator. Features ======== @@ -18,7 +17,6 @@ Features * data liberation: export and import all your account with a JSON file; * export and import feeds with OPML files; * export articles to HTML; -* e-mail notification; * favorite articles; * detection of inactive feeds; * share articles with Google +, Pinboard and reddit; diff --git a/conf.py b/conf.py index 296f784d..16e71890 100644 --- a/conf.py +++ b/conf.py @@ -53,7 +53,6 @@ if not ON_HEROKU: WEBSERVER_PORT = int(config.get('webserver', 'port')) WEBSERVER_SECRET = config.get('webserver', 'secret') - NOTIFICATION_ENABLED = int(config.get('notification', 'enabled')) == 1 NOTIFICATION_EMAIL = config.get('notification', 'email') NOTIFICATION_HOST = config.get('notification', 'host') NOTIFICATION_PORT = int(config.get('notification', 'port')) @@ -83,7 +82,6 @@ else: WEBSERVER_PORT = int(os.environ.get('PORT', 5000)) WEBSERVER_SECRET = os.environ.get('SECRET_KEY', None) - NOTIFICATION_ENABLED = True NOTIFICATION_EMAIL = os.environ.get('NOTIFICATION_EMAIL', '') POSTMARK_API_KEY = os.environ.get('POSTMARK_API_KEY', '') diff --git a/conf/conf.cfg-sample b/conf/conf.cfg-sample index aab5ab5f..813b2ac2 100644 --- a/conf/conf.cfg-sample +++ b/conf/conf.cfg-sample @@ -17,7 +17,6 @@ host = 0.0.0.0 port = 5000 secret = a secret only you know [notification] -enabled = 0 email = pyAggr3g470r@no-reply.com host = smtp.googlemail.com port = 465 diff --git a/migrations/versions/1b750a389c22_remove_email_notification_column.py b/migrations/versions/1b750a389c22_remove_email_notification_column.py new file mode 100644 index 00000000..5ec748a8 --- /dev/null +++ b/migrations/versions/1b750a389c22_remove_email_notification_column.py @@ -0,0 +1,22 @@ +"""remove email_notification column + +Revision ID: 1b750a389c22 +Revises: 48f561c0ce6 +Create Date: 2015-02-25 23:01:07.253429 + +""" + +# revision identifiers, used by Alembic. +revision = '1b750a389c22' +down_revision = '48f561c0ce6' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.drop_column('feed', 'email_notification') + + +def downgrade(): + op.add_column('feed', sa.Column('email_notification', sa.Boolean(), default=False)) diff --git a/pyaggr3g470r/export.py b/pyaggr3g470r/export.py index f60bb3a9..5f54a0c1 100644 --- a/pyaggr3g470r/export.py +++ b/pyaggr3g470r/export.py @@ -212,7 +212,6 @@ def export_json(user): "description": feed.description, "link": feed.link, "site_link": feed.site_link, - "email_notification": feed.email_notification, "enabled": feed.enabled, "created_date": feed.created_date.strftime('%s'), "articles": [ { diff --git a/pyaggr3g470r/forms.py b/pyaggr3g470r/forms.py index 3e987082..58abb864 100644 --- a/pyaggr3g470r/forms.py +++ b/pyaggr3g470r/forms.py @@ -83,7 +83,6 @@ class AddFeedForm(Form): title = TextField(lazy_gettext("Title"), [validators.Optional()]) link = TextField(lazy_gettext("Feed link"), [validators.Optional()]) site_link = TextField(lazy_gettext("Site link")) - email_notification = BooleanField(lazy_gettext("Email notification"), default=False) enabled = BooleanField(lazy_gettext("Check for updates"), default=True) submit = SubmitField(lazy_gettext("Save")) diff --git a/pyaggr3g470r/models.py b/pyaggr3g470r/models.py index b7a75d5f..21e9ee34 100644 --- a/pyaggr3g470r/models.py +++ b/pyaggr3g470r/models.py @@ -105,7 +105,6 @@ class Feed(db.Model): description = db.Column(db.String(), default="FR") link = db.Column(db.String()) site_link = db.Column(db.String(), default="") - email_notification = db.Column(db.Boolean(), default=False) enabled = db.Column(db.Boolean(), default=True) created_date = db.Column(db.DateTime(), default=datetime.now) articles = db.relationship('Article', backref = 'source', lazy = 'dynamic', cascade='all,delete-orphan', diff --git a/pyaggr3g470r/notifications.py b/pyaggr3g470r/notifications.py index 8b6ff0c9..1acf782e 100644 --- a/pyaggr3g470r/notifications.py +++ b/pyaggr3g470r/notifications.py @@ -19,7 +19,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from pyaggr3g470r import utils from pyaggr3g470r import conf from pyaggr3g470r import emails @@ -59,13 +58,3 @@ def new_password_notification(user, password): (password, ) plaintext += "\n\nIt is advised to replace it as soon as connected to pyAggr3g470r.\n\nSee you," emails.send(to=user.email, bcc=conf.NOTIFICATION_EMAIL, subject="[pyAggr3g470r] New password", plaintext=plaintext) - -def new_article_notification(user, feed, article): - """ - New article notification. - """ - subject = '[pyAggr3g470r] ' + feed.title + ": " + article.title - html = """\n\n%s\n\n\n%s\n\n""" % \ - (feed.title + ": " + article.title, article.content) - plaintext = utils.clear_string(html) - emails.send(to=user.email, bcc=conf.NOTIFICATION_EMAIL, subject=subject, plaintext=plaintext, html=html) \ No newline at end of file diff --git a/pyaggr3g470r/rest.py b/pyaggr3g470r/rest.py index 6f5dd9b9..1f354167 100644 --- a/pyaggr3g470r/rest.py +++ b/pyaggr3g470r/rest.py @@ -237,7 +237,6 @@ class FeedListAPI(Resource): self.reqparse.add_argument('description', type = unicode, default = "", location = 'json') self.reqparse.add_argument('link', type = unicode, location = 'json') self.reqparse.add_argument('site_link', type = unicode, default = "", location = 'json') - self.reqparse.add_argument('email_notification', type = bool, default = False, location = 'json') self.reqparse.add_argument('enabled', type = bool, default = True ,location = 'json') super(FeedListAPI, self).__init__() @@ -251,7 +250,6 @@ class FeedListAPI(Resource): "description": feed.description, "link": feed.link, "site_link": feed.site_link, - "email_notification": feed.email_notification, "enabled": feed.enabled, "created_date": feed.created_date } @@ -271,7 +269,6 @@ class FeedListAPI(Resource): return jsonify({'message': 'missing argument: %s' % (k,)}) new_feed = Feed(title=feed_dict["title"], description=feed_dict["description"], link=feed_dict["link"], site_link=feed_dict["site_link"], - email_notification=feed_dict["email_notification"], enabled=feed_dict["enabled"]) g.user.feeds.append(new_feed) try: @@ -292,7 +289,6 @@ class FeedAPI(Resource): self.reqparse.add_argument('description', type = unicode, location = 'json') self.reqparse.add_argument('link', type = unicode, location = 'json') self.reqparse.add_argument('site_link', type = unicode, location = 'json') - self.reqparse.add_argument('email_notification', type = bool, location = 'json') self.reqparse.add_argument('enabled', type = bool ,location = 'json') super(FeedAPI, self).__init__() @@ -332,8 +328,6 @@ class FeedAPI(Resource): feed.link = args['link'] if None is not args.get('site_link', None): feed.site_link = args['site_link'] - if None is not args.get('email_notification', None): - feed.email_notification = args['email_notification'] if None is not args.get('enabled', None): feed.enabled = args['enabled'] db.session.commit() diff --git a/pyaggr3g470r/templates/edit_feed.html b/pyaggr3g470r/templates/edit_feed.html index f1a61b89..1238e257 100644 --- a/pyaggr3g470r/templates/edit_feed.html +++ b/pyaggr3g470r/templates/edit_feed.html @@ -15,11 +15,6 @@ {{ form.site_link.label }} {{ form.site_link(class_="form-control", placeholder="Optional") }} {% for error in form.site_link.errors %} {{ error }}
{% endfor %} - {% if not_on_heroku %} - {{ form.email_notification.label }} - {{ form.email_notification(class_="checkbox") }} - {% endif %} - {{ form.enabled.label }} {{ form.enabled(class_="checkbox") }} diff --git a/pyaggr3g470r/utils.py b/pyaggr3g470r/utils.py index c6264106..972909af 100755 --- a/pyaggr3g470r/utils.py +++ b/pyaggr3g470r/utils.py @@ -30,8 +30,7 @@ __license__ = "AGPLv3" # This file provides functions used for: # - the database management; # - generation of tags cloud; -# - HTML processing; -# - e-mail notifications. +# - HTML processing. # import re @@ -129,7 +128,7 @@ def import_opml(email, opml_content): new_feed = Feed(title=title, description=description, link=link, site_link=site_link, - email_notification=False, enabled=True) + enabled=True) user.feeds.append(new_feed) nb += 1 @@ -154,7 +153,7 @@ def import_json(email, json_content): continue new_feed = Feed(title=feed["title"], description="", link=feed["link"], \ - site_link=feed["site_link"], email_notification=feed["email_notification"], \ + site_link=feed["site_link"], \ created_date=datetime.datetime.fromtimestamp(int(feed["created_date"])), enabled=feed["enabled"]) user.feeds.append(new_feed) diff --git a/pyaggr3g470r/views.py b/pyaggr3g470r/views.py index f0422c3c..e5e07cde 100644 --- a/pyaggr3g470r/views.py +++ b/pyaggr3g470r/views.py @@ -656,8 +656,7 @@ def edit_feed(feed_id=None): existing_feed = [feed for feed in g.user.feeds if feed.link == form.link.data] if len(existing_feed) == 0: new_feed = Feed(title=form.title.data, description="", link=form.link.data, \ - site_link=form.site_link.data, email_notification=form.email_notification.data, \ - enabled=form.enabled.data) + site_link=form.site_link.data, enabled=form.enabled.data) g.user.feeds.append(new_feed) #user.feeds = sorted(user.feeds, key=lambda t: t.title.lower()) db.session.commit() -- cgit From 1db261d5eb8b07dfb96cc599edd997fa826b09f1 Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Thu, 26 Feb 2015 07:42:31 +0100 Subject: Release 6.2. The system of email notifications for new articles has been removed. --- NEWS.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 90b70512..730a3dec 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,5 +1,9 @@ pyAggr3g470r project news +6.2: 2015-02-26 + The system of email notifications for new articles has been removed. + This feature was hardly used. + 6.1: 2015-02-23 Improvements: articles are now identified with the id provided by the RSS/ATOM feed. -- cgit From 1894cfd312d4bd1c51b9ee63f25792f14dcfc665 Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Fri, 27 Feb 2015 07:52:19 +0100 Subject: Added a section about the requirements to the documentation. --- documentation/index.rst | 3 ++- documentation/requirements.rst | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 documentation/requirements.rst diff --git a/documentation/index.rst b/documentation/index.rst index d01dc583..947612a1 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -7,12 +7,13 @@ Welcome to pyAggr3g470r's documentation! ======================================== -Deployment and configuration +Configuration and deployment ============================ .. toctree:: :maxdepth: 2 + requirements deployment Web services diff --git a/documentation/requirements.rst b/documentation/requirements.rst new file mode 100644 index 00000000..a3630144 --- /dev/null +++ b/documentation/requirements.rst @@ -0,0 +1,16 @@ +Requirements +============ + +The complete list of required Python modules is in the file +``requirements.txt``. + +The core technologies used are: + +* `Flask `_ for the web backend; +* `asyncio `_ for the crawler; +* `SQLAlchemy `_ for the data base. + +Python 3.4 is highly recommended, especially for the feed crawler. +The web server is working with Python 2.7 and Python 3. + +It is possible to connect your own crawler to the RESTful API. -- cgit From c4fdfed1341fd6ae4bcb62939e599c2937680343 Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Fri, 27 Feb 2015 07:53:36 +0100 Subject: Updated version number in the documentation. --- documentation/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index b148de9d..00190f45 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -48,9 +48,9 @@ copyright = u'2015, Cédric Bonhomme' # built documents. # # The short X.Y version. -version = '6.0' +version = '6.2' # The full version, including alpha/beta/rc tags. -release = '6.0' +release = '6.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit From 2d05b4853ef8cf77389d99b7b6cd34f13986aa1e Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Sun, 1 Mar 2015 19:07:31 +0100 Subject: This is now useless. --- bootstrap.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/bootstrap.py b/bootstrap.py index d13d4799..85bac49b 100644 --- a/bootstrap.py +++ b/bootstrap.py @@ -1,18 +1,8 @@ # required imports and code exection for basic functionning -import sys -if 'threading' in sys.modules: - raise Exception('threading module loaded before patching!') import conf import logging -if not (conf.WEBSERVER_DEBUG or conf.ON_HEROKU): - import gevent.monkey - gevent.monkey.patch_thread() - - - - def set_logging(log_path, log_level=logging.INFO, log_format='%(asctime)s %(levelname)s %(message)s'): logger = logging.getLogger('pyaggr3g470r') -- cgit From e6692694aa5383f1c7aff3a00344575ea22065a7 Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Mon, 2 Mar 2015 08:13:47 +0100 Subject: Typo. --- pyaggr3g470r/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaggr3g470r/models.py b/pyaggr3g470r/models.py index 21e9ee34..8bc9e76b 100644 --- a/pyaggr3g470r/models.py +++ b/pyaggr3g470r/models.py @@ -98,7 +98,7 @@ class Role(db.Model): class Feed(db.Model): """ - Represent a station. + Represent a feed. """ id = db.Column(db.Integer, primary_key = True) title = db.Column(db.String(), default="No title") -- cgit