![]() | This user account is a bot operated by Misza13 (talk). It is used to make repetitive automated or semi-automated edits that would be extremely tedious to do manually, in accordance with the bot policy. This bot does not yet have the approval of the community, or approval has been withdrawn or expired, and therefore shouldn't be making edits that appear to be unassisted except in the operator's or its own user and user talk space. Administrators: if this bot is making edits that appear to be unassisted to pages not in the operator's or its own userspace, please block it. |
Emergency bot shutoff button
Administrators: Use this button if the bot is malfunctioning. (direct link)
Non-administrators can a malfunctioning bot to Wikipedia:Administrators' noticeboard/Incidents.
This bot's IRC companion sits in the cvn-wp-en channel and uses this account to edit {{Wdefcon}} on request made in the channel.
Detailed instructions: tools:~misza13/cgi-bin/wdefconbot.py
Archived approval of the bot is available at Wikipedia:Bots/Requests for approvals/Archive4#User:WdefconBot
Source
editThis is the bot's source code. It assumes that the file lies in the pywikipedia/ directory (an already logged-in pywikipedia framework is required to work) and is executed from there. To adjust the configuration, modify constants specified at the end of file.
#!/usr/bin/env python
import re, socket, time, wikipedia
class WdefconBot:
def __init__(self):
self.LASTLEVEL = '0'
self.LASTEDITED = 0
self.LOGfile = open('defbotlog.txt', 'a+')
self.site = wikipedia.getSite()
self.IRC = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
def log(self,nick,text):
TIME = time.gmtime()
self.LOGfile.write("[%04d-%02d-%02d %02d:%02d.%02d] (%s) :%s\n" % (TIME[0:6] + (nick, text)))
self.LOGfile.flush()
def irc_conn(self,server,port):
self.IRC.connect((server,port))
def login(self,nickname, password, username, realname, hostname='hostname', servername='server'):
self.IRC.send("PASS %s\n" % password)
self.IRC.send("USER %s %s %s :%s\n" % (username, hostname, servername, realname))
self.IRC.send("NICK %s\n" % nickname)
self.nick = nickname
def join(self,channel):
self.IRC.send("JOIN %s\n" % channel)
self.channel = channel
def do_say(self,target,text):
self.IRC.send("PRIVMSG %s :%s\n" % (target, text))
def do_ctcp(self,target,text):
self.IRC.send("PRIVMSG %s :\001%s\001\n" % (target, text))
def user_access(self,hostmask):
asteriskRE = re.compile('\*')
for mask in ACCESSLIST.keys():
maskRE = re.compile(asteriskRE.sub('.*?',mask))
if maskRE.match(hostmask):
return ACCESSLIST[mask]
return 0
def get_defcon(self):
wdefcon = wikipedia.Page(self.site,"Template:Wdefcon")
text = wdefcon.get()
p = text.find('\n|level=')
if p == -1:
return ("-1","");
p1 = text.find('\n|info=')
p2 = text.find('\n|align=')
if p1 == -1 or p2 == -1:
return (text[p+8], "Unknown. Template damaged?")
info = text[p1+7:p2]
info = re.compile('\n|<!--.*?-->|<.+?>').sub('',info)
info = re.compile('\[\[[^\|]*\|(.*)\]\]').sub(r'\1',info)
info = re.compile('\[\[([^\|]*?)\]\]').sub(r'\1',info)
return (text[p+8],info)
def do_defcon_check(self,force):
defcon = self.get_defcon()
if defcon[0] == self.LASTLEVEL and force == 0:
return
self.log("WdefconBot","Wdefcon level is %s and the description is: %s" % defcon)
self.LASTLEVEL = defcon[0]
if defcon[0] == -1:
self.do_say(self.channel,"Error while retrieving level! Template vandalised?")
else:
self.do_say(self.channel,"The current WikiDefcon level is %s and the description is: %s" % defcon)
def main_loop(self):
try:
while True:
buffer = self.IRC.recv(1024)
if buffer == '':
break
msg = buffer.split()
if msg[0] == "PING":
self.IRC.send("PONG %s\n" % msg[1])
if msg[1] == 'PRIVMSG' and msg[2].lower() == NICKNAME.lower() and msg[3].find('VERSION') != -1:
nick = msg[0][:msg[0].find("!")].lstrip(':')
print "Replying to VERSION by %s..." % nick
self.IRC.send('NOTICE %s :\001VERSION Misza\'s WdefconBot 2.0\001\n' % nick)
if nick == 'freenode-connect':
self.join(CHANNEL)
continue
if msg[1] == 'PRIVMSG':
self.log(msg[0].lstrip(':'),' '.join(msg[3:]).lstrip(':'))
command = msg[3].lower().lstrip(':')
if command == 'force':
if self.user_access(msg[0]) >= 80:
self.IRC.send(' '.join(msg[4:])+'\n')
continue
if command == 'say':
if bot.user_access(msg[0]) >= 50:
self.do_say(self.channel,' '.join(msg[4:]))
continue
if command == 'act':
if bot.user_access(msg[0]) >= 50:
self.do_ctcp(self.channel,'ACTION ' + ' '.join(msg[4:]))
continue
if command == 'msg':
if bot.user_access(msg[0]) >= 60:
self.do_say(msg[4],' '.join(msg[5:]))
continue
if command == 'ctcp':
if bot.user_access(msg[0]) >= 60:
self.do_ctcp(msg[4],' '.join(msg[5:]))
continue
if command == 'quit':
if self.user_access(msg[0]) >= 0:
self.IRC.send("PART %s :Bye!\n" % CHANNEL)
self.IRC.send("QUIT\n")
continue
if msg[1] == 'PRIVMSG' and msg[2] == CHANNEL:
nick_name = msg[0][:msg[0].find("!")]
nick = nick_name.lstrip(':')
command = msg[3].lower().lstrip(':')
params = ' '.join(msg[4:])
if command == '!wdefcon' and self.user_access(msg[0]) >= 0:
self.log(msg[0].lstrip(':'),'!wdefcon '+params)
if params == '':
self.do_defcon_check(1)
continue
edit = re.match('edit level=([0-5]) info=(.*)',params)
if edit:
TIME = time.time()
if TIME - self.LASTEDITED < EDITINTERVAL*60:
self.do_say(self.channel,nick +
': I have edited %0.1f minutes ago. I\'m disallowed to edit faster than once every %d minutes.' %
((TIME-self.LASTEDITED)/60, EDITINTERVAL))
continue
self.LASTEDITED = TIME
wdefcon = wikipedia.Page(self.site,TEMPLATEPAGE)
wikipedia.setAction('Changing level to '+
edit.group(1)+' on behalf of IRC user '+nick)
wdefcon.put('{{subst:User:MiszaBot/Wdefcon template|level=' +
edit.group(1)+'|info='+edit.group(2)+' —IRC user \'\''+nick+
'\'\' ~~~~~|noinclude1=<noinclude>|noinclude2=</noinclude>}}')
self.do_ctcp(self.channel,
'ACTION has set the WikiDefcon level to %s and description to "%s"' % edit.groups())
continue
self.do_say(self.channel,nick+
': Syntax for editing is: !wdefcon edit level=[0-5] info=<situation description>')
continue
if re.match('\[\[User:.*?\]\].*?\[\[Template:Wdefcon\]\].*?".*"',' '.join(msg[3:])):
self.do_defcon_check(0)
continue
finally:
self.LOGfile.close()
wikipedia.stopme()
if __name__ == '__main__':
SERVER = 'irc.freenode.net'
PORT = 6667
NICKNAME = 'WdefconBot2' #Put your bot's nickname
PASSWORD = 'XXXXX' #Put your NickServ password here
USERNAME = 'defcon'
REALNAME = 'Misza\'s WdefconBot 2.0'
CHANNEL = '#vcn-tech' #Channel to work in (needs a pgkbot clone to report changes)
TEMPLATEPAGE = 'Template:Wdefcon'
ACCESSLIST = { #Add users' hostmasks and their access levels (100 being owner)
'*!*@wikimedia/Misza13': 100
} #Set a user's access negative to make the bot ignore him
EDITINTERVAL = 5 #Minimal timespan (in minutes) between edits
bot = WdefconBot()
bot.irc_conn(SERVER,PORT)
bot.login(NICKNAME,PASSWORD,USERNAME,REALNAME)
bot.join(CHANNEL)
bot.main_loop()