comparison MoinMoin/macro/RecentChanges.py @ 0:77665d8e2254

tag of nonpublic@localhost--archive/moin--enterprise--1.5--base-0 (automatically generated log message) imported from: moin--main--1.5--base-0
author Thomas Waldmann <tw-public@gmx.de>
date Thu, 22 Sep 2005 15:09:50 +0000
parents
children 3ffdb52c6969
comparison
equal deleted inserted replaced
-1:000000000000 0:77665d8e2254
1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - RecentChanges Macro
4
5 Parameter "ddiffs" by Ralf Zosel <ralf@zosel.com>, 04.12.2003.
6
7 @copyright: 2000-2004 by Jürgen Hermann <jh@web.de>
8 @license: GNU GPL, see COPYING for details.
9 """
10
11 import re, time
12 from MoinMoin import util, wikiutil, config
13 from MoinMoin.Page import Page
14 from MoinMoin.logfile import editlog
15
16 _DAYS_SELECTION = [1, 2, 3, 7, 14, 30, 60, 90]
17 _MAX_DAYS = 7
18 _MAX_PAGENAME_LENGTH = 15 # 35
19
20 #############################################################################
21 ### RecentChanges Macro
22 #############################################################################
23
24 Dependencies = ["time"] # ["user", "pages", "pageparams", "bookmark"]
25
26 def format_comment(request, line):
27 comment = line.comment
28 _ = request.getText
29 if line.action.startswith('ATT'):
30 import urllib
31
32 # TODO: refactor this into the log in 1.5
33 # line.extra is urlencoded then converted to unicode.
34 # urllib.unquote require ascii - unquote(u'%xx') == u'%xx'
35 filename = line.extra.encode('ascii', 'replace')
36 filename = unicode(urllib.unquote(filename), config.charset,
37 'replace')
38
39 if line.action == 'ATTNEW':
40 comment = _("Upload of attachment '%(filename)s'.") % {
41 'filename': filename}
42 elif line.action == 'ATTDEL':
43 comment = _("Attachment '%(filename)s' deleted.") % {
44 'filename': filename}
45 elif line.action == 'ATTDRW':
46 comment = _("Drawing '%(filename)s' saved.") % {
47 'filename': filename}
48 elif line.action.find('/REVERT') != -1:
49 rev = int(line.extra)
50 comment = _("Revert to revision %(rev)d.") % {'rev': rev}
51 return comment
52
53 def format_page_edits(macro, lines, bookmark_usecs):
54 request = macro.request
55 _ = request.getText
56 d = {} # dict for passing stuff to theme
57 line = lines[0]
58 pagename = line.pagename
59 tnow = time.time()
60 is_new = lines[-1].action == 'SAVENEW'
61 # check whether this page is newer than the user's bookmark
62 hilite = line.ed_time_usecs > (bookmark_usecs or line.ed_time_usecs)
63 page = Page(request, line.pagename)
64
65 html_link = ''
66 if not page.exists():
67 # indicate page was deleted
68 html_link = request.theme.make_icon('deleted')
69 elif is_new:
70 # show "NEW" icon if page was created after the user's bookmark
71 if hilite:
72 html_link = request.theme.make_icon('new')
73 elif hilite:
74 # show "UPDATED" icon if page was edited after the user's bookmark
75 img = request.theme.make_icon('updated')
76 html_link = wikiutil.link_tag(request,
77 wikiutil.quoteWikinameURL(pagename) + "?action=diff&date=%d" % bookmark_usecs,
78 img, formatter=macro.formatter, pretty_url=1)
79 else:
80 # show "DIFF" icon else
81 img = request.theme.make_icon('diffrc')
82 html_link = wikiutil.link_tag(request,
83 wikiutil.quoteWikinameURL(line.pagename) + "?action=diff",
84 img, formatter=macro.formatter, pretty_url=1)
85
86 # print name of page, with a link to it
87 force_split = len(page.page_name) > _MAX_PAGENAME_LENGTH
88
89 d['icon_html'] = html_link
90 d['pagelink_html'] = page.link_to(request, text=page.split_title(request, force=force_split))
91
92 # print time of change
93 d['time_html'] = None
94 if request.cfg.changed_time_fmt:
95 tdiff = long(tnow - wikiutil.version2timestamp(long(line.ed_time_usecs))) / 60 # has to be long for py 2.2.x
96 if tdiff < 1440:
97 d['time_html'] = _("%(hours)dh %(mins)dm ago") % {
98 'hours': int(tdiff/60), 'mins': tdiff%60}
99 else:
100 d['time_html'] = time.strftime(request.cfg.changed_time_fmt, line.time_tuple)
101
102 # print editor name or IP
103 d['editors'] = None
104 if request.cfg.show_hosts:
105 if len(lines) > 1:
106 counters = {}
107 for idx in range(len(lines)):
108 name = lines[idx].getEditor(request)
109 if not counters.has_key(name): counters[name] = []
110 counters[name].append(idx+1)
111 poslist = map(None, counters.values(), counters.keys())
112 poslist.sort()
113 ##request.write(repr(counters.items()))
114 d['editors'] = []
115 for positions, name in poslist:
116 d['editors'].append("%s&nbsp;[%s]" % (
117 name, util.rangelist(positions)))
118 else:
119 d['editors'] = [line.getEditor(request)]
120
121 comments = []
122 for idx in range(len(lines)):
123 comment = format_comment(request, lines[idx])
124 if comment:
125 comments.append((idx+1, wikiutil.escape(comment)))
126
127 d['changecount'] = len(lines)
128 d['comments'] = comments
129
130 img = request.theme.make_icon('info')
131 info_html = wikiutil.link_tag(request,
132 wikiutil.quoteWikinameURL(line.pagename) + "?action=info",
133 img, formatter=macro.formatter, pretty_url=1)
134 d['info_html'] = info_html
135
136 return request.theme.recentchanges_entry(d)
137
138 def cmp_lines(first, second):
139 return cmp(first[0], second[0])
140
141 def print_abandoned(macro, args, **kw):
142 request = macro.request
143 _ = request.getText
144 d = {}
145 pagename = macro.formatter.page.page_name
146 d['q_page_name'] = wikiutil.quoteWikinameURL(pagename)
147 msg = None
148
149 pages = request.rootpage.getPageList()
150 last_edits = []
151 for name in pages:
152 log = Page(request, name)._last_edited(request)
153 if log:
154 last_edits.append(log)
155 # we don't want all Systempages at the beginning of the abandoned list
156 # line = editlog.EditLogLine({})
157 # line.pagename = page
158 # line.ed_time = 0
159 # line.comment = 'not edited'
160 # line.action = ''
161 # line.userid = ''
162 # line.hostname = ''
163 # line.addr = ''
164 # last_edits.append(line)
165 del pages
166 last_edits.sort()
167
168 # set max size in days
169 max_days = min(int(request.form.get('max_days', [0])[0]), _DAYS_SELECTION[-1])
170 # default to _MAX_DAYS for users without bookmark
171 if not max_days:
172 max_days = _MAX_DAYS
173 d['rc_max_days'] = max_days
174
175 # give known user the option to extend the normal display
176 if request.user.valid:
177 d['rc_days'] = _DAYS_SELECTION
178 else:
179 d['rc_days'] = None
180
181 d['rc_update_bookmark'] = None
182 request.write(request.theme.recentchanges_header(d))
183
184 length = len(last_edits)
185
186 index = 0
187 last_index = 0
188 day_count = 0
189
190 if length > 0:
191 line = last_edits[index]
192 line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
193 this_day = line.time_tuple[0:3]
194 day = this_day
195
196 while 1:
197
198 index += 1
199
200 if (index>length):
201 break
202
203 if index < length:
204 line = last_edits[index]
205 line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
206 day = line.time_tuple[0:3]
207
208 if (day != this_day) or (index==length):
209 d['bookmark_link_html'] = None
210 d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(last_edits[last_index].ed_time_usecs))
211 request.write(request.theme.recentchanges_daybreak(d))
212 this_day = day
213
214 for page in last_edits[last_index:index]:
215 request.write(format_page_edits(macro, [page], None))
216 last_index = index
217 day_count += 1
218 if (day_count >= max_days):
219 break
220
221 d['rc_msg'] = msg
222 request.write(request.theme.recentchanges_footer(d))
223
224 def execute(macro, args, **kw):
225 # handle abandoned keyword
226 if kw.get('abandoned', 0):
227 print_abandoned(macro, args, **kw)
228 return ''
229
230 request = macro.request
231 _ = request.getText
232 user = request.user
233 page = macro.formatter.page
234 pagename = page.page_name
235
236 d = {}
237 d['q_page_name'] = wikiutil.quoteWikinameURL(pagename)
238
239 log = editlog.EditLog(request)
240
241 tnow = time.time()
242 msg = ""
243
244 # get bookmark from valid user
245 bookmark_usecs = request.user.getBookmark() or 0
246
247 # add bookmark link if valid user
248 d['rc_curr_bookmark'] = None
249 d['rc_update_bookmark'] = None
250 if request.user.valid:
251 d['rc_curr_bookmark'] = _('(no bookmark set)')
252 if bookmark_usecs:
253 currentBookmark = wikiutil.version2timestamp(bookmark_usecs)
254 currentBookmark = user.getFormattedDateTime(currentBookmark)
255 currentBookmark = _('(currently set to %s)') % currentBookmark
256
257 url = wikiutil.quoteWikinameURL(pagename) + "?action=bookmark&time=del"
258 deleteBookmark = wikiutil.link_tag(request, url, _("Delete Bookmark"),
259 formatter=macro.formatter)
260 d['rc_curr_bookmark'] = currentBookmark + ' ' + deleteBookmark
261
262 version = wikiutil.timestamp2version(tnow)
263 url = wikiutil.quoteWikinameURL(pagename) + \
264 "?action=bookmark&time=%d" % version
265 d['rc_update_bookmark'] = wikiutil.link_tag(request, url, _("Set bookmark"),
266 formatter=macro.formatter)
267
268 # set max size in days
269 max_days = min(int(request.form.get('max_days', [0])[0]), _DAYS_SELECTION[-1])
270 # default to _MAX_DAYS for useres without bookmark
271 if not max_days and not bookmark_usecs:
272 max_days = _MAX_DAYS
273 d['rc_max_days'] = max_days
274
275 # give known user the option to extend the normal display
276 if request.user.valid:
277 d['rc_days'] = _DAYS_SELECTION
278 else:
279 d['rc_days'] = []
280
281 request.write(request.theme.recentchanges_header(d))
282
283 pages = {}
284 ignore_pages = {}
285
286 today = request.user.getTime(tnow)[0:3]
287 this_day = today
288 day_count = 0
289
290 for line in log.reverse():
291
292 if not request.user.may.read(line.pagename):
293 continue
294
295 line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
296 day = line.time_tuple[0:3]
297 hilite = line.ed_time_usecs > (bookmark_usecs or line.ed_time_usecs)
298
299 if ((this_day != day or (not hilite and not max_days))) and len(pages) > 0:
300 # new day or bookmark reached: print out stuff
301 this_day = day
302 for page in pages:
303 ignore_pages[page] = None
304 pages = pages.values()
305 pages.sort(cmp_lines)
306 pages.reverse()
307
308 if request.user.valid:
309 d['bookmark_link_html'] = wikiutil.link_tag(
310 request,
311 wikiutil.quoteWikinameURL(
312 macro.formatter.page.page_name) + "?action=bookmark&time=%d" % (pages[0][0].ed_time_usecs,),
313 _("set bookmark"),
314 formatter=macro.formatter)
315 else:
316 d['bookmark_link_html'] = None
317 d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(pages[0][0].ed_time_usecs))
318 request.write(request.theme.recentchanges_daybreak(d))
319
320 for page in pages:
321 request.write(format_page_edits(macro, page, bookmark_usecs))
322 pages = {}
323 day_count += 1
324 if max_days and (day_count >= max_days):
325 break
326
327 elif this_day != day:
328 # new day but no changes
329 this_day = day
330
331 if ignore_pages.has_key(line.pagename):
332 continue
333
334 # end listing by default if user has a bookmark and we reached it
335 if not max_days and not hilite:
336 msg = _('[Bookmark reached]')
337 break
338
339 if pages.has_key(line.pagename):
340 pages[line.pagename].append(line)
341 else:
342 pages[line.pagename] = [line]
343 else:
344 if len(pages) > 0:
345 # end of loop reached: print out stuff
346 # XXX duplicated code from above
347 # but above does not trigger if we have the first day in wiki history
348 for page in pages:
349 ignore_pages[page] = None
350 pages = pages.values()
351 pages.sort(cmp_lines)
352 pages.reverse()
353
354 if request.user.valid:
355 d['bookmark_link_html'] = wikiutil.link_tag(
356 request,
357 wikiutil.quoteWikinameURL(
358 macro.formatter.page.page_name) + "?action=bookmark&time=%d" % (pages[0][0].ed_time_usecs,),
359 _("Set bookmark"),
360 formatter=macro.formatter)
361 else:
362 d['bookmark_link_html'] = None
363 d['date'] = request.user.getFormattedDate(wikiutil.version2timestamp(pages[0][0].ed_time_usecs))
364 request.write(request.theme.recentchanges_daybreak(d))
365
366 for page in pages:
367 request.write(format_page_edits(macro, page, bookmark_usecs))
368
369
370 d['rc_msg'] = msg
371 request.write(request.theme.recentchanges_footer(d))
372
373 return ''
374
375