aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf.py11
-rw-r--r--pyaggr3g470r/controllers/abstract.py4
-rw-r--r--pyaggr3g470r/templates/layout.html11
-rw-r--r--pyaggr3g470r/views/views.py92
4 files changed, 60 insertions, 58 deletions
diff --git a/conf.py b/conf.py
index 03ff23a2..05899bbb 100644
--- a/conf.py
+++ b/conf.py
@@ -1,11 +1,9 @@
#! /usr/bin/env python
-#-*- coding: utf-8 -*-
-
+# -*- coding: utf-8 -*-
""" Program variables.
This file contain the variables used by the application.
"""
-
import os
basedir = os.path.abspath(os.path.dirname(__file__))
@@ -29,7 +27,7 @@ DEFAULTS = {"python": "/usr/bin/python3.4",
"nb_worker": "100",
"default_max_error": "3",
"log_path": "pyaggr3g470r.log",
- "user_agent": "pyAggr3g470r " \
+ "user_agent": "pyAggr3g470r "
"(https://bitbucket.org/cedricbonhomme/pyaggr3g470r)",
"resolve_article_url": "false",
"http_proxy": "",
@@ -42,7 +40,7 @@ DEFAULTS = {"python": "/usr/bin/python3.4",
"host": "0.0.0.0",
"port": "5000",
"crawling_method": "classic",
-}
+ }
if not ON_HEROKU:
try:
@@ -105,7 +103,8 @@ else:
"(X11; Debian; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0"
RESOLVE_ARTICLE_URL = int(os.environ.get('RESOLVE_ARTICLE_URL', 0)) == 1
DEFAULT_MAX_ERROR = int(os.environ.get('DEFAULT_MAX_ERROR', 6))
- CRAWLING_METHOD = os.environ.get('CRAWLING_METHOD', DEFAULTS['crawling_method'])
+ CRAWLING_METHOD = os.environ.get('CRAWLING_METHOD',
+ DEFAULTS['crawling_method'])
WEBSERVER_DEBUG = False
WEBSERVER_HOST = '0.0.0.0'
diff --git a/pyaggr3g470r/controllers/abstract.py b/pyaggr3g470r/controllers/abstract.py
index 8f0a8e3f..29905c0c 100644
--- a/pyaggr3g470r/controllers/abstract.py
+++ b/pyaggr3g470r/controllers/abstract.py
@@ -25,7 +25,7 @@ class AbstractController(object):
each parameters of the function is treated as an equality unless the
name of the parameter ends with either "__gt", "__lt", "__ge", "__le",
- "__ne" or "__in".
+ "__ne", "__in" ir "__like".
"""
if self.user_id is not None:
filters[self._user_id_key] = self.user_id
@@ -43,6 +43,8 @@ class AbstractController(object):
db_filters.add(getattr(self._db_cls, key[:-4]) != value)
elif key.endswith('__in'):
db_filters.add(getattr(self._db_cls, key[:-4]).in_(value))
+ elif key.endswith('__like'):
+ db_filters.add(getattr(self._db_cls, key[:-6]).like(value))
else:
db_filters.add(getattr(self._db_cls, key) == value)
return db_filters
diff --git a/pyaggr3g470r/templates/layout.html b/pyaggr3g470r/templates/layout.html
index 484bbdc7..06567953 100644
--- a/pyaggr3g470r/templates/layout.html
+++ b/pyaggr3g470r/templates/layout.html
@@ -86,6 +86,7 @@
<li><a href="{{ url_for("profile") }}"><span class="glyphicon glyphicon-user"></span> {{ _('Profile') }}</a></li>
<li><a href="{{ url_for("management") }}"><span class="glyphicon glyphicon-cog"></span> {{ _('Your data') }}</a></li>
{% if g.user.is_admin() %}
+ <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span> {{ _('About') }}</a></li>
<li role="presentation" class="divider"></li>
<li><a href="{{ url_for("dashboard") }}"><span class="glyphicon glyphicon-dashboard"></span> {{ _('Dashboard') }}</a></li>
<li role="presentation" class="divider"></li>
@@ -101,9 +102,15 @@
</a>
<ul class="dropdown-menu">
<li>
- <form class="navbar-form" method=get action="/search" role="search">
+ <form class="navbar-form" method=get action="{{ url_for("search") }}" role="search">
<div class="input-group">
- <input type="text" class="form-control" name="query" placeholder="Search">
+ {% if filter_ %}<input type="hidden" name="filter_" value="{{ filter_ }}" />{% endif %}
+ {% if limit %}<input type="hidden" name="limit" value="{{ limit }}" />{% endif %}
+ <label for="search_title">{{ _("Title") }}</label>
+ <input type="checkbox" name="search_title" {% if search_title == 'on' or not (search_title == 'on' or search_content == 'on') %}checked{%endif%}/>
+ <label for="search_content">{{ _("Content") }}</label>
+ <input type="checkbox" name="search_content" {% if search_content == 'on' %}checked{%endif%}/>
+ <input type="text" class="form-control" name="query" placeholder="{{ _("Search") }}" {% if search_query %} value="{{ search_query }}"{% endif %} />
</div>
</form>
</li>
diff --git a/pyaggr3g470r/views/views.py b/pyaggr3g470r/views/views.py
index d0c06da0..83012d7c 100644
--- a/pyaggr3g470r/views/views.py
+++ b/pyaggr3g470r/views/views.py
@@ -235,13 +235,8 @@ def signup():
return render_template('signup.html', form=form)
-@app.route('/')
-@login_required
-def home(favorites=False):
- """
- Home page for connected users. Displays by default unread articles.
- """
- head_title = gettext('Favorites') if favorites else ''
+
+def render_home(filters={}, head_title='', page_to_render='home', **kwargs):
feed_contr = FeedController(g.user.id)
arti_contr = ArticleController(g.user.id)
feeds = {feed.id: feed.title for feed in feed_contr.read()}
@@ -250,14 +245,12 @@ def home(favorites=False):
in_error = {feed.id: feed.error_count for feed in
feed_contr.read(error_count__gt=2)}
- filter_ = request.args.get('filter_', 'all' if favorites else 'unread')
+ filter_ = request.args.get('filter_',
+ 'unread' if page_to_render == 'home' else 'all')
sort_ = request.args.get('sort_', 'date')
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:
@@ -271,12 +264,18 @@ def home(favorites=False):
limit = int(limit)
articles = articles.limit(limit)
- def gen_url(filter_=filter_, sort_=sort_, limit=limit, feed=feed_id):
- return url_for('favorites' if favorites else 'home',
- filter_=filter_, sort_=sort_, limit=limit, feed=feed)
+ def gen_url(filter_=filter_, sort_=sort_, limit=limit, feed=feed_id,
+ **kwargs):
+ if page_to_render == 'search':
+ kwargs['query'] = request.args.get('query', '')
+ kwargs['search_title'] = request.args.get('search_title', 'on')
+ kwargs['search_content'] = request.args.get('searc_content', 'off')
+ return url_for(page_to_render, filter_=filter_, sort_=sort_,
+ limit=limit, feed=feed, **kwargs)
articles = list(articles)
- if not articles and not favorites and feed_id:
+ if (page_to_render == 'home' and feed_id or page_to_render == 'search') \
+ and not articles:
return redirect(gen_url(filter_='all'))
if sort_ == "feed":
@@ -285,13 +284,40 @@ 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, favorites=favorites)
+ head_title=head_title, **kwargs)
+
+
+@app.route('/')
+@login_required
+def home():
+ "Home page for connected users. Displays by default unread articles."
+ return render_home()
@app.route('/favorites')
@login_required
def favorites():
- return home(favorites=True)
+ return render_home({'like': True}, gettext('Favorites'), 'favorites')
+
+
+@app.route('/search', methods=['GET'])
+@login_required
+def search():
+ "Search articles corresponding to the query."
+ if 'query' not in request.args:
+ flash(gettext("No text to search were provided."), "warning")
+ return render_home()
+ query = request.args['query']
+ filters = {}
+ search_title = request.args.get('search_title')
+ search_content = request.args.get('search_content')
+ if search_title == 'on':
+ filters['title__like'] = "%%%s%%" % query
+ if search_content == 'on':
+ filters['content__like'] = "%%%s%%" % query
+ return render_home(filters, "%s %s" % (gettext('Search:'), query),
+ 'search', search_query=query, search_title=search_title,
+ search_content=search_content)
@app.route('/fetch', methods=['GET'])
@@ -472,38 +498,6 @@ def export_opml():
response.headers['Content-Disposition'] = 'attachment; filename=feeds.opml'
return response
-@app.route('/search', methods=['GET'])
-@login_required
-def search():
- """
- Search articles corresponding to the query.
- """
- if conf.ON_HEROKU:
- flash(gettext("Full text search is not yet implemented for Heroku."), "warning")
- return redirect(url_for('home'))
- user = User.query.filter(User.id == g.user.id).first()
-
- search_result, result = [], []
- nb_articles = 0
-
- query = request.args.get('query', None)
- if query is not None:
- try:
- search_result, nb_articles = fastsearch.search(user.id, query)
- except Exception as e:
- flash(gettext('An error occured') + ' (%s).' % e, 'danger')
- light_feed = namedtuple('Feed', ['id', 'title', 'articles'], verbose=False, rename=False)
- for feed_id in search_result:
- for feed in user.feeds:
- if feed.id == feed_id:
- articles = []
- for article_id in search_result[feed_id]:
- current_article = Article.query.filter(Article.user_id == g.user.id, Article.id == article_id).first()
- articles.append(current_article)
- articles = sorted(articles, key=lambda t: t.date, reverse=True)
- result.append(light_feed(feed.id, feed.title, articles))
- break
- return render_template('search.html', feeds=result, nb_articles=nb_articles, query=query)
@app.route('/management', methods=['GET', 'POST'])
@login_required
bgstack15