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;">&nbsp;</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'&', '&amp')
 567     targettext = targettext.replace(u'>', '&gt;')
 568     targettext = targettext.replace(u'<', '&lt;')
 569     targettext = targettext.replace(u'\n', '<br>')
 570     targettext = targettext.replace(u'"', '&quot;')
 571     targettext = targettext.replace(u'\t', '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;')
 572     targettext = targettext.replace(u'  ', '&nbsp;&nbsp;')
 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.
  • [get | view] (2008-04-30 13:57:43, 45.4 KB) [[attachment:PageComment2-0.981-only_logged_in_user.py]]
  • [get | view] (2005-11-18 08:51:22, 19.1 KB) [[attachment:PageComment2-090.py]]
  • [get | view] (2005-11-18 16:50:49, 21.6 KB) [[attachment:PageComment2-091.py]]
  • [get | view] (2005-11-19 06:31:25, 21.8 KB) [[attachment:PageComment2-092.py]]
  • [get | view] (2005-11-20 07:24:45, 26.0 KB) [[attachment:PageComment2-094.py]]
  • [get | view] (2005-11-20 08:56:20, 26.1 KB) [[attachment:PageComment2-095.py]]
  • [get | view] (2005-11-29 20:06:02, 31.4 KB) [[attachment:PageComment2-096.py]]
  • [get | view] (2006-01-05 08:41:48, 44.6 KB) [[attachment:PageComment2-097.py]]
  • [get | view] (2006-04-17 13:35:45, 45.4 KB) [[attachment:PageComment2-098.py]]
  • [get | view] (2006-05-02 00:31:43, 45.4 KB) [[attachment:PageComment2-0981.py]]
  • [get | view] (2008-01-29 19:38:32, 45.4 KB) [[attachment:PageComment2-099-moin16.py]]
  • [get | view] (2007-05-01 15:51:21, 46.5 KB) [[attachment:PageComment2-099-rg.py]]
  • [get | view] (2008-02-19 19:41:42, 45.4 KB) [[attachment:PageComment2-0991-moin16.py]]
  • [get | view] (2008-02-27 14:38:41, 45.8 KB) [[attachment:PageComment2-0992-moin16.py]]
  • [get | view] (2011-07-19 13:47:24, 47.7 KB) [[attachment:PageComment2-0993-moin193.py]]
  • [get | view] (2007-05-01 15:52:09, 1.6 KB) [[attachment:PageComment2-981-099-rg.diff.gz]]
  • [get | view] (2005-11-29 19:59:21, 42.1 KB) [[attachment:snap-pagecomment2.jpg]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.