Merge remote branch 'remotes/hanaku/pagination'
Conflicts: mediagoblin/user_pages/views.py
This commit is contained in:
commit
af4d0b5cb0
@ -44,3 +44,22 @@ def require_active_login(controller):
|
|||||||
return controller(request, *args, **kwargs)
|
return controller(request, *args, **kwargs)
|
||||||
|
|
||||||
return _make_safe(new_controller_func, controller)
|
return _make_safe(new_controller_func, controller)
|
||||||
|
|
||||||
|
|
||||||
|
def uses_pagination(controller):
|
||||||
|
"""
|
||||||
|
Check request GET 'page' key for wrong values
|
||||||
|
"""
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
page = int(request.str_GET['page'])
|
||||||
|
if page < 0:
|
||||||
|
return exc.HTTPNotFound()
|
||||||
|
except ValueError:
|
||||||
|
return exc.HTTPNotFound()
|
||||||
|
except KeyError:
|
||||||
|
request.str_GET['page'] = 1
|
||||||
|
|
||||||
|
return controller(request, *args, **kwargs)
|
||||||
|
|
||||||
|
return _make_safe(wrapper,controller)
|
||||||
|
@ -20,17 +20,10 @@
|
|||||||
{% if user %}
|
{% if user %}
|
||||||
<h1>User page for '{{ user.username }}'</h1>
|
<h1>User page for '{{ user.username }}'</h1>
|
||||||
|
|
||||||
{#- 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 -#}
|
|
||||||
<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. #}
|
||||||
|
36
mediagoblin/templates/mediagoblin/utils/object_gallery.html
Normal file
36
mediagoblin/templates/mediagoblin/utils/object_gallery.html
Normal 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/>.
|
||||||
|
#}
|
||||||
|
|
||||||
|
{% block object_gallery_content -%}
|
||||||
|
<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>
|
||||||
|
{% include "mediagoblin/utils/pagination.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
47
mediagoblin/templates/mediagoblin/utils/pagination.html
Normal file
47
mediagoblin/templates/mediagoblin/utils/pagination.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{# 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/>.
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# only display if {{pagination}} is defined #}
|
||||||
|
|
||||||
|
{% if pagination %}
|
||||||
|
<div class=pagination>
|
||||||
|
|
||||||
|
{% if pagination.has_prev %}
|
||||||
|
<a href={{ pagination.get_page_url(request.path_info,
|
||||||
|
pagination.page-1, request.GET) }}>« Prev</>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- for page in pagination.iter_pages() %}
|
||||||
|
{% if page %}
|
||||||
|
{% if page != pagination.page %}
|
||||||
|
<a href={{ pagination.get_page_url(request.path_info,
|
||||||
|
page, request.GET) }}>{{ page }}</a>
|
||||||
|
{% else %}
|
||||||
|
<strong>{{ page }}</strong>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class=ellipsis>…</span>
|
||||||
|
{% endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
|
||||||
|
{% if pagination.has_next %}
|
||||||
|
<a href={{ pagination.get_page_url(request.path_info,
|
||||||
|
pagination.page+1, request.GET) }}>Next »</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
from webob import Response, exc
|
from webob import Response, exc
|
||||||
from mediagoblin.db.util import ObjectId, DESCENDING
|
from mediagoblin.db.util import ObjectId, DESCENDING
|
||||||
|
from mediagoblin.util import Pagination
|
||||||
|
|
||||||
|
from mediagoblin.decorators import uses_pagination
|
||||||
|
|
||||||
|
@uses_pagination
|
||||||
def user_home(request):
|
def user_home(request):
|
||||||
"""'Homepage' of a User()"""
|
"""'Homepage' of a User()"""
|
||||||
user = request.db.User.find_one({
|
user = request.db.User.find_one({
|
||||||
@ -26,18 +29,27 @@ def user_home(request):
|
|||||||
if not user:
|
if not user:
|
||||||
return exc.HTTPNotFound()
|
return exc.HTTPNotFound()
|
||||||
|
|
||||||
medias = request.db.MediaEntry.find({
|
cursor = request.db.MediaEntry \
|
||||||
'uploader': user,
|
.find({'uploader': user, 'state': 'processed'}) \
|
||||||
'state': 'processed'}).sort('created', DESCENDING)
|
.sort('created', DESCENDING)
|
||||||
|
|
||||||
|
|
||||||
|
pagination = Pagination( int(request.str_GET['page']), cursor)
|
||||||
|
media_entries = pagination()
|
||||||
|
|
||||||
|
#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()"""
|
||||||
@ -56,3 +68,4 @@ def media_home(request):
|
|||||||
template.render(
|
template.render(
|
||||||
{'request': request,
|
{'request': request,
|
||||||
'media': media}))
|
'media': media}))
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@ import translitcodec
|
|||||||
|
|
||||||
from mediagoblin import globals as mgoblin_globals
|
from mediagoblin import globals as mgoblin_globals
|
||||||
|
|
||||||
|
import urllib
|
||||||
|
from math import ceil
|
||||||
|
import copy
|
||||||
|
import decorators
|
||||||
|
from webob import exc
|
||||||
|
|
||||||
TESTS_ENABLED = False
|
TESTS_ENABLED = False
|
||||||
def _activate_testing():
|
def _activate_testing():
|
||||||
@ -290,3 +295,66 @@ def setup_gettext(locale):
|
|||||||
|
|
||||||
mgoblin_globals.setup_globals(
|
mgoblin_globals.setup_globals(
|
||||||
translations=this_gettext)
|
translations=this_gettext)
|
||||||
|
|
||||||
|
|
||||||
|
class Pagination(object):
|
||||||
|
"""
|
||||||
|
Pagination class,
|
||||||
|
initialization through __init__(self, cursor, page=1, per_page=2):
|
||||||
|
get actual data slice through __call__()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page, cursor, per_page=2):
|
||||||
|
"""
|
||||||
|
initializes Pagination
|
||||||
|
-- page, requested page
|
||||||
|
-- per_page, number of objects per page
|
||||||
|
-- cursor, db cursor
|
||||||
|
"""
|
||||||
|
self.page = page
|
||||||
|
self.per_page = per_page
|
||||||
|
self.cursor = cursor
|
||||||
|
self.total_count = self.cursor.count()
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
"""
|
||||||
|
returns slice of objects for the requested page
|
||||||
|
"""
|
||||||
|
return self.cursor.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 get_page_url(self, path_info, page_no, get_params=None):
|
||||||
|
"""
|
||||||
|
Get a new page based of the path_info, the new page number,
|
||||||
|
and existing get parameters.
|
||||||
|
"""
|
||||||
|
new_get_params = copy.copy(get_params or {})
|
||||||
|
new_get_params['page'] = page_no
|
||||||
|
return "%s?%s" % (
|
||||||
|
path_info, urllib.urlencode(new_get_params))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user