changeset 5518:b23b1d2b1391

info action: added pagination in history viewer.
author Eugene Syromyatnikov <evgsyr@gmail.com>
date Mon, 08 Feb 2010 06:07:52 +0300
parents 2c992293ece4
children ace26ca9c562
files MoinMoin/action/info.py MoinMoin/config/multiconfig.py
diffstat 2 files changed, 159 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/info.py	Mon Feb 08 00:18:20 2010 +0100
+++ b/MoinMoin/action/info.py	Mon Feb 08 06:07:52 2010 +0300
@@ -75,12 +75,147 @@
     def history(page, pagename, request):
         # show history as default
         _ = request.getText
-        default_count, limit_max_count = request.cfg.history_count
+        default_count, limit_max_count = request.cfg.history_count[0:2]
+        paging = request.cfg.history_paging
+
         try:
             max_count = int(request.values.get('max_count', default_count))
-        except:
+        except ValueError:
             max_count = default_count
-        max_count = min(max_count, limit_max_count)
+        max_count = max(1, min(max_count, limit_max_count))
+
+        # read in the complete log of this page
+        log = editlog.EditLog(request, rootpagename=pagename)
+
+        offset = 0
+        paging_info_html = ""
+        paging_nav_html = ""
+        count_select_html = ""
+
+        f = request.formatter
+
+        if paging:
+            log_size = log.lines()
+
+            try:
+                offset = int(request.values.get('offset', 0))
+            except ValueError:
+                offset = 0
+            offset = max(min(offset, log_size - 1), 0)
+
+            paging_info_html += f.paragraph(1, css_class="searchstats info-paging-info") + _("Showing page edit history entries from '''%(start_offset)d''' to '''%(end_offset)d''' out of '''%(total_count)d''' entries total.", wiki=True) % {
+                'start_offset': offset + 1,
+                'end_offset': min(log_size, offset + max_count),
+                'total_count': log_size,
+            } + f.paragraph(0)
+
+            # generating offset navigating links
+            if max_count < log_size or offset != 0:
+                offset_links = []
+                cur_offset = max_count
+                near_count = 5 # request.cfg.pagination_size
+
+                min_offset = max(0, (offset + max_count - 1) / max_count - near_count)
+                max_offset = min((log_size - 1) / max_count, offset / max_count + near_count)
+                offset_added = False
+
+                def add_offset_link(offset, caption=None):
+                    offset_links.append(f.table_cell(1, css_class="info-offset-item") +
+                        page.link_to(request, on=1, querystr={
+                            'action': 'info',
+                            'offset': str(offset),
+                            'max_count': str(max_count),
+                            }, css_class="info-offset-nav-link", rel="nofollow") + f.text(caption or str(offset + 1)) + page.link_to(request, on=0) +
+                        f.table_cell(0)
+                    )
+
+                # link to previous page - only if not at start
+                if offset > 0:
+                    add_offset_link(((offset - 1) / max_count) * max_count, _("Newer"))
+
+                # link to beggining of event log - if min_offset is not minimal
+                if min_offset > 0:
+                    add_offset_link(0)
+                    # adding gap only if min_offset not explicitly following beginning
+                    if min_offset > 1:
+                        offset_links.append(f.table_cell(1, css_class="info-offset-gap") + f.text(u'\u2026') + f.table_cell(0))
+
+                # generating near pages links
+                for cur_offset in range(min_offset, max_offset + 1):
+                    # note that current offset may be not multiple of max_count,
+                    # so we check whether we should add current offset marker like this
+                    if not offset_added and offset <= cur_offset * max_count:
+                        # current info history view offset
+                        offset_links.append(f.table_cell(1, css_class="info-offset-item info-cur-offset") + f.text(str(offset + 1)) + f.table_cell(0))
+                        offset_added = True
+
+                    # add link, if not at this offset
+                    if offset != cur_offset * max_count:
+                        add_offset_link(cur_offset * max_count)
+
+                # link to the last page of event log
+                if max_offset < (log_size - 1) / max_count:
+                    if max_offset < (log_size - 1) / max_count - 1:
+                        offset_links.append(f.table_cell(1, css_class="info-offset-gap") + f.text(u'\u2026') + f.table_cell(0))
+                    add_offset_link(((log_size - 1) / max_count) * max_count)
+
+                # special case - if offset is greater than max_offset * max_count
+                if offset > max_offset * max_count:
+                    offset_links.append(f.table_cell(1, css_class="info-offset-item info-cur-offset") + f.text(str(offset + 1)) + f.table_cell(0))
+
+                # link to next page
+                if offset < (log_size - max_count):
+                    add_offset_link(((offset + max_count) / max_count) * max_count, _("Older"))
+
+                # generating html
+                paging_nav_html += "".join([
+                    f.table(1, css_class="searchpages"),
+                    f.table_row(1),
+                    "".join(offset_links),
+                    f.table_row(0),
+                    f.table(0),
+                ])
+
+        # generating max_count switcher
+        # we do it only in case history_count has additional values
+        if len(request.cfg.history_count) > 2:
+            max_count_possibilities = list(set(request.cfg.history_count))
+            max_count_possibilities.sort()
+            max_count_html = []
+            cur_count_added = False
+
+
+            for count in max_count_possibilities:
+                # max count value can be not in list of predefined values
+                if max_count <= count and not cur_count_added:
+                    max_count_html.append("".join([
+                        f.span(1, css_class="info-count-item info-cur-count"),
+                        f.text(str(max_count)),
+                        f.span(0),
+                    ]))
+                    cur_count_added = True
+
+                # checking for limit_max_count to prevent showing unavailable options
+                if max_count != count and count <= limit_max_count:
+                    max_count_html.append("".join([
+                        f.span(1, css_class="info-count-item"),
+                        page.link_to(request, on=1, querystr={
+                            'action': 'info',
+                            'offset': str(offset),
+                            'max_count': str(count),
+                            }, css_class="info-count-link", rel="nofollow"),
+                        f.text(str(count)),
+                        page.link_to(request, on=0),
+                        f.span(0),
+                    ]))
+
+            count_select_html += "".join([
+                f.span(1, css_class="info-count-selector"),
+                    f.text(" ("),
+                    f.text(_("%s items per page")) % (f.span(1, css_class="info-count-selector info-count-selector-divider") + f.text(" | ") + f.span(0)).join(max_count_html),
+                    f.text(")"),
+                f.span(0),
+            ])
 
         # open log for this page
         from MoinMoin.util.dataset import TupleDataset, Column
