From 0f7ad3962d5d1068bb6f29943c7bce0e6a6e8483 Mon Sep 17 00:00:00 2001 From: ael-code Date: Thu, 10 Mar 2016 22:23:51 +0100 Subject: [PATCH 1/5] web gui: drop usage of js to make list item clickable on `search.html` and `recents.html` pages we were using javascript to make item of list of the results clickable. This was causing some problems: - right click on div did not show any link - ctrl-click did not open another page on firefox - ctrl-clcik on the title was opening two pages :) Now we've drop js for this job and we simply wrap the item
with an block. --- webant/static/item_list.css | 7 ++++++- webant/static/js/ui-main.js | 3 --- webant/templates/recents.html | 13 ++++++------- webant/templates/search.html | 21 ++++++++------------- 4 files changed, 20 insertions(+), 24 deletions(-) delete mode 100644 webant/static/js/ui-main.js diff --git a/webant/static/item_list.css b/webant/static/item_list.css index 5ac230c..fa2bae9 100644 --- a/webant/static/item_list.css +++ b/webant/static/item_list.css @@ -26,10 +26,15 @@ .meta-list .glyphicon{ margin-right: 4px; } -#item-list .item-div:first-of-type{ +#item-list > a:nth-child(1) > .item-div:nth-child(1) { border-top: 1px solid #EEE; } +#item-list > a, #item-list > a:hover { + color: #232323; + text-decoration: none; +} + #item-list .item-div{ border-bottom: 1px solid #EEE; margin: 0px; diff --git a/webant/static/js/ui-main.js b/webant/static/js/ui-main.js deleted file mode 100644 index e64bfd9..0000000 --- a/webant/static/js/ui-main.js +++ /dev/null @@ -1,3 +0,0 @@ -$( ".dyn-href" ).click(function() { - window.location.href = $(this).attr('href'); -}); diff --git a/webant/templates/recents.html b/webant/templates/recents.html index c47e7e0..34b7712 100644 --- a/webant/templates/recents.html +++ b/webant/templates/recents.html @@ -45,20 +45,19 @@

{%trans%}Recently added items{%endtrans%}

{% for b in items %} -
+ + + {% endfor %}
@@ -92,5 +92,4 @@

{%trans%}Recently added items{%endtrans%}

