1 # -*- coding: iso-8859-1 -*-
3 MoinMoin - Despam action
5 Mass revert changes done by some specific author / bot.
7 @copyright: 2005 by ???, Thomas Waldmann
8 @license: GNU GPL, see COPYING for details.
11 DAYS = 30 # we look for spam edits in the last x days
15 from MoinMoin.logfile import editlog
16 from MoinMoin.util.dataset import TupleDataset, Column
17 from MoinMoin.widget.browser import DataBrowserWidget
18 from MoinMoin import wikiutil, Page, PageEditor
19 from MoinMoin.macro import RecentChanges
21 def render(editor_tuple):
22 etype, evalue = editor_tuple
23 if etype in ('ip', 'email', ):
25 elif etype == 'interwiki':
30 ret = '%s:%s' % evalue
32 ret = repr(editor_tuple)
35 def show_editors(request, pagename, timestamp):
38 timestamp = int(timestamp * 1000000)
39 log = editlog.EditLog(request)
42 for line in log.reverse():
43 if line.ed_time_usecs < timestamp:
46 if not request.user.may.read(line.pagename):
49 editor = line.getInterwikiEditorData(request)
50 if not line.pagename in pages:
51 pages[line.pagename] = 1
52 editors[editor] = editors.get(editor, 0) + 1
54 editors = [(nr, editor) for editor, nr in editors.iteritems()]
58 pg = Page.Page(request, pagename)
60 dataset = TupleDataset()
61 dataset.columns = [Column('editor', label=_("Editor"), align='left'),
62 Column('pages', label=_("Pages"), align='right'),
63 Column('link', label='', align='left')]
64 for nr, editor in editors:
65 dataset.addRow((render(editor), unicode(nr),
66 pg.link_to(request, text=_("Select Author"),
69 'editor': repr(editor),
72 table = DataBrowserWidget(request)
73 table.setData(dataset)
74 return table.render(method="GET")
79 def show_pages(request, pagename, editor, timestamp):
82 timestamp = int(timestamp * 1000000)
83 log = editlog.EditLog(request)
85 # mimic macro object for use of RecentChanges subfunctions
87 macro.request = request
88 macro.formatter = request.html_formatter
90 request.write("<table>")
91 for line in log.reverse():
92 if line.ed_time_usecs < timestamp:
95 if not request.user.may.read(line.pagename):
98 if not line.pagename in pages:
99 pages[line.pagename] = 1
100 if repr(line.getInterwikiEditorData(request)) == editor:
101 line.time_tuple = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs))
102 request.write(RecentChanges.format_page_edits(macro, [line], timestamp))
107 <form method="post" action="%s">
108 <input type="hidden" name="action" value="Despam">
109 <input type="hidden" name="editor" value="%s">
110 <input type="submit" name="ok" value="%s">
113 ''' % (request.href(pagename), wikiutil.url_quote(editor), _("Revert all!")))
115 def revert_page(request, pagename, editor):
116 if not request.user.may.revert(pagename):
119 log = editlog.EditLog(request, rootpagename=pagename)
123 for line in log.reverse():
126 if repr(line.getInterwikiEditorData(request)) != editor:
129 if repr(line.getInterwikiEditorData(request)) != editor:
133 if rev == u"00000000": # page created by spammer
134 comment = u"Page deleted by Despam action"
135 pg = PageEditor.PageEditor(request, pagename, do_editor_backup=0)
137 savemsg = pg.deletePage(comment)
138 except pg.SaveError, msg:
139 savemsg = unicode(msg)
140 else: # page edited by spammer
141 oldpg = Page.Page(request, pagename, rev=int(rev))
142 pg = PageEditor.PageEditor(request, pagename, do_editor_backup=0)
144 savemsg = pg.saveText(oldpg.get_raw_body(), 0, extra=rev, action="SAVE/REVERT")
145 except pg.SaveError, msg:
146 savemsg = unicode(msg)
149 def revert_pages(request, editor, timestamp):
152 editor = wikiutil.url_unquote(editor)
153 timestamp = int(timestamp * 1000000)
154 log = editlog.EditLog(request)
157 for line in log.reverse():
158 if line.ed_time_usecs < timestamp:
161 if not request.user.may.read(line.pagename):
164 if not line.pagename in pages:
165 pages[line.pagename] = 1
166 if repr(line.getInterwikiEditorData(request)) == editor:
167 revertpages.append(line.pagename)
169 request.write("Pages to revert:<br>%s" % "<br>".join(revertpages))
170 for pagename in revertpages:
171 request.write("Begin reverting %s ...<br>" % pagename)
172 msg = revert_page(request, pagename, editor)
174 request.write("<p>%s: %s</p>" % (
175 Page.Page(request, pagename).link_to(request), msg))
176 request.write("Finished reverting %s.<br>" % pagename)
178 def execute(pagename, request):
180 # check for superuser
181 if not request.user.isSuperUser():
182 request.theme.add_msg(_('You are not allowed to use this action.'), "error")
183 return Page.Page(request, pagename).send_page()
185 editor = request.form.get('editor')
186 timestamp = time.time() - DAYS * 24 * 3600
187 ok = request.form.get('ok', 0)
189 request.theme.send_title("Despam", pagename=pagename)
190 # Start content (important for RTL support)
191 request.write(request.formatter.startContent("content"))
194 revert_pages(request, editor, timestamp)
196 show_pages(request, pagename, editor, timestamp)
198 request.write(show_editors(request, pagename, timestamp))
200 # End content and send footer
201 request.write(request.formatter.endContent())
202 request.theme.send_footer(pagename)
203 request.theme.send_closing_html()