@@ -112,11 +247,14 @@
         may_write = request.user.may.write(pagename)
         may_delete = request.user.may.delete(pagename)
 
-        # read in the complete log of this page
-        log = editlog.EditLog(request, rootpagename=pagename)
         count = 0
         pgactioncount = 0
         for line in log.reverse():
+            count += 1
+
+            if paging and count <= offset:
+                continue
+
             rev = int(line.rev)
             actions = []
             if line.action in ('SAVE', 'SAVENEW', 'SAVE/REVERT', 'SAVE/RENAME', ):
@@ -166,8 +304,7 @@
                 wikiutil.escape(comment) or '&nbsp;',
                 "&nbsp;".join(a for a in actions if a),
             ))
-            count += 1
-            if count >= max_count:
+            if (count >= max_count + offset) or (paging and count >= log_size):
                 break
 
         # print version history
@@ -187,7 +324,20 @@
         div.append(history_table.render(method="GET"))
 
         form = html.FORM(method="GET", action="")
+        if paging:
+            form.append(f.div(1, css_class="info-paging-info") + paging_info_html + count_select_html + f.div(0))
+            form.append("".join([
+                f.div(1, css_class="info-paging-nav info-paging-nav-top"),
+                paging_nav_html,
+                f.div(0),
+            ]))
         form.append(div)
+        if paging:
+            form.append("".join([
+                f.div(1, css_class="info-paging-nav info-paging-nav-bottom"),
+                paging_nav_html,
+                f.div(0)
+            ]))
         request.write(unicode(form))
 
     # main function
--- a/MoinMoin/config/multiconfig.py	Mon Feb 08 00:18:20 2010 +0100
+++ b/MoinMoin/config/multiconfig.py	Mon Feb 08 06:07:52 2010 +0300
@@ -880,7 +880,8 @@
 
     ('edit_bar', ['Edit', 'Comments', 'Discussion', 'Info', 'Subscribe', 'Quicklink', 'Attachments', 'ActionsMenu'],
      'list of edit bar entries'),
-    ('history_count', (100, 200), "number of revisions shown for info/history action (default_count_shown, max_count_shown)"),
+    ('history_count', (100, 200, 5, 10, 25, 50), "Number of revisions shown for info/history action (default_count_shown, max_count_shown, [other values shown as page size choices]). At least first two values (default and maximum) should be provided. If additional values are provided, user will be able to change number of items per page in the UI."),
+    ('history_paging', True, "Enable paging for history. Warning: because event log functions are rather unefficient, enabling this option may lead to possibility of producing heavy requests!"),
 
     ('show_hosts', True,
      "if True, show host names and IPs. Set to False to hide them."),