add legacy version of tenquestionmarks irc bot

This commit is contained in:
Adrian Malacoda
2017-02-04 21:13:24 -06:00
parent a3bed71cdd
commit ee0ec3f727
25 changed files with 7460 additions and 0 deletions

0
modules/__init__.py Executable file
View File

28
modules/echobox.py Executable file
View File

@@ -0,0 +1,28 @@
"""An echobox is a device that, upon feeding it an input, stores it and
outputs a previously submitted input.
Usage: !echobox input"""
import random
import urllib
import urllib2
def echobox(nick,channel,tenquestionmarks,input):
"""The echobox command submits some text into an "echobox", or
a collection of quotes. After doing so, it outputs a random
quote from that colleciton."""
if input == None or input == "":
return tenquestionmarks.html("<b>Echobox error</b>: You need to type something after !echobox, because I'm too lazy to come up with something for you.")
result = ""
if "web_echobox_url" in tenquestionmarks.config()["echobox"]:
service_target = "%s?%s" % (tenquestionmarks.config()["echobox"]["web_echobox_url"],urllib.urlencode({"input": input, "nick": nick, "chan": channel}))
result = urllib2.urlopen(service_target).read()
else:
echobox = tenquestionmarks.get_json("echobox.json")
if "echoes" not in echobox:
echobox["echoes"] = []
echobox["echoes"].append(input)
tenquestionmarks.put_json("echobox.json",echobox)
result = random.choice(echobox["echoes"])
return tenquestionmarks.html("<b>Echobox</b>: %s" % (result))

7
modules/eightball.py Executable file
View File

@@ -0,0 +1,7 @@
"""Ask the eight-ball a yes/no question, and it will give you a reasonable answer.
Usage: !eightball question"""
import random
def eightball(nick,channel,tenquestionmarks,question):
return tenquestionmarks.html("<b>Eightball:</b> %s" % (random.choice(tenquestionmarks.config()["eightball"]["responses"])))

65
modules/help.py Executable file
View File

@@ -0,0 +1,65 @@
"""Help system for this tenquestionmarks-based bot.
Usage:
- !tqmhelp -> display an overview of all modules
- !tqmhelp module -> display help for a specific module
- !tqmhelp module command -> display help for a specific command
"""
import types
import inspect
def tqmhelp(nick,channel,tenquestionmarks,module,command=None):
output = []
bnick = tenquestionmarks.config()["nick"]
if module == "":
output.append("%s help index\n" % (bnick))
output.append("--------------------------------\n")
output.append("In this bot, commands are grouped into modules.\n")
output.append("For help with a specific module, type !tqmhelp followed by \n")
output.append("the name of the module.\n")
output.append("This bot contains the following modules:\n")
output.append("--------------------------------\n")
for submod in tenquestionmarks.modules():
output.append("<b>%s</b>\n" % (submod))
submodobj = tenquestionmarks.modules()[submod]
if not submodobj.__doc__ == None:
output.append(submodobj.__doc__)
output.append("\n--------------------------------\n")
elif not command == None:
try:
modobj = tenquestionmarks.modules()[module]
except KeyError:
return tenquestionmarks.html("<b>Help error</b>: No module named %s" % (module))
if not hasattr(modobj,command):
return tenquestionmarks.html("<b>Help error</b>: No command %s in module %s" % (command,module))
output.append("%s help for command %s.%s\n" % (bnick, module, command))
output.append("--------------------------------\n")
commandobj = getattr(modobj,command)
output.append("<b>Command %s.%s</b>\n" % (module, command))
argspec = inspect.getargspec(commandobj)
del argspec.args[0]
del argspec.args[0]
del argspec.args[0]
output.append("<b>Usage:</b> !%s.%s %s\n" % (module, command, " ".join(argspec.args)))
if not commandobj.__doc__ == None:
output.append(commandobj.__doc__)
else:
try:
modobj = tenquestionmarks.modules()[module]
except KeyError:
return tenquestionmarks.html("<b>Help error</b>: No module named %s" % (module))
output.append("%s help for module %s\n" % (bnick, module))
output.append("--------------------------------\n")
for var in vars(modobj):
varvalue = vars(modobj)[var]
if not (var.startswith("on_") or var.startswith("_")) and isinstance(varvalue,types.FunctionType):
output.append("<b>Command %s.%s</b>\n" % (module, var))
argspec = inspect.getargspec(varvalue)
del argspec.args[0]
del argspec.args[0]
del argspec.args[0]
output.append("<b>Usage:</b> !%s.%s %s\n" % (module, var, " ".join(argspec.args)))
if not varvalue.__doc__ == None:
output.append(varvalue.__doc__)
output.append("\n--------------------------------\n")
return tenquestionmarks.html("".join(output))

57
modules/rss.py Executable file
View File

@@ -0,0 +1,57 @@
"""RSS feed aggregator. This module contains no user-facing commands."""
import sys
import os
import threading
import traceback
import feedparser
def on_connected(tenquestionmarks):
_rss_loop(tenquestionmarks,tenquestionmarks.config()["rss"]["frequency"])
def _rss_loop(tenquestionmarks, frequency=900.0):
try:
old_entries_file = os.path.join(tenquestionmarks.directory(),"old-feed-entries")
FILE = open(old_entries_file, "r")
filetext = FILE.read()
FILE.close()
except IOError:
filetext = ""
open(old_entries_file, "w").close()
filetext = filetext.decode("UTF-8")
for feed in tenquestionmarks.config()["rss"]["feeds"]:
feedname = ""
if isinstance(tenquestionmarks.config()["rss"]["feeds"],dict):
feedname = feed
feed = tenquestionmarks.config()["rss"]["feeds"][feed]
NextFeed = False
tenquestionmarks.log("refresh","Refreshing feed %s" % (feed))
d = feedparser.parse(feed)
for entry in d.entries:
title = entry.title
try:
title = title.encode("ascii")
except UnicodeEncodeError, uee:
title = tenquestionmarks.degrade_to_ascii(title)
except UnicodeDecodeError, ude:
title = tenquestionmarks.degrade_to_ascii(title)
if title in filetext:
tenquestionmarks.log("refresh","Old entry: %s" % (title))
NextFeed = True
else:
FILE = open(old_entries_file, "a")
try:
FILE.write(title + u"\n")
except Exception, e:
traceback.print_exc(file=sys.stdout)
tenquestionmarks.log("Error","%s %s" % (e,title))
FILE.close()
tenquestionmarks.queue(tenquestionmarks.config()["rss"]["format"] % ({"title": title, "link": entry.link, "feedname": feedname}))
if NextFeed:
break
def refresher(): _rss_loop(tenquestionmarks,frequency)
t = threading.Timer(frequency, refresher) # TODO: make this static
t.start()