diff --git a/admin.py b/admin.py new file mode 100644 index 0000000..d9a7673 --- /dev/null +++ b/admin.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +""" +admin.py - Phenny Admin Module +Copyright 2008-9, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def join(phenny, input): + """Join the specified channel. This is an admin-only command.""" + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + channel, key = input.group(1), input.group(2) + if not key: + phenny.write(['JOIN'], channel) + else: phenny.write(['JOIN', channel, key]) +join.rule = r'\.join (#\S+)(?: *(\S+))?' +#join.commands = ['join'] +join.priority = 'low' +join.example = '.join #example or .join #example key' + +def part(phenny, input): + """Part the specified channel. This is an admin-only command.""" + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + phenny.write(['PART'], input.group(2)) +part.commands = ['part'] +part.priority = 'low' +part.example = '.part #example' + +def quit(phenny, input): + """Quit from the server. This is an owner-only command.""" + # Can only be done in privmsg by the owner + if input.sender.startswith('#'): return + if input.owner: + phenny.write(['QUIT']) + __import__('os')._exit(0) +quit.commands = ['quit'] +quit.priority = 'low' + +def msg(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + a, b = input.group(2), input.group(3) + if (not a) or (not b): return + if input.admin: + phenny.msg(a, b) +msg.rule = (['msg'], r'(#?\S+) (.+)') +msg.priority = 'low' + +def me(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + msg = '\x01ACTION %s\x01' % input.group(3) + phenny.msg(input.group(2) or input.sender, msg) +me.rule = (['me'], r'(#?\S+) (.+)') +me.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/calc.py b/calc.py new file mode 100755 index 0000000..cae7cfe --- /dev/null +++ b/calc.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# coding=utf-8 +""" +calc.py - Phenny Calculator Module +Copyright 2008, Sean B. Palmer, inamidst.com +Modified by Sfan5 2012 +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re +import web + +r_result = re.compile(r'(?i)(.*?)') +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)') +] + +def c(phenny, input): + """Google calculator.""" + if not input.group(2): + return phenny.reply("Nothing to calculate.") + q = input.group(2).encode('utf-8') + q = q.replace('\xcf\x95', 'phi') # utf-8 U+03D5 + q = q.replace('\xcf\x80', 'pi') # utf-8 U+03C0 + print("[LOG]: %s calculated '%s'" % (input.nick,q)) + uri = 'http://www.google.com/ig/calculator?q=' + bytes = web.get(uri + web.urllib.quote(q)) + parts = bytes.split('",') + answer = [p for p in parts if p.startswith('rhs: "')][0][6:] + if answer: + answer = answer.decode('unicode-escape') + answer = ''.join(chr(ord(c)) for c in answer) + answer = answer.decode('utf-8') + answer = answer.replace(u'\xc2\xa0', ',') + answer = answer.replace('', '^(') + answer = answer.replace('', ')') + answer = web.decode(answer) + phenny.say(answer) + else: phenny.say('Sorry, no result.') +c.commands = ['c'] +c.example = '.c 5 + 3' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/ping.py b/ping.py new file mode 100755 index 0000000..23219ac --- /dev/null +++ b/ping.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +""" +ping.py - Phenny Ping Module +Author: Sean B. Palmer, inamidst.com +About: http://inamidst.com/phenny/ +""" + +import random + +def hello(phenny, input): + greeting = random.choice(('Hi', 'Hey', 'Hello')) + punctuation = random.choice(('', '!')) + phenny.say(greeting + ' ' + input.nick + punctuation) +hello.rule = r'(?i)(hi|hello|hey) $nickname[ \t]*$' + +def interjection(phenny, input): + phenny.say(input.nick + '!') +interjection.rule = r'$nickname!' +interjection.priority = 'high' +interjection.thread = False + +if __name__ == '__main__': + print __doc__.strip() diff --git a/reload.py b/reload.py new file mode 100644 index 0000000..dfd0e8e --- /dev/null +++ b/reload.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +""" +reload.py - Phenny Module Reloader Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import sys, os.path, time, imp +import irc + +def f_reload(phenny, input): + """Reloads a module, for use by admins only.""" + if not input.admin: return + + name = input.group(2) + if name == phenny.config.owner: + return phenny.reply('What?') + + if (not name) or (name == '*'): + phenny.variables = None + phenny.commands = None + phenny.setup() + return phenny.reply('done') + + if not sys.modules.has_key(name): + return phenny.reply('%s: no such module!' % name) + + # Thanks to moot for prodding me on this + path = sys.modules[name].__file__ + if path.endswith('.pyc') or path.endswith('.pyo'): + path = path[:-1] + if not os.path.isfile(path): + return phenny.reply('Found %s, but not the source file' % name) + + module = imp.load_source(name, path) + sys.modules[name] = module + if hasattr(module, 'setup'): + module.setup(phenny) + + mtime = os.path.getmtime(module.__file__) + modified = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(mtime)) + + phenny.register(vars(module)) + phenny.bind_commands() + + phenny.reply('%r (version: %s)' % (module, modified)) +f_reload.name = 'reload' +f_reload.rule = ('$nick', ['reload'], r'(\S+)?') +f_reload.priority = 'low' +f_reload.thread = False + +if __name__ == '__main__': + print __doc__.strip() diff --git a/rssnotify.py b/rssnotify.py new file mode 100755 index 0000000..f4923c0 --- /dev/null +++ b/rssnotify.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +""" +rssnotify.py - Phenny RssNotify Module +Copyright 2012, Sfan5 +""" +import feedparser, time, urllib # sudo easy_install feedparser +rssnotify = {} + +def get_arrayindex(array,val): + for i in range(0,len(array)): + if array[i] == val: + return i + return -1 + +rssnotify["last_updated_feeds"] = {} + +rssnotify["last_update"] = time.time() +rssnotify["dont_print_first_message"] = False +rssnotify["update_cooldown"] = 30 # in seconds +rssnotify["say_to_channel"] = '#minetest' +rssnotify["show_commit_link"] = True +rssnotify["use_git.io"] = True + + + +def rsscheck(phenny, input): + t = time.time() + if rssnotify["last_update"] > t-rssnotify["update_cooldown"]: + return + rssnotify["last_update"] = t + print("[LOG]: Checking RSS Feeds...") + start = time.time() + feeds = [ + 'https://github.com/celeron55/minetest/commits/master.atom', + 'https://github.com/celeron55/minetest_game/commits/master.atom' + ] + for url in feeds: + options = { + 'agent': 'Mozilla/5.0 (MinetestBot)', + 'referrer': 'http://minetest.net' + } + feed = feedparser.parse(url, **options) + if len(feed.entries) == 0: continue + last_entry = feed.entries[0] + feednum = get_arrayindex(feeds,url) + if not feednum in rssnotify["last_updated_feeds"].keys(): + rssnotify["last_updated_feeds"][feednum] = -1 + if rssnotify["last_updated_feeds"][feednum] != last_entry.updated: + rssnotify["last_updated_feeds"][feednum] = last_entry.updated + commiter = last_entry.authors[0].href.replace('https://github.com/',"") + commiter_realname = last_entry.authors[0].name + reponame = url.replace("https://github.com/","").replace("/commits/master.atom","") + commit_hash = last_entry.links[0].href.replace("https://github.com/" + reponame + "/commit/","")[:10] + commit_time = last_entry.updated + print("[LOG]: Found RSS Update for URL '%s'" % (url)) + if rssnotify["dont_print_first_message"]: + continue # Don't print first Message + if rssnotify["show_commit_link"]: + if rssnotify["use_git.io"]: + params = urllib.urlencode({'url' : last_entry.link}) # git.io only works with *.github.com links + u = urllib.urlopen("http://git.io/create", params) + commit_link = "http://git.io/" + u.read() + else: + commit_link = last_entry.link + else: + commit_link = "" + + + if commiter.lower() != commiter_realname.lower(): + #phenny.say("GIT: %s (%s) commited to %s: %s %s %s" % (commiter,commiter_realname,reponame,last_entry.title,commit_hash,commit_time)) + phenny.write(['PRIVMSG',rssnotify["say_to_channel"]],"GIT: %s (%s) commited to %s: %s %s %s %s" % (commiter, commiter_realname, reponame, last_entry.title, commit_hash, commit_time, commit_link)) + else: + #phenny.say("GIT: %s commited to %s: %s %s %s" % (commiter,reponame,last_entry.title,commit_hash,commit_time)) + phenny.write(['PRIVMSG',rssnotify["say_to_channel"]],"GIT: %s commited to %s: %s %s %s %s" % (commiter, reponame, last_entry.title, commit_hash, commit_time, commit_link)) + end = time.time() + if rssnotify["dont_print_first_message"]: + rssnotify["dont_print_first_message"] = False + print("[LOG]: Checked " + str(len(feeds)) + " RSS Feeds in %0.3f seconds" % (end-start)) + +rsscheck.priority = 'high' +rsscheck.rule = r'.*' +rsscheck.event = '*' +rsscheck.thread = True + +if __name__ == '__main__': + print __doc__.strip() diff --git a/search.py b/search.py new file mode 100755 index 0000000..e0b35e1 --- /dev/null +++ b/search.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +""" +search.py - Phenny Web Search Module +Copyright 2008-9, Sean B. Palmer, inamidst.com +Modified by Sfan5 2012 +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import web, re + +search_badwords = ["porn","p0rn","pr0n","pron","redtube","sex","pussy","hot","weed","smoking","drug","penis","vagina"] #Thank KikaRz and LandMine for this +search_badnicks = ["KikaRz","LandMine","LandMineMT"] + +class Grab(web.urllib.URLopener): + def __init__(self, *args): + self.version = 'Mozilla/5.0 (MinetestBot)' + web.urllib.URLopener.__init__(self, *args) + self.addheader('Referer', 'http://minetest.net') + def http_error_default(self, url, fp, errcode, errmsg, headers): + return web.urllib.addinfourl(fp, [headers, errcode], "http:" + url) + +def google_ajax(query): + """Search using AjaxSearch, and return its JSON.""" + if isinstance(query, unicode): + query = query.encode('utf-8') + uri = 'http://ajax.googleapis.com/ajax/services/search/web' + args = '?v=1.0&safe=off&q=' + web.urllib.quote(query) + handler = web.urllib._urlopener + web.urllib._urlopener = Grab() + bytes = web.get(uri + args) + web.urllib._urlopener = handler + return web.json(bytes) + +def google_search(query): + results = google_ajax(query) + try: return results['responseData']['results'][0]['unescapedUrl'] + except IndexError: return None + except TypeError: + print results + return False + +def google_count(query): + results = google_ajax(query) + if not results.has_key('responseData'): return '0' + if not results['responseData'].has_key('cursor'): return '0' + if not results['responseData']['cursor'].has_key('estimatedResultCount'): + return '0' + return results['responseData']['cursor']['estimatedResultCount'] + +def formatnumber(n): + """Format a number with beautiful commas.""" + parts = list(str(n)) + for i in range((len(parts) - 3), 0, -3): + parts.insert(i, ',') + return ''.join(parts) + + +def g(phenny, input): + """Queries Google for the specified input.""" + query = input.group(2) + if not query: + return phenny.reply('.g what?') + for bw in search_badwords: + if bw in query: + print("[LOG]: %s queried Google Result for '%s' | DENIED: Badword" % (input.nick,query)) + return phenny.reply("Search term contains badword") + for bn in search_badnicks: + if bn in input.nick: + print("[LOG]: %s queried Google Result for '%s' | DENIED: Badnick" % (input.nick,query)) + return phenny.reply("Nope!") + query = query.encode('utf-8') + print("[LOG]: %s queried Google Result for '%s'" % (input.nick,query)) + uri = google_search(query) + if uri: + phenny.reply(uri) + if not hasattr(phenny.bot, 'last_seen_uri'): + phenny.bot.last_seen_uri = {} + phenny.bot.last_seen_uri[input.sender] = uri + elif uri is False: phenny.reply("Problem getting data from Google.") + else: phenny.reply("No results found for '%s'." % query) +g.commands = ['g'] +g.priority = 'high' +g.example = '.g minetest' + +def gc(phenny, input): + if not input.group(2): + return phenny.reply("No query term.") + query = input.group(2).encode('utf-8') + result = new_gc(query) + for bw in search_badwords: + if bw in query: + print("[LOG]: %s queried Google Result Number for '%s' | DENIED: Badword" % (input.nick,query)) + return phenny.reply("Search term contains badword") + for bn in search_badnicks: + if bn in input.nick: + print("[LOG]: %s queried Google Result Number for '%s' | DENIED: Badnick" % (input.nick,query)) + return phenny.reply("Nope!") + print("[LOG]: %s queried Google Result Number for '%s'" % (input.nick,query)) + if result: + phenny.say(query + ": " + result) + else: phenny.reply("Sorry, couldn't get a result.") + +def new_gc(query): + uri = 'https://www.google.com/search?hl=en&q=' + uri = uri + web.urllib.quote(query).replace('+', '%2B') + if '"' in query: uri += '&tbs=li:1' + bytes = web.get(uri) + if "did not match any documents" in bytes: + return "0" + for result in re.compile(r'(?ims)([0-9,]+) results?').findall(bytes): + return result + return None + +gc.commands = ['gc'] +gc.priority = 'high' +gc.example = '.gc minetest' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/server.py b/server.py new file mode 100755 index 0000000..a0f7b3d --- /dev/null +++ b/server.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +""" +server.py - Phenny Minetest Server Module +Copyright 2012, Sfan5 +""" + +import web, math, random +from xml.dom import minidom + +def read_server(): + bytes = web.get("http://servers.minetest.ru/") + shim = '' + shim2 = '
' + if shim in bytes and shim2 in bytes: + bytes = bytes.split(shim, 1).pop() + bytes = bytes.split(shim2, 1)[0] + bytes = "" + bytes + "
" # Root Tag needed + print("DBG bytes = '%s'" % bytes) + dom = minidom.parseString(bytes) + l = dom.getElementsByTagName("tr") + chosen = l[int(math.floor(random.random()*(len(l)-1))+1)] + datas = chosen.getElementsByTagName("td") + name = datas[0].firstChild.data # Server Name + addr = datas[1].firstChild.data # Server Address + status = datas[3].firstChild.data # Status (up/down) + statuspercent = datas[4].firstChild.firstChild.data # Status Percent + return format(name,addr,status,statuspercent) + return "Unknown Error" + + +def format(name,addr,status,statuspercent): + if status == "up": + return "%s | %s %s (%s)" % (name,addr,status,statuspercent) + else: + return "%s | %s %s" % (name,addr,status) +def server(phenny, input): + phenny.reply(read_server()) + +server.commands = ['sv', 'server'] +server.thread = True + +if __name__ == '__main__': + print __doc__ diff --git a/serverup.py b/serverup.py new file mode 100755 index 0000000..0127b90 --- /dev/null +++ b/serverup.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +""" +serverup.py - Minetest-Server Ping Module +Copyright 2012, sfan5 +""" + +import socket, time + +def serverup(phenny, input): + arg = input.group(2) + if not arg: + return phenny.reply("Give me a Server Address") + if not '.' in arg: + return phenny.reply("Invalid Address") + if ':' in arg: + address = arg.split(':')[0] + try: + port = int(arg.split(':')[1]) + except: + return phenny.reply("Invalid Port") + else: + address = arg + port = 30000 + try: + start = time.time() + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.settimeout(2.5) + buf = "\x4f\x45\x74\x03\x00\x00\x00\x01" + sock.sendto(buf, (address, port)) + data, addr = sock.recvfrom(1000) + if data: + peer_id = data[12:14] + buf = "\x4f\x45\x74\x03" + peer_id + "\x00\x00\x03" + sock.sendto(buf, (address, port)) + sock.close() + end = time.time() + phenny.reply("%s is up (%0.3fms)" % (arg,end-start)) + else: + phenny.reply("%s seems to be down " % arg) + except: + phenny.reply("%s seems to be down " % arg) + + + +serverup.commands = ['up'] +serverup.thread = True + +if __name__ == '__main__': + print __doc__ diff --git a/startup.py b/startup.py new file mode 100755 index 0000000..297dfb5 --- /dev/null +++ b/startup.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +""" +startup.py - Phenny Startup Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import threading, time + +def setup(phenny): + # by clsn + phenny.data = {} + refresh_delay = 300.0 + + if hasattr(phenny.config, 'refresh_delay'): + try: refresh_delay = float(phenny.config.refresh_delay) + except: pass + + def close(): + print "Nobody PONGed our PING, restarting" + phenny.handle_close() + + def pingloop(): + timer = threading.Timer(refresh_delay, close, ()) + phenny.data['startup.setup.timer'] = timer + phenny.data['startup.setup.timer'].start() + # print "PING!" + phenny.write(('PING', phenny.config.host)) + phenny.data['startup.setup.pingloop'] = pingloop + + def pong(phenny, input): + try: + # print "PONG!" + phenny.data['startup.setup.timer'].cancel() + time.sleep(refresh_delay + 60.0) + pingloop() + except: pass + pong.event = 'PONG' + pong.thread = True + pong.rule = r'.*' + phenny.variables['pong'] = pong + + # Need to wrap handle_connect to start the loop. + inner_handle_connect = phenny.handle_connect + + def outer_handle_connect(): + inner_handle_connect() + if phenny.data.get('startup.setup.pingloop'): + phenny.data['startup.setup.pingloop']() + + phenny.handle_connect = outer_handle_connect + +def startup(phenny, input): + import time + + if hasattr(phenny.config, 'serverpass'): + phenny.write(('PASS', phenny.config.serverpass)) + + if hasattr(phenny.config, 'password'): + phenny.msg('NickServ', 'IDENTIFY %s' % phenny.config.password) + time.sleep(5) + + # Cf. http://swhack.com/logs/2005-12-05#T19-32-36 + for channel in phenny.channels: + phenny.write(('JOIN', channel)) + time.sleep(0.5) +startup.rule = r'(.*)' +startup.event = '251' +startup.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/twitter.py b/twitter.py new file mode 100755 index 0000000..82df3e1 --- /dev/null +++ b/twitter.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +""" +twitter.py - Phenny Twitter Module +Copyright 2012, Sean B. Palmer, inamidst.com +Modified by Sfan5 2012 +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re, time +import web + +r_username = re.compile(r'^[a-zA-Z0-9_]{1,15}$') +r_link = re.compile(r'^https?://twitter.com/\S+$') +r_p = re.compile(r'(?ims)(

]*>.*?') +r_paragraph = re.compile(r'(?ims)]*>.*?

|]*>.*?') +r_tag = re.compile(r'<(?!!)[^>]+>') +r_whitespace = re.compile(r'[\t\r\n ]+') +r_redirect = re.compile( + r'(?ims)class=.redirectText.>\s*') + s = s.replace('<', '<') + s = s.replace('&', '&') + s = s.replace(' ', ' ') + return s + +def text(html): + html = r_tag.sub('', html) + html = r_whitespace.sub(' ', html) + return unescape(html).strip() + +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)) + + 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() + + 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') + print("[LOG]: %s queried Minetest Wiki for '%s'" % (input.nick,origterm)) + + 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'] +wik.priority = 'high' + +if __name__ == '__main__': + print __doc__.strip()