$(this).text(date.toLocaleString()); }); - {% endblock scripts %} diff --git a/webant/templates/search.html b/webant/templates/search.html index dd4109f..55dda37 100644 --- a/webant/templates/search.html +++ b/webant/templates/search.html @@ -28,11 +28,11 @@ {% block content %}
- + - +
{% trans num = books|length%}{{num}} result was found for{%pluralize%}{{num}} results were found for{% endtrans %} {{ query }}
@@ -50,20 +50,19 @@
{% for b in books %} - {% endif %}
{% endblock content %} - -{% block scripts %} - {{super()}} - -{% endblock scripts %} From 68827ef45aee3a03b23a5a23ef58667886e4c671 Mon Sep 17 00:00:00 2001 From: ael-code Date: Sun, 13 Mar 2016 19:01:37 +0100 Subject: [PATCH 2/5] webant: enable pagination on search page. --- webant/templates/search.html | 34 ++++++++++++++++++++++++++++++++- webant/util.py | 32 +++++++++++++++++++++++++++++++ webant/webant.py | 37 +++++++++++++++++++++++++++++++++--- 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/webant/templates/search.html b/webant/templates/search.html index 55dda37..8a179b3 100644 --- a/webant/templates/search.html +++ b/webant/templates/search.html @@ -34,7 +34,7 @@
- {% trans num = books|length%}{{num}} result was found for{%pluralize%}{{num}} results were found for{% endtrans %} {{ query }} + {% trans num = total%}{{num}} result was found for{%pluralize%}{{num}} results were found for{% endtrans %} {{ query }}
{% if not books %} @@ -80,6 +80,38 @@ {% endfor %}
+ + {% if pagination %} +
+ {% set search_url = ("%s?q=%s&size=%d&page=" | format(url_for('search'), query, size)) %} + +
+ {% endif %} + {% endif %}
{% endblock content %} diff --git a/webant/util.py b/webant/util.py index 574e605..bd33d41 100644 --- a/webant/util.py +++ b/webant/util.py @@ -98,6 +98,38 @@ def add_routes(fapp, routes, prefix=""): fapp.add_url_rule(**r) +def get_centered_pagination(current, total, visible=5): + ''' Return the range of pages to render in a pagination menu. + + The current page is always kept in the middle except + for the edge cases. + + Reeturns a dict + { prev, first, current, last, next } + + :param current: the current page + :param total: total number of pages available + :param visible: number of pages visible + ''' + inc = visible/2 + first = current - inc + last = current + inc + if (total <= visible): + first = 1 + last = total + elif (last > total): + first = total - (visible-1) + last = total + elif (first < 1): + first = 1 + last = visible + return dict(prev = current-1 if(current > 1) else None, + first=first, + current = current, + last=last, + next = current+1 if(current < total) else None) + + class AuthtFromSession(Authenticator): USERID_KEY = 'user_id' diff --git a/webant/webant.py b/webant/webant.py index cbbfdc6..d25be45 100644 --- a/webant/webant.py +++ b/webant/webant.py @@ -68,7 +68,9 @@ def __init__(self, import_name, conf={}): defaults = { 'BOOTSTRAP_SERVE_LOCAL': True, 'AGHERANT_DESCRIPTIONS': [], - 'API_URL': "/api/v1" + 'API_URL': '/api/v1', + 'RESULTS_PER_PAGE': 30, + 'MAX_RESULTS_PER_PAGE': 100 } defaults.update(conf) super(LibreantViewApp, self).__init__(import_name, defaults) @@ -98,7 +100,31 @@ def search(): query = request.args.get('q', None) if query is None: return renderErrorPage(message='No query given', httpCode=400) - res = app.archivant._db.user_search(query)['hits']['hits'] + + try: + page = int(request.args.get('page', 1)) + except ValueError: + return renderErrorPage(message='Invalid page number', httpCode=400) + if(page < 1): + return renderErrorPage(message='Invalid page number', httpCode=400) + + try: + size = int(request.args.get('size', app.config['RESULTS_PER_PAGE'])) + except ValueError: + return renderErrorPage(message='Invalid size number', httpCode=400) + if(size < 1 or size > app.config['MAX_RESULTS_PER_PAGE']): + return renderErrorPage(message='Invalid size number', httpCode=400) + + from_ = (page-1)*size + res = app.archivant._db.get_books_querystring(query, from_=from_, size=size) + totalRes = res['hits']['total'] + totalPages = (totalRes == 0) + totalRes/size + (totalRes % size > 0) + if(page > totalPages): + return renderErrorPage(message='Page number too high, maximum is {}'.format(totalPages), httpCode=400) + pagination=util.get_centered_pagination(current=page, total=totalPages) + if pagination['first'] == pagination['last']: + pagination = None + res = res['hits']['hits'] books = [] for b in res: src = b['_source'] @@ -109,7 +135,12 @@ def search(): ['text/html', 'text/xml', 'application/rss+xml', 'opensearch']) if (not format) or (format is 'text/html'): - return render_template('search.html', books=books, query=query) + return render_template('search.html', + books=books, + query=query, + total=totalRes, + pagination=pagination, + size=size) elif format in ['opensearch', 'text/xml', 'application/rss+xml']: return Response(render_template('opens.xml', books=books, query=query), From 6915e34c60e10f18dcc8cdcabff3dd804a398319 Mon Sep 17 00:00:00 2001 From: ael-code Date: Sun, 13 Mar 2016 19:19:01 +0100 Subject: [PATCH 3/5] wrap pagination template inside a jinjia macro --- webant/templates/pagination.html | 27 +++++++++++++++++++++++ webant/templates/search.html | 38 +++++++++----------------------- 2 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 webant/templates/pagination.html diff --git a/webant/templates/pagination.html b/webant/templates/pagination.html new file mode 100644 index 0000000..5573023 --- /dev/null +++ b/webant/templates/pagination.html @@ -0,0 +1,27 @@ +{% macro pagination(prev, first, current, last, next, target_url) %} + +{% endmacro %} diff --git a/webant/templates/search.html b/webant/templates/search.html index 8a179b3..ee9ed5a 100644 --- a/webant/templates/search.html +++ b/webant/templates/search.html @@ -82,34 +82,16 @@ {% if pagination %} -
- {% set search_url = ("%s?q=%s&size=%d&page=" | format(url_for('search'), query, size)) %} - -
+ {% set search_url = ("%s?q=%s&size=%d&page=" | format(url_for('search'), query, size))+"%d" %} + {% import 'pagination.html' as pag %} +
+ {{ pag.pagination(pagination['prev'], + pagination['first'], + pagination['current'], + pagination['last'], + pagination['next'], + target_url = search_url) }} +
{% endif %} {% endif %} From 9b6f58c45005829a4257aa863c6b11e08c03c2cd Mon Sep 17 00:00:00 2001 From: ael-code Date: Mon, 14 Mar 2016 02:02:21 +0100 Subject: [PATCH 4/5] pagination: added support for rel=(prev|next) This allows bot to understand which is the following page Additional details can be found here: https://support.google.com/webmasters/answer/1663744 --- webant/templates/pagination.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webant/templates/pagination.html b/webant/templates/pagination.html index 5573023..184c27c 100644 --- a/webant/templates/pagination.html +++ b/webant/templates/pagination.html @@ -3,7 +3,7 @@
    {% if prev %}
  • - +
  • @@ -17,7 +17,7 @@ {% endfor %} {% if next %}
  • - +
  • From 770ba4c67177fa884de8e085677c4578bc6e57fe Mon Sep 17 00:00:00 2001 From: ael-code Date: Mon, 14 Mar 2016 11:58:45 +0100 Subject: [PATCH 5/5] expose RESULTS_PER_PAGE default configuration --- conf/defaults.py | 3 ++- webant/api/archivant_api.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/defaults.py b/conf/defaults.py index 7ea0251..9701549 100644 --- a/conf/defaults.py +++ b/conf/defaults.py @@ -10,7 +10,8 @@ 'PRESET_PATHS': ([], "list of paths where to look for presets definition"), 'AGHERANT_DESCRIPTIONS': (None, "list of description urls of nodes to aggregate"), 'BOOTSTRAP_SERVE_LOCAL': (True, "decide to serve bootstrap related files as local content"), - 'MAX_RESULTS_PER_PAGE': (50, "number of max results for one request"), + 'RESULTS_PER_PAGE': (30, "number of results displayed per page"), + 'MAX_RESULTS_PER_PAGE': (100, "maximum number of results that can be delivered to one request"), 'USERS_DATABASE': (None, "url of the database used for users managment"), 'PWD_SALT_SIZE': (16, "size of the salt used by password hashing algorithm"), 'PWD_ROUNDS': (pbkdf2_sha256.default_rounds, "number of rounds runs by password hashing algorithm") diff --git a/webant/api/archivant_api.py b/webant/api/archivant_api.py index 66b6dd6..82b8d88 100644 --- a/webant/api/archivant_api.py +++ b/webant/api/archivant_api.py @@ -24,7 +24,7 @@ def get_volumes(): size = int(request.args.get('size', 10)) except ValueError: raise ApiError("Bad Request", 400, details="could not covert 'size' parameter to number") - if size > current_app.config.get('MAX_RESULTS_PER_PAGE', 50): + if size > current_app.config['MAX_RESULTS_PER_PAGE']: raise ApiError("Request Entity Too Large", 413, details="'size' parameter is too high") q_res = current_app.archivant._db.get_books_querystring(query=q, from_=from_, size=size)