-
Notifications
You must be signed in to change notification settings - Fork 2
/
plugin.py
174 lines (143 loc) · 5.36 KB
/
plugin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
###
# Copyright (c) 2012, Martin Milata
# Published under WTFPL.
###
import json
import time
import urllib.request, urllib.parse, urllib.error
import supybot.conf as conf
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.ircmsgs as ircmsgs
import supybot.schedule as schedule
import supybot.callbacks as callbacks
def iso_to_timestamp(s):
st = time.strptime(s, '%Y-%m-%dT%H:%M:%SZ')
return int(time.mktime(st))
filename = conf.supybot.directories.data.dirize('MediaWikiRecentChanges.last')
class MediaWikiRecentChanges(callbacks.Plugin):
"""
Announces recent changes of a MediaWiki instance. You need to set the
'url' config variable to the one you want to watch and the enable the
'announce' parameters for channels where you want the change notifications
to appear.
"""
def __init__(self, irc):
self.__parent = super(MediaWikiRecentChanges, self)
self.__parent.__init__(irc)
self.irc = irc
self.pluginConf = conf.supybot.plugins.MediaWikiRecentChanges
self.last_change = self.loadTimeStamp()
self.scheduleNextCheck()
def die(self):
# remove scheduler event
try:
schedule.removeEvent('mwrcEvent')
except KeyError:
pass
self.__parent.die()
def scheduleNextCheck(self):
def event():
self.log.debug('MWRC: Firing scheduler event')
try:
self.announceNewChanges(self.irc)
finally:
self.scheduleNextCheck()
self.log.debug('MWRC: Scheduling next check')
schedule.addEvent(event,
time.time() + self.pluginConf.waitPeriod(),
'mwrcEvent'
)
@wrap
def wikichanges(self, irc, msg, args):
"""takes no arguments
Prints latest changes on MediaWiki instance.
"""
try:
changes = self.getRecentChanges()
except Exception as e:
irc.reply('Error: ' + utils.web.strError(e))
else:
for change in changes:
irc.reply(change[1], prefixNick=False)
def getRecentChanges(self):
url = self.buildQueryURL()
#self.log.debug(url)
json_response = utils.web.getUrl(url)
response = json.loads(json_response)
messages = []
for change in response['query']['recentchanges']:
if change['type'] == 'edit':
msg = 'User {user} modified {url}'
elif change['type'] == 'new':
msg = 'User {user} created {url}'
else:
self.log.warning('Ignoring unknown change type: %s',
change['type'])
continue
msg = msg.format(user=change['user'],
url=self.buildTitleURL(change['title'])
)
if change['comment']:
msg = '{0} - {1}'.format(msg, change['comment'])
change_ts = iso_to_timestamp(change['timestamp'])
messages.append((change_ts, msg))
return messages[::-1]
def announceNewChanges(self, irc):
try:
changes = self.getRecentChanges()
except Exception as e:
self.log.error('MWRC: Cannot retrieve recent changes: %s' %
utils.web.strError(e))
return
changes = [change for change in changes if change[0] > self.last_change]
try:
self.last_change = max([change[0] for change in changes])
self.saveTimeStamp(self.last_change)
except ValueError:
pass
messages = [change[1] for change in changes]
chans = 0
for channel in list(irc.state.channels.keys()):
if self.pluginConf.announce.get(channel)():
chans += 1
for msg in messages:
irc.queueMsg(ircmsgs.privmsg(channel, msg))
def buildQueryURL(self):
url_parts = list(urllib.parse.urlparse(self.pluginConf.apiUrl()))
query = {
'action': 'query',
'list' : 'recentchanges',
'format': 'json',
'rcprop': 'user|comment|timestamp|title',
'rctype': 'edit|new',
}
if self.pluginConf.namespaces():
query['rcnamespace'] = '|'.join(map(str,
self.pluginConf.namespaces()))
if not self.pluginConf.showMinor():
query['rcshow'] = '!minor'
query['rclimit'] = self.pluginConf.limit()
url_parts[4] = urllib.parse.urlencode(query)
return urllib.parse.urlunparse(url_parts)
def buildTitleURL(self, title):
template = self.pluginConf.pageUrl()
return template.format(page=title.replace(' ', '_'))
def loadTimeStamp(self):
try:
with open(filename, 'r') as f:
contents = f.read()
return int(contents, 10)
except Exception as e:
self.log.error('MWRC: cannot load last change timestamp: %s' % e)
return 0
def saveTimeStamp(self, last_change):
try:
with open(filename, 'w') as f:
f.write(str(last_change))
except Exception as e:
self.log.error('MWRC: cannot save last change timestamp: %s' % e)
Class = MediaWikiRecentChanges
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: