diff --git a/.gitignore b/.gitignore index 20e8101..5fa7446 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ persist config +config.ssl gitflow *.db *.log diff --git a/config.default b/config.default index 97710d6..4bda1b0 100644 --- a/config.default +++ b/config.default @@ -1,64 +1,77 @@ { - "connections": - { - "esper": - { - "server": "irc.esper.net", - "nick": "MyCloudBot", - "user": "cloudbot", - "realname": "CloudBot - http://git.io/cloudbotirc", - "mode": "", - "nickserv_password": "", - "nickserv_user": "", - "channels": ["#cloudbot", "#cloudbot2"], - "invite_join": true, - "auto_rejoin": false, - "command_prefix": "." - } - }, - "disabled_plugins": [], - "disabled_commands": [], - "acls": {}, - "api_keys": - { - "tvdb": "", - "wolframalpha": "", - "lastfm": "", - "rottentomatoes": "", - "soundcloud": "", - "twitter_consumer_key": "", - "twitter_consumer_secret": "", - "twitter_access_token": "", - "twitter_access_secret": "", - "wunderground": "", - "googletranslate": "", - "rdio_key": "", - "rdio_secret": "" - }, - "permissions": { - "admins": { - "perms": ["adminonly", "addfactoid", "delfactoid", "ignore", "botcontrol", "permissions_users", "op"], - "users": ["examplea!user@example.com", "exampleb!user@example.com"] + "connections": { + "hackint": { + "server": "irc.hackint.eu", + "nick": "antibot", + "user": "antibot", + "realname": "CloudBot - http://git.io/cloudbotirc", + "mode": "", + "_nickserv_password": "", + "-nickserv_user": "", + "channels": [ + "#ChaosChemnitz", + "#logbot" + ], + "invite_join": true, + "auto_rejoin": false, + "command_prefix": "." + } }, - "moderators": { - "perms": ["addfactoid", "delfactoid", "ignore"], - "users": ["examplec!user@example.com"] - } - }, - "plugins": - { - "factoids": - { - "prefix": false + "disabled_plugins": [], + "disabled_commands": [], + "acls": {}, + "api_keys": { + "tvdb": "", + "wolframalpha": "", + "lastfm": "", + "rottentomatoes": "", + "soundcloud": "", + "twitter_consumer_key": "", + "twitter_consumer_secret": "", + "twitter_access_token": "", + "twitter_access_secret": "", + "wunderground": "", + "googletranslate": "", + "rdio_key": "", + "rdio_secret": "" }, - "ignore": - { - "ignored": [] - } - }, - "censored_strings": - [ - "mypass", - "mysecret" - ] + "permissions": { + "admins": { + "perms": [ + "adminonly", + "addfactoid", + "delfactoid", + "ignore", + "botcontrol", + "permissions_users", + "op" + ], + "users": [ + "examplea!user@example.com", + "exampleb!user@example.com" + ] + }, + "moderators": { + "perms": [ + "addfactoid", + "delfactoid", + "ignore" + ], + "users": [ + "stummi!~Stummi@stummi.org" + ] + } + }, + "plugins": { + "factoids": { + "prefix": false + }, + "ignore": { + "ignored": [] + } + }, + "censored_strings": [ + "mypass", + "mysecret" + ] } diff --git a/core/irc.py b/core/irc.py index 35d4efa..40831e3 100644 --- a/core/irc.py +++ b/core/irc.py @@ -44,7 +44,16 @@ class crlf_tcp(object): return socket.socket(socket.AF_INET, socket.TCP_NODELAY) def run(self): - self.socket.connect((self.host, self.port)) + noerror = 0 + while 1: + try: + self.socket.connect((self.host, self.port)) + break + except socket.gaierror as e: + time.sleep(5) + except socket.timeout as e: + time.sleep(5) + thread.start_new_thread(self.recv_loop, ()) thread.start_new_thread(self.send_loop, ()) @@ -55,17 +64,25 @@ class crlf_tcp(object): return socket.timeout def handle_receive_exception(self, error, last_timestamp): + print("Receive exception: %s" % (error)) if time.time() - last_timestamp > self.timeout: + print("Receive timeout. Restart connection.") self.iqueue.put(StopIteration) self.socket.close() return True return False + def handle_send_exception(self, error): + print("Send exception: %s" % (error)) + self.iqueue.put(StopIteration) + self.socket.close() + return True + def recv_loop(self): last_timestamp = time.time() while True: try: - data = self.recv_from_socket(4096) + data = self.recv_from_socket(4096) self.ibuffer += data if data: last_timestamp = time.time() @@ -79,6 +96,8 @@ class crlf_tcp(object): if self.handle_receive_exception(e, last_timestamp): return continue + except AttributeError: + return while '\r\n' in self.ibuffer: line, self.ibuffer = self.ibuffer.split('\r\n', 1) @@ -86,13 +105,19 @@ class crlf_tcp(object): def send_loop(self): while True: - line = self.oqueue.get().splitlines()[0][:500] - print ">>> %r" % line - self.obuffer += line.encode('utf-8', 'replace') + '\r\n' - while self.obuffer: - sent = self.socket.send(self.obuffer) - self.obuffer = self.obuffer[sent:] + try: + line = self.oqueue.get().splitlines()[0][:500] + if line == StopIteration: + return + print ">>> %r" % line + self.obuffer += line.encode('utf-8', 'replace') + '\r\n' + while self.obuffer: + sent = self.socket.send(self.obuffer) + self.obuffer = self.obuffer[sent:] + except socket.error as e: + self.handle_send_exception(e) + return class crlf_ssl_tcp(crlf_tcp): """Handles ssl tcp connetions that consist of utf-8 lines ending with crlf""" @@ -114,10 +139,13 @@ class crlf_ssl_tcp(crlf_tcp): def handle_receive_exception(self, error, last_timestamp): # this is terrible - if not "timed out" in error.args[0]: - raise + #if not "timed out" in error.args[0]: + # raise return crlf_tcp.handle_receive_exception(self, error, last_timestamp) + def handle_send_exception(self, error): + return crlf_tcp.handle_send_exception(self, error) + irc_prefix_rem = re.compile(r'(.*?) (.*?) (.*)').match irc_noprefix_rem = re.compile(r'()(.*?) (.*)').match diff --git a/plugins/attacks.py b/disabled_stuff/attacks.py similarity index 100% rename from plugins/attacks.py rename to disabled_stuff/attacks.py diff --git a/plugins/brainfuck.py b/disabled_stuff/brainfuck.py similarity index 100% rename from plugins/brainfuck.py rename to disabled_stuff/brainfuck.py diff --git a/plugins/choose.py b/disabled_stuff/choose.py similarity index 100% rename from plugins/choose.py rename to disabled_stuff/choose.py diff --git a/plugins/coin.py b/disabled_stuff/coin.py similarity index 100% rename from plugins/coin.py rename to disabled_stuff/coin.py diff --git a/plugins/correction.py b/disabled_stuff/correction.py similarity index 100% rename from plugins/correction.py rename to disabled_stuff/correction.py diff --git a/plugins/cryptocoins.py b/disabled_stuff/cryptocoins.py similarity index 100% rename from plugins/cryptocoins.py rename to disabled_stuff/cryptocoins.py diff --git a/plugins/cypher.py b/disabled_stuff/cypher.py similarity index 100% rename from plugins/cypher.py rename to disabled_stuff/cypher.py diff --git a/plugins/data/8ball_responses.txt b/disabled_stuff/data/8ball_responses.txt similarity index 100% rename from plugins/data/8ball_responses.txt rename to disabled_stuff/data/8ball_responses.txt diff --git a/disabled_stuff/data/GeoLiteCity.dat b/disabled_stuff/data/GeoLiteCity.dat new file mode 100644 index 0000000..e94f60e Binary files /dev/null and b/disabled_stuff/data/GeoLiteCity.dat differ diff --git a/plugins/data/flirts.txt b/disabled_stuff/data/flirts.txt similarity index 100% rename from plugins/data/flirts.txt rename to disabled_stuff/data/flirts.txt diff --git a/plugins/data/fortunes.txt b/disabled_stuff/data/fortunes.txt similarity index 100% rename from plugins/data/fortunes.txt rename to disabled_stuff/data/fortunes.txt diff --git a/plugins/data/geoip_regions.json b/disabled_stuff/data/geoip_regions.json similarity index 100% rename from plugins/data/geoip_regions.json rename to disabled_stuff/data/geoip_regions.json diff --git a/plugins/data/insults.txt b/disabled_stuff/data/insults.txt similarity index 100% rename from plugins/data/insults.txt rename to disabled_stuff/data/insults.txt diff --git a/plugins/data/itemids.txt b/disabled_stuff/data/itemids.txt similarity index 100% rename from plugins/data/itemids.txt rename to disabled_stuff/data/itemids.txt diff --git a/plugins/data/kills.json b/disabled_stuff/data/kills.json similarity index 100% rename from plugins/data/kills.json rename to disabled_stuff/data/kills.json diff --git a/plugins/data/kills.txt b/disabled_stuff/data/kills.txt similarity index 100% rename from plugins/data/kills.txt rename to disabled_stuff/data/kills.txt diff --git a/plugins/data/larts.txt b/disabled_stuff/data/larts.txt similarity index 100% rename from plugins/data/larts.txt rename to disabled_stuff/data/larts.txt diff --git a/plugins/data/name_files/dragons.json b/disabled_stuff/data/name_files/dragons.json similarity index 100% rename from plugins/data/name_files/dragons.json rename to disabled_stuff/data/name_files/dragons.json diff --git a/plugins/data/name_files/dwarves.json b/disabled_stuff/data/name_files/dwarves.json similarity index 100% rename from plugins/data/name_files/dwarves.json rename to disabled_stuff/data/name_files/dwarves.json diff --git a/plugins/data/name_files/elves_female.json b/disabled_stuff/data/name_files/elves_female.json similarity index 100% rename from plugins/data/name_files/elves_female.json rename to disabled_stuff/data/name_files/elves_female.json diff --git a/plugins/data/name_files/elves_male.json b/disabled_stuff/data/name_files/elves_male.json similarity index 100% rename from plugins/data/name_files/elves_male.json rename to disabled_stuff/data/name_files/elves_male.json diff --git a/plugins/data/name_files/fantasy.json b/disabled_stuff/data/name_files/fantasy.json similarity index 100% rename from plugins/data/name_files/fantasy.json rename to disabled_stuff/data/name_files/fantasy.json diff --git a/plugins/data/name_files/female.json b/disabled_stuff/data/name_files/female.json similarity index 100% rename from plugins/data/name_files/female.json rename to disabled_stuff/data/name_files/female.json diff --git a/plugins/data/name_files/general.json b/disabled_stuff/data/name_files/general.json similarity index 100% rename from plugins/data/name_files/general.json rename to disabled_stuff/data/name_files/general.json diff --git a/plugins/data/name_files/hobbits.json b/disabled_stuff/data/name_files/hobbits.json similarity index 100% rename from plugins/data/name_files/hobbits.json rename to disabled_stuff/data/name_files/hobbits.json diff --git a/plugins/data/name_files/inns.json b/disabled_stuff/data/name_files/inns.json similarity index 100% rename from plugins/data/name_files/inns.json rename to disabled_stuff/data/name_files/inns.json diff --git a/plugins/data/name_files/items.json b/disabled_stuff/data/name_files/items.json similarity index 100% rename from plugins/data/name_files/items.json rename to disabled_stuff/data/name_files/items.json diff --git a/plugins/data/name_files/male.json b/disabled_stuff/data/name_files/male.json similarity index 100% rename from plugins/data/name_files/male.json rename to disabled_stuff/data/name_files/male.json diff --git a/plugins/data/name_files/narn.json b/disabled_stuff/data/name_files/narn.json similarity index 100% rename from plugins/data/name_files/narn.json rename to disabled_stuff/data/name_files/narn.json diff --git a/plugins/data/name_files/warrior_cats.json b/disabled_stuff/data/name_files/warrior_cats.json similarity index 100% rename from plugins/data/name_files/warrior_cats.json rename to disabled_stuff/data/name_files/warrior_cats.json diff --git a/plugins/data/recipes.txt b/disabled_stuff/data/recipes.txt similarity index 100% rename from plugins/data/recipes.txt rename to disabled_stuff/data/recipes.txt diff --git a/plugins/data/slaps.json b/disabled_stuff/data/slaps.json similarity index 100% rename from plugins/data/slaps.json rename to disabled_stuff/data/slaps.json diff --git a/plugins/data/slogans.txt b/disabled_stuff/data/slogans.txt similarity index 100% rename from plugins/data/slogans.txt rename to disabled_stuff/data/slogans.txt diff --git a/plugins/dice.py b/disabled_stuff/dice.py similarity index 100% rename from plugins/dice.py rename to disabled_stuff/dice.py diff --git a/plugins/dictionary.py b/disabled_stuff/dictionary.py similarity index 92% rename from plugins/dictionary.py rename to disabled_stuff/dictionary.py index b13db4b..5b4123b 100644 --- a/plugins/dictionary.py +++ b/disabled_stuff/dictionary.py @@ -19,10 +19,10 @@ def define(inp): '//div[@class="example"]') if not definition: - return 'No results for ' + inp + ' :(' + return u'No results for {} :('.format(inp) def format_output(show_examples): - result = '{}: '.format(h.xpath('//dt[@class="title-word"]/a/text()')[0]) + result = u'{}: '.format(h.xpath('//dt[@class="title-word"]/a/text()')[0]) correction = h.xpath('//span[@class="correct-word"]/text()') if correction: @@ -77,7 +77,7 @@ def etymology(inp): etym = h.xpath('//dl') if not etym: - return 'No etymology found for {} :('.format(inp) + return u'No etymology found for {} :('.format(inp) etym = etym[0].text_content() diff --git a/plugins/domainr.py b/disabled_stuff/domainr.py similarity index 100% rename from plugins/domainr.py rename to disabled_stuff/domainr.py diff --git a/plugins/down.py b/disabled_stuff/down.py similarity index 100% rename from plugins/down.py rename to disabled_stuff/down.py diff --git a/plugins/drama.py b/disabled_stuff/drama.py similarity index 100% rename from plugins/drama.py rename to disabled_stuff/drama.py diff --git a/plugins/eightball.py b/disabled_stuff/eightball.py similarity index 100% rename from plugins/eightball.py rename to disabled_stuff/eightball.py diff --git a/plugins/encrypt.py b/disabled_stuff/encrypt.py similarity index 100% rename from plugins/encrypt.py rename to disabled_stuff/encrypt.py diff --git a/plugins/fact.py b/disabled_stuff/fact.py similarity index 100% rename from plugins/fact.py rename to disabled_stuff/fact.py diff --git a/plugins/factoids.py b/disabled_stuff/factoids.py similarity index 100% rename from plugins/factoids.py rename to disabled_stuff/factoids.py diff --git a/plugins/fishbans.py b/disabled_stuff/fishbans.py similarity index 100% rename from plugins/fishbans.py rename to disabled_stuff/fishbans.py diff --git a/plugins/fmylife.py b/disabled_stuff/fmylife.py similarity index 100% rename from plugins/fmylife.py rename to disabled_stuff/fmylife.py diff --git a/plugins/fortune.py b/disabled_stuff/fortune.py similarity index 100% rename from plugins/fortune.py rename to disabled_stuff/fortune.py diff --git a/disabled_stuff/freddy.py b/disabled_stuff/freddy.py new file mode 100644 index 0000000..c77fa5a --- /dev/null +++ b/disabled_stuff/freddy.py @@ -0,0 +1,13 @@ +from util import hook, http, web +from subprocess import check_output, CalledProcessError + +@hook.command +def freddycode(inp): + """freddycode - Check if the Freddy Fresh code is correct.""" + + try: + return "Freddy: '%s' ist %s" % (inp, \ + check_output(["/bin/freddycheck", inp])) + except CalledProcessError as err: + return "Freddy: Skript returned %s" % (str(err)) + diff --git a/plugins/geoip.py b/disabled_stuff/geoip.py similarity index 100% rename from plugins/geoip.py rename to disabled_stuff/geoip.py diff --git a/plugins/github.py b/disabled_stuff/github.py similarity index 100% rename from plugins/github.py rename to disabled_stuff/github.py diff --git a/plugins/google.py b/disabled_stuff/google.py similarity index 100% rename from plugins/google.py rename to disabled_stuff/google.py diff --git a/plugins/google_translate.py b/disabled_stuff/google_translate.py similarity index 100% rename from plugins/google_translate.py rename to disabled_stuff/google_translate.py diff --git a/plugins/googleurlparse.py b/disabled_stuff/googleurlparse.py similarity index 100% rename from plugins/googleurlparse.py rename to disabled_stuff/googleurlparse.py diff --git a/plugins/history.py b/disabled_stuff/history.py similarity index 100% rename from plugins/history.py rename to disabled_stuff/history.py diff --git a/plugins/horoscope.py b/disabled_stuff/horoscope.py similarity index 100% rename from plugins/horoscope.py rename to disabled_stuff/horoscope.py diff --git a/plugins/hulu.py b/disabled_stuff/hulu.py similarity index 100% rename from plugins/hulu.py rename to disabled_stuff/hulu.py diff --git a/plugins/imdb.py b/disabled_stuff/imdb.py similarity index 100% rename from plugins/imdb.py rename to disabled_stuff/imdb.py diff --git a/plugins/imgur.py b/disabled_stuff/imgur.py similarity index 100% rename from plugins/imgur.py rename to disabled_stuff/imgur.py diff --git a/plugins/isup.py b/disabled_stuff/isup.py similarity index 100% rename from plugins/isup.py rename to disabled_stuff/isup.py diff --git a/plugins/kernel.py b/disabled_stuff/kernel.py similarity index 100% rename from plugins/kernel.py rename to disabled_stuff/kernel.py diff --git a/plugins/kill.py b/disabled_stuff/kill.py similarity index 100% rename from plugins/kill.py rename to disabled_stuff/kill.py diff --git a/plugins/lastfm.py b/disabled_stuff/lastfm.py similarity index 100% rename from plugins/lastfm.py rename to disabled_stuff/lastfm.py diff --git a/plugins/lmgtfy.py b/disabled_stuff/lmgtfy.py similarity index 100% rename from plugins/lmgtfy.py rename to disabled_stuff/lmgtfy.py diff --git a/plugins/log.py b/disabled_stuff/log.py similarity index 100% rename from plugins/log.py rename to disabled_stuff/log.py diff --git a/plugins/lyrics.py b/disabled_stuff/lyrics.py similarity index 100% rename from plugins/lyrics.py rename to disabled_stuff/lyrics.py diff --git a/plugins/metacritic.py b/disabled_stuff/metacritic.py similarity index 100% rename from plugins/metacritic.py rename to disabled_stuff/metacritic.py diff --git a/plugins/minecraft_bukget.py b/disabled_stuff/minecraft_bukget.py similarity index 100% rename from plugins/minecraft_bukget.py rename to disabled_stuff/minecraft_bukget.py diff --git a/plugins/minecraft_items.py b/disabled_stuff/minecraft_items.py similarity index 100% rename from plugins/minecraft_items.py rename to disabled_stuff/minecraft_items.py diff --git a/plugins/minecraft_ping.py b/disabled_stuff/minecraft_ping.py similarity index 100% rename from plugins/minecraft_ping.py rename to disabled_stuff/minecraft_ping.py diff --git a/plugins/minecraft_status.py b/disabled_stuff/minecraft_status.py similarity index 100% rename from plugins/minecraft_status.py rename to disabled_stuff/minecraft_status.py diff --git a/plugins/minecraft_user.py b/disabled_stuff/minecraft_user.py similarity index 100% rename from plugins/minecraft_user.py rename to disabled_stuff/minecraft_user.py diff --git a/plugins/minecraft_wiki.py b/disabled_stuff/minecraft_wiki.py similarity index 100% rename from plugins/minecraft_wiki.py rename to disabled_stuff/minecraft_wiki.py diff --git a/plugins/mlia.py b/disabled_stuff/mlia.py similarity index 100% rename from plugins/mlia.py rename to disabled_stuff/mlia.py diff --git a/plugins/namegen.py b/disabled_stuff/namegen.py similarity index 100% rename from plugins/namegen.py rename to disabled_stuff/namegen.py diff --git a/plugins/newegg.py b/disabled_stuff/newegg.py similarity index 100% rename from plugins/newegg.py rename to disabled_stuff/newegg.py diff --git a/plugins/newgrounds.py b/disabled_stuff/newgrounds.py similarity index 100% rename from plugins/newgrounds.py rename to disabled_stuff/newgrounds.py diff --git a/plugins/notes.py b/disabled_stuff/notes.py similarity index 100% rename from plugins/notes.py rename to disabled_stuff/notes.py diff --git a/plugins/osrc.py b/disabled_stuff/osrc.py similarity index 100% rename from plugins/osrc.py rename to disabled_stuff/osrc.py diff --git a/plugins/password.py b/disabled_stuff/password.py similarity index 100% rename from plugins/password.py rename to disabled_stuff/password.py diff --git a/plugins/plpaste.py b/disabled_stuff/plpaste.py similarity index 100% rename from plugins/plpaste.py rename to disabled_stuff/plpaste.py diff --git a/plugins/potato.py b/disabled_stuff/potato.py similarity index 100% rename from plugins/potato.py rename to disabled_stuff/potato.py diff --git a/plugins/pre.py b/disabled_stuff/pre.py similarity index 100% rename from plugins/pre.py rename to disabled_stuff/pre.py diff --git a/plugins/python.py b/disabled_stuff/python.py similarity index 100% rename from plugins/python.py rename to disabled_stuff/python.py diff --git a/plugins/qrcode.py b/disabled_stuff/qrcode.py similarity index 100% rename from plugins/qrcode.py rename to disabled_stuff/qrcode.py diff --git a/plugins/quote.py b/disabled_stuff/quote.py similarity index 100% rename from plugins/quote.py rename to disabled_stuff/quote.py diff --git a/plugins/rdio.py b/disabled_stuff/rdio.py similarity index 100% rename from plugins/rdio.py rename to disabled_stuff/rdio.py diff --git a/disabled_stuff/recipe.py b/disabled_stuff/recipe.py new file mode 100644 index 0000000..0e04572 --- /dev/null +++ b/disabled_stuff/recipe.py @@ -0,0 +1,106 @@ +import random + +from util import hook, http, web + +metadata_url = "http://omnidator.appspot.com/microdata/json/?url={}" + +base_url = "http://www.cookstr.com" +search_url = base_url + "/searches" +random_url = search_url + "/surprise" + +# set this to true to censor this plugin! +censor = True +phrases = [ + u"EAT SOME FUCKING \x02{}\x02", + u"YOU WON'T NOT MAKE SOME FUCKING \x02{}\x02", + u"HOW ABOUT SOME FUCKING \x02{}?\x02", + u"WHY DON'T YOU EAT SOME FUCKING \x02{}?\x02", + u"MAKE SOME FUCKING \x02{}\x02", + u"INDUCE FOOD COMA WITH SOME FUCKING \x02{}\x02" +] + +clean_key = lambda i: i.split("#")[1] + + +class ParseError(Exception): + pass + + +def get_data(url): + """ Uses the omnidator API to parse the metadata from the provided URL """ + try: + omni = http.get_json(metadata_url.format(url)) + except (http.HTTPError, http.URLError) as e: + raise ParseError(e) + schemas = omni["@"] + for d in schemas: + if d["a"] == "": + data = {clean_key(key): value for (key, value) in d.iteritems() + if key.startswith("http://schema.org/Recipe")} + return data + raise ParseError("No recipe data found") + + +@hook.command(autohelp=False) +def recipe(inp): + """recipe [term] - Gets a recipe for [term], or ets a random recipe if [term] is not provided""" + if inp: + # get the recipe URL by searching + try: + search = http.get_soup(search_url, query=inp.strip()) + except (http.HTTPError, http.URLError) as e: + return "Could not get recipe: {}".format(e) + + # find the list of results + result_list = search.find('div', {'class': 'found_results'}) + + if result_list: + results = result_list.find_all('div', {'class': 'recipe_result'}) + else: + return "No results" + + # pick a random front page result + result = random.choice(results) + + # extract the URL from the result + url = base_url + result.find('div', {'class': 'image-wrapper'}).find('a')['href'] + + else: + # get a random recipe URL + try: + page = http.open(random_url) + except (http.HTTPError, http.URLError) as e: + return "Could not get recipe: {}".format(e) + url = page.geturl() + + # use get_data() to get the recipe info from the URL + try: + data = get_data(url) + except ParseError as e: + return "Could not parse recipe: {}".format(e) + + name = data["name"].strip() + return u"Try eating \x02{}!\x02 - {}".format(name, web.try_isgd(url)) + + +@hook.command(autohelp=False) +def dinner(inp): + """dinner - WTF IS FOR DINNER""" + try: + page = http.open(random_url) + except (http.HTTPError, http.URLError) as e: + return "Could not get recipe: {}".format(e) + url = page.geturl() + + try: + data = get_data(url) + except ParseError as e: + return "Could not parse recipe: {}".format(e) + + name = data["name"].strip().upper() + text = random.choice(phrases).format(name) + + if censor: + text = text.replace("FUCK", "F**K") + + return u"{} - {}".format(text, web.try_isgd(url)) diff --git a/plugins/reddit.py b/disabled_stuff/reddit.py similarity index 100% rename from plugins/reddit.py rename to disabled_stuff/reddit.py diff --git a/plugins/regex_chans.py b/disabled_stuff/regex_chans.py similarity index 100% rename from plugins/regex_chans.py rename to disabled_stuff/regex_chans.py diff --git a/plugins/rottentomatoes.py b/disabled_stuff/rottentomatoes.py similarity index 100% rename from plugins/rottentomatoes.py rename to disabled_stuff/rottentomatoes.py diff --git a/plugins/rss.py b/disabled_stuff/rss.py similarity index 100% rename from plugins/rss.py rename to disabled_stuff/rss.py diff --git a/plugins/shorten.py b/disabled_stuff/shorten.py similarity index 100% rename from plugins/shorten.py rename to disabled_stuff/shorten.py diff --git a/plugins/slap.py b/disabled_stuff/slap.py similarity index 100% rename from plugins/slap.py rename to disabled_stuff/slap.py diff --git a/plugins/slogan.py b/disabled_stuff/slogan.py similarity index 100% rename from plugins/slogan.py rename to disabled_stuff/slogan.py diff --git a/plugins/snopes.py b/disabled_stuff/snopes.py similarity index 100% rename from plugins/snopes.py rename to disabled_stuff/snopes.py diff --git a/plugins/soundcloud.py b/disabled_stuff/soundcloud.py similarity index 100% rename from plugins/soundcloud.py rename to disabled_stuff/soundcloud.py diff --git a/plugins/spellcheck.py b/disabled_stuff/spellcheck.py similarity index 100% rename from plugins/spellcheck.py rename to disabled_stuff/spellcheck.py diff --git a/plugins/spotify.py b/disabled_stuff/spotify.py similarity index 100% rename from plugins/spotify.py rename to disabled_stuff/spotify.py diff --git a/disabled_stuff/status.py b/disabled_stuff/status.py new file mode 100644 index 0000000..977ac8e --- /dev/null +++ b/disabled_stuff/status.py @@ -0,0 +1,53 @@ +from util import hook +import re +import time +from subprocess import check_output + +def getstatus(): + try: + return check_output("sudo /bin/chch-status", shell=True).strip("\n").decode("utf-8") + except: + return "unbekannt" + +@hook.command("status", autohelp=False) +def cmd_status(inp, reply=None): + """status - Return the door status""" + reply("Chaostreff Status: %s" % (getstatus())) + +@hook.event("TOPIC") +def topic_update(info, conn=None, chan=None): + """topic_update -- Update the topic on TOPIC command""" + status = getstatus() + + topic = info[-1] + + sstr = "Status: %s" % (status) + if sstr in topic: + return + + if 'Status: ' in topic: + new_topic = re.sub("Status: [^ ]*", sstr, topic) + else: + new_topic = "%s | %s" % (topic.rstrip(' |'), sstr) + + if new_topic != topic: + conn.send("TOPIC %s :%s" % (chan, new_topic)) + +@hook.event("332") +def e332_update(info, conn=None, chan=None): + """e332_update -- run after current topic was requested""" + chan = info[1] + topic_update(info, conn=conn, chan=chan) + +@hook.singlethread +@hook.event("353") +def e353_update(info, conn=None, chan=None): + """e353_update -- runs after a channel was joined""" + chan = info[2] + if chan.lower() == "#chaoschemnitz": + conn.send("PRIVMSG Chanserv :op #chaoschemnitz") + + while True: + conn.send("TOPIC %s" % (chan)) + time.sleep(60) + diff --git a/plugins/steam.py b/disabled_stuff/steam.py similarity index 100% rename from plugins/steam.py rename to disabled_stuff/steam.py diff --git a/plugins/steam_calc.py b/disabled_stuff/steam_calc.py similarity index 100% rename from plugins/steam_calc.py rename to disabled_stuff/steam_calc.py diff --git a/plugins/stock.py b/disabled_stuff/stock.py similarity index 100% rename from plugins/stock.py rename to disabled_stuff/stock.py diff --git a/plugins/suggest.py b/disabled_stuff/suggest.py similarity index 55% rename from plugins/suggest.py rename to disabled_stuff/suggest.py index 0e02210..ec66144 100644 --- a/plugins/suggest.py +++ b/disabled_stuff/suggest.py @@ -1,5 +1,3 @@ -import json - from util import hook, http, text from bs4 import BeautifulSoup @@ -7,20 +5,14 @@ from bs4 import BeautifulSoup @hook.command def suggest(inp): """suggest -- Gets suggested phrases for a google search""" - - page = http.get('http://google.com/complete/search', - output='json', client='hp', q=inp) - page_json = page.split('(', 1)[1][:-1] - - suggestions = json.loads(page_json)[1] - suggestions = [suggestion[0] for suggestion in suggestions] + suggestions = http.get_json('http://suggestqueries.google.com/complete/search', client='firefox', q=inp)[1] if not suggestions: return 'no suggestions found' out = u", ".join(suggestions) - # defuckify text + # defuckify text (might not be needed now, but I'll keep it) soup = BeautifulSoup(out) out = soup.get_text() diff --git a/plugins/system.py b/disabled_stuff/system.py similarity index 100% rename from plugins/system.py rename to disabled_stuff/system.py diff --git a/plugins/tell.py b/disabled_stuff/tell.py similarity index 100% rename from plugins/tell.py rename to disabled_stuff/tell.py diff --git a/plugins/time_plugin.py b/disabled_stuff/time_plugin.py similarity index 100% rename from plugins/time_plugin.py rename to disabled_stuff/time_plugin.py diff --git a/plugins/title.py b/disabled_stuff/title.py similarity index 100% rename from plugins/title.py rename to disabled_stuff/title.py diff --git a/plugins/tvdb.py b/disabled_stuff/tvdb.py similarity index 100% rename from plugins/tvdb.py rename to disabled_stuff/tvdb.py diff --git a/plugins/twitch.py b/disabled_stuff/twitch.py similarity index 100% rename from plugins/twitch.py rename to disabled_stuff/twitch.py diff --git a/plugins/twitter.py b/disabled_stuff/twitter.py similarity index 100% rename from plugins/twitter.py rename to disabled_stuff/twitter.py diff --git a/plugins/update.py b/disabled_stuff/update.py similarity index 100% rename from plugins/update.py rename to disabled_stuff/update.py diff --git a/disabled_stuff/urban.py b/disabled_stuff/urban.py new file mode 100644 index 0000000..48da433 --- /dev/null +++ b/disabled_stuff/urban.py @@ -0,0 +1,66 @@ +import re +import random + +from util import hook, http, text + + +base_url = 'http://api.urbandictionary.com/v0' +define_url = base_url + "/define" +random_url = base_url + "/random" + +@hook.command('u', autohelp=False) +@hook.command(autohelp=False) +def urban(inp): + """urban [id] -- Looks up on urbandictionary.com.""" + + if inp: + # clean and split the input + inp = inp.lower().strip() + parts = inp.split() + + # if the last word is a number, set the ID to that number + if parts[-1].isdigit(): + id_num = int(parts[-1]) + # remove the ID from the input string + del parts[-1] + inp = " ".join(parts) + else: + id_num = 1 + + # fetch the definitions + page = http.get_json(define_url, term=inp, referer="http://m.urbandictionary.com") + + if page['result_type'] == 'no_results': + return 'Not found.' + else: + # get a random definition! + page = http.get_json(random_url, referer="http://m.urbandictionary.com") + id_num = None + + definitions = page['list'] + + if id_num: + # try getting the requested definition + try: + definition = definitions[id_num - 1] + + def_text = " ".join(definition['definition'].split()) # remove excess spaces + def_text = text.truncate_str(def_text, 200) + except IndexError: + return 'Not found.' + + url = definition['permalink'] + output = u"[%i/%i] %s :: %s" % \ + (id_num, len(definitions), def_text, url) + + else: + definition = random.choice(definitions) + + def_text = " ".join(definition['definition'].split()) # remove excess spaces + def_text = text.truncate_str(def_text, 200) + + name = definition['word'] + url = definition['permalink'] + output = u"\x02{}\x02: {} :: {}".format(name, def_text, url) + + return output diff --git a/plugins/utility.py b/disabled_stuff/utility.py similarity index 100% rename from plugins/utility.py rename to disabled_stuff/utility.py diff --git a/plugins/validate.py b/disabled_stuff/validate.py similarity index 100% rename from plugins/validate.py rename to disabled_stuff/validate.py diff --git a/plugins/valvesounds.py b/disabled_stuff/valvesounds.py similarity index 100% rename from plugins/valvesounds.py rename to disabled_stuff/valvesounds.py diff --git a/plugins/vimeo.py b/disabled_stuff/vimeo.py similarity index 100% rename from plugins/vimeo.py rename to disabled_stuff/vimeo.py diff --git a/plugins/weather.py b/disabled_stuff/weather.py similarity index 100% rename from plugins/weather.py rename to disabled_stuff/weather.py diff --git a/plugins/wikipedia.py b/disabled_stuff/wikipedia.py similarity index 89% rename from plugins/wikipedia.py rename to disabled_stuff/wikipedia.py index 6b3827a..90461f4 100644 --- a/plugins/wikipedia.py +++ b/disabled_stuff/wikipedia.py @@ -42,8 +42,8 @@ def wiki(inp): if title.lower() not in desc.lower(): desc = title + desc - desc = re.sub('\s+', ' ', desc).strip() # remove excess spaces + desc = u' '.join(desc.split()) # remove excess spaces desc = text.truncate_str(desc, 200) - return '{} :: {}'.format(desc, http.quote(url, ':/')) + return u'{} :: {}'.format(desc, http.quote(url, ':/')) diff --git a/plugins/wolframalpha.py b/disabled_stuff/wolframalpha.py similarity index 100% rename from plugins/wolframalpha.py rename to disabled_stuff/wolframalpha.py diff --git a/plugins/xkcd.py b/disabled_stuff/xkcd.py similarity index 100% rename from plugins/xkcd.py rename to disabled_stuff/xkcd.py diff --git a/plugins/yahooanswers.py b/disabled_stuff/yahooanswers.py similarity index 100% rename from plugins/yahooanswers.py rename to disabled_stuff/yahooanswers.py diff --git a/plugins/youtube.py b/disabled_stuff/youtube.py similarity index 99% rename from plugins/youtube.py rename to disabled_stuff/youtube.py index 67627db..e63bca3 100644 --- a/plugins/youtube.py +++ b/disabled_stuff/youtube.py @@ -34,7 +34,6 @@ def get_video_description(video_id): out += u' - length \x02{}\x02'.format(timeformat.format_time(length, simple=True)) if 'ratingCount' in data: - # format likes = plural(int(data['likeCount']), "like") dislikes = plural(data['ratingCount'] - int(data['likeCount']), "dislike") diff --git a/plugins/bad_version.py b/plugins/bad_version.py new file mode 100644 index 0000000..9465f2d --- /dev/null +++ b/plugins/bad_version.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from util import hook +from thread import start_new_thread +from time import sleep + +def wait_and_send(conn, wait, msg): + sleep(wait) + conn.send(msg) + +@hook.command("check") +def check_nick(inp, conn=None): + conn.send("PRIVMSG %s :\x01VERSION\x01" % inp) + + +@hook.event("JOIN") +def handle_join(info, input=None, conn=None): + start_new_thread(wait_and_send, (conn, 5, "PRIVMSG %s :\x01VERSION\x01" % input.nick)) + +@hook.event("NOTICE") +def handle_ctcp_rply(info, input=None, conn=None, nick=None): + print "notice..." + print "-%s-" % input.lastparam + if input.lastparam == ("\1VERSION %s\1" % "mIRC v7.22 Khaled Mardam-Bey"): + for chan in conn.channels: + if chan != "#logbot": + conn.send("KICK %s %s :bad version" % (chan, nick)) + conn.send("MODE %s +b %s!*@*$#logbot" % (chan, nick)) + diff --git a/plugins/bandwidth.py b/plugins/bandwidth.py new file mode 100644 index 0000000..ea23333 --- /dev/null +++ b/plugins/bandwidth.py @@ -0,0 +1,21 @@ +from util import hook, http, web +from subprocess import check_output, CalledProcessError +from datetime import datetime + +@hook.command("bw", autohelp=False) +def bw(inp): + """bw - list last bandwidth measurement to the outside.""" + + try: + o = check_output("/bin/chch-bandwidth") + except CalledProcessError as err: + return "chch-bandwidth: returned %s" % (str(err)) + + os = o.split(",") + upl = int(os[-1])/1024.0/1024.0 + dl = int(os[-2])/1024.0/1024.0 + ts = os[0] + tsd = datetime.strptime(ts, "%Y%m%d%H%M%S") + + return "%s: upl = %f Mbit/s; dl = %f Mbit/s;" % (tsd, upl, dl) + diff --git a/plugins/chch_worker.py b/plugins/chch_worker.py new file mode 100644 index 0000000..e57a9cc --- /dev/null +++ b/plugins/chch_worker.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +from util import hook +import re +import time +import requests +import urllib +from subprocess import check_output +import json +import socket +import struct + +#def run_ecmd(cmd): +## baseuri = "http://netio.chch.lan.ffc/ecmd?" +## baseuri = "http://10.8.128.35/ecmd?" +# baseuri = "http://127.0.0.1:4280/ecmd?" +# cmds = "%20".join(cmd) +# req = requests.get("%s%s" % (baseuri, cmds)) +# return req.text.strip() + +#def run_udp(cmd): +# ip="127.0.0.1" +# port=49152 +# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# # 100 ms timeout +# s.settimeout(0.1) +# s.connect((ip, port)) +# s.send(cmd) +# try: +# rec = s.recv(1024) +# except: +# rec = "" +# s.close() +# return rec + +## lamp_lounge handling +#@hook.command("lamp_lounge", autohelp=True) +#def cmd_lamp_lounge(inp, reply=None): +# """lamp_lounge color - set the lamp color""" +# args = inp.split(" ") +# if len(args) < 1: +# reply("lamp_lounge color - set the lamp color") +# return +# +# if len(args[0]) != 6: +# reply("lamp_lounge color - set the lamp color") +# return +# +# c = "a\x00\x03" + struct.pack('BBB', int(args[0][2:4], 16), int(args[0][0:2], 16), int(args[0][4:6], 16)) +# +# rep = run_tcp(c) +# +# if len(rep) < 3: +# reply("Error: no reply") +# return +# +# if rep[0] == 'a': +# reply("OK") +# elif rep[0] == 'e': +# reply("error: " + rep[3:]) +# else: +# reply("fatal error") + +@hook.command("corridor_light_toggle", autohelp=False) +def cmd_corridor_light_toggle(inp, reply=None): + """toggle corridor light modes""" + reply(check_output("echo corridor_light_toggle | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +@hook.command("corridor_light", autohelp=False) +def cmd_corridor_light(inp, reply=None): + """set corridor light color""" + args = inp.split(" ") + if len(args) < 1: + reply("corridor_light color - set the light color") + return + + if len(args[0]) != 6: + reply("corridor_light color - set the light color") + return + + reply(check_output("echo corridor_light " + args[0] + " | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +@hook.command("lounge_light_toggle", autohelp=False) +def cmd_lounge_light_toggle(inp, reply=None): + """toggle lounge light modes""" + reply(check_output("echo lounge_light_toggle | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +@hook.command("lounge_light", autohelp=False) +def cmd_lounge_light(inp, reply=None): + """set lounge light color""" + args = inp.split(" ") + if len(args) < 1: + reply("lounge_light color - set the light color") + return + + if len(args[0]) != 6: + reply("lounge_light color - set the light color") + return + + reply(check_output("echo lounge_light " + args[0] + " | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +@hook.command("elab_light_toggle", autohelp=False) +def cmd_elab_light_toggle(inp, reply=None): + """toggle e-lab light modes""" + reply(check_output("echo e-lab_light_toggle | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +@hook.command("elab_light", autohelp=False) +def cmd_elab_light(inp, reply=None): + """set e-lab light color""" + args = inp.split(" ") + if len(args) < 1: + reply("e-lab_light color - set the light color") + return + + if len(args[0]) != 6: + reply("e-lab_light color - set the light color") + return + + reply(check_output("echo e-lab_light " + args[0] + " | ssh -q -p 2322 command@127.0.0.1", shell=True).strip("\n").decode("utf-8")) + +## Lamp handling +#@hook.command("lamp", autohelp=True) +#def cmd_lamp(inp, reply=None): +# """lamp color [mode] - set the lamp color""" +# args = inp.split(" ") +# if len(args) < 1: +# reply("""lamp color [mode] - set the lamp color""") +# return +# +# if len(args[0]) != 6: +# reply("""lamp color [mode] - set the lamp color""") +# return +# +# cmode = "s" +# if len(args) > 1: +# if args[1] == "s" or args[1] == "y" or args[1] == "f": +# cmode = args[1] +# +# c = [] +# c.append([5, int(args[0][0:2], 16)]) +# c.append([4, int(args[0][2:4], 16)]) +# c.append([3, int(args[0][4:6], 16)]) +# +# for ce in c: +# res = run_ecmd(["channel", str(ce[0]), str(ce[1]), cmode]) +# if res != "OK": +# return +# reply("OK") + +#@hook.command("lamp_fadestep", autohelp=True) +#def cmd_lamp_fadestep(inp, reply=None): +# """lamp_fadestep step - set the lamp fadestep""" +# args = inp.split(" ") +# +# if len(args) < 1: +# reply("""lamp_fadestep step - set the lamp fadestep""") +# return +# +# reply(run_ecmd(["fadestep", args[0]])) + +#@hook.command("lamp_fadestep_get", autohelp=False) +#def cmd_lamp_fadestep_get(inp, reply=None): +# """lamp_fadestep_get - get the lamp fadestep""" +# reply(run_ecmd(["fadestep"])) +# +#@hook.command("lamp_channels", autohelp=False) +#def cmd_lamp_channels(inp, reply=None): +# """lamp_chanels - get the lamp channel count""" +# reply(run_ecmd(["channels"])) + +# Wiki handling +def wiki_changes(cmd=False): + tmpfile = "/tmp/wikichanges.timestamp.txt" + basewikiuri = "https://www.chaoschemnitz.de/index.php?title=%s" + wikiapiuri = "https://www.chaoschemnitz.de/api.php?"\ + "action=query&list=recentchanges&format=json&"\ + "rcprop=user|userid|comment|parsedcomment|timestamp|"\ + "title|sha1|sizes|redirect|loginfo|tags|flags"\ + "&rclist=edit|external|new|log" + + try: + fdch = open(tmpfile, "rw") + timestamp = fdch.read() + fdch.close() + except IOError: + timestamp = None + + try: + r = requests.get(wikiapiuri, verify=False) + except: + return [] + + rarr = [] + changes = r.json()["query"]["recentchanges"] + ntimestamp = changes[0]["timestamp"] + for change in changes: + if change["timestamp"] == timestamp: + break + uri = basewikiuri % (urllib.quote(change["title"].encode("utf-8"), safe="")) + rarr.append("wiki: %s changed '%s' ( %s ) comment: %s" %\ + (change["user"], change["title"], uri,\ + change["comment"].strip("\r\n\t"))) + + if cmd == False: + fdch = open(tmpfile, "w+") + fdch.write("%s" % (ntimestamp)) + fdch.close() + + return rarr + +def print_wiki_changes(info, conn=None, chan=None): + """print_wiki_changes - print wiki changes, when the worker calls""" + ch = wiki_changes(cmd=False) + if len(ch) == 0: + return + for c in ch[::-1]: + conn.msg("#chaoschemnitz", c) + time.sleep(0.5) + +@hook.command("wikichanges", autohelp=False) +def cmd_wikichanges(inp, reply=None): + """wikichanges - Return new recent wiki changes""" + ch = wiki_changes(cmd=True) + if len(ch) == 0: + reply("No changes since the last call were made to the wiki.") + else: + for c in ch[::-1][-4:]: + reply(c) + time.sleep(0.5) + +# Status handling +def getstatus(): +# try: + fd = requests.get('http://www.chaoschemnitz.de/chch.json') + chch_info = fd.json() + if 'message' in chch_info['state']: + message = chch_info['state']['message'] + if " | " in message: + message = message.split(" | ", 1)[0] + else: + message = "" + + if chch_info['state']['open']: + state = "geƶffnet".decode("utf-8") + else: + state = "geschlossen" + + return "%s (%s)" % (state, message) +# return check_output("sudo /bin/chch-status", shell=True).strip("\n").decode("utf-8") +# except: +# return "unbekannt" + +@hook.command("status", autohelp=False) +def cmd_status(inp, reply=None): + """status - Return the door status""" + reply("Chaostreff Status: %s" % (getstatus())) + +@hook.event("TOPIC") +def topic_update(info, conn=None, chan=None): + print("topic update") + """topic_update -- Update the topic on TOPIC command""" + if chan != "#ChaosChemnitz": + return + + status = getstatus() + print("status: %s" % (status.encode('utf8'))) + + topic = info[-1].split(" | ") + print("topic: %s" % ([ elem.encode('utf8') for elem in topic ])) + + sstr = "Status: %s" % (status) + print("sstr: %s" % (sstr.encode('utf8'))) + didset = False + i = 0 + while i < len(topic): + if sstr in topic[i]: + print("Found current status in topic.") + didset = True + break + if 'Status: ' in topic[i]: + print("Found Status field in topic.") + didset = True + topic[i] = sstr + i += 1 + if didset == False: + print("No topic fiel was found, appending.") + topic.append(sstr) + + newtopic = " | ".join(topic) + if newtopic != info[-1]: + conn.send("TOPIC %s :%s" % (chan, newtopic)) + +@hook.event("332") +def e332_update(info, conn=None, chan=None): + """e332_update -- run after current topic was requested, runs worker tasks too""" + chan = info[1] + topic_update(info, conn=conn, chan=chan) + print_wiki_changes(info, conn=conn, chan=chan) + +@hook.singlethread +@hook.event("353") +def e353_update(info, conn=None, chan=None): + """e353_update -- runs after a channel (#chaoschemnitz) was joined""" + chan = info[2] + if chan.lower() == "#chaoschemnitz": + conn.send("PRIVMSG Chanserv :op #chaoschemnitz") + + while True: + time.sleep(60) + conn.send("TOPIC %s" % (chan)) + diff --git a/plugins/statuslog.py b/plugins/statuslog.py new file mode 100644 index 0000000..e70c7f8 --- /dev/null +++ b/plugins/statuslog.py @@ -0,0 +1,76 @@ +import os +import codecs +import time +import re + +from util import hook + +timestamp_format = '%H:%M:%S' + +formats = { + 'PRIVMSG': '<%(nick)s> %(msg)s', + 'PART': '-!- %(nick)s [%(user)s@%(host)s] has left %(chan)s', + 'JOIN': '-!- %(nick)s [%(user)s@%(host)s] has joined %(param0)s', + 'MODE': '-!- mode/%(chan)s [%(param_tail)s] by %(nick)s', + 'KICK': '-!- %(param1)s was kicked from %(chan)s by %(nick)s [%(msg)s]', + 'TOPIC': '-!- %(nick)s changed the topic of %(chan)s to: %(msg)s', + 'QUIT': '-!- %(nick)s has quit [%(msg)s]', + 'PING': '', + 'NOTICE': '-%(nick)s- %(msg)s' +} + +ctcp_formats = { + 'ACTION': '* %(nick)s %(ctcpmsg)s', + 'VERSION': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', + 'PING': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', + 'TIME': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', + 'FINGER': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s' +} + +irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])') + + +def gmtime(format): + return time.strftime(format, time.gmtime()) + + +def beautify(input): + format = formats.get(input.command, '%(raw)s') + args = dict(input) + + leng = len(args['paraml']) + for n, p in enumerate(args['paraml']): + args['param' + str(n)] = p + args['param_' + str(abs(n - leng))] = p + + args['param_tail'] = ' '.join(args['paraml'][1:]) + args['msg'] = irc_color_re.sub('', args['msg']) + + if input.command == 'PRIVMSG' and input.msg.count('\x01') >= 2: + ctcp = input.msg.split('\x01', 2)[1].split(' ', 1) + if len(ctcp) == 1: + ctcp += [''] + args['ctcpcmd'], args['ctcpmsg'] = ctcp + format = ctcp_formats.get(args['ctcpcmd'], + '%(nick)s [%(user)s@%(host)s] requested unknown CTCP ' + '%(ctcpcmd)s from %(chan)s: %(ctcpmsg)s') + + return format % args + +@hook.singlethread +@hook.event('*') +def log(paraml, input=None, bot=None): + timestamp = gmtime(timestamp_format) + + if input.command == 'QUIT': # these are temporary fixes until proper + input.chan = 'quit' # presence tracking is implemented + if input.command == 'NICK': + input.chan = 'nick' + + beau = beautify(input) + + if beau == '': # don't log this + return + + print timestamp, input.chan, beau.encode('utf8', 'ignore') + diff --git a/plugins/urban.py b/plugins/urban.py deleted file mode 100644 index e64ea80..0000000 --- a/plugins/urban.py +++ /dev/null @@ -1,47 +0,0 @@ -import re - -from util import hook, http, text - - -base_url = 'http://www.urbandictionary.com/iphone/search/define' - - -@hook.command('u') -@hook.command -def urban(inp): - """urban [id] -- Looks up on urbandictionary.com.""" - - # clean and split the input - inp = inp.lower().strip() - parts = inp.split() - - # if the last word is a number, set the ID to that number - if parts[-1].isdigit(): - id_num = int(parts[-1]) - # remove the ID from the input string - del parts[-1] - inp = " ".join(parts) - else: - id_num = 1 - - # fetch the definitions - page = http.get_json(base_url, term=inp, referer="http://m.urbandictionary.com") - definitions = page['list'] - - if page['result_type'] == 'no_results': - return 'Not found.' - - # try getting the requested definition - try: - definition = definitions[id_num - 1]['definition'].replace('\r\n', ' ') - definition = re.sub('\s+', ' ', definition).strip() # remove excess spaces - definition = text.truncate_str(definition, 200) - except IndexError: - return 'Not found.' - - url = definitions[id_num - 1]['permalink'] - - output = u"[%i/%i] %s :: %s" % \ - (id_num, len(definitions), definition, url) - - return output diff --git a/restartcloudbot.sh b/restartcloudbot.sh new file mode 100755 index 0000000..25f2324 --- /dev/null +++ b/restartcloudbot.sh @@ -0,0 +1,11 @@ +#!/bin/bash +cd $(dirname $0) + +( +while true +do + sudo -u cloudbot ./cloudbot.py 2>&1 | logger -s -t $(basename $0) + sleep 10 +done +) & +disown $!