From b343dc73e5ea4aaf1314b6b277c3806f15ac0635 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Wed, 8 Apr 2015 12:33:40 +0200 Subject: moving feed views related code in views.feed and massive use of url_for --- pyaggr3g470r/views/views.py | 80 ++------------------------------------------- 1 file changed, 2 insertions(+), 78 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 17d79cab..b329afae 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -249,8 +249,9 @@ def home(): .group_by(Article.feed_id).all() in_error = {feed.id: feed.error_count for feed in FeedController(g.user.id).read(error_count__gt=2).all()} + def gen_url(filter_=filter_, limit=limit, feed=feed_id): - return '?filter_=%s&limit=%s&feed=%d' % (filter_, limit, feed) + return url_for('home', filter_=filter_, limit=limit, feed=feed) return render_template('home.html', gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, unread=dict(unread), articles=articles.all(), @@ -283,7 +284,6 @@ def about(): @app.route('/mark_as/', methods=['GET']) -@app.route('/mark_as//feed/', methods=['GET']) @app.route('/mark_as//article/', methods=['GET']) @login_required @feed_access_required @@ -557,82 +557,6 @@ def history(year=None, month=None): articles=articles, year=year, month=month) -@app.route('/bookmarklet', methods=['GET']) -@app.route('/create_feed', methods=['GET', 'POST']) -@app.route('/edit_feed/', methods=['GET', 'POST']) -@login_required -@feed_access_required -def edit_feed(feed_id=None): - """ - Add or edit a feed. - """ - form = AddFeedForm() - - if request.method == 'POST': - if form.validate() == False: - return render_template('edit_feed.html', form=form) - if feed_id is not None: - # Edit an existing feed - feed = FeedController(g.user.id).get(id=feed_id) - form.populate_obj(feed) - if feed.enabled: - # set the error count to 0 - feed.error_count = 0 - feed.last_error = "" - db.session.commit() - flash(gettext('Feed successfully updated.'), 'success') - return redirect('/edit_feed/' + str(feed_id)) - else: - # Create a new feed - existing_feed = [f for f in g.user.feeds if f.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, enabled=form.enabled.data) - g.user.feeds.append(new_feed) - #user.feeds = sorted(user.feeds, key=lambda t: t.title.lower()) - db.session.commit() - flash(gettext('Feed successfully created.'), 'success') - - utils.fetch(g.user.id, Feed.query.filter(Feed.link == form.link.data).first().id) - flash(gettext("Downloading articles for the new feed..."), 'info') - - return redirect('/edit_feed/' + str(new_feed.id)) - else: - flash(gettext('Feed already in the database.'), 'warning') - return redirect('/edit_feed/' + str(existing_feed[0].id)) - - if request.method == 'GET': - if feed_id is not None: - feed = FeedController(g.user.id).get(id=feed_id) - form = AddFeedForm(obj=feed) - return render_template('edit_feed.html', action=gettext("Edit the feed"), form=form, feed=feed, \ - not_on_heroku = not conf.ON_HEROKU) - - # Enable the user to add a feed with a bookmarklet - if None is not request.args.get('url', None): - existing_feed = [f for f in g.user.feeds if feed.link == request.args.get('url', None)] - if len(existing_feed) == 0: - g.user.feeds.append(Feed(link=request.args.get('url', None))) - db.session.commit() - return jsonify({"message":"ok"}) - return jsonify({"message":"Feed already in the database."}) - - # Return an empty form in order to create a new feed - return render_template('edit_feed.html', action=gettext("Add a feed"), form=form, \ - not_on_heroku = not conf.ON_HEROKU) - -@app.route('/delete_feed/', methods=['GET']) -@login_required -@feed_access_required -def delete_feed(feed_id=None): - """ - Delete a feed with all associated articles. - """ - feed = Feed.query.filter(Feed.id == feed_id).first() - db.session.delete(feed) - db.session.commit() - flash(gettext('Feed') + ' ' + feed.title + ' ' + gettext('successfully deleted.'), 'success') - return redirect(redirect_url()) @app.route('/profile', methods=['GET', 'POST']) @login_required -- cgit From 5dfa537113c65a0596589c3683f7dba69323e8a7 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Wed, 8 Apr 2015 14:52:14 +0200 Subject: getting things out of the view a little more --- pyaggr3g470r/views/views.py | 48 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index b329afae..27dce8a9 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -34,25 +34,25 @@ import datetime from collections import namedtuple from bootstrap import application as app, db from flask import render_template, request, flash, session, \ - url_for, redirect, g, current_app, make_response, jsonify + url_for, redirect, g, current_app, make_response from flask.ext.login import LoginManager, login_user, logout_user, \ login_required, current_user, AnonymousUserMixin from flask.ext.principal import Principal, Identity, AnonymousIdentity, \ identity_changed, identity_loaded, Permission,\ RoleNeed, UserNeed from flask.ext.babel import gettext -from sqlalchemy import func, or_ +from sqlalchemy import or_ from sqlalchemy.exc import IntegrityError from werkzeug import generate_password_hash import conf from pyaggr3g470r import utils, notifications, export -from pyaggr3g470r import controllers from pyaggr3g470r.models import User, Feed, Article, Role from pyaggr3g470r.decorators import feed_access_required from pyaggr3g470r.forms import SignupForm, SigninForm, AddFeedForm, \ ProfileForm, InformationMessageForm, RecoverPasswordForm -from pyaggr3g470r.controllers import FeedController +from pyaggr3g470r.controllers import UserController, FeedController, \ + ArticleController if not conf.ON_HEROKU: import pyaggr3g470r.search as fastsearch @@ -93,7 +93,7 @@ def before_request(): @login_manager.user_loader def load_user(email): # Return an instance of the User model - return controllers.UserController().get(email=email) + return UserController().get(email=email) # @@ -153,7 +153,7 @@ def login(): form = SigninForm() if form.validate_on_submit(): - user = controllers.UserController().get(email=form.email.data) + user = UserController().get(email=form.email.data) login_user(user) g.user = user session['email'] = form.email.data @@ -229,32 +229,34 @@ def home(): """ Home page for connected users. Displays by default unread articles. """ - feeds = {feed.id: feed.title for feed in g.user.feeds} - articles = Article.query.filter(Article.feed_id.in_(feeds.keys()), - Article.user_id == g.user.id) + feed_contr = FeedController(g.user.id) + arti_contr = ArticleController(g.user.id) + feeds = {feed.id: feed.title for feed in feed_contr.read()} + + unread = arti_contr.get_unread() + in_error = {feed.id: feed.error_count for feed in + feed_contr.read(error_count__gt=2)} + filter_ = request.args.get('filter_', 'unread') feed_id = int(request.args.get('feed', 0)) limit = request.args.get('limit', 1000) + + filters = {} if filter_ != 'all': - articles = articles.filter(Article.readed == (filter_ == 'read')) + filters['readed'] = filter_ == 'read' if feed_id: - articles = articles.filter(Article.feed_id == feed_id) + filters['feed_id'] = feed_id - articles = articles.order_by(Article.date.desc()) + articles = arti_contr.read(**filters).order_by(Article.date.desc()) if limit != 'all': limit = int(limit) articles = articles.limit(limit) - unread = db.session.query(Article.feed_id, func.count(Article.id))\ - .filter(Article.readed == False, Article.user_id == g.user.id)\ - .group_by(Article.feed_id).all() - in_error = {feed.id: feed.error_count for feed in - FeedController(g.user.id).read(error_count__gt=2).all()} def gen_url(filter_=filter_, limit=limit, feed=feed_id): return url_for('home', filter_=filter_, limit=limit, feed=feed) return render_template('home.html', gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, - unread=dict(unread), articles=articles.all(), + unread=unread, articles=list(articles), in_error=in_error, default_max_error = conf.DEFAULT_MAX_ERROR) @@ -383,7 +385,7 @@ def inactives(): List of inactive feeds. """ nb_days = int(request.args.get('nb_days', 365)) - user = controllers.UserController(g.user.id).get(email=g.user.email) + user = UserController(g.user.id).get(email=g.user.email) today = datetime.datetime.now() inactives = [] for feed in user.feeds: @@ -430,7 +432,7 @@ def export_articles(): """ Export all articles to HTML or JSON. """ - user = controllers.UserController(g.user.id).get(id=g.user.id) + user = UserController(g.user.id).get(id=g.user.id) if request.args.get('format') == "HTML": # Export to HTML try: @@ -463,7 +465,7 @@ def export_opml(): """ Export all feeds to OPML. """ - user = controllers.UserController(g.user.id).get(id=g.user.id) + user = UserController(g.user.id).get(id=g.user.id) response = make_response(render_template('opml.xml', user=user, now=datetime.datetime.now())) response.headers['Content-Type'] = 'application/xml' @@ -564,7 +566,7 @@ def profile(): """ Edit the profile of the currently logged user. """ - user = controllers.UserController(g.user.id).get(id=g.user.id) + user = UserController(g.user.id).get(id=g.user.id) form = ProfileForm() if request.method == 'POST': @@ -590,7 +592,7 @@ def delete_account(): """ Delete the account of the user (with all its data). """ - user = controllers.UserController(g.user.id).get(id=g.user.id) + user = UserController(g.user.id).get(id=g.user.id) if user is not None: db.session.delete(user) db.session.commit() -- cgit From dcf258d6741254c2176b287e86435cbe46316a41 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Thu, 9 Apr 2015 11:56:27 +0200 Subject: auto redirect to the all including filter when landing on no result --- pyaggr3g470r/views/views.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 27dce8a9..fb2a5f87 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -254,10 +254,14 @@ def home(): def gen_url(filter_=filter_, limit=limit, feed=feed_id): return url_for('home', filter_=filter_, limit=limit, feed=feed) + + articles = list(articles) + if not articles: + return redirect(gen_url(filter_='all')) + return render_template('home.html', gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, - unread=unread, articles=list(articles), - in_error=in_error, + unread=unread, articles=articles, in_error=in_error, default_max_error = conf.DEFAULT_MAX_ERROR) -- cgit From 01ccc02384a8b11d7ef33db2e13195d1e27bf850 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sat, 11 Apr 2015 14:22:44 +0200 Subject: removing unread page --- pyaggr3g470r/views/views.py | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index fb2a5f87..ff33b576 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -363,24 +363,6 @@ def favorites(): nb_favorites += len(articles) return render_template('favorites.html', feeds=result, nb_favorites=nb_favorites) -@app.route('/unread/', methods=['GET']) -@app.route('/unread', methods=['GET']) -@login_required -def unread(feed_id=None): - """ - List unread articles. - """ - if feed_id is not None: - feeds_with_unread = Feed.query.filter(Feed.user_id == g.user.id, Feed.id == feed_id) - else: - feeds_with_unread = Feed.query.filter(Feed.user_id == g.user.id, Feed.articles.any(readed=False)) - result, nb_unread = [], 0 - light_feed = namedtuple('Feed', ['id', 'title', 'articles'], verbose=False, rename=False) - for feed in feeds_with_unread: - articles = Article.query.filter(Article.user_id == g.user.id, Article.feed_id == feed.id, Article.readed == False).all() - result.append(light_feed(feed.id, feed.title, articles)) - nb_unread += len(articles) - return render_template('unread.html', feeds=result, nb_unread=nb_unread) @app.route('/inactives', methods=['GET']) @login_required -- cgit From d8e46270e1a879ea9a5fda8852ad7ddede95695d Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sat, 11 Apr 2015 15:20:03 +0200 Subject: regrouping favorties and home, redoing the tab selection jscode --- pyaggr3g470r/views/views.py | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index ff33b576..623cf5d4 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -224,11 +224,14 @@ def signup(): return render_template('signup.html', form=form) @app.route('/') +@app.route('/favorites') @login_required def home(): """ Home page for connected users. Displays by default unread articles. """ + favorites = request.path.startswith('/favorites') + head_title = gettext('Favorites') if favorites else '' feed_contr = FeedController(g.user.id) arti_contr = ArticleController(g.user.id) feeds = {feed.id: feed.title for feed in feed_contr.read()} @@ -237,11 +240,13 @@ def home(): in_error = {feed.id: feed.error_count for feed in feed_contr.read(error_count__gt=2)} - filter_ = request.args.get('filter_', 'unread') + filter_ = request.args.get('filter_', 'all' if favorites else 'unread') feed_id = int(request.args.get('feed', 0)) limit = request.args.get('limit', 1000) filters = {} + if favorites: + filters['like'] = True if filter_ != 'all': filters['readed'] = filter_ == 'read' if feed_id: @@ -256,12 +261,13 @@ def home(): return url_for('home', filter_=filter_, limit=limit, feed=feed) articles = list(articles) - if not articles: + if not articles and not favorites: return redirect(gen_url(filter_='all')) return render_template('home.html', gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, unread=unread, articles=articles, in_error=in_error, + head_title=head_title, default_max_error = conf.DEFAULT_MAX_ERROR) @@ -348,22 +354,6 @@ def delete(article_id=None): return redirect(url_for('home')) -@app.route('/favorites', methods=['GET']) -@login_required -def favorites(): - """ - List favorites articles. - """ - feeds_with_like = Feed.query.filter(Feed.user_id == g.user.id, Feed.articles.any(like=True)) - result, nb_favorites = [], 0 - light_feed = namedtuple('Feed', ['id', 'title', 'articles'], verbose=False, rename=False) - for feed in feeds_with_like: - articles = Article.query.filter(Article.user_id == g.user.id, Article.feed_id == feed.id, Article.like == True).all() - result.append(light_feed(feed.id, feed.title, articles)) - nb_favorites += len(articles) - return render_template('favorites.html', feeds=result, nb_favorites=nb_favorites) - - @app.route('/inactives', methods=['GET']) @login_required def inactives(): -- cgit From 21da20f5d592aabcb60096768dcac76baa626315 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sat, 11 Apr 2015 16:14:19 +0200 Subject: first take on redoing the menu --- pyaggr3g470r/views/views.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 623cf5d4..3d3c47f6 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -224,13 +224,11 @@ def signup(): return render_template('signup.html', form=form) @app.route('/') -@app.route('/favorites') @login_required -def home(): +def home(favorites=False): """ Home page for connected users. Displays by default unread articles. """ - favorites = request.path.startswith('/favorites') head_title = gettext('Favorites') if favorites else '' feed_contr = FeedController(g.user.id) arti_contr = ArticleController(g.user.id) @@ -271,6 +269,12 @@ def home(): default_max_error = conf.DEFAULT_MAX_ERROR) +@app.route('/favorites') +@login_required +def favorties(): + return home(favorites=True) + + @app.route('/fetch', methods=['GET']) @app.route('/fetch/', methods=['GET']) @login_required -- cgit From 35a5e7466f7b78251eab82a7f6b060361333f206 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sat, 11 Apr 2015 16:17:25 +0200 Subject: no redirect from home if no feed has been tfiltered in --- pyaggr3g470r/views/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 3d3c47f6..512fdf06 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -259,7 +259,7 @@ def home(favorites=False): return url_for('home', filter_=filter_, limit=limit, feed=feed) articles = list(articles) - if not articles and not favorites: + if not articles and not favorites and feed_id: return redirect(gen_url(filter_='all')) return render_template('home.html', gen_url=gen_url, feed_id=feed_id, -- cgit From ea60cca948469daaff940698f27f3cb9a53300c3 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sun, 12 Apr 2015 14:28:03 +0200 Subject: making the favorites link switch to home when the displayed page is favorites --- pyaggr3g470r/views/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 512fdf06..4e610d63 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -265,13 +265,13 @@ def home(favorites=False): return render_template('home.html', gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, unread=unread, articles=articles, in_error=in_error, - head_title=head_title, + head_title=head_title, favorites=favorites, default_max_error = conf.DEFAULT_MAX_ERROR) @app.route('/favorites') @login_required -def favorties(): +def favorites(): return home(favorites=True) -- cgit From f9037d73297dc8d5ca862ae674075cb7580be4a4 Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sun, 12 Apr 2015 14:41:28 +0200 Subject: improving look and feel of home page --- pyaggr3g470r/views/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'pyaggr3g470r/views/views.py') diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py index 4e610d63..e06e1a9d 100644 --- a/pyaggr3g470r/views/views.py +++ b/pyaggr3g470r/views/views.py @@ -249,6 +249,9 @@ def home(favorites=False): filters['readed'] = filter_ == 'read' if feed_id: filters['feed_id'] = feed_id + if head_title: + head_title += ' - ' + head_title += feed_contr.get(id=feed_id).title articles = arti_contr.read(**filters).order_by(Article.date.desc()) if limit != 'all': @@ -256,7 +259,8 @@ def home(favorites=False): articles = articles.limit(limit) def gen_url(filter_=filter_, limit=limit, feed=feed_id): - return url_for('home', filter_=filter_, limit=limit, feed=feed) + return url_for('favorites' if favorites else 'home', + filter_=filter_, limit=limit, feed=feed) articles = list(articles) if not articles and not favorites and feed_id: -- cgit