# HG changeset patch # User Pawel Solyga # Date 1242383821 -7200 # Node ID 71a5bc0f0398b746738a1bf3e27836acd0f644a6 # Parent e8262ca32109ce9675cd1eb6fdd302f22ad6cea5 Revert not finished 1000 limitation fix commit (ef7222d484). We are going to put this into separate branch until it's finished. diff -r e8262ca32109 -r 71a5bc0f0398 app/soc/views/helper/lists.py --- a/app/soc/views/helper/lists.py Tue May 12 15:52:53 2009 +0200 +++ b/app/soc/views/helper/lists.py Fri May 15 12:37:01 2009 +0200 @@ -22,6 +22,7 @@ '"Pawel Solyga" ', ] +import logging from soc.logic import dicts from soc.logic.models.user import logic as user_logic @@ -60,8 +61,6 @@ OFFSET_KEY = 'offset_%d' LIMIT_KEY = 'limit_%d' -OFFSET_LINKID_KEY = 'offset_linkid_%d' -REVERSE_DIRECTION_KEY = 'reverse_sort_direction_%d' def makeOffsetKey(limit_idx): @@ -72,14 +71,6 @@ return LIMIT_KEY % limit_idx -def makeOffsetLinkidKey(limit_idx): - return OFFSET_LINKID_KEY % limit_idx - - -def makeReverseDirectionKey(limit_idx): - return REVERSE_DIRECTION_KEY % limit_idx - - def getListParameters(request, list_index): """Retrieves, converts and validates values for one list @@ -119,44 +110,30 @@ else: limit = min(DEF_MAX_PAGINATION, limit) - result = dict(limit=limit, offset=offset) - offset_linkid = request.GET.get(makeOffsetLinkidKey(list_index), - '') - # TODO(dbentley): URL unescape - result['offset_linkid'] = offset_linkid - - reverse_direction = makeReverseDirectionKey(list_index) in request.GET - result['reverse_direction'] = reverse_direction - - return result + return dict(limit=limit, offset=offset) -class LinkCreator(object): - """A way to create links for a page. +def generateLinkFromGetArgs(request, offset_and_limits): + """Constructs the get args for the url. """ - def __init__(self, request, list_idx, limit): - self.path = request.path - self.base_params = dict( - i for i in request.GET.iteritems() if - i[0].startswith('offset_') or i[0].startswith('limit_')) - self.idx = list_idx - self.base_params[makeLimitKey(self.idx)] = limit + + args = ["%s=%s" % (k, v) for k, v in offset_and_limits.iteritems()] + link_suffix = '?' + '&'.join(args) + + return request.path + link_suffix + - def create(self, offset_linkid=None, export=False, reverse_direction=False): - params = self.base_params.copy() - if offset_linkid is not None: - # TODO(dbentley): URL encode - if offset_linkid == '': - try: - del params[makeOffsetLinkidKey(self.idx)] - except KeyError: - pass - else: - params[makeOffsetLinkidKey(self.idx)]=offset_linkid - if reverse_direction: - params[makeReverseDirectionKey(self.idx)]=True - link_suffix = '&'.join('%s=%s' % (k, v) for k, v in params.iteritems()) - return '%s?%s' % (self.path, link_suffix) +def generateLinkForRequest(request, base_params, updated_params): + """Create a link to the same page as request but with different params + + Params: + request: the request for the page + base_params: the base parameters + updated_params: the parameters to update + """ + params = base_params.copy() + params.update(updated_params) + return generateLinkFromGetArgs(request, params) def getListContent(request, params, filter=None, order=None, @@ -197,36 +174,13 @@ # as we only use this logic for getForFields, which is never overridden logic = params['logic'] - limit_key = makeLimitKey(idx) - # offset_key = makeOffsetKey(idx) - # offset_linkid_key = makeOffsetLinkidKey(idx) - # reverse_direction_key = makeReverseDirectionKey(idx) + limit_key, offset_key = makeLimitKey(idx), makeOffsetKey(idx) list_params = getListParameters(request, idx) limit, offset = list_params['limit'], list_params['offset'] - offset_linkid = list_params['offset_linkid'] - reverse_direction = list_params['reverse_direction'] pagination_form = makePaginationForm(request, list_params['limit'], limit_key) - if offset_linkid: - if filter is None: - filter = {} - - if reverse_direction: - filter['link_id <'] = offset_linkid - else: - filter['link_id >'] = offset_linkid - - if order is None: - order = [] - if reverse_direction: - order.append('-link_id') - else: - order.append('link_id') - - - # Fetch one more to see if there should be a 'next' link data = logic.getForFields(filter=filter, limit=limit+1, offset=offset, order=order) @@ -235,61 +189,46 @@ return None more = len(data) > limit - if reverse_direction: - data.reverse() + + if more: + del data[limit:] + + newest = next = prev = export_link = '' + + base_params = dict(i for i in request.GET.iteritems() if + i[0].startswith('offset_') or i[0].startswith('limit_')) + + if params.get('list_key_order'): + export_link = generateLinkForRequest(request, base_params, {'export' : idx}) if more: - if reverse_direction: - data = data[1:] - else: - data = data[:limit] - - should_have_next_link = True - if not reverse_direction and not more: - should_have_next_link = False + # TODO(dbentley): here we need to implement a new field "last_key" + next = generateLinkForRequest(request, base_params, {offset_key : offset+limit, + limit_key : limit}) - # Calculating should_have_previous_link is tricky. It's possible we could - # be creating a previous link to a page that would have 0 entities. - # That would be suboptimal; what's a better way? - should_have_previous_link = False - if offset_linkid: - should_have_previous_link = True - if reverse_direction and not more: - should_have_previous_link = False + if offset > 0: + # TODO(dbentley): here we need to implement previous in the good way. + prev = generateLinkForRequest(request, base_params, + { offset_key : max(0, offset-limit), + limit_key : limit }) - if data: - first_displayed_item = data[0] - last_displayed_item = data[-1] - else: - class Dummy(object): - pass - first_displayed_item = last_displayed_item = Dummy() - first_displayed_item.link_id = None - newest = next = prev = export_link = '' - - link_creator = LinkCreator(request, idx, limit) + if offset > limit: + # Having a link to the first doesn't make sense on the first page (we're on + # it). It also doesn't make sense on the second page (because the first + # page is the previous page). - if params.get('list_key_order'): - export_link = link_creator.create(export=True) - - if should_have_next_link: - next = link_creator.create(offset_linkid=last_displayed_item.link_id) - - if should_have_previous_link: - prev = link_creator.create(offset_linkid=first_displayed_item.link_id, - reverse_direction=True) - - newest = link_creator.create(offset_linkid='') - - # TODO(dbentley): add a "last" link (which is now possible because we can - # query with a reverse linkid sorting + # NOTE(dbentley): I personally disagree that it's simpler to do that way, + # because sometimes you want to go to the first page without having to + # consider what page you're on now. + newest = generateLinkForGetArgs(request, base_params, {offset_key : 0, + limit_key : limit}) content = { 'idx': idx, 'data': data, 'export': export_link, - 'first': first_displayed_item.link_id, - 'last': last_displayed_item.link_id, + 'first': offset+1, + 'last': len(data) > 1 and offset+len(data) or None, 'logic': logic, 'limit': limit, 'newest': newest,