added Pagination class, usage description in Pagination,__call__

added pagination.html, object_gallery.html as templates
This commit is contained in:
Bernhard Keller 2011-05-18 17:32:49 +02:00
parent 931f318cbc
commit ae85ed0f97
6 changed files with 183 additions and 16 deletions

View File

@ -23,14 +23,9 @@
{#- Should we outsource such a media 'gallery' view to it's own file? {#- Should we outsource such a media 'gallery' view to it's own file?
It could be useful for the home page and other views too -#} It could be useful for the home page and other views too -#}
<ul> <ul>
{%- for entry in media_entries %}
<li> {% include "mediagoblin/utils/object_gallery.html" %}
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
user= entry.uploader.username, m_id= entry._id) }}">
<img src="{{ request.app.public_store.file_url(
entry['media_files']['thumb']) }}" /></a>
</li>
{%- endfor %}
</ul> </ul>
{% else %} {% else %}
{# This *should* not occur as the view makes sure we pass in a user. #} {# This *should* not occur as the view makes sure we pass in a user. #}

View File

@ -0,0 +1,36 @@
{#
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011 Free Software Foundation, Inc
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
<div>
{% if media_entries %}
<ul>
{% for entry in media_entries %}
<li>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
user= entry.uploader.username, m_id= entry._id) }}">
<img src="{{ request.app.public_store.file_url(
entry['media_files']['thumb']) }}" /></a>
</li>
{% endfor %}
</ul>
{% import 'mediagoblin/utils/pagination.html' as paginationmacro %}
{{ paginationmacro.render_pagination(pagination) }}
{% endif %}
</div>

View File

@ -0,0 +1,41 @@
{# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011 Free Software Foundation, Inc
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% macro render_pagination(pagination) %}
{# only display if {{pagination}} is defined #}
{% if pagination %}
<div class=pagination>
{%- for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<a href={{pagination.url_generator(page)}}>{{ page }}</a>
{% else %}
<strong>{{ page }}</strong>
{% endif %}
{% else %}
<span class=ellipsis></span>
{% endif %}
{%- endfor %}
{% if pagination.has_next %}
<a href={{pagination.url_generator(pagination.page+1)}}>Next &raquo;</a>
{% endif %}
</div>
{% endif %}
{% endmacro %}

View File

@ -18,7 +18,7 @@ from webob import Response, exc
from pymongo import DESCENDING from pymongo import DESCENDING
from mongokit import ObjectId from mongokit import ObjectId
import wtforms import wtforms
from ..util import Pagination
def user_home(request): def user_home(request):
"""'Homepage' of a User()""" """'Homepage' of a User()"""
@ -28,18 +28,26 @@ def user_home(request):
if not user: if not user:
return exc.HTTPNotFound() return exc.HTTPNotFound()
medias = request.db.MediaEntry.find({ pagination = Pagination()
'uploader': user, media_entries = pagination(
'state': 'processed'}).sort('created', DESCENDING) { 'per_page': 2,
'request': request,
'collection':'MediaEntry',
'query': { 'uploader':user, 'state':'processed'} } )
#if no data is available, return NotFound
if media_entries == None:
return exc.HTTPNotFound()
template = request.template_env.get_template( template = request.template_env.get_template(
'mediagoblin/user_pages/user.html') 'mediagoblin/user_pages/user.html')
return Response( return Response(
template.render( template.render(
{'request': request, {'request': request,
'user': user, 'user': user,
'media_entries': medias})) 'media_entries': media_entries,
'pagination': pagination}))
def media_home(request): def media_home(request):
"""'Homepage' of a MediaEntry()""" """'Homepage' of a MediaEntry()"""
@ -58,3 +66,4 @@ def media_home(request):
template.render( template.render(
{'request': request, {'request': request,
'media': media})) 'media': media}))

View File

@ -26,6 +26,10 @@ import translitcodec
from mediagoblin import globals as mgoblin_globals from mediagoblin import globals as mgoblin_globals
import urllib
from pymongo import ASCENDING, DESCENDING
from math import ceil
TESTS_ENABLED = False TESTS_ENABLED = False
def _activate_testing(): def _activate_testing():
@ -290,3 +294,85 @@ def setup_gettext(locale):
mgoblin_globals.setup_globals( mgoblin_globals.setup_globals(
translations=this_gettext) translations=this_gettext)
class Pagination(object):
"""
Pagination class
"""
def __init__(self):
pass
def __call__(self, args):
"""
input values:
{'page': ..., --- requested page
'per_page': ..., --- objects per page
'request': ..., --- webob request object for url generation
'collection' ... --- db collection, thats to be queried
'query': {'user': xxx}, query restrictions, db.collection.find(query)
}
add:
option for sorting attribute
ascending, descending option
range based pagination
"""
self.per_page = args['per_page']
self.request = args['request']
try:
self.page = abs(int(args['request'].str_GET['page']))
# set default page, if page value is not set
except KeyError:
self.page = 1
# return None(404 Error) if page is set, but has no value or has an invalid value
except ValueError:
return None
######################################################
#
# db queries should be changed into range based pagination
# save count and current page in some user session data
#
######################################################
collection = getattr(self.request.db, args['collection'])
self.total_count = collection.find(args['query']).count()
#check if requested page is valid, not larger than available number of pages
if self.page > self.pages:
return None
return collection.find(args['query']).sort('created',DESCENDING) \
.skip((self.page-1)*self.per_page).limit(self.per_page)
@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 iter_pages(self, left_edge=2, left_current=2,
right_current=5, right_edge=2):
last = 0
for num in xrange(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_generator(self, page):
return '%s?%s' % (self.request.path_info, \
urllib.urlencode({'page':str(page)}))