| @@ -1,114 +1,12 @@ | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| ###### | |||||
| ###### | |||||
| ###### NOTE: | ###### NOTE: | ||||
| ###### This is an old commands file from the previous version of EarwigBot. | ###### This is an old commands file from the previous version of EarwigBot. | ||||
| ###### It is not used by the new EarwigBot and is simply here for reference | ###### It is not used by the new EarwigBot and is simply here for reference | ||||
| ###### when developing new commands. | ###### when developing new commands. | ||||
| ###### | |||||
| ###### | |||||
| ### EarwigBot | ### EarwigBot | ||||
| ## Import basics. | |||||
| import sys, socket, string, time, codecs, os, traceback, thread, re, urllib, web, math, unicodedata | |||||
| ## Import our functions. | |||||
| import config | |||||
| ## Set up constants. | |||||
| HOST, PORT, NICK, IDENT, REALNAME, CHANS, REPORT_CHAN, WELCOME_CHAN, HOST2, CHAN2, OWNER, ADMINS, ADMINS_R, PASS = config.host, config.port, config.nick, config.ident, config.realname, config.chans, config.report_chan, config.welcome_chan, config.host2, config.chan2, config.owner, config.admins, config.admin_readable, config.password | |||||
| def get_commandList(): | |||||
| return {'quiet': 'quiet', | |||||
| 'welcome': 'welcome', | |||||
| 'greet': 'welcome', | |||||
| 'linker': 'linker', | |||||
| 'auth': 'auth', | |||||
| 'access': 'access', | |||||
| 'join': 'join', | |||||
| 'part': 'part', | |||||
| 'restart': 'restart', | |||||
| 'quit': 'quit', | |||||
| 'die': 'quit', | |||||
| 'msg': 'msg', | |||||
| 'me': 'me', | |||||
| 'calc': 'calc', | |||||
| 'dice': 'dice', | |||||
| 'tock': 'tock', | |||||
| 'beats': 'beats', | |||||
| 'copyvio': 'copyvio', | |||||
| 'copy': 'copyvio', | |||||
| 'copyright': 'copyvio', | |||||
| 'dict': 'dictionary', | |||||
| 'dictionary': 'dictionary', | |||||
| 'ety': 'etymology', | |||||
| 'etymology': 'etymology', | |||||
| 'lang': 'langcode', | |||||
| 'langcode': 'langcode', | |||||
| 'num': 'number', | |||||
| 'number': 'number', | |||||
| 'count': 'number', | |||||
| 'c': 'number', | |||||
| 'nick': 'nick', | |||||
| 'op': 'op', | |||||
| 'deop': 'deop', | |||||
| 'voice': 'voice', | |||||
| 'devoice': 'devoice', | |||||
| 'pend': 'pending', | |||||
| 'pending': 'pending', | |||||
| 'sub': 'submissions', | |||||
| 'submissions': 'submissions', | |||||
| 'praise': 'praise', | |||||
| 'leonard': 'leonard', | |||||
| 'groovedog': 'groovedog', | |||||
| 'earwig': 'earwig', | |||||
| 'macmed': 'macmed', | |||||
| 'cubs197': 'cubs197', | |||||
| 'sparksboy': 'sparksboy', | |||||
| 'tim_song': 'tim_song', | |||||
| 'tim': 'tim_song', | |||||
| 'blurpeace': 'blurpeace', | |||||
| 'sausage': 'sausage', | |||||
| 'mindstormskid': 'mindstormskid', | |||||
| 'mcjohn': 'mcjohn', | |||||
| 'fetchcomms': 'fetchcomms', | |||||
| 'trout': 'trout', | |||||
| 'kill': 'kill', | |||||
| 'destroy': 'kill', | |||||
| 'murder': 'kill', | |||||
| 'fish': 'fish', | |||||
| 'report': 'report', | |||||
| 'commands': 'commands', | |||||
| 'help': 'help', | |||||
| 'doc': 'help', | |||||
| 'documentation': 'help', | |||||
| 'mysql': 'mysql', | |||||
| 'remind': 'reminder', | |||||
| 'reminder': 'reminder', | |||||
| 'notes': 'notes', | |||||
| 'note': 'notes', | |||||
| 'about': 'notes', | |||||
| 'data': 'notes', | |||||
| 'database': 'notes', | |||||
| 'hash': 'hash', | |||||
| 'lookup': 'lookup', | |||||
| 'ip': 'lookup' | |||||
| } | |||||
| def main(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| try: | |||||
| parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s) | |||||
| except Exception: | |||||
| trace = traceback.format_exc() # Traceback. | |||||
| print trace # Print. | |||||
| lines = list(reversed(trace.splitlines())) # Convert lines to process traceback.... | |||||
| report2 = [lines[0].strip()] | |||||
| for line in lines: | |||||
| line = line.strip() | |||||
| if line.startswith('File "/'): | |||||
| report2.append(line[0].lower() + line[1:]) | |||||
| break | |||||
| else: report2.append('source unknown') | |||||
| say(report2[0] + ' (' + report2[1] + ')', chan) | |||||
| def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | ||||
| authy = auth(host) | authy = auth(host) | ||||
| if command == "access": | if command == "access": | ||||
| @@ -117,128 +15,6 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| reply(a, chan, nick) | reply(a, chan, nick) | ||||
| reply(b, chan, nick) | reply(b, chan, nick) | ||||
| return | return | ||||
| if command == "join": | |||||
| if authy == "owner" or authy == "admin": | |||||
| try: | |||||
| channel = line2[4] | |||||
| except Exception: | |||||
| channel = chan | |||||
| s.send("JOIN %s\r\n" % channel) | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "part": | |||||
| if authy == "owner" or authy == "admin": | |||||
| try: | |||||
| channel = line2[4] | |||||
| except Exception: | |||||
| channel = chan | |||||
| s.send("PART %s\r\n" % channel) | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "restart": | |||||
| import thread | |||||
| if authy == "owner": | |||||
| s.send("QUIT\r\n") | |||||
| time.sleep(5) | |||||
| os.system("nice -15 python main.py") | |||||
| exit() | |||||
| else: | |||||
| reply("Only the owner, %s, can stop the bot. This incident will be reported." % OWNER, chan, nick) | |||||
| return | |||||
| if command == "quit" or command == "die": | |||||
| if authy != "owner": | |||||
| if command != "suicide": | |||||
| reply("Only the owner, %s, can stop the bot. This incident will be reported." % OWNER, chan, nick) | |||||
| else: | |||||
| say("\x01ACTION hands %s a gun... have fun :D\x01" % nick, nick) | |||||
| else: | |||||
| if command == "suicide": | |||||
| say("\x01ACTION stabs himself with a knife.\x01", chan) | |||||
| time.sleep(0.2) | |||||
| try: | |||||
| s.send("QUIT :%s\r\n" % ' '.join(line2[4:])) | |||||
| except Exception: | |||||
| s.send("QUIT\r\n") | |||||
| __import__('os')._exit(0) | |||||
| return | |||||
| if command == "msg": | |||||
| if authy == "owner" or authy == "admin": | |||||
| say(' '.join(line2[5:]), line2[4]) | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "me": | |||||
| if authy == "owner" or authy == "admin": | |||||
| say("\x01ACTION %s\x01" % ' '.join(line2[5:]), line2[4]) | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "calc": | |||||
| r_result = re.compile(r'(?i)<A NAME=results>(.*?)</A>') | |||||
| r_tag = re.compile(r'<\S+.*?>') | |||||
| subs = [ | |||||
| (' in ', ' -> '), | |||||
| (' over ', ' / '), | |||||
| (u'£', 'GBP '), | |||||
| (u'€', 'EUR '), | |||||
| ('\$', 'USD '), | |||||
| (r'\bKB\b', 'kilobytes'), | |||||
| (r'\bMB\b', 'megabytes'), | |||||
| (r'\bGB\b', 'kilobytes'), | |||||
| ('kbps', '(kilobits / second)'), | |||||
| ('mbps', '(megabits / second)') | |||||
| ] | |||||
| try: | |||||
| q = ' '.join(line2[4:]) | |||||
| except Exception: | |||||
| say("0?", chan) | |||||
| return | |||||
| query = q[:] | |||||
| for a, b in subs: | |||||
| query = re.sub(a, b, query) | |||||
| query = query.rstrip(' \t') | |||||
| precision = 5 | |||||
| if query[-3:] in ('GBP', 'USD', 'EUR', 'NOK'): | |||||
| precision = 2 | |||||
| query = web.urllib.quote(query.encode('utf-8')) | |||||
| uri = 'http://futureboy.us/fsp/frink.fsp?fromVal=' | |||||
| bytes = web.get(uri + query) | |||||
| m = r_result.search(bytes) | |||||
| if m: | |||||
| result = m.group(1) | |||||
| result = r_tag.sub('', result) # strip span.warning tags | |||||
| result = result.replace('>', '>') | |||||
| result = result.replace('(undefined symbol)', '(?) ') | |||||
| if '.' in result: | |||||
| try: result = str(round(float(result), precision)) | |||||
| except ValueError: pass | |||||
| if not result.strip(): | |||||
| result = '?' | |||||
| elif ' in ' in q: | |||||
| result += ' ' + q.split(' in ', 1)[1] | |||||
| say(q + ' = ' + result[:350], chan) | |||||
| else: reply("Sorry, can't calculate that.", chan, nick) | |||||
| return | |||||
| if command == "dice": | |||||
| import random | |||||
| try: | |||||
| set = range(int(line2[4]), int(line2[5]) + 1) | |||||
| except Exception: | |||||
| set = range(1, 7) | |||||
| num = random.choice(set) | |||||
| reply("You rolled a %s." % num, chan, nick) | |||||
| if len(set) < 30: | |||||
| say("Set consisted of %s." % set, nick) | |||||
| else: | |||||
| say("Set consisted of %s... and %s others." % (set[:30], len(set) - 30), nick) | |||||
| return | |||||
| if command == "tock": | if command == "tock": | ||||
| u = urllib.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') | u = urllib.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') | ||||
| info = u.info() | info = u.info() | ||||
| @@ -250,28 +26,9 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| beats = int(math.floor(beats)) | beats = int(math.floor(beats)) | ||||
| say('@%03i' % beats, chan) | say('@%03i' % beats, chan) | ||||
| return | return | ||||
| if command == "copyvio" or command == "copy" or command == "copyright": | |||||
| url = "http://en.wikipedia.org/wiki/User:EarwigBot/AfC copyvios" | |||||
| query = urllib.urlopen(url) | |||||
| data = query.read() | |||||
| url = "http://toolserver.org/~earwig/earwigbot/pywikipedia/error.txt" | |||||
| query = urllib.urlopen(url) | |||||
| data2 = query.read() | |||||
| if "critical" in data2: | |||||
| text = "AfC copyvio situation is CRITICAL: Major disaster." | |||||
| elif "exceed" in data2: | |||||
| text = "AfC copyvio situation is CRITICAL: Queries exceeded error." | |||||
| elif "spam" in data2: | |||||
| text = "AfC copyvio situation is CRITICAL: Spamfilter error." | |||||
| elif "<h3>" in data: | |||||
| text = "AfC copyvio situation is BAD: Unsolved copyvios at [[User:EarwigBot/AfC copyvios]]" | |||||
| else: | |||||
| text = "AfC copyvio situation is OK: OK." | |||||
| reply(text, chan, nick) | |||||
| return | |||||
| if command == "dict" or command == "dictionary": | if command == "dict" or command == "dictionary": | ||||
| def trim(thing): | |||||
| if thing.endswith(' '): | |||||
| def trim(thing): | |||||
| if thing.endswith(' '): | |||||
| thing = thing[:-6] | thing = thing[:-6] | ||||
| return thing.strip(' :.') | return thing.strip(' :.') | ||||
| r_li = re.compile(r'(?ims)<li>.*?</li>') | r_li = re.compile(r'(?ims)<li>.*?</li>') | ||||
| @@ -289,20 +46,20 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| bytes = web.get(uri % word) | bytes = web.get(uri % word) | ||||
| results = {} | results = {} | ||||
| wordkind = None | wordkind = None | ||||
| for kind, sense in r_info.findall(bytes): | |||||
| for kind, sense in r_info.findall(bytes): | |||||
| kind, sense = trim(kind), trim(sense) | kind, sense = trim(kind), trim(sense) | ||||
| if kind: wordkind = kind | if kind: wordkind = kind | ||||
| elif sense: | |||||
| elif sense: | |||||
| results.setdefault(wordkind, []).append(sense) | results.setdefault(wordkind, []).append(sense) | ||||
| result = word.encode('utf-8') + ' - ' | result = word.encode('utf-8') + ' - ' | ||||
| for key in sorted(results.keys()): | |||||
| if results[key]: | |||||
| for key in sorted(results.keys()): | |||||
| if results[key]: | |||||
| result += (key or '') + ' 1. ' + results[key][0] | result += (key or '') + ' 1. ' + results[key][0] | ||||
| if len(results[key]) > 1: | |||||
| if len(results[key]) > 1: | |||||
| result += ', 2. ' + results[key][1] | result += ', 2. ' + results[key][1] | ||||
| result += '; ' | result += '; ' | ||||
| result = result.rstrip('; ') | result = result.rstrip('; ') | ||||
| if result.endswith('-') and (len(result) < 30): | |||||
| if result.endswith('-') and (len(result) < 30): | |||||
| reply('Sorry, no definition found.', chan, nick) | reply('Sorry, no definition found.', chan, nick) | ||||
| else: say(result, chan) | else: say(result, chan) | ||||
| return | return | ||||
| @@ -313,19 +70,19 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| r_tag = re.compile(r'<(?!!)[^>]+>') | r_tag = re.compile(r'<(?!!)[^>]+>') | ||||
| r_whitespace = re.compile(r'[\t\r\n ]+') | r_whitespace = re.compile(r'[\t\r\n ]+') | ||||
| abbrs = [ | abbrs = [ | ||||
| 'cf', 'lit', 'etc', 'Ger', 'Du', 'Skt', 'Rus', 'Eng', 'Amer.Eng', 'Sp', | |||||
| 'Fr', 'N', 'E', 'S', 'W', 'L', 'Gen', 'J.C', 'dial', 'Gk', | |||||
| '19c', '18c', '17c', '16c', 'St', 'Capt', 'obs', 'Jan', 'Feb', 'Mar', | |||||
| 'cf', 'lit', 'etc', 'Ger', 'Du', 'Skt', 'Rus', 'Eng', 'Amer.Eng', 'Sp', | |||||
| 'Fr', 'N', 'E', 'S', 'W', 'L', 'Gen', 'J.C', 'dial', 'Gk', | |||||
| '19c', '18c', '17c', '16c', 'St', 'Capt', 'obs', 'Jan', 'Feb', 'Mar', | |||||
| 'Apr', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'c', 'tr', 'e', 'g' | 'Apr', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'c', 'tr', 'e', 'g' | ||||
| ] | ] | ||||
| t_sentence = r'^.*?(?<!%s)(?:\.(?= [A-Z0-9]|\Z)|\Z)' | t_sentence = r'^.*?(?<!%s)(?:\.(?= [A-Z0-9]|\Z)|\Z)' | ||||
| r_sentence = re.compile(t_sentence % ')(?<!'.join(abbrs)) | r_sentence = re.compile(t_sentence % ')(?<!'.join(abbrs)) | ||||
| def unescape(s): | |||||
| def unescape(s): | |||||
| s = s.replace('>', '>') | s = s.replace('>', '>') | ||||
| s = s.replace('<', '<') | s = s.replace('<', '<') | ||||
| s = s.replace('&', '&') | s = s.replace('&', '&') | ||||
| return s | return s | ||||
| def text(html): | |||||
| def text(html): | |||||
| html = r_tag.sub('', html) | html = r_tag.sub('', html) | ||||
| html = r_whitespace.sub(' ', html) | html = r_whitespace.sub(' ', html) | ||||
| return unescape(html).strip() | return unescape(html).strip() | ||||
| @@ -335,24 +92,24 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| reply("Please enter a word.", chan, nick) | reply("Please enter a word.", chan, nick) | ||||
| return | return | ||||
| def ety(word): | def ety(word): | ||||
| if len(word) > 25: | |||||
| if len(word) > 25: | |||||
| raise ValueError("Word too long: %s[...]" % word[:10]) | raise ValueError("Word too long: %s[...]" % word[:10]) | ||||
| word = {'axe': 'ax/axe'}.get(word, word) | word = {'axe': 'ax/axe'}.get(word, word) | ||||
| bytes = web.get(etyuri % word) | bytes = web.get(etyuri % word) | ||||
| definitions = r_definition.findall(bytes) | definitions = r_definition.findall(bytes) | ||||
| if not definitions: | |||||
| if not definitions: | |||||
| return None | return None | ||||
| defn = text(definitions[0]) | defn = text(definitions[0]) | ||||
| m = r_sentence.match(defn) | m = r_sentence.match(defn) | ||||
| if not m: | |||||
| if not m: | |||||
| return None | return None | ||||
| sentence = m.group(0) | sentence = m.group(0) | ||||
| try: | |||||
| try: | |||||
| sentence = unicode(sentence, 'iso-8859-1') | sentence = unicode(sentence, 'iso-8859-1') | ||||
| sentence = sentence.encode('utf-8') | sentence = sentence.encode('utf-8') | ||||
| except: pass | except: pass | ||||
| maxlength = 275 | maxlength = 275 | ||||
| if len(sentence) > maxlength: | |||||
| if len(sentence) > maxlength: | |||||
| sentence = sentence[:maxlength] | sentence = sentence[:maxlength] | ||||
| words = sentence[:-5].split(' ') | words = sentence[:-5].split(' ') | ||||
| words.pop() | words.pop() | ||||
| @@ -361,86 +118,19 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| return sentence + ' - ' + (etyuri % word) | return sentence + ' - ' + (etyuri % word) | ||||
| try: | try: | ||||
| result = ety(word.encode('utf-8')) | result = ety(word.encode('utf-8')) | ||||
| except IOError: | |||||
| except IOError: | |||||
| msg = "Can't connect to etymonline.com (%s)" % (etyuri % word) | msg = "Can't connect to etymonline.com (%s)" % (etyuri % word) | ||||
| reply(msg, chan, nick) | reply(msg, chan, nick) | ||||
| return | return | ||||
| except AttributeError: | |||||
| except AttributeError: | |||||
| result = None | result = None | ||||
| if result is not None: | |||||
| if result is not None: | |||||
| reply(result, chan, nick) | reply(result, chan, nick) | ||||
| else: | |||||
| else: | |||||
| uri = etysearch % word | uri = etysearch % word | ||||
| msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri) | msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri) | ||||
| reply(msg, chan, nick) | reply(msg, chan, nick) | ||||
| return | return | ||||
| if command == "num" or command == "number" or command == "count" or command == "c": | |||||
| try: | |||||
| params = string.lower(line2[4]) | |||||
| except Exception: | |||||
| params = False | |||||
| if params == "old" or params == "afc" or params == "a": | |||||
| number = unicode(int(len(re.findall("title=", urllib.urlopen("http://en.wikipedia.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Pending_AfC_submissions&cmlimit=500").read()))) - 2) | |||||
| reply("There are currently %s pending AfC submissions." % number, chan, nick) | |||||
| elif params == "redirect" or params == "redir" or params == "redirs" or params == "redirects" or params == "r": | |||||
| redir_data = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Articles_for_creation/Redirects").read() | |||||
| redirs = (string.count(redir_data, "<h2>") - 1) - (string.count(redir_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| reply("There are currently %s open redirect requests." % redirs, chan, nick) | |||||
| elif params == "files" or params == "ffu" or params == "file" or params == "image" or params == "images" or params == "ifu" or params == "f": | |||||
| file_data = re.sub("<h2>Contents</h2>", "", urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Files_for_upload").read()) | |||||
| files = (string.count(file_data, "<h2>") - 1) - (string.count(file_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| reply("There are currently %s open file upload requests." % files, chan, nick) | |||||
| elif params == "aggregate" or params == "agg": | |||||
| subs = unicode(int(len(re.findall("title=", urllib.urlopen("http://en.wikipedia.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Pending_AfC_submissions&cmlimit=500").read()))) - 2) | |||||
| redir_data = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Articles_for_creation/Redirects").read() | |||||
| file_data = re.sub("<h2>Contents</h2>", "", urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Files_for_upload").read()) | |||||
| redirs = (string.count(redir_data, "<h2><span class=\"editsection\">")) - (string.count(redir_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| files = (string.count(file_data, "<h2>") - 1) - (string.count(file_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| aggregate = (int(subs) * 5) + (int(redirs) * 2) + (int(files) * 2) | |||||
| if aggregate == 0: | |||||
| stat = "clear" | |||||
| elif aggregate < 60: | |||||
| stat = "almost clear" | |||||
| elif aggregate < 125: | |||||
| stat = "small backlog" | |||||
| elif aggregate < 175: | |||||
| stat = "average backlog" | |||||
| elif aggregate < 250: | |||||
| stat = "backlogged" | |||||
| elif aggregate < 300: | |||||
| stat = "heavily backlogged" | |||||
| else: | |||||
| stat = "severely backlogged" | |||||
| reply("Aggregate is currently %s (%s)." % (aggregate, stat), chan, nick) | |||||
| else: | |||||
| subs = unicode(int(len(re.findall("title=", urllib.urlopen("http://en.wikipedia.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Pending_AfC_submissions&cmlimit=500").read()))) - 2) | |||||
| redir_data = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Articles_for_creation/Redirects").read() | |||||
| file_data = re.sub("<h2>Contents</h2>", "", urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Wikipedia:Files_for_upload").read()) | |||||
| redirs = (string.count(redir_data, "<h2><span class=\"editsection\">")) - (string.count(redir_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| files = (string.count(file_data, "<h2>") - 1) - (string.count(file_data, '<table class="navbox collapsible collapsed" style="text-align: left; border: 0px; margin-top: 0.2em;">')) | |||||
| reply("There are currently %s pending submissions, %s open redirect requests, and %s open file upload requests." % (subs, redirs, files), chan, nick) | |||||
| return | |||||
| if command == "nick": | |||||
| if authy == "owner": | |||||
| try: | |||||
| new_nick = line2[4] | |||||
| except Exception: | |||||
| reply("Please specify a nick to change to.", chan, nick) | |||||
| return | |||||
| s.send("NICK %s\r\n" % new_nick) | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "op" or command == "deop" or command == "voice" or command == "devoice": | |||||
| if authy == "owner" or authy == "admin": | |||||
| try: | |||||
| user = line2[4] | |||||
| except Exception: | |||||
| user = nick | |||||
| say("%s %s %s" % (command, chan, user), "ChanServ") | |||||
| else: | |||||
| reply("You aren't authorized to use that command.", chan, nick) | |||||
| return | |||||
| if command == "pend" or command == "pending": | if command == "pend" or command == "pending": | ||||
| say("Pending submissions status page: <http://en.wikipedia.org/wiki/WP:AFC/S>.", chan) | say("Pending submissions status page: <http://en.wikipedia.org/wiki/WP:AFC/S>.", chan) | ||||
| say("Pending submissions category: <http://en.wikipedia.org/wiki/Category:Pending_AfC_submissions>.", chan) | say("Pending submissions category: <http://en.wikipedia.org/wiki/Category:Pending_AfC_submissions>.", chan) | ||||
| @@ -481,53 +171,6 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| report = "\x02First %s pending AfC submissions:\x0F %s" % (number, s) | report = "\x02First %s pending AfC submissions:\x0F %s" % (number, s) | ||||
| say(report, chan) | say(report, chan) | ||||
| return | return | ||||
| if command == "praise" or command == "leonard" or command == "groovedog" or command == "earwig" or command == "macmed" or command == "cubs197" or command == "sparksboy" or command == "tim_song" or command == "tim" or command == "sausage" or command == "mindstormskid" or command == "mcjohn" or command == "fetchcomms" or command == "blurpeace": | |||||
| bad = False | |||||
| if command == "leonard": | |||||
| special = "AfC redirect reviewer" | |||||
| user = "Leonard^Bloom" | |||||
| elif command == "groovedog": | |||||
| special = "heh" | |||||
| user = "GrooveDog" | |||||
| elif command == "earwig": | |||||
| special = "Python programmer" | |||||
| user = "Earwig" | |||||
| elif command == "macmed": | |||||
| special = "CSD tagger" | |||||
| user = "MacMed" | |||||
| elif command == "mindstormskid": | |||||
| special = "Lego fanatic" | |||||
| user = "MindstormsKid" | |||||
| elif command == "cubs197": | |||||
| special = "IRC dude" | |||||
| user = "Cubs197" | |||||
| elif command == "sparksboy": | |||||
| special = "pet owner" | |||||
| user = "SparksBoy" | |||||
| elif command == "tim_song" or command == "tim": | |||||
| special = "JavaScript programmer" | |||||
| user = "Tim_Song" | |||||
| elif command == "sausage": | |||||
| special = "helper" | |||||
| user = "chzz" | |||||
| elif command == "mcjohn": | |||||
| special = "edit summary writer" | |||||
| user = "McJohn" | |||||
| elif command == "fetchcomms": | |||||
| special = "n00b" | |||||
| user = "Fetchcomms" | |||||
| elif command == "blurpeace": | |||||
| special = "Commons admin" | |||||
| user = "Blurpeace" | |||||
| else: | |||||
| say("Only a true fool would use that command, %s." % nick, chan) | |||||
| # say("The users who you can praise are: Leonard^Bloom, GrooveDog, Earwig, MacMed, Cubs197, SparksBoy, MindstormsKid, Chzz, McJohn, Tim_Song, Fetchcomms, and Blurpeace.", chan) | |||||
| return | |||||
| if not bad: | |||||
| say("\x02%s\x0F is the bestest %s evah!" % (user, special), chan) | |||||
| if bad: | |||||
| say("\x02%s\x0F is worstest %s evah!" % (user, special), chan) | |||||
| return | |||||
| if command == "trout": | if command == "trout": | ||||
| try: | try: | ||||
| user = line2[4] | user = line2[4] | ||||
| @@ -548,196 +191,6 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| else: | else: | ||||
| reply("I refuse to hurt anything with \"Earwig\" in its name :P", chan, nick) | reply("I refuse to hurt anything with \"Earwig\" in its name :P", chan, nick) | ||||
| return | return | ||||
| if command == "kill" or command == "destroy" or command == "murder": | |||||
| reply("Who do you think I am? The Mafia?", chan, nick) | |||||
| return | |||||
| if command == "fish": | |||||
| try: | |||||
| user = line2[4] | |||||
| fish = ' '.join(line2[5:]) | |||||
| except Exception: | |||||
| reply("Hahahahahahahaha...", chan, nick) | |||||
| return | |||||
| normal = unicodedata.normalize('NFKD', unicode(string.lower(user))) | |||||
| if "itself" in normal: | |||||
| reply("I'm not that stupid ;)", chan, nick) | |||||
| return | |||||
| elif "earwigbot" in normal: | |||||
| reply("I'm not that stupid ;)", chan, nick) | |||||
| elif "earwig" not in normal and "ear wig" not in normal: | |||||
| text = 'slaps %s around a bit with a %s.' % (user, fish) | |||||
| msg = '\x01ACTION %s\x01' % text | |||||
| say(msg, chan) | |||||
| else: | |||||
| reply("I refuse to hurt anything with \"Earwig\" in its name :P", chan, nick) | |||||
| return | |||||
| if command == "report": | |||||
| def find_status(name="", talk=False): | |||||
| enname = re.sub(" ", "_", name) | |||||
| if talk == True: | |||||
| enname = "Wikipedia_talk:Articles_for_creation/%s" % enname | |||||
| if talk == False: | |||||
| enname = "Wikipedia:Articles_for_creation/%s" % enname | |||||
| url = "http://en.wikipedia.org/w/api.php?action=query&titles=%s&prop=revisions&rvprop=content" % enname | |||||
| query = urllib.urlopen(url) | |||||
| data = query.read() | |||||
| status = "" | |||||
| if "{{AFC submission|D" in data or "{{AFC submission|d" in data: | |||||
| reason = re.findall("(D|d)\|(.*?)\|", data) | |||||
| if reason[0][1] != "reason": | |||||
| status = "Declined, reason is '%s'" % reason[0][1] | |||||
| if reason[0][1] == "reason": | |||||
| status = "Declined, reason is a custom reason" | |||||
| if "{{AFC submission|H" in data or "{{AFC submission|h" in data: | |||||
| reason = re.findall("(H|h)\|(.*?)\|", data) | |||||
| if reason[0][1] != "reason": | |||||
| status = "Held, reason is '%s'" % reason[0][1] | |||||
| if reason[0][1] == "reason": | |||||
| status = "Held, reason is a custom reason" | |||||
| if "{{AFC submission||" in data: | |||||
| status = "Pending" | |||||
| if "{{AFC submission|R" in data or "{{AFC submission|r" in data: | |||||
| status = "Reviewing" | |||||
| if not status: | |||||
| exist = exists(name=enname) | |||||
| if exist == True: | |||||
| status = "Accepted" | |||||
| if exist == False: | |||||
| status = "Not found" | |||||
| return status | |||||
| def exists(name=""): | |||||
| url = "http://en.wikipedia.org/wiki/%s" % name | |||||
| query = urllib.urlopen(url) | |||||
| data = query.read() | |||||
| if "Wikipedia does not have a" in data: | |||||
| return False | |||||
| return True | |||||
| def get_submitter(name="", talk=False): | |||||
| enname = re.sub(" ", "_", name) | |||||
| if talk == True: | |||||
| enname = "Wikipedia_talk:Articles_for_creation/%s" % enname | |||||
| if talk == False: | |||||
| enname = "Wikipedia:Articles_for_creation/%s" % enname | |||||
| url = "http://en.wikipedia.org/w/api.php?action=query&titles=%s&prop=revisions&rvprop=user&rvdir=newer&rvlimit=1" % enname | |||||
| query = urllib.urlopen(url) | |||||
| data = query.read() | |||||
| extract = re.findall("user="(.*?)"", data) | |||||
| if "anon=" in data: | |||||
| anon = True | |||||
| else: | |||||
| anon = False | |||||
| try: | |||||
| return extract[0], anon | |||||
| except BaseException: | |||||
| print extract | |||||
| return "", anon | |||||
| try: | |||||
| rawSub = line2[4] | |||||
| rawSub = ' '.join(line2[4:]) | |||||
| except Exception: | |||||
| reply("You need to specify a submission name in order to use %s!" % command, chan, nick) | |||||
| return | |||||
| talk = False | |||||
| if "[[" in rawSub and "]]" in rawSub: | |||||
| name = re.sub("\[\[(.*)\]\]", "\\1", rawSub) | |||||
| name = re.sub(" ", "_", name) | |||||
| name = urllib.quote(name, ":/") | |||||
| name = "http://en.wikipedia.org/wiki/%s" % name | |||||
| if "talk:" in name: | |||||
| talk = True | |||||
| elif "http://" in rawSub: | |||||
| name = rawSub | |||||
| if "talk:" in name: | |||||
| talk = True | |||||
| elif "en.wikipedia.org" in rawSub: | |||||
| name = "http://%s" % rawSub | |||||
| if "talk:" in name: | |||||
| talk = True | |||||
| elif "Wikipedia:" in rawSub or "Wikipedia_talk:" in rawSub or "Wikipedia talk:" in rawSub: | |||||
| name = re.sub(" ", "_", rawSub) | |||||
| name = urllib.quote(name, ":/") | |||||
| name = "http://en.wikipedia.org/wiki/%s" % name | |||||
| if "talk:" in name: | |||||
| talk = True | |||||
| else: | |||||
| url = "http://en.wikipedia.org/wiki/" | |||||
| pagename = re.sub(" ", "_", rawSub) | |||||
| pagename = urllib.quote(pagename, ":/") | |||||
| pagename = "Wikipedia:Articles_for_creation/%s" % pagename | |||||
| page = urllib.urlopen("%s%s" % (url, pagename)) | |||||
| text = page.read() | |||||
| name = "http://en.wikipedia.org/wiki/%s" % pagename | |||||
| if "Wikipedia does not have a" in text: | |||||
| pagename = re.sub(" ", "_", rawSub) | |||||
| pagename = urllib.quote(pagename, ":/") | |||||
| pagename = "Wikipedia_talk:Articles_for_creation/%s" % pagename | |||||
| page = urllib.urlopen("%s%s" % (url, pagename)) | |||||
| name = "http://en.wikipedia.org/wiki/%s" % pagename | |||||
| talk = True | |||||
| unname = re.sub("http://en.wikipedia.org/wiki/Wikipedia:Articles_for_creation/", "", name) | |||||
| unname = re.sub("http://en.wikipedia.org/wiki/Wikipedia_talk:Articles_for_creation/", "", unname) | |||||
| unname = re.sub("_", " ", unname) | |||||
| if "talk" in unname: | |||||
| talk = True | |||||
| submitter, anon = get_submitter(name=unname, talk=talk) | |||||
| status = find_status(name=unname, talk=talk) | |||||
| if submitter != "": | |||||
| if anon == True: | |||||
| submitter_page = "Special:Contributions/%s" % submitter | |||||
| if anon == False: | |||||
| unsubmit = re.sub(" ", "_", submitter) | |||||
| unsubmit = urllib.quote(unsubmit, ":/") | |||||
| submitter_page = "User:%s" % unsubmit | |||||
| if status == "Accepted": | |||||
| submitterm = "Reviewer" | |||||
| else: | |||||
| submitterm = "Submitter" | |||||
| line1 = "\x02AfC submission report for %s:" % unname | |||||
| line2 = "\x02URL: \x0301\x0F%s" % name | |||||
| if submitter != "": | |||||
| line3 = "\x02%s: \x0F\x0302%s (\x0301\x0Fhttp://en.wikipedia.org/wiki/%s)." % (submitterm, submitter, submitter_page) | |||||
| line4 = "\x02Status: \x0F\x0302%s." % status | |||||
| say(line1, chan) | |||||
| time.sleep(0.1) | |||||
| say(line2, chan) | |||||
| time.sleep(0.1) | |||||
| if submitter != "": | |||||
| say(line3, chan) | |||||
| time.sleep(0.1) | |||||
| say(line4, chan) | |||||
| return | |||||
| if command == "commands": | |||||
| if chan.startswith("#"): | |||||
| reply("Please use that command in a private message.", chan, nick) | |||||
| return | |||||
| others2 = get_commandList().values() | |||||
| others = [] | |||||
| for com in others2: | |||||
| if com == "copyvio" or com == "number" or com == "pending" or com == "report" or com == "submissions" or com == "access" or com == "help" or com == "join" or com == "linker" or com == "nick" or com == "op" or com == "part" or com == "quiet" or com == "quit" or com == "restart" or com == "voice" or com == "welcome" or com == "fish" or com == "praise" or com == "trout" or com == "notes": | |||||
| continue | |||||
| if com in others: continue | |||||
| others.append(com) | |||||
| others.sort() | |||||
| say("\x02AFC commands:\x0F copyvio, number, pending, report, submissions.", chan) | |||||
| time.sleep(0.1) | |||||
| say("\x02Bot operation and channel maintaince commands:\x0F access, help, join, linker, nick, op, part, quiet, quit, restart, voice, welcome.", chan) | |||||
| time.sleep(0.1) | |||||
| say("\x02Fun commands:\x0F fish, praise, trout, and numerous easter eggs", chan) | |||||
| time.sleep(0.1) | |||||
| say("\x02Other commands:\x0F %s" % ', '.join(others), chan) | |||||
| time.sleep(0.1) | |||||
| say("The bot maintains a mini-wiki. Type \"!notes help\" for more information.", chan) | |||||
| time.sleep(0.1) | |||||
| say("See http://enwp.org/User:The_Earwig/Bots/IRC for details. For help on a specific command, type '!help command'.", chan) | |||||
| return | |||||
| if command == "help" or command == "doc" or command == "documentation": | |||||
| try: | |||||
| com = line2[4] | |||||
| except Exception: | |||||
| reply("Hi, I'm a bot that does work for Articles for Creation. You can find information about me at http://enwp.org/User:The_Earwig/Bots/IRC. Say \"!commands\" to me in a private message for some of my abilities. Earwig is my owner and creator, and you can contact him at http://enwp.org/User_talk:The_Earwig.", chan, nick) | |||||
| return | |||||
| say("Sorry, command documentation has not been implemented yet.", chan) | |||||
| return | |||||
| if command == "mysql": | if command == "mysql": | ||||
| if authy != "owner": | if authy != "owner": | ||||
| reply("You aren't authorized to use this command.", chan, nick) | reply("You aren't authorized to use this command.", chan, nick) | ||||
| @@ -781,17 +234,6 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| time.sleep(times) | time.sleep(times) | ||||
| os.remove("/home/earwig/public_html/reports/%s/%s" % (database[:-2], file)) | os.remove("/home/earwig/public_html/reports/%s/%s" % (database[:-2], file)) | ||||
| return | return | ||||
| if command == "remind" or command == "reminder": | |||||
| try: | |||||
| times = int(line2[4]) | |||||
| content = ' '.join(line2[5:]) | |||||
| except Exception: | |||||
| reply("Please specify a time and a note in the following format: !remind <time> <note>.", chan, nick) | |||||
| return | |||||
| reply("Set reminder for \"%s\" in %s seconds." % (content, times), chan, nick) | |||||
| time.sleep(times) | |||||
| reply(content, chan, nick) | |||||
| return | |||||
| if command == "notes" or command == "note" or command == "about" or command == "data" or command == "database": | if command == "notes" or command == "note" or command == "about" or command == "data" or command == "database": | ||||
| try: | try: | ||||
| action = line2[4] | action = line2[4] | ||||
| @@ -925,26 +367,6 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| reply("NotImplementedError", chan, nick) | reply("NotImplementedError", chan, nick) | ||||
| elif action == "report": | elif action == "report": | ||||
| reply("NotImplementedError", chan, nick) | reply("NotImplementedError", chan, nick) | ||||
| if command == "hash": | |||||
| import hashlib | |||||
| try: | |||||
| hashVia = line2[4] | |||||
| hashText = line2[5] | |||||
| hashText = ' '.join(line2[5:]) | |||||
| except Exception: | |||||
| reply("Please provide a string and method to hash by.", chan, nick) | |||||
| return | |||||
| try: | |||||
| hashed = eval("hashlib.%s(\"%s\").hexdigest()" % (hashVia, hashText)) | |||||
| reply(hashed, chan, nick) | |||||
| except Exception: | |||||
| try: | |||||
| hashing = hashlib.new(hashVia) | |||||
| hashing.update(hashText) | |||||
| hashed = hashing.hexdigest() | |||||
| reply(hashed, chan, nick) | |||||
| except Exception: | |||||
| reply("Error.", chan, nick) | |||||
| if command == "langcode" or command == "lang" or command == "language": | if command == "langcode" or command == "lang" or command == "language": | ||||
| try: | try: | ||||
| lang = line2[4] | lang = line2[4] | ||||
| @@ -976,4 +398,4 @@ def parse(command, line, line2, nick, chan, host, auth, notice, say, reply, s): | |||||
| hashes.append(newHex) | hashes.append(newHex) | ||||
| normalizedIP = "%s.%s.%s.%s" % (hashes[0], hashes[1], hashes[2], hashes[3]) | normalizedIP = "%s.%s.%s.%s" % (hashes[0], hashes[1], hashes[2], hashes[3]) | ||||
| reply(normalizedIP, chan, nick) | reply(normalizedIP, chan, nick) | ||||
| return | |||||
| return | |||||