Add pager to browse page.

This commit is contained in:
Edward Betts 2019-09-29 20:19:40 +01:00
parent 146b79bde8
commit c2727e6fc8
5 changed files with 95 additions and 11 deletions

18
app.py
View file

@ -4,6 +4,7 @@ from flask import Flask, render_template, url_for, redirect, request, g, jsonify
from depicts import (utils, wdqs, commons, mediawiki, painting, saam, database, from depicts import (utils, wdqs, commons, mediawiki, painting, saam, database,
dia, rijksmuseum, npg, museodelprado, barnesfoundation, dia, rijksmuseum, npg, museodelprado, barnesfoundation,
wd_catalog) wd_catalog)
from depicts.pager import Pagination, init_pager
from depicts.model import DepictsItem, DepictsItemAltLabel, Edit, PaintingItem from depicts.model import DepictsItem, DepictsItemAltLabel, Edit, PaintingItem
from requests_oauthlib import OAuth1Session from requests_oauthlib import OAuth1Session
from urllib.parse import urlencode from urllib.parse import urlencode
@ -24,6 +25,7 @@ user_agent = 'Mozilla/5.0 (X11; Linux i586; rv:32.0) Gecko/20160101 Firefox/32.0
app = Flask(__name__) app = Flask(__name__)
app.config.from_object('config.default') app.config.from_object('config.default')
database.init_db(app.config['DB_URL']) database.init_db(app.config['DB_URL'])
init_pager(app)
find_more_props = { find_more_props = {
'P135': 'movement', 'P135': 'movement',
@ -664,20 +666,24 @@ def browse_page():
page_size = 45 page_size = 45
item_map = wdqs.build_browse_item_map(bindings) item_map = wdqs.build_browse_item_map(bindings)
items = []
all_items = []
for item in item_map.values(): for item in item_map.values():
if len(item['image_filename']) != 1: if len(item['image_filename']) != 1:
continue continue
item['image_filename'] = item['image_filename'][0] item['image_filename'] = item['image_filename'][0]
items.append(item) all_items.append(item)
if len(items) >= page_size:
break page = utils.get_int_arg('page') or 1
pager = Pagination(page, page_size, len(all_items))
items = pager.slice(all_items)
filenames = [cur['image_filename'] for cur in items] filenames = [cur['image_filename'] for cur in items]
thumbwidth = app.config['THUMBWIDTH'] thumbwidth = app.config['THUMBWIDTH']
filename = f'cache/{flat}_{page_size}_images.json' filename = f'cache/{flat}_{page}_{page_size}_images.json'
if os.path.exists(filename): if os.path.exists(filename):
detail = json.load(open(filename)) detail = json.load(open(filename))
else: else:
@ -694,6 +700,8 @@ def browse_page():
facets=facets, facets=facets,
prop_labels=find_more_props, prop_labels=find_more_props,
label=title, label=title,
pager=pager,
page=page,
labels=find_more_props, labels=find_more_props,
bindings=bindings, bindings=bindings,
total=len(bindings), total=len(bindings),

47
depicts/pager.py Normal file
View file

@ -0,0 +1,47 @@
from math import ceil
from flask import request, url_for
class Pagination(object):
def __init__(self, page, per_page, total_count):
self.page = page
self.per_page = per_page
self.total_count = total_count
@property
def pages(self):
return int(ceil(self.total_count / float(self.per_page)))
@property
def has_prev(self):
return self.page > 1
@property
def has_next(self):
return self.page < self.pages
def slice(self, items):
first = ((self.page - 1) * self.per_page)
last = self.page * self.per_page
return items[first:last]
def iter_pages(self, left_edge=2, left_current=6,
right_current=6, right_edge=2):
last = 0
for num in range(1, self.pages + 1):
if num <= left_edge or \
(num > self.page - left_current - 1 and \
num < self.page + right_current) or \
num > self.pages - right_edge:
if last + 1 != num:
yield None
yield num
last = num
def url_for_other_page(page):
args = request.view_args.copy()
args.update(request.args)
args['page'] = page
return url_for(request.endpoint, **args)
def init_pager(app):
app.jinja_env.globals['url_for_other_page'] = url_for_other_page

View file

@ -1,3 +1,4 @@
from flask import request
from itertools import islice from itertools import islice
import urllib.parse import urllib.parse
import inflect import inflect
@ -70,4 +71,6 @@ def wiki_url(title, site, ns=None):
return f'https://{host}/wiki/' + url_ns + urllib.parse.quote(title.replace(' ', '_')) return f'https://{host}/wiki/' + url_ns + urllib.parse.quote(title.replace(' ', '_'))
def get_int_arg(name):
if name in request.args and request.args[name].isdigit():
return int(request.args[name])

View file

@ -1,3 +1,4 @@
{% from "macro.html" import render_pagination %}
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ label }}{% endblock %} {% block title %}{{ label }}{% endblock %}
@ -51,11 +52,7 @@
{% endfor %} {% endfor %}
</div> </div>
{# {{ render_pagination(pager) }}
{% for item in items %}
<pre>{{ item | pprint }}</pre>
{% endfor %}
#}
</div> </div>
{% endblock %} {% endblock %}

29
templates/macro.html Normal file
View file

@ -0,0 +1,29 @@
{% macro render_pagination(pagination) %}
{% if pagination.pages > 1 %}
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if pagination.has_prev %}
<li class="page-item"><a class="page-link" href="{{ url_for_other_page(pagination.page - 1) }}">&laquo; Previous</a></li>
{% endif %}
{%- for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<li class="page-item"><a class="page-link" href="{{ url_for_other_page(page) }}">{{ page }}</a></li>
{% else %}
<li class="page-item active"><a class="page-link" href="{{ url_for_other_page(page) }}">{{ page }} <span class="sr-only">(current)</span></a></li>
{% endif %}
{% else %}
<li><span class="ellipsis"></span></li>
{% endif %}
{%- endfor %}
{% if pagination.has_next %}
<li class="page-item">
<a class="page-link" href="{{ url_for_other_page(pagination.page + 1) }}" aria-label="Next">
<span aria-hidden="true">Next &raquo;</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endmacro %}