Back to index

moin  1.9.0~rc2
RecentChanges.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - RecentChanges Macro
00004 
00005     Parameter "ddiffs" by Ralf Zosel <ralf@zosel.com>, 04.12.2003.
00006 
00007     @copyright: 2000-2004 Juergen Hermann <jh@web.de>
00008     @license: GNU GPL, see COPYING for details.
00009 """
00010 import time
00011 
00012 from MoinMoin import util, wikiutil
00013 from MoinMoin.Page import Page
00014 from MoinMoin.logfile import editlog
00015 
00016 _DAYS_SELECTION = [1, 2, 3, 7, 14, 30, 60, 90]
00017 _MAX_DAYS = 7
00018 _MAX_PAGENAME_LENGTH = 15 # 35
00019 _MAX_COMMENT_LENGTH = 20
00020 
00021 #############################################################################
00022 ### RecentChanges Macro
00023 #############################################################################
00024 
00025 Dependencies = ["time"] # ["user", "pages", "pageparams", "bookmark"]
00026 
00027 def format_comment(request, line):
00028     comment = line.comment
00029     action = line.action
00030     _ = request.getText
00031     if action.startswith('ATT'):
00032         filename = wikiutil.url_unquote(line.extra)
00033         if action == 'ATTNEW':
00034             comment = _("Upload of attachment '%(filename)s'.") % {
00035                 'filename': filename}
00036         elif action == 'ATTDEL':
00037             comment = _("Attachment '%(filename)s' deleted.") % {
00038                 'filename': filename}
00039         elif action == 'ATTDRW':
00040             comment = _("Drawing '%(filename)s' saved.") % {
00041                 'filename': filename}
00042     elif '/REVERT' in action:
00043         rev = int(line.extra)
00044         comment = (_("Revert to revision %(rev)d.") % {'rev': rev}) + " " + comment
00045     elif '/RENAME' in action:
00046         comment = (_("Renamed from '%(oldpagename)s'.") % {'oldpagename': line.extra}) + " " + comment
00047 
00048     return wikiutil.make_breakable(comment, _MAX_COMMENT_LENGTH)
00049 
00050 def format_page_edits(macro, lines, bookmark_usecs):
00051     request = macro.request
00052     _ = request.getText
00053     d = {} # dict for passing stuff to theme
00054     line = lines[0]
00055     pagename = line.pagename
00056     rev = int(line.rev)
00057     tnow = time.time()
00058     is_new = lines[-1].action == 'SAVENEW'
00059     is_renamed = lines[-1].action == 'SAVE/RENAME'
00060     # check whether this page is newer than the user's bookmark
00061     hilite = line.ed_time_usecs > (bookmark_usecs or line.ed_time_usecs)
00062     page = Page(request, pagename)
00063 
00064     html_link = ''
00065     if not page.exists():
00066         img = request.theme.make_icon('deleted')
00067         revbefore = rev - 1
00068         if revbefore and page.exists(rev=revbefore, domain='standard'):
00069             # indicate page was deleted and show diff to last existing revision of it
00070             html_link = page.link_to_raw(request, img, querystr={'action': 'diff'}, rel='nofollow')
00071         else:
00072             # just indicate page was deleted
00073             html_link = img
00074     elif page.isConflict():
00075         img = request.theme.make_icon('conflict')
00076         html_link = page.link_to_raw(request, img, querystr={'action': 'edit'}, rel='nofollow')
00077     elif hilite:
00078         # show special icons if change was after the user's bookmark
00079         if is_new:
00080             img = 'new'
00081         elif is_renamed:
00082             img = 'renamed'
00083         else:
00084             img = 'updated'
00085         img = request.theme.make_icon(img)
00086         html_link = page.link_to_raw(request, img, querystr={'action': 'diff', 'date': '%d' % bookmark_usecs}, rel='nofollow')
00087     else:
00088         # show "DIFF" icon else
00089         img = request.theme.make_icon('diffrc')
00090         html_link = page.link_to_raw(request, img, querystr={'action': 'diff'}, rel='nofollow')
00091 
00092     # print name of page, with a link to it
00093     force_split = len(page.page_name) > _MAX_PAGENAME_LENGTH
00094 
00095     d['icon_html'] = html_link
00096     d['pagelink_html'] = page.link_to(request, text=page.split_title(force=force_split))
00097 
00098     # print time of change
00099     d['time_html'] = None
00100     if request.cfg.changed_time_fmt:
00101         tdiff = long(tnow - wikiutil.version2timestamp(long(line.ed_time_usecs))) / 60 # has to be long for py 2.2.x
00102         if tdiff < 100:
00103             d['time_html'] = _("%(mins)dm ago") % {
00104                 'mins': tdiff}
00105         else:
00106             d['time_html'] = time.strftime(request.cfg.changed_time_fmt, line.time_tuple)
00107 
00108     # print editor name or IP
00109     d['editors'] = None
00110     if request.cfg.show_names:
00111         if len(lines) > 1:
00112             counters = {}
00113             for idx in range(len(lines)):
00114                 name = lines[idx].getEditor(request)
00115                 if not name in counters:
00116                     counters[name] = []
00117                 counters[name].append(idx+1)
00118             poslist = [(v, k) for k, v in counters.items()]
00119             poslist.sort()
00120             d['editors'] = []
00121             for positions, name in poslist:
00122                 d['editors'].append("%s&nbsp;[%s]" % (
00123                     name, util.rangelist(positions)))
00124         else:
00125             d['editors'] = [line.getEditor(request)]
00126 
00127     comments = []
00128     for idx in range(len(lines)):
00129         comment = format_comment(request, lines[idx])
00130         if comment:
00131             comments.append((idx+1, wikiutil.escape(comment)))
00132 
00133     d['changecount'] = len(lines)
00134     d['comments'] = comments
00135 
00136     img = request.theme.make_icon('info')
00137     d['info_html'] = page.link_to_raw(request, img, querystr={'action': 'info'}, rel='nofollow')
00138 
00139     return request.theme.recentchanges_entry(d)
00140 
00141 def cmp_lines(first, second):
00142     return cmp(first[0], second[0])
00143 
00144 def print_abandoned(macro):
00145     request = macro.request
00146     _ = request.getText
00147     output = []
00148     d = {}
00149     page = macro.formatter.page
00150     pagename = page.page_name
00151     d['page'] = page
00152     d['q_page_name'] = wikiutil.quoteWikinameURL(pagename)
00153     msg = None
00154 
00155     pages = request.rootpage.getPageList()
00156     last_edits = []
00157     for name in pages:
00158         log = Page(request, name).editlog_entry()
00159         if log:
00160             last_edits.append(log)
00161         #   we don't want all Systempages at the beginning of the abandoned list
00162         #    line = editlog.EditLogLine({})
00163         #    line.pagename = page
00164         #    line.ed_time = 0
00165         #    line.comment = 'not edited'
00166         #    line.action = ''
00167         #    line.userid = ''
00168         #    line.hostname = ''
00169         #    line.addr = ''
00170         #    last_edits.append(line)
00171     del pages
00172     last_edits.sort()
00173 
00174     # set max size in days
00175     max_days = min(int(request.values.get('max_days', 0)), _DAYS_SELECTION[-1])
00176     # default to _MAX_DAYS for users without bookmark
00177     if not max_days:
00178         max_days = _MAX_DAYS
00179     d['rc_max_days'] = max_days
00180 
00181     # give known user the option to extend the normal display
00182     if request.user.valid:
00183         d['rc_days'] = _DAYS_SELECTION
00184     else:
00185         d['rc_days'] = None
00186 
00187     d['rc_update_bookmark'] = None
00188     output.append(request.theme.recentchanges_header(d))
00189 
00190     length = len(last_edits)
00191 
00192     index = 0
00193     last_index = 0
00194     day_count = 0
00195 
00196     if length > 0:
00197         line = last_edits[index]
00198         line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
00199         this_day = line.time_tuple[0:3]
00200         day = this_day
00201 
00202     while 1:
00203 
00204         index += 1
00205 
00206         if index > length:
00207             break
00208 
00209         if index < length:
00210             line = last_edits[index]
00211             line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
00212             day = line.time_tuple[0:3]
00213 
00214         if (day != this_day) or (index == length):
00215             d['bookmark_link_html'] = None
00216             d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(last_edits[last_index].ed_time_usecs))
00217             output.append(request.theme.recentchanges_daybreak(d))
00218             this_day = day
00219 
00220             for page in last_edits[last_index:index]:
00221                 output.append(format_page_edits(macro, [page], None))
00222             last_index = index
00223             day_count += 1
00224             if (day_count >= max_days):
00225                 break
00226 
00227     d['rc_msg'] = msg
00228     output.append(request.theme.recentchanges_footer(d))
00229     return ''.join(output)
00230 
00231 
00232 def macro_RecentChanges(macro, abandoned=False):
00233     # handle abandoned keyword
00234     if abandoned:
00235         return print_abandoned(macro)
00236 
00237     request = macro.request
00238     _ = request.getText
00239     output = []
00240     user = request.user
00241     page = macro.formatter.page
00242     pagename = page.page_name
00243 
00244     d = {}
00245     d['page'] = page
00246     d['q_page_name'] = wikiutil.quoteWikinameURL(pagename)
00247 
00248     log = editlog.EditLog(request)
00249 
00250     tnow = time.time()
00251     msg = ""
00252 
00253     # get bookmark from valid user
00254     bookmark_usecs = request.user.getBookmark() or 0
00255 
00256     # add bookmark link if valid user
00257     d['rc_curr_bookmark'] = None
00258     d['rc_update_bookmark'] = None
00259     if request.user.valid:
00260         d['rc_curr_bookmark'] = _('(no bookmark set)')
00261         if bookmark_usecs:
00262             currentBookmark = wikiutil.version2timestamp(bookmark_usecs)
00263             currentBookmark = user.getFormattedDateTime(currentBookmark)
00264             currentBookmark = _('(currently set to %s)') % currentBookmark
00265             deleteBookmark = page.link_to(request, _("Delete bookmark"), querystr={'action': 'bookmark', 'time': 'del'}, rel='nofollow')
00266             d['rc_curr_bookmark'] = currentBookmark + ' ' + deleteBookmark
00267 
00268         version = wikiutil.timestamp2version(tnow)
00269         d['rc_update_bookmark'] = page.link_to(request, _("Set bookmark"), querystr={'action': 'bookmark', 'time': '%d' % version}, rel='nofollow')
00270 
00271     # set max size in days
00272     max_days = min(int(request.values.get('max_days', 0)), _DAYS_SELECTION[-1])
00273     # default to _MAX_DAYS for useres without bookmark
00274     if not max_days and not bookmark_usecs:
00275         max_days = _MAX_DAYS
00276     d['rc_max_days'] = max_days
00277 
00278     # give known user the option to extend the normal display
00279     if request.user.valid:
00280         d['rc_days'] = _DAYS_SELECTION
00281     else:
00282         d['rc_days'] = []
00283 
00284     output.append(request.theme.recentchanges_header(d))
00285 
00286     pages = {}
00287     ignore_pages = {}
00288 
00289     today = request.user.getTime(tnow)[0:3]
00290     this_day = today
00291     day_count = 0
00292 
00293     for line in log.reverse():
00294 
00295         if not request.user.may.read(line.pagename):
00296             continue
00297 
00298         line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
00299         day = line.time_tuple[0:3]
00300         hilite = line.ed_time_usecs > (bookmark_usecs or line.ed_time_usecs)
00301 
00302         if ((this_day != day or (not hilite and not max_days))) and len(pages) > 0:
00303             # new day or bookmark reached: print out stuff
00304             this_day = day
00305             for p in pages:
00306                 ignore_pages[p] = None
00307             pages = pages.values()
00308             pages.sort(cmp_lines)
00309             pages.reverse()
00310 
00311             if request.user.valid:
00312                 bmtime = pages[0][0].ed_time_usecs
00313                 d['bookmark_link_html'] = page.link_to(request, _("Set bookmark"), querystr={'action': 'bookmark', 'time': '%d' % bmtime}, rel='nofollow')
00314             else:
00315                 d['bookmark_link_html'] = None
00316             d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(pages[0][0].ed_time_usecs))
00317             output.append(request.theme.recentchanges_daybreak(d))
00318 
00319             for p in pages:
00320                 output.append(format_page_edits(macro, p, bookmark_usecs))
00321             pages = {}
00322             day_count += 1
00323             if max_days and (day_count >= max_days):
00324                 break
00325 
00326         elif this_day != day:
00327             # new day but no changes
00328             this_day = day
00329 
00330         if line.pagename in ignore_pages:
00331             continue
00332 
00333         # end listing by default if user has a bookmark and we reached it
00334         if not max_days and not hilite:
00335             msg = _('[Bookmark reached]')
00336             break
00337 
00338         if line.pagename in pages:
00339             pages[line.pagename].append(line)
00340         else:
00341             pages[line.pagename] = [line]
00342     else:
00343         if len(pages) > 0:
00344             # end of loop reached: print out stuff
00345             # XXX duplicated code from above
00346             # but above does not trigger if we have the first day in wiki history
00347             for p in pages:
00348                 ignore_pages[p] = None
00349             pages = pages.values()
00350             pages.sort(cmp_lines)
00351             pages.reverse()
00352 
00353             if request.user.valid:
00354                 bmtime = pages[0][0].ed_time_usecs
00355                 d['bookmark_link_html'] = page.link_to(request, _("Set bookmark"), querystr={'action': 'bookmark', 'time': '%d' % bmtime}, rel='nofollow')
00356             else:
00357                 d['bookmark_link_html'] = None
00358             d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(pages[0][0].ed_time_usecs))
00359             output.append(request.theme.recentchanges_daybreak(d))
00360 
00361             for p in pages:
00362                 output.append(format_page_edits(macro, p, bookmark_usecs))
00363 
00364 
00365     d['rc_msg'] = msg
00366     output.append(request.theme.recentchanges_footer(d))
00367 
00368     return ''.join(output)
00369 
00370