c712028b1d01f793dc584c79c30568c950eff81d
[backwash] / backwash.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 # http://pywikipediabot.sourceforge.net/
5 # svn co http://svn.wikimedia.org/svnroot/pywikipedia/trunk/pywikipedia pywikipedia
6
7
8 import sys
9 import re
10 import iso8601
11 from simplemediawiki import MediaWiki
12
13 # TODO:
14 # - any space names in page names need to be turned into '_'s 
15 # - we need to de-interwikify any interwiki links given to Wiki:
16 # - normalize messages for non-unix linebreaks
17
18 class Wiki:
19     def __init__(self, url):
20         self.url = url
21         self.wiki = MediaWiki(self.url + 'api.php')
22
23     def get_revid_for_date(self, page, date):
24         wc = self.wiki.call({
25             'action': 'query',
26             'prop': 'revisions',
27             'titles': page,
28             'rvlimit': 1,
29             'redirects': 'true',
30             'rvstart': date,
31             'rvdir' : 'newer',
32             'rvprop' : 'timestamp|ids'})
33         pages = wc['query']['pages']
34         return pages[pages.keys()[0]]['revisions'][0]['revid']
35
36     def get_edit_token(self, page):
37         wc = self.wiki.call({
38             'action' : 'query',
39             'prop': 'info',
40             'page': page,
41             'intoken' : 'edit'})
42         import pprint
43         pprint.pprint(wc)
44         pages = wc['query']['pages']
45         page = pages[pages.keys()[0]]
46         return page['edittoken']
47
48     def get_talk_page(self, page):
49         if ':' in page:
50             (namespace, rest) = page.split(':', 1)
51             return '%s_talk:%s' % (namespace, rest)
52         else:
53             return 'Talk:%s' % page
54
55     def get_page_text(self, page):
56         wc = self.wiki.call({
57             'action': 'query',
58             'prop': 'revisions',
59             'titles': page,
60             'redirects': 'true',
61             'rvprop' : 'content'})
62         pages = wc['query']['pages']
63         return pages[pages.keys()[0]]['revisions'][0]['revid']
64
65         #query&prop=revisions&rvprop=content&format=xml&titles=Main%20Page
66         pass
67         
68     def append_to_talk_page(self, page):
69         talk_page = self.get_talk_page(page)
70         edit_token = self.get_edit_token(page)
71
72         wc = self.wiki.call({
73             'action' : 'edit',
74             'title': talk_page,
75             'bot' : 'true',
76             'token' : self.get_edit_token(page)})
77         import pprint
78         pprint.pprint(wc)
79         pages = wc['query']['pages']
80         page = pages[pages.keys()[0]]
81         return page['edittoken']
82
83         
84
85 def make_link(wiki, page, revision):
86     return '%s/index.php?title=%s&oldid=%s' % (wiki, page, revision)
87
88 class WikiEdit:
89     fields = ['page', 'date', 'e-mail', 'export-date', 'redirect', 'page-revision', 'user-agent', 'username', 'wiki']
90     datefields = ['date', 'export-date']
91
92     def __init__(self, headers={}, body=''):
93         self.headers = headers
94         self.body = body
95
96     def to_comment(self):
97         assembly = [('date', 'On %s,'),
98                     ('username', ' [[User:%s]]'), 
99                     (' an anonymous user'),
100                     ('e-mail', ' (<a href="mailto:%s">e-mail</a>)'),
101                     (' made a comment',),
102                     ('user-agent', ' (using %s)')
103                     ]
104
105         comment = ": "
106         for stage in assembly:
107             if len(stage) == 1:
108                 comment += stage[0]
109             elif self.headers.has_key(stage[0]):
110                 comment += stage[1] % (self.headers[stage[0]])
111             elif len(stage) == 3:
112                 comment += stage[2]
113
114         return comment + ":\n\n" + self.body
115
116     @classmethod
117     def from_string(cls, s):
118         body_index = s.index('\n\n')
119         # headers = dict([(X[:X.index(':')], X[X.index(':')+1:].strip()) for X in s[:body_index].split('\n')])
120         kvs = [re.split(': *', key_value, 1) for key_value in s[:body_index].splitlines()]
121         headers = dict([(key.lower(), value) for (key, value) in kvs])
122         body = s[body_index+2:]
123         return cls(headers, body)
124
125
126     
127     # @classmethod
128     # defomrom_string(cls, s):
129     #     body_index = s.index('\n\n')
130     # ders = dict([(X[:X.index(':')], X[X.index(':')+1:].strip()) for X in s[:body_index].split('\n')])
131     #     kvs = [re.split(': *', key_value, 1) for key_value in s[:body_index].splitlines()]
132     #     headers = dict([(key.lower(), value) for (key, value) in kvs])
133     #     print headers
134     #     body = s[body_index+2:]
135     #     return cls(headers, body)
136
137
138 def parse_edits(lines):
139     edits = []
140     #cur = WikiEdit()
141     #message_body = False
142     acc = ""
143     for line in lines:
144         if line.startswith('Page:'):
145             if '\n\n' in acc:
146                 we = WikiEdit.from_string(acc)
147                 edits.append(we)
148                 print we, we.headers, we.body
149                 #sys.exit(0)
150                 acc = ""
151         acc += line
152     
153         #     cur = WikiEdit()
154         #     edits.append(cur)
155         #     message_body = False
156
157         # if line == '\n':
158         #     message_body = True
159
160         # elif message_body:
161         #     cur.body += line
162
163         # else:
164         #     key_end = line.index(':')
165         #     cur.headers[line[:key_end]] = line[key_end+1:].strip()
166
167     if acc != '':
168         we = WikiEdit.from_string(acc)
169         edits.append(we)
170         print (we, we.headers, we.body)
171
172     return edits
173
174 if __name__ =='__main__':
175     # parse the .wpe file on standard
176     edits = parse_edits(sys.stdin)
177
178     for edit in edits:
179         # if there is an export date but no revision, lets go to wiki an
180         # find out what the revision id is
181         if edit.headers.has_key("export-date") and \
182                 not edit.headers.has_key("page-revision"):
183             wiki = Wiki(edit.headers['wiki'])
184             revid = wiki.get_revid_for_date(edit.headers["page"], edit.headers["export-date"])
185         else:
186             revid = edit.headers['page-revision']
187
188         print revid
189         # rvdir=newer&rvprop=timestamp|ids
190
191         edit_msg = edit.to_comment()
192         print edit_msg
193
194 # iso8601.parse_date("2007-06-20T12:34:40+03:00")

Benjamin Mako Hill || Want to submit a patch?