Attachment 'PageComment2-095.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 """
3 PageComment2.py Version 0.95 Nov. 20, 2005
4
5 This macro gives a form to post a new comment to the page and shows a list of the posted comments.
6
7 @copyright: 2005 by Seungik Lee <seungiklee<at>gmail.com> http://cds.icu.ac.kr/~silee/
8 @license: GPL
9
10 Usage: [[PageComment2]]
11
12 Features:
13
14 - Simple usage, just put [[PageComment2]] on any page.
15 - Lets anonymous users post a new comment with an input form.
16 - Shows a list of the posted comments.
17 - Support for comment deletion by given password.
18 - Support for administrative action, e.g.,
19 - to delete a comment without entering a given password
20
21 Parameters:
22
23 - pagename: the page name which the comments are retrieved for. by default the page itself.
24 If the user has no 'read' ACL for that page, it does not allow to insert/view comments.
25 e.g., pagename=AnotherPage
26
27 - section: the section name of the page. The comments in different sections are managed in separated sub pages.
28 Section name should be alphanumeric format ([a-zA-Z0-9] in regular expression).
29 If not, all the non-alphanumric characters are removed.
30 e.g., section=1, section=News, section=Opinion
31
32 - inputonly: shows input form only. list of the comments are shown to admin users only.
33 - inputonly=0; default, all list is shown to all users including anonymous users
34 - inputonly=1; shown to admin users only (who has the page delete privilege)
35
36 - commentonly: shows the list of comments only.
37 - commentonly=0; default, both of the list and input form will be shown
38 - commentonly=1; only the list of comments will be shown
39
40 - countonly: returns the number of the comments posted to this page
41 - countonly=0; default, normal form (input form; list of comments)
42 - countonly=1; just return the number of comments.
43 e.g., 'There are [[PageComments(countonly=1)]] comments here'
44
45 - rows: the # of rows of the textarea. default 2. e.g., rows=2
46
47 - cols: the # of columns of the textarea. default 60. e.g., cols=60
48
49 - maxlength: limitation on # of characters for comment text. default 0 (no limit). e.g., maxlength=500
50
51 - newerfirst: order of the list of comments.
52 - newerfirst=0: default, newer ones are listed at the end
53 - newerfirst=1: newer ones are listed at the top
54
55 - tablewidth: the width of the table format for PageComment2, default '' (none).
56 e.g., tablewidth=600, tablewidth=100%
57
58 Change Log
59
60 - Nov. 20, 2005 - Version 0.95
61 - some minor bugs are fixed
62
63 - Nov. 20, 2005 - Version 0.94
64 - some parameters are added
65 - some minor bugs are fixed
66
67 - Nov. 19, 2005 - Version 0.92
68 - some minor bugs are fixed
69 - 'olderfirst' parameter replaced with 'newerfirst'
70
71 - Nov. 19, 2005 - Version 0.91
72 - some parameters are added
73 - validates smiley markup
74 - modified view
75
76 - Nov. 18, 2005 - Version 0.90 (Release 2)
77 - No text data file support any more: Comment is stored in the sub wiki page.
78 - (does not compatible with Release 1: PageComment.py)
79 - Custom icon (smiley) can be inserted
80 - Pre-fill the name input field with his/her login name
81 - Logs at add/remove comments
82 - Added some parameters
83
84 - Oct. 08, 2005 - Version 0.82
85 - Changed the directory the data file stored to be secured
86
87 - Oct. 07, 2005 - Version 0.81
88 - Unicode encoding related bugs in deletecomment function are patched.
89 - Instruction bugs are patched.
90
91 - Oct. 06, 2005 - Version 0.80
92 - The initial version is released.
93
94
95 Notes
96
97 - 'Gallery.py' developed by Simon Ryan has inspired this macro.
98 - Thanks to many of the MoinMoin users for valuable comments.
99 - Visit http://moinmoin.wikiwikiweb.de/MacroMarket/PageComment2 for more detail
100
101 """
102
103 from MoinMoin import config, wikiutil
104 import StringIO, time, re
105 from MoinMoin.Page import Page
106 from MoinMoin.PageEditor import PageEditor
107 from MoinMoin.parser import wiki
108
109
110 class Globs:
111 # A quick place to plonk those shared variables
112
113 adminmsg = ''
114 datapagename = ''
115 pagename = ''
116 curpagename = ''
117 cursubname = ''
118 admin = ''
119 macro = ''
120 defaultacl = ''
121 defaulticon = ''
122 formid = 0
123
124 class Params:
125
126 rows = 0
127 cols = 0
128 maxlength = 0
129 newerfirst = 0
130 tablewidth = ''
131 commentfirst = 0
132 pagename = ''
133 commentonly = 0
134 inputonly = 0
135 countonly = 0
136 section = ''
137
138
139 def execute(macro, args):
140
141 # INITIALIZATION ----------------------------------------
142 getparams(args)
143 setglobalvalues(macro)
144
145 # internal variables
146 request = macro.request
147 _ = request.getText
148
149 if not Globs.pagename == Globs.curpagename:
150 if not macro.request.user.may.read(Globs.pagename):
151 return macro.formatter.rawHTML(u'PageComment: %s' % _('You are not allowed to view this page.'))
152 elif not Page(request, Globs.pagename).exists():
153 return macro.formatter.rawHTML(u'PageComment: %s' % _('This page is already deleted or was never created!'))
154
155
156 if Params.countonly:
157 html = len(fetchcomments())
158 return macro.formatter.rawHTML('%s' % html)
159
160 datapagename = Globs.datapagename
161
162 # form vals
163 comicon = Globs.defaulticon
164 comauthor = ''
165 comtext = ''
166 compasswd = ''
167 comrev = 0
168
169 addcommand = u'addcomment%d' % Globs.formid
170 delcommand = u'delcomment%d' % Globs.formid
171
172 action = macro.form.get('commentaction', [''])[0]
173
174 if action == addcommand:
175
176 # process form input for comment add
177 form_fields = {'comicon': Globs.defaulticon, 'comauthor': '', 'comtext': '', 'compasswd': '', 'comrev': 0}
178 required_fields = {'comauthor': _('Name'), 'comtext': _('Text'), 'compasswd': _('Password'), 'comrev': 'Rev. #'}
179
180 formvals, missingfields = getforminput(macro.form, form_fields, required_fields)
181
182 comicon = formvals['comicon']
183 comauthor = formvals['comauthor']
184 comtext = formvals['comtext']
185 compasswd = formvals['compasswd']
186 comrev = formvals['comrev']
187
188 if not len(missingfields) == len(required_fields):
189 if not missingfields:
190 flag = addcomment(macro, comicon, comauthor, comtext, compasswd, comrev)
191
192 if flag:
193 comicon = Globs.defaulticon
194 comauthor = ''
195 comtext = ''
196 compasswd = ''
197 comrev = 0
198 else:
199 message( _('Required attribute "%(attrname)s" missing') % { 'attrname': u', '.join(missingfields) } )
200
201 elif action == delcommand:
202
203 # process form input for comment delete
204 form_fields = {'delkey': '', 'delpasswd': ''}
205 required_fields = {'delkey': 'Comment Key', 'delpasswd': 'Password'}
206
207 formvals, missingfields = getforminput(macro.form, form_fields, required_fields)
208
209 delkey = formvals['delkey']
210 delpasswd = formvals['delpasswd']
211
212 if not len(missingfields) == len(required_fields):
213 if not missingfields:
214 deletecomment(macro, delkey, delpasswd)
215 else:
216 message( _('Required attribute "%(attrname)s" missing') % { 'attrname': u', '.join(missingfields) } )
217
218 # format output
219 html = []
220
221 html.append(u'<a name="pagecomment%d">' % Globs.formid)
222 html.append(u'<table class="pagecomment" %s>' % Params.tablewidth)
223 html.append(u'<tr><td style="border-width: 0px;">')
224 html.append(u'<font style="color: #aa0000;">%s</font>' % Globs.adminmsg)
225 html.append(u'</td></tr>')
226
227 if Params.commentfirst:
228 html.append(showcommentsection())
229 html.append(commentformsection(comauthor, comtext, compasswd, comicon, comrev))
230 else:
231 html.append(commentformsection(comauthor, comtext, compasswd, comicon, comrev))
232 html.append(showcommentsection())
233
234 html.append(u'</table>')
235
236 return macro.formatter.rawHTML(u'\n'.join(html))
237
238
239 def commentformsection(comauthor, comtext, compasswd, comicon, comrev):
240 html = []
241
242 if not Params.commentonly:
243 html.append(u'<tr><td style="border-width: 0px;">')
244 html.append(u'<table class="commentform"><tr><td style="border-width: 1px;">')
245 html.append(commentform(comauthor, comtext, compasswd, comicon, comrev))
246 html.append(u'</td></tr></table>')
247 html.append(u'</td></tr>')
248
249 return u'\n'.join(html)
250
251
252 def showcommentsection():
253 html = []
254 if (not Params.inputonly) or Globs.admin:
255 html.append(deleteform())
256 html.append(u'<tr><td style="border: 0px;">')
257 html.append(showcomment())
258 html.append(u'</td></tr>')
259 else:
260 html.append(u'<tr><td style="text-align: center; border: 0px; font-size: 0.8em; color: #aaaaaa;">(The posted comments are shown to administrators only.)</td></tr>')
261
262 return u'\n'.join(html)
263
264 def getforminput(form, inputfields, requiredfields):
265
266 formvals = {}
267 missingfields = []
268
269 for item in inputfields.keys():
270 formvals[item] = form.get(item, [inputfields[item]])[0]
271 if (not formvals[item]) and (item in requiredfields):
272 missingfields.append(requiredfields[item])
273
274 return formvals, missingfields
275
276 def getparams(args):
277 # process arguments
278
279 params = {}
280 if args:
281 # Arguments are comma delimited key=value pairs
282 sargs = args.split(',')
283
284 for item in sargs:
285 sitem = item.split('=')
286
287 if len(sitem) == 2:
288 key, value = sitem[0], sitem[1]
289 params[key.strip()] = value.strip()
290
291 Params.pagename = params.get('pagename', '')
292
293 Params.section = params.get('section', '')
294 if Params.section:
295 Params.section = getescapedsectionname(Params.section)
296
297 try:
298 Params.inputonly = int(params.get('inputonly', 0))
299 except ValueError:
300 Params.inputonly = 0
301
302 try:
303 Params.commentonly = int(params.get('commentonly', 0))
304 except ValueError:
305 Params.commentonly = 0
306
307 try:
308 Params.countonly = int(params.get('countonly', 0))
309 except ValueError:
310 Params.countonly = 0
311
312 try:
313 Params.newerfirst = int(params.get('newerfirst', 0))
314 except ValueError:
315 Params.newerfirst = 0
316
317 try:
318 Params.commentfirst = int(params.get('commentfirst', 0))
319 except ValueError:
320 Params.commentfirst = 0
321
322 try:
323 Params.rows = int(params.get('rows', 2))
324 except ValueError:
325 Params.rows = 2
326
327 try:
328 Params.cols = int(params.get('cols', 60))
329 except ValueError:
330 Params.cols = 60
331
332 try:
333 Params.maxlength = int(params.get('maxlength', 0))
334 except ValueError:
335 Params.maxlength = 0
336
337 Params.tablewidth = params.get('tablewidth', '')
338 if Params.tablewidth:
339 Params.tablewidth = ' width="%s" ' % Params.tablewidth
340
341 def setglobalvalues(macro):
342
343 # Global variables
344 Globs.macro = macro
345 Globs.defaultacl = u'#acl All:'
346 Globs.adminmsg = ''
347 Globs.defaulticon = ''
348
349 Globs.curpagename = macro.formatter.page.page_name
350
351 if Params.pagename:
352 Globs.pagename = Params.pagename
353 else:
354 Globs.pagename = Globs.curpagename
355
356 Globs.cursubname = Globs.curpagename.split('/')[-1]
357 Globs.datapagename = u'%s/%s%s' % (Globs.pagename, 'PageCommentData', Params.section)
358
359 # Figure out if we have delete privs
360 try:
361 if macro.request.user.may.delete(Globs.datapagename):
362 Globs.admin = 'true'
363 else:
364 Globs.admin = ''
365 except AttributeError:
366 Globs.admin = ''
367 pass
368
369 # set form id
370
371 formid = int(macro.form.get('formid', ['0'])[0])
372 formid += 1
373
374 Globs.formid = formid
375 macro.form['formid'] = ['%d' % formid]
376
377 def message(astring):
378 Globs.adminmsg = u'%s\n' % astring
379
380
381 def commentform(tmpauthor, tmptext, tmppasswd, tmpicon, comrev):
382 # A form for posting a new comment
383 request = Globs.macro.request
384 datapagename = Globs.datapagename
385 _ = request.getText
386
387 cellstyle = u'border-width: 0px; vertical-align: middle; font-size: 0.9em; line-height: 1em;'
388
389 pg = Page( request, datapagename )
390
391 if pg.exists():
392 comrev = pg.current_rev()
393 else:
394 comrev = 0
395
396 if request.user.valid:
397 html1 = [
398 u'<input type="hidden" value="%s" name="comauthor">' % request.user.name,
399 u'<input type="hidden" value="*" name="compasswd">',
400 u'<tr><td style="%s">%s: <i>%s</i></td>' % (cellstyle, _('Name'), request.user.name),
401 u'<td style="%s">%s: ****</td>' % (cellstyle, _('Password')),
402 ]
403 else:
404 html1 = [
405 u'<tr><td style="%s">%s: <input type="text" size="10" maxlength="20" name="comauthor" value="%s"></td>' % (cellstyle, _('Name'), tmpauthor),
406 u'<td style="%s">%s: <input type="password" size="6" maxlength="10" name="compasswd" value="%s"></td>' % (cellstyle, _('Password'), tmppasswd),
407 ]
408
409 html1 = u'\n'.join(html1)
410 html2 = [
411 u'<div id="commentform">',
412 u'<form action="%s#pagecomment%d" name="comment" METHOD="POST">' % (Globs.cursubname, Globs.formid),
413 u'<table class="addcommentform">',
414 u'%s' % html1,
415 # u'<td style="%s">Smiley: <input type="text" size="4" maxlength="4" name="comicon" value="%s"></td></tr>' % (cellstyle, tmpicon),
416 u'<td style="%s">Smiley: %s</td></tr>' % (cellstyle, getsmileymarkuplist(tmpicon)),
417 u'<tr><td colspan="3" style="%s"><textarea name="comtext" rows="%d" cols="%d">%s</textarea></td></tr>' % (cellstyle, Params.rows, Params.cols, tmptext),
418 u'<tr><td colspan="3" align="center" style="%s"><input type="submit" value="%s"></td></tr>' % (cellstyle, _('Save')),
419 u'</table>',
420 u'<input type="hidden" name="action" value="show" >',
421 u'<input type="hidden" name="comrev" value="%s">' % comrev,
422 u'<input type="hidden" name="commentaction" value="addcomment%d">' % Globs.formid,
423 u'</form>',
424 u'</div>',
425 ]
426
427
428 return u'\n'.join(html2)
429
430 def addcomment(macro, comicon, comauthor, comtext, compasswd, comrev):
431 # Add a comment with inputs
432
433 request = Globs.macro.request
434 cfg = request.cfg
435 _ = request.getText
436
437 # check input
438 if comicon and (not comicon in config.smileys.keys()):
439 message('Please use smiley markup only')
440 return 0
441
442 if Params.maxlength and (len(comtext) > Params.maxlength):
443 message('Comment text is limited to %d characters. (%d characters now)' % (Params.maxlength, len(comtext)) )
444 return 0
445
446 if not comtext.strip():
447 message('Please fill the comment text')
448 return 0
449
450 datapagename = Globs.datapagename
451
452 pg = PageEditor( request, datapagename )
453 pagetext = pg.get_raw_body()
454
455 comtext = convertdelimiter(comtext)
456
457 if request.user.valid:
458 comloginuser = 'TRUE'
459 comauthor = request.user.name
460 else:
461 comloginuser = ''
462 comauthor = convertdelimiter(comauthor)
463
464 newcomment = [
465 u'{{{',
466 u'%s' % comicon,
467 u'%s' % comauthor,
468 u'%s' % time.strftime(cfg.datetime_fmt, time.localtime(time.time())),
469 u'',
470 u'%s' % comtext,
471 u'}}}',
472 u'##PASSWORD %s' % compasswd,
473 u'##LOGINUSER %s' % comloginuser,
474 ]
475
476 newpagetext = u'%s\n\n%s' % (pagetext, u'\n'.join(newcomment))
477
478 if not pg.exists():
479 action = 'SAVENEW'
480 defaultacl = Globs.defaultacl
481 warnmessages = '\'\'\'\'\'DO NOT EDIT THIS PAGE!!\'\'\' This page is automatically generated by Page``Comment macro.\'\'\n----'
482 newpagetext = u'%s\n%s\n%s' % (defaultacl, warnmessages, newpagetext)
483 else:
484 action = 'SAVE'
485
486 newpagetext = pg.normalizeText( newpagetext )
487
488 comment = 'New comment by "%s"' % comauthor
489 pg._write_file(newpagetext, action, u'Modified by PageComment macro')
490 addLogEntry(request, 'COMNEW', Globs.pagename, comment)
491
492 # message(_('The comment is added'))
493 message(_('Thank you for your changes. Your attention to detail is appreciated.'))
494 return 1
495
496 def showcomment():
497
498 request = Globs.macro.request
499 _ = request.getText
500
501 commentlist = fetchcomments()
502
503 if Params.newerfirst:
504 commentlist.reverse()
505
506 html = []
507 cur_index = 0
508 cellstyle = u'border-width: 0px; border-top-width: 1px; vertical-align: top; font-size: 0.9em; line-height: 1em;'
509
510 html.append(u'<div id="commentlist"><table width="100%" class="commentlist">')
511
512 for item in commentlist:
513 if Globs.admin or (item['loginuser'] and request.user.valid and request.user.name == item['name']):
514 htmlcommentdel = [
515 u' <font style="font-size: 0.9em;">',
516 u'<a style="color: #aa0000;" href="javascript: requesttodeleteadmin%d(document.delform%d, \'%s\');" title="%s">X</a>' % (Globs.formid, Globs.formid, item['key'], _('Delete')),
517 u'</font>',
518 ]
519 elif item['loginuser']:
520 htmlcommentdel = []
521
522 else:
523 htmlcommentdel = [
524 u' <font style="font-size: 0.9em;">',
525 u'<a style="color: #aa0000;" href="javascript: requesttodelete%d(document.delform%d, \'%s\');" title="%s">X</a>' % (Globs.formid, Globs.formid, item['key'], _('Delete')),
526 u'</font>',
527 ]
528
529 htmlcomment = [
530 u'<tr><td class="commenticon" style="%s width: 20px;">%s</td>' % (cellstyle, getsmiley(item['icon'])),
531 u'<td class="commentauthor" style="%s"' % cellstyle,
532 u'>%s</td>' % converttext(item['name']),
533 u'<td style="%s width: 10px;"> </td>' % cellstyle,
534 u'<td class="commenttext" style="%s width: 100%%;">%s</td>' % (cellstyle, converttext(item['text'])),
535 u'<td class="commentdate" style="%s text-align: right; font-size: 0.8em; " nowrap>%s%s</td></tr>' % (cellstyle, item['date'].replace(' ', '<br>'), u''.join(htmlcommentdel)),
536 ]
537
538 html.append(u'\n'.join(htmlcomment))
539
540 html.append(u'</table></div>')
541
542 return u'\n'.join(html)
543
544 def getescapedsectionname(targettext):
545 regex = r'\W'
546 pattern = re.compile(regex, re.UNICODE)
547 sectionname = pattern.sub('', targettext)
548
549 return sectionname
550
551
552 def getsmiley(markup):
553
554 if markup in config.smileys.keys():
555 formatter = Globs.macro.formatter
556 return formatter.smiley(markup)
557 else:
558 return ''
559
560
561 def converttext(targettext):
562 # Converts some special characters of html to plain-text style
563 # What else to handle?
564
565 # targettext = targettext.strip()
566 targettext = targettext.replace(u'&', '&')
567 targettext = targettext.replace(u'>', '>')
568 targettext = targettext.replace(u'<', '<')
569 targettext = targettext.replace(u'\n', '<br>')
570 targettext = targettext.replace(u'"', '"')
571 targettext = targettext.replace(u'\t', ' ')
572 targettext = targettext.replace(u' ', ' ')
573
574 return targettext
575
576 def convertdelimiter(targettext):
577 # Converts delimeter to other string to avoid a crash
578
579 targettext = targettext.replace('{{{', '{ { {')
580 targettext = targettext.replace('}}}', '} } }')
581
582 return targettext
583
584
585 def deleteform():
586 # Javascript codes for deleting or restoring a comment
587
588 request = Globs.macro.request
589 _ = request.getText
590
591 htmlresult = []
592
593 html = [
594 '<script language="javascript">',
595 '<!--',
596 ]
597 htmlresult.append(u'\n'.join(html))
598
599 html = [
600 ' function requesttodeleteadmin%d(delform, comkey) {' % Globs.formid,
601 ' if (confirm("%s")) {;' % _('Really delete this page?'),
602 ' delform.delkey.value = comkey;',
603 ' delform.delpasswd.value = "****";',
604 ' delform.submit();',
605 ' }',
606 ' }',
607 ' function requesttodelete%d(delform, comkey) {' % Globs.formid,
608 ' var passwd = prompt("%s:", "");' % _('Please specify a password!'),
609 ' if(!(passwd == "" || passwd == null)) {',
610 ' delform.delkey.value = comkey;',
611 ' delform.delpasswd.value = passwd;',
612 ' delform.submit();',
613 ' }',
614 ' }',
615 ]
616
617 htmlresult.append(u'\n'.join(html))
618
619 html = [
620 '//-->',
621 '</script>',
622 '<form name="delform%d" action="%s#pagecomment%d" METHOD="post">' % (Globs.formid, Globs.cursubname, Globs.formid),
623 '<input type="hidden" value="show" name="action">',
624 '<input name="delpasswd" type="hidden" value="****">',
625 '<input name="delkey" type="hidden" value="">',
626 '<input type="hidden" name="commentaction" value="delcomment%s">' % Globs.formid,
627 '</form>',
628 ]
629 htmlresult.append(u'\n'.join(html))
630
631 return u'\n'.join(htmlresult)
632
633
634 def filtercomment(index='', name='', passwd=''):
635
636 # filter by index
637 if index:
638 filteredlist1 = fetchcomments(index, index)
639 else:
640 filteredlist1 = fetchcomments()
641
642 # filter by name
643 filteredlist2 = []
644 if name:
645 for item in filteredlist1:
646 if name == item['name']:
647 filteredlist2.append(item)
648 else:
649 filteredlist2 = filteredlist1
650
651 # filter by password
652 filteredlist3 = []
653 if passwd:
654 for item in filteredlist2:
655 if passwd == item['passwd']:
656 filteredlist3.append(item)
657 else:
658 filteredlist3 = filteredlist2
659
660 return filteredlist3
661
662
663 def fetchcomments(startindex=1, endindex=9999):
664
665 commentlist = []
666
667 request = Globs.macro.request
668 formatter = Globs.macro.formatter
669 datapagename = Globs.datapagename
670
671 pg = Page( request, datapagename )
672 pagetext = pg.get_raw_body()
673
674 regex = r'^(#acl\s*.*)$'
675 pattern = re.compile(regex, re.UNICODE + re.MULTILINE + re.IGNORECASE)
676 pagetext = pattern.sub('', pagetext)
677
678 regex = ur"""
679 ^[\{]{3}\n
680 ^(?P<icon>[^\n]*)\n
681 ^(?P<name>[^\n]*)\n
682 ^(?P<date>[^\n]*)\n\n
683 ^(?P<text>\s*.*?[^}]*)[\}]{3}[\n]*
684 ^[#]{2}PASSWORD[ ](?P<passwd>[^\n]*)[\n]*
685 ^[#]{2}LOGINUSER[ ](?P<loginuser>[^\n]*)[\n]*"""
686
687 pattern = re.compile(regex, re.UNICODE + re.MULTILINE + re.VERBOSE)
688 commentitems = pattern.findall(pagetext)
689
690 cur_index = 0
691
692 for item in commentitems:
693 comment = {}
694 cur_index += 1
695
696 if cur_index < startindex:
697 continue
698
699 comment['index'] = cur_index
700 comment['icon'] = item[0]
701 comment['name'] = item[1]
702 comment['date'] = item[2]
703 comment['text'] = item[3]
704 comment['passwd'] = item[4]
705 comment['loginuser'] = item[5]
706
707 # experimental
708 comment['key'] = comment['date'].strip()
709
710 commentlist.append(comment)
711
712 if cur_index >= endindex:
713 break
714
715 return commentlist
716
717 def deletecomment(macro, delkey, delpasswd):
718 # Deletes a comment with given index and password
719
720 request = Globs.macro.request
721 formatter = Globs.macro.formatter
722 datapagename = Globs.datapagename
723 _ = request.getText
724
725 pg = PageEditor( request, datapagename )
726 pagetext = pg.get_raw_body()
727
728 regex = ur"""
729 (?P<comblock>^[\{]{3}\n
730 ^(?P<icon>[^\n]*)\n
731 ^(?P<name>[^\n]*)\n
732 ^(?P<date>[^\n]*)[\n]+
733 ^(?P<text>\s*.*?[^}]*)[\}]{3}[\n]*
734 ^[#]{2}PASSWORD[ ](?P<passwd>[^\n]*)[\n]*
735 ^[#]{2}LOGINUSER[ ](?P<loginuser>[^\n]*)[\n$]*)"""
736
737 pattern = re.compile(regex, re.UNICODE + re.MULTILINE + re.VERBOSE)
738 commentitems = pattern.findall(pagetext)
739
740 for item in commentitems:
741
742 if delkey == item[3].strip():
743 comauthor = item[2]
744 if Globs.admin or (request.user.valid and request.user.name == comauthor) or delpasswd == item[5]:
745 newpagetext = pagetext.replace(item[0], '', 1)
746
747 action = 'SAVE'
748 comment = 'comment deleted by "%s"' % comauthor
749 pg._write_file(newpagetext, action, u'Modified by PageComment macro')
750 addLogEntry(request, 'COMDEL', Globs.pagename, comment)
751
752 message(_('The comment is deleted'))
753
754 return
755 else:
756 message(_('Sorry, wrong password.'))
757 return
758
759 message(_('No such comment'))
760
761
762 def addLogEntry(request, action, pagename, msg):
763 # Add an entry to the edit log on adding comments.
764 from MoinMoin.logfile import editlog
765 t = wikiutil.timestamp2version(time.time())
766 msg = unicode(msg)
767
768 # TODO: for now we simply write 2 logs, maybe better use some multilog stuff
769 # Write to global log
770 log = editlog.EditLog(request)
771 log.add(request, t, 99999999, action, pagename, request.remote_addr, msg)
772
773 # Write to local log
774 log = editlog.EditLog(request, rootpagename=pagename)
775 log.add(request, t, 99999999, action, pagename, request.remote_addr, msg)
776
777 def getsmileymarkuplist(defaulticon):
778
779 html = [
780 u'<select name="comicon">',
781 u' <option value=""></option>',
782 ]
783
784 for smiley in config.smileys.keys():
785 if defaulticon.strip() == smiley:
786 html.append(u' <option selected>%s</option>' % wikiutil.escape(smiley))
787 else:
788 html.append(u' <option>%s</option>' % wikiutil.escape(smiley))
789
790 html.append(u'</select>')
791
792 return u'\n'.join(html)
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.