diff --git a/.gitignore b/.gitignore index e7afa1b..2844c3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.py[cod] *~ +__pycache__ diff --git a/COMMANDS.md b/COMMANDS.md index f029c87..d84cb3c 100644 --- a/COMMANDS.md +++ b/COMMANDS.md @@ -45,9 +45,7 @@ Required arguments are enclosed in { and }, optional arguments are enclosed in [
]*>.*?
|(.+?)
') +r_sentenceend = re.compile(r'\.[^\.]') +transforms = [ + re.compile(r'(?i)]+>(.+?)'), + re.compile(r'(?i)(.+?)'), + re.compile(r'(?i)(.+?)'), +] -abbrs = ['etc', 'ca', 'cf', 'Co', 'Ltd', 'Inc', 'Mt', 'Mr', 'Mrs', - 'Dr', 'Ms', 'Rev', 'Fr', 'St', 'Sgt', 'pron', 'approx', 'lit', - 'syn', 'transl', 'sess', 'fl', 'Op', 'Dec', 'Brig', 'Gen'] \ - + list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') \ - + list('abcdefghijklmnopqrstuvwxyz') -t_sentence = r'^.{5,}?(?') - s = s.replace('<', '<') - s = s.replace('&', '&') - s = s.replace(' ', ' ') - return s + log.log("event", "%s queried Developer Wiki for '%s'" % (log.fmt_user(input), term), phenny) + term = web.urlencode(term) -def text(html): - html = r_tag.sub('', html) - html = r_whitespace.sub(' ', html) - return unescape(html).strip() + data, scode = web.get(wikiuri_g % term) + if scode == 404: + return phenny.say("No such page.") + data = str(data, "utf-8") -def devwikipedia(term, language='en', last=False): - global devwikiuri - if not '%' in term: - if isinstance(term, unicode): - t = term.encode('utf-8') - else: t = term - q = urllib.quote(t) - u = devwikiuri % (q) - bytes = web.get(u) - else: bytes = web.get(devwikiuri % (term)) + m = re.search(r_content, data) + if not m: + return phenny.say("Sorry, did not find anything.") + data = data[m.span()[1]:] - if bytes.startswith('\x1f\x8b\x08\x00\x00\x00\x00\x00'): - f = StringIO.StringIO(bytes) - f.seek(0) - gzip_file = gzip.GzipFile(fileobj=f) - bytes = gzip_file.read() - gzip_file.close() - f.close() + m = re.search(r_paragraph, data) + if not m: + return phenny.say("Sorry, did not find anything.") + data = m.group(1) + for transform in transforms: + data = re.sub(transform, '\g<1>', data) + m = re.search(r_sentenceend, data) + if m: + data = data[:m.span()[1]-1] + phenny.say('"%s" - %s ' % (web.decode(data), wikiuri_r % term)) - bytes = r_tr.sub('', bytes) - - if not last: - r = r_redirect.search(bytes[:4096]) - if r: - term = urllib.unquote(r.group(1)) - return devwikipedia(term, language=language, last=True) - - paragraphs = r_paragraph.findall(bytes) - - if not paragraphs: - if not last: - term = search(term) - return devwikipedia(term, language=language, last=True) - return None - - # Pre-process - paragraphs = [para for para in paragraphs - if (para and 'technical limitations' not in para - and 'window.showTocToggle' not in para - and 'Deletion_policy' not in para - and 'Template:AfD_footer' not in para - and not (para.startswith('') and - para.endswith('
')) - and not 'disambiguation)"' in para) - and not '(images and media)' in para - and not 'This article contains a' in para - and not 'id="coordinates"' in para - and not 'class="thumb' in para] - # and not 'style="display:none"' in para] - - for i, para in enumerate(paragraphs): - para = para.replace('', '|') - para = para.replace('', '|') - paragraphs[i] = text(para).strip() - - # Post-process - paragraphs = [para for para in paragraphs if - (para and not (para.endswith(':') and len(para) < 150))] - - para = text(paragraphs[0]) - m = r_sentence.match(para) - - if not m: - if not last: - term = search(term) - return devwikipedia(term, language=language, last=True) - return None - sentence = m.group(0) - - maxlength = 275 - if len(sentence) > maxlength: - sentence = sentence[:maxlength] - words = sentence[:-5].split(' ') - words.pop() - sentence = ' '.join(words) + ' [...]' - - if (('using the Article Wizard if you wish' in sentence) - or ('or add a request for it' in sentence) - or ('in existing articles' in sentence)): - if not last: - term = search(term) - return devwikipedia(term, language=language, last=True) - return None - - sentence = '"' + sentence.replace('"', "'") + '"' - sentence = sentence.decode('utf-8').encode('utf-8') - devwikiuri = devwikiuri.decode('utf-8').encode('utf-8') - term = term.decode('utf-8').encode('utf-8') - return sentence + ' - ' + (devwikiuri % (term)) - -def devwik(phenny, input): - origterm = input.groups()[1] - if not origterm: - return phenny.say('Perhaps you meant "!devwik Zen"?') - origterm = origterm.encode('utf-8') - log.log("event", "%s queried Devwiki for '%s'" % (log.fmt_user(input), origterm), phenny) - - term = urllib.unquote(origterm) - language = 'en' - if term.startswith(':') and (' ' in term): - a, b = term.split(' ', 1) - a = a.lstrip(':') - if a.isalpha(): - language, term = a, b - term = term.replace(' ', '_') - - try: result = devwikipedia(term, language) - except IOError: - args = (language, devwikiuri % (term)) - error = "Can't connect to dev.minetest.net (%s)" % args - return phenny.say(error) - - if result is not None: - phenny.say(result) - else: phenny.say('Can\'t find anything in Dev Wiki for "%s".' % origterm) - -devwik.commands = ['dev', 'devwik', 'devwiki'] -devwik.priority = 'high' +wiki.commands = ['devwik', 'devwiki'] +wiki.priority = 'high' if __name__ == '__main__': - print __doc__.strip() + print(__doc__.strip()) diff --git a/forumutils.py b/forumutils.py index d9392c5..cda849f 100755 --- a/forumutils.py +++ b/forumutils.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ forumutils.py - Phenny Minetest Forum Module -Copyright 2012, Sfan5 +Copyright 2012, sfan5 """ import web @@ -137,4 +137,4 @@ search_forumuser_limit.commands = ['searchforumuserlimit', 'sfulimit'] search_forumuser_limit.priority = 'low' if __name__ == '__main__': - print __doc__ + print(__doc__) diff --git a/log.py b/log.py old mode 100644 new mode 100755 index 6072071..41d0037 --- a/log.py +++ b/log.py @@ -7,36 +7,36 @@ Copyright 2014, sfan5 import time loglevels = { - 'TEXT': 'TXT', # TEXT: purely informal message that appears in masses e.g. a command being executed - 'EVENT': 'EVT', # EVENT: like TEXT events but more likely someone wants to see those - 'ACTION': 'ACT', # ACTION: something the bot decided on doing automatically, requires attention - 'WARNING': 'WRN', # WARNING: a warning + 'TEXT': 'TXT', # TEXT: purely informal message that appears in masses e.g. a command being executed + 'EVENT': 'EVT', # EVENT: like TEXT events but more likely someone wants to see those + 'ACTION': 'ACT', # ACTION: something the bot decided on doing automatically, requires attention + 'WARNING': 'WRN', # WARNING: a warning } actionchannel = "##minetestbot" actionhighlight = "sfan5" def log(level, text, phenny): - level = level.upper() - f = open("bot.log", "ab") - f.write(time.strftime("%F %H:%M:%S %z") + "\t" + loglevels[level] + "\t" + text.encode('utf-8') + "\n") - f.close() - if level == 'ACTION': - phenny.write(['PRIVMSG', actionchannel], actionhighlight + ": " + text) - print(level + " " + text) + level = level.upper() + f = open("bot.log", "a") + f.write(time.strftime("%F %H:%M:%S %z") + "\t" + loglevels[level] + "\t" + text + "\n") + f.close() + if level == 'ACTION': + phenny.write(['PRIVMSG', actionchannel], actionhighlight + ": " + text) + print(level + " " + text) def fmt_user(input): - return "%s(%s)" % (input.nick, input.hostmask) + return "%s(%s)" % (input.nick, input.hostmask) class SomeObject(object): - pass + pass log_api = SomeObject() log_api.log = log log_api.fmt_user = fmt_user _export = { - 'log': log_api, + 'log': log_api, } def log_text(phenny, input, func): diff --git a/ping.py b/ping.py index 5b679ce..e674974 100755 --- a/ping.py +++ b/ping.py @@ -20,8 +20,8 @@ interjection.priority = 'high' def l3(phenny, input): phenny.say('<3 ' + input.nick) -l3.rule = r'<3 $nickname' +l3.rule = r'<3 $nickname\s*' l3.priority = 'low' if __name__ == '__main__': - print __doc__.strip() + print(__doc__.strip()) diff --git a/reload.py b/reload.py index a52f4ee..c28a456 100755 --- a/reload.py +++ b/reload.py @@ -24,7 +24,7 @@ def f_reload(phenny, input): phenny.setup() return phenny.reply('done') - if not sys.modules.has_key(name): + if not name in sys.modules: return phenny.reply('%s: no such module!' % name) # Thanks to moot for prodding me on this @@ -53,4 +53,4 @@ f_reload.priority = 'low' f_reload.thread = False if __name__ == '__main__': - print __doc__.strip() + print(__doc__.strip()) diff --git a/rssnotify.py b/rssnotify.py index 0bd3f36..43dd971 100755 --- a/rssnotify.py +++ b/rssnotify.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ rssnotify.py - Phenny RssNotify Module -Copyright 2013, Sfan5 +Copyright 2013, sfan5 """ import time, urllib, re import feedparser # sudo pip install feedparser @@ -51,7 +51,7 @@ def rsscheck(phenny, input): ('https://github.com/Uberi/MineTest-WorldEdit/commits/master.atom', allchans), ('https://github.com/Jeija/minetest-mod-mesecons/commits/master.atom', allchans), ] - for v in xrange(0, len(feeds)): + for v in range(0, len(feeds)): url = feeds[v][0] feednum = v options = { @@ -111,7 +111,7 @@ def rsscheck(phenny, input): phenny.write(['PRIVMSG', ch],"GIT: %s commited to %s: %s %s %s %s" % (commiter, reponame, feed_entry.title, commit_hash, commit_time, commit_link)) if len(feed.entries) > 0: m = -1 - for i in xrange(0, len(feed.entries)): + for i in range(0, len(feed.entries)): if to_unix_time(feed.entries[i].updated) > m: m = to_unix_time(feed.entries[i].updated) rssnotify["last_updated_feeds"][feednum] = m @@ -128,4 +128,4 @@ rsscheck.event = '*' rsscheck.nohook = True if __name__ == '__main__': - print __doc__.strip() + print(__doc__.strip()) diff --git a/rutils.py b/rutils.py index 11a78a7..3b63fa8 100755 --- a/rutils.py +++ b/rutils.py @@ -12,7 +12,7 @@ def rev(phenny, input): """reverse string""" if not input.group(2): return phenny.reply("Nothing to reverse.") - q = input.group(2).encode('utf-8') + q = input.group(2) s = "" for i in range(1,len(q)): s += q[-i] @@ -27,7 +27,7 @@ def make_thing(cmds, func): if not input.group(2): return q = input.group(2).encode('utf-8') try: - phenny.say(rs(func(q))) + phenny.say(rs(func(q).decode('utf-8'))) except BaseException as e: phenny.reply("Failed to handle data") m.commands = cmds @@ -41,17 +41,6 @@ b32d = make_thing(['b32d','base32decode'], base64.b32decode) b16e = make_thing(['b16e','base16encode'], base64.b16encode) b16d = make_thing(['b16d','base16decode'], base64.b16decode) -def crc32(phenny, input): - """crc32 hash""" - if not input.group(2): - return phenny.reply("Nothing to hash.") - q = input.group(2).encode('utf-8') - h = binascii.crc32(q) - return phenny.say(rs(str(h) + "(" + hex(h) + ")")) - -crc32.commands = ['crc32'] -crc32.priority = 'low' - def hash_(phenny, input): if not input.group(2): return phenny.reply("Usage: hash]*>.*?
|(.+?)
') +r_sentenceend = re.compile(r'\.[^\.]') +transforms = [ + re.compile(r'(?i)]+>(.+?)'), + re.compile(r'(?i)(.+?)'), + re.compile(r'(?i)(.+?)'), +] -abbrs = ['etc', 'ca', 'cf', 'Co', 'Ltd', 'Inc', 'Mt', 'Mr', 'Mrs', - 'Dr', 'Ms', 'Rev', 'Fr', 'St', 'Sgt', 'pron', 'approx', 'lit', - 'syn', 'transl', 'sess', 'fl', 'Op', 'Dec', 'Brig', 'Gen'] \ - + list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') \ - + list('abcdefghijklmnopqrstuvwxyz') -t_sentence = r'^.{5,}?(?') - s = s.replace('<', '<') - s = s.replace('&', '&') - s = s.replace(' ', ' ') - return s + log.log("event", "%s queried Wiki for '%s'" % (log.fmt_user(input), term), phenny) + term = web.urlencode(term) -def text(html): - html = r_tag.sub('', html) - html = r_whitespace.sub(' ', html) - return unescape(html).strip() + data, scode = web.get(wikiuri_g % term) + if scode == 404: + return phenny.say("No such page.") + data = str(data, "utf-8") -def wikipedia(term, language='en', last=False): - global wikiuri - if not '%' in term: - if isinstance(term, unicode): - t = term.encode('utf-8') - else: t = term - q = urllib.quote(t) - u = wikiuri % (q) - bytes = web.get(u) - else: bytes = web.get(wikiuri % (term)) + m = re.search(r_content, data) + if not m: + return phenny.say("Sorry, did not find anything.") + data = data[m.span()[1]:] - if bytes.startswith('\x1f\x8b\x08\x00\x00\x00\x00\x00'): - f = StringIO.StringIO(bytes) - f.seek(0) - gzip_file = gzip.GzipFile(fileobj=f) - bytes = gzip_file.read() - gzip_file.close() - f.close() + m = re.search(r_paragraph, data) + if not m: + return phenny.say("Sorry, did not find anything.") + data = m.group(1) + for transform in transforms: + data = re.sub(transform, '\g<1>', data) + m = re.search(r_sentenceend, data) + if m: + data = data[:m.span()[1]-1] + phenny.say('"%s" - %s ' % (web.decode(data), wikiuri_r % term)) - bytes = r_tr.sub('', bytes) - - if not last: - r = r_redirect.search(bytes[:4096]) - if r: - term = urllib.unquote(r.group(1)) - return wikipedia(term, language=language, last=True) - - paragraphs = r_paragraph.findall(bytes) - - if not paragraphs: - if not last: - term = search(term) - return wikipedia(term, language=language, last=True) - return None - - # Pre-process - paragraphs = [para for para in paragraphs - if (para and 'technical limitations' not in para - and 'window.showTocToggle' not in para - and 'Deletion_policy' not in para - and 'Template:AfD_footer' not in para - and not (para.startswith('') and - para.endswith('
')) - and not 'disambiguation)"' in para) - and not '(images and media)' in para - and not 'This article contains a' in para - and not 'id="coordinates"' in para - and not 'class="thumb' in para] - # and not 'style="display:none"' in para] - - for i, para in enumerate(paragraphs): - para = para.replace('', '|') - para = para.replace('', '|') - paragraphs[i] = text(para).strip() - - # Post-process - paragraphs = [para for para in paragraphs if - (para and not (para.endswith(':') and len(para) < 150))] - - para = text(paragraphs[0]) - m = r_sentence.match(para) - - if not m: - if not last: - term = search(term) - return wikipedia(term, language=language, last=True) - return None - sentence = m.group(0) - - maxlength = 275 - if len(sentence) > maxlength: - sentence = sentence[:maxlength] - words = sentence[:-5].split(' ') - words.pop() - sentence = ' '.join(words) + ' [...]' - - if (('using the Article Wizard if you wish' in sentence) - or ('or add a request for it' in sentence) - or ('in existing articles' in sentence)): - if not last: - term = search(term) - return wikipedia(term, language=language, last=True) - return None - - sentence = '"' + sentence.replace('"', "'") + '"' - sentence = sentence.decode('utf-8').encode('utf-8') - wikiuri = wikiuri.decode('utf-8').encode('utf-8') - term = term.decode('utf-8').encode('utf-8') - return sentence + ' - ' + (wikiuri % (term)) - -def wik(phenny, input): - origterm = input.groups()[1] - if not origterm: - return phenny.say('Perhaps you meant "!wik Zen"?') - origterm = origterm.encode('utf-8') - - log.log("event", "%s queried Wiki for '%s'" % (log.fmt_user(input), origterm), phenny) - - term = urllib.unquote(origterm) - language = 'en' - if term.startswith(':') and (' ' in term): - a, b = term.split(' ', 1) - a = a.lstrip(':') - if a.isalpha(): - language, term = a, b - term = term[0].upper() + term[1:] - term = term.replace(' ', '_') - - try: result = wikipedia(term, language) - except IOError: - args = (language, wikiuri % (term)) - error = "Can't connect to wiki.minetest.com (%s)" % args - return phenny.say(error) - - if result is not None: - phenny.say(result) - else: phenny.say('Can\'t find anything in Wiki for "%s".' % origterm) - -wik.commands = ['wik', 'wiki'] -wik.priority = 'high' +wiki.commands = ['wik', 'wiki'] +wiki.priority = 'high' if __name__ == '__main__': - print __doc__.strip() + print(__doc__.strip())