PEP8 clean

This commit is contained in:
nemunaire 2014-11-13 02:51:49 +01:00
parent e1aff6c4cf
commit 2dfe1f0e9a
15 changed files with 330 additions and 160 deletions

View File

@ -14,6 +14,7 @@ nemubotversion = 3.4
from more import Response
def load(context):
"""Load this module"""
global DATAS
@ -25,9 +26,10 @@ def load(context):
DATAS.getNode("variables").setIndex("name")
def help_full ():
def help_full():
return "TODO"
def set_variable(name, value, creator):
var = ModuleState("variable")
var["name"] = name
@ -35,6 +37,7 @@ def set_variable(name, value, creator):
var["creator"] = creator
DATAS.getNode("variables").addChild(var)
def get_variable(name, msg=None):
if name == "sender" or name == "from" or name == "nick":
return msg.frm
@ -47,14 +50,19 @@ def get_variable(name, msg=None):
else:
return ""
@hook("cmd_hook", "set")
def cmd_set(msg):
if len (msg.cmds) > 2:
if len(msg.cmds) > 2:
set_variable(msg.cmds[1], " ".join(msg.cmds[2:]), msg.nick)
res = Response("Variable \$%s définie." % msg.cmds[1], channel=msg.channel)
res = Response("Variable \$%s définie." % msg.cmds[1],
channel=msg.channel)
save()
return res
return Response("!set prend au minimum deux arguments : le nom de la variable et sa valeur.", channel=msg.channel)
return Response("!set prend au minimum deux arguments : "
"le nom de la variable et sa valeur.",
channel=msg.channel)
@hook("cmd_hook", "listalias")
def cmd_listalias(msg):
@ -68,7 +76,10 @@ def cmd_listalias(msg):
res.append("%s n'a pas encore créé d'alias" % user)
return Response(" ; ".join(res), channel=msg.channel)
else:
return Response("Alias connus : %s." % ", ".join(DATAS.getNode("aliases").index.keys()), channel=msg.channel)
return Response("Alias connus : %s." %
", ".join(DATAS.getNode("aliases").index.keys()),
channel=msg.channel)
@hook("cmd_hook", "listvars")
def cmd_listvars(msg):
@ -82,18 +93,21 @@ def cmd_listvars(msg):
res.append("%s n'a pas encore créé de variable" % user)
return Response(" ; ".join(res), channel=msg.channel)
else:
return Response("Variables connues : %s." % ", ".join(DATAS.getNode("variables").index.keys()), channel=msg.channel)
return Response("Variables connues : %s." %
", ".join(DATAS.getNode("variables").index.keys()),
channel=msg.channel)
@hook("cmd_hook", "alias")
def cmd_alias(msg):
if len (msg.cmds) > 1:
if len(msg.cmds) > 1:
res = list()
for alias in msg.cmds[1:]:
if alias[0] == "!":
alias = alias[1:]
if alias in DATAS.getNode("aliases").index:
res.append(Response("!%s correspond à %s" % (alias,
DATAS.getNode("aliases").index[alias]["origin"]),
res.append(Response("!%s correspond à %s" %
(alias, DATAS.getNode("aliases").index[alias]["origin"]),
channel=msg.channel))
else:
res.append(Response("!%s n'est pas un alias" % alias,
@ -103,9 +117,10 @@ def cmd_alias(msg):
return Response("!alias prend en argument l'alias à étendre.",
channel=msg.channel)
@hook("cmd_hook", "unalias")
def cmd_unalias(msg):
if len (msg.cmds) > 1:
if len(msg.cmds) > 1:
res = list()
for alias in msg.cmds[1:]:
if alias[0] == "!" and len(alias) > 1:
@ -113,31 +128,38 @@ def cmd_unalias(msg):
if alias in DATAS.getNode("aliases").index:
if DATAS.getNode("aliases").index[alias]["creator"] == msg.nick or msg.frm_owner:
DATAS.getNode("aliases").delChild(DATAS.getNode("aliases").index[alias])
res.append(Response("%s a bien été supprimé" % alias, channel=msg.channel))
res.append(Response("%s a bien été supprimé" % alias,
channel=msg.channel))
else:
res.append(Response("Vous n'êtes pas le createur de l'alias %s." % alias, channel=msg.channel))
res.append(Response("Vous n'êtes pas le createur de "
"l'alias %s." % alias,
channel=msg.channel))
else:
res.append(Response("%s n'est pas un alias" % alias, channel=msg.channel))
res.append(Response("%s n'est pas un alias" % alias,
channel=msg.channel))
return res
else:
return Response("!unalias prend en argument l'alias à supprimer.", channel=msg.channel)
return Response("!unalias prend en argument l'alias à supprimer.",
channel=msg.channel)
def replace_variables(cnt, msg=None):
cnt = cnt.split(' ')
unsetCnt = list()
for i in range(0, len(cnt)):
if i not in unsetCnt:
res = re.match("^([^$]*)(\\\\)?\\$([a-zA-Z0-9]+)(.*)$", cnt[i])
if res is not None:
try:
varI = int(res.group(3))
unsetCnt.append(varI)
cnt[i] = res.group(1) + msg.cmds[varI] + res.group(4)
except:
if res.group(2) != "":
cnt[i] = res.group(1) + "$" + res.group(3) + res.group(4)
else:
cnt[i] = res.group(1) + get_variable(res.group(3), msg) + res.group(4)
if i not in unsetCnt:
res = re.match("^([^$]*)(\\\\)?\\$([a-zA-Z0-9]+)(.*)$", cnt[i])
if res is not None:
try:
varI = int(res.group(3))
unsetCnt.append(varI)
cnt[i] = res.group(1) + msg.cmds[varI] + res.group(4)
except:
if res.group(2) != "":
cnt[i] = res.group(1) + "$" + res.group(3) + res.group(4)
else:
cnt[i] = (res.group(1) + get_variable(res.group(3), msg) +
res.group(4))
return " ".join(cnt)
@ -174,7 +196,8 @@ def parseask(msg):
alias["origin"] = result.group(3)
alias["creator"] = msg.nick
DATAS.getNode("aliases").addChild(alias)
res = Response("Nouvel alias %s défini avec succès." % result.group(1), channel=msg.channel)
res = Response("Nouvel alias %s défini avec succès." %
result.group(1), channel=msg.channel)
save()
return res
return None

View File

@ -15,17 +15,22 @@ nemubotversion = 3.4
from more import Response
def load(context):
global DATAS
DATAS.setIndex("name", "birthday")
def help_full():
return "!anniv /who/: gives the remaining time before the anniversary of /who/\n!age /who/: gives the age of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)"
return ("!anniv /who/: gives the remaining time before the anniversary of "
"/who/\n!age /who/: gives the age of /who/\nIf /who/ is not given,"
" gives the remaining time before your anniversary.\n\n To set you"
"r birthday, say it to nemubot :)")
def findName(msg):
if len(msg.cmds) < 2 or msg.cmds[1].lower() == "moi" or msg.cmds[1].lower() == "me":
if (len(msg.cmds) < 2 or msg.cmds[1].lower() == "moi" or
msg.cmds[1].lower() == "me"):
name = msg.nick.lower()
else:
name = msg.cmds[1].lower()
@ -35,9 +40,9 @@ def findName(msg):
if name in DATAS.index:
matches.append(name)
else:
for k in DATAS.index.keys ():
if k.find (name) == 0:
matches.append (k)
for k in DATAS.index.keys():
if k.find(name) == 0:
matches.append(k)
return (matches, name)
@ -52,9 +57,9 @@ def cmd_anniv(msg):
if (tyd.day == datetime.today().day and
tyd.month == datetime.today().month):
return Response(countdown_format(
DATAS.index[name].getDate("born"), "",
"C'est aujourd'hui l'anniversaire de %s !"
" Il a %s. Joyeux anniversaire :)" % (name, "%s")),
DATAS.index[name].getDate("born"), "",
"C'est aujourd'hui l'anniversaire de %s !"
" Il a %s. Joyeux anniversaire :)" % (name, "%s")),
msg.channel)
else:
if tyd < datetime.today():
@ -69,6 +74,7 @@ def cmd_anniv(msg):
" de %s. Quand est-il né ?" % name,
msg.channel, msg.nick)
@hook("cmd_hook", "age")
def cmd_age(msg):
(matches, name) = findName(msg)
@ -85,6 +91,7 @@ def cmd_age(msg):
" Quand est-il né ?" % name, msg.channel, msg.nick)
return True
@hook("ask_default")
def parseask(msg):
res = re.match(r"^(\S+)\s*('s|suis|est|is|was|were)?\s+(birthday|geburtstag|née? |nee? le|born on).*$", msg.text, re.I)

View File

@ -11,6 +11,7 @@ nemubotversion = 3.4
from more import Response
def load(context):
if not CONF or not CONF.hasNode("goodreadsapi") or not CONF.getNode("goodreadsapi").hasAttribute("key"):
print ("You need a Goodreads API key in order to use this "
@ -19,24 +20,34 @@ def load(context):
"https://www.goodreads.com/api/keys")
return None
def get_book(title):
response = web.getXML("https://www.goodreads.com/book/title.xml?key=%s&title=%s" % (CONF.getNode("goodreadsapi")["key"], urllib.parse.quote(title)))
"""Retrieve a book from its title"""
response = web.getXML("https://www.goodreads.com/book/title.xml?key=%s&title=%s" %
(CONF.getNode("goodreadsapi")["key"], urllib.parse.quote(title)))
if response is not None and response.hasNode("book"):
return response.getNode("book")
else:
return None
def search_books(title):
response = web.getXML("https://www.goodreads.com/search.xml?key=%s&q=%s" % (CONF.getNode("goodreadsapi")["key"], urllib.parse.quote(title)))
"""Get a list of book matching given title"""
response = web.getXML("https://www.goodreads.com/search.xml?key=%s&q=%s" %
(CONF.getNode("goodreadsapi")["key"], urllib.parse.quote(title)))
if response is not None and response.hasNode("search"):
return response.getNode("search").getNode("results").getNodes("work")
else:
return []
def search_author(name):
response = web.getXML("https://www.goodreads.com/api/author_url/%s?key=%s" % (urllib.parse.quote(name), CONF.getNode("goodreadsapi")["key"]))
"""Looking for an author"""
response = web.getXML("https://www.goodreads.com/api/author_url/%s?key=%s" %
(urllib.parse.quote(name), CONF.getNode("goodreadsapi")["key"]))
if response is not None and response.hasNode("author") and response.getNode("author").hasAttribute("id"):
response = web.getXML("https://www.goodreads.com/author/show/%s.xml?key=%s" % (urllib.parse.quote(response.getNode("author")["id"]), CONF.getNode("goodreadsapi")["key"]))
response = web.getXML("https://www.goodreads.com/author/show/%s.xml?key=%s" %
(urllib.parse.quote(response.getNode("author")["id"]), CONF.getNode("goodreadsapi")["key"]))
if response is not None and response.hasNode("author"):
return response.getNode("author")
return None
@ -53,10 +64,10 @@ def cmd_book(msg):
res = Response(channel=msg.channel)
res.append_message("%s, writed by %s: %s" % (book.getNode("title").getContent(),
book.getNode("authors").getNode("author").getNode("name").getContent(),
web.striphtml(book.getNode("description").getContent())
))
web.striphtml(book.getNode("description").getContent())))
return res
@hook("cmd_hook", "search_books")
def cmd_books(msg):
if len(msg.cmds) < 2:
@ -64,16 +75,21 @@ def cmd_books(msg):
title = " ".join(msg.cmds[1:])
res = Response(channel=msg.channel,
title="%s" % (title), count=" (%d more books)")
title="%s" % (title),
count=" (%d more books)")
for book in search_books(title):
res.append_message("%s, writed by %s" % (book.getNode("best_book").getNode("title").getContent(), book.getNode("best_book").getNode("author").getNode("name").getContent()))
res.append_message("%s, writed by %s" % (book.getNode("best_book").getNode("title").getContent(),
book.getNode("best_book").getNode("author").getNode("name").getContent()))
return res
@hook("cmd_hook", "author_books")
def cmd_author(msg):
if len(msg.cmds) < 2:
raise IRCException("please give me an author to search")
ath = search_author(" ".join(msg.cmds[1:]))
return Response([b.getNode("title").getContent() for b in ath.getNode("books").getNodes("book")], channel=msg.channel, title=ath.getNode("name").getContent())
return Response([b.getNode("title").getContent() for b in ath.getNode("books").getNodes("book")],
channel=msg.channel,
title=ath.getNode("name").getContent())

View File

@ -26,6 +26,7 @@ from networkbot import NetworkBot
nemubotversion = 3.4
NODATA = True
def getserver(toks, context, prompt):
"""Choose the server in toks or prompt"""
if len(toks) > 1 and toks[0] in context.servers:
@ -35,6 +36,7 @@ def getserver(toks, context, prompt):
else:
return (None, toks)
@hook("prompt_cmd", "close")
def close(data, toks, context, prompt):
"""Disconnect and forget (remove from the servers list) the server"""
@ -51,6 +53,7 @@ def close(data, toks, context, prompt):
prompt.selectedServer = None
return
@hook("prompt_cmd", "connect")
def connect(data, toks, context, prompt):
"""Make the connexion to a server"""
@ -66,6 +69,7 @@ def connect(data, toks, context, prompt):
else:
print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "disconnect")
def disconnect(data, toks, context, prompt):
"""Close the connection to a server"""
@ -83,6 +87,7 @@ def disconnect(data, toks, context, prompt):
else:
print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "discover")
def discover(data, toks, context, prompt):
"""Discover a new bot on a server"""
@ -93,10 +98,12 @@ def discover(data, toks, context, prompt):
bot = context.add_networkbot(srv, name)
bot.connect()
else:
print (" %s is not a valid fullname, for example: nemubot!nemubotV3@bot.nemunai.re")
print (" %s is not a valid fullname, for example: "
"nemubot!nemubotV3@bot.nemunai.re")
else:
print (" Please SELECT a server or give its name in first argument.")
@hook("prompt_cmd", "hotswap")
def hotswap(data, toks, context, prompt):
"""Reload a server class"""
@ -114,6 +121,7 @@ def hotswap(data, toks, context, prompt):
else:
print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "join")
@hook("prompt_cmd", "leave")
@hook("prompt_cmd", "part")
@ -134,7 +142,7 @@ def join(data, toks, context, prompt):
return
if len(toks) <= rd:
print ("%s: not enough arguments." % toks[0])
print("%s: not enough arguments." % toks[0])
return
if toks[0] == "join":
@ -146,6 +154,7 @@ def join(data, toks, context, prompt):
srv.write("PART %s" % toks[rd])
return
@hook("prompt_cmd", "save")
def save_mod(data, toks, context, prompt):
"""Force save module data"""
@ -161,6 +170,7 @@ def save_mod(data, toks, context, prompt):
print ("save: no module named `%s´" % mod)
return
@hook("prompt_cmd", "send")
def send(data, toks, context, prompt):
"""Send a message on a channel"""
@ -182,7 +192,7 @@ def send(data, toks, context, prompt):
print ("send: not enough arguments.")
return
#Check the server is connected
# Check the server is connected
if not srv.connected:
print ("send: server `%s' not connected." % srv.id)
return
@ -202,6 +212,7 @@ def send(data, toks, context, prompt):
srv.send_response(TextMessage(" ".join(toks[rd:]), server=None, to=[chan]))
return "done"
@hook("prompt_cmd", "zap")
def zap(data, toks, context, prompt):
"""Hard change connexion state"""
@ -216,20 +227,28 @@ def zap(data, toks, context, prompt):
else:
print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "top")
def top(data, toks, context, prompt):
"""Display consumers load information"""
print("Queue size: %d, %d thread(s) running (counter: %d)" % (context.cnsr_queue.qsize(), len(context.cnsr_thrd), context.cnsr_thrd_size))
print("Queue size: %d, %d thread(s) running (counter: %d)" %
(context.cnsr_queue.qsize(),
len(context.cnsr_thrd),
context.cnsr_thrd_size))
if len(context.events) > 0:
print("Events registered: %d, next in %d seconds" % (len(context.events), context.events[0].time_left.seconds))
print("Events registered: %d, next in %d seconds" %
(len(context.events),
context.events[0].time_left.seconds))
else:
print("No events registered")
for th in context.cnsr_thrd:
if th.is_alive():
print("################ Stack trace for thread %u ################" % th.ident)
print(("#" * 15 + " Stack trace for thread %u " + "#" * 15) %
th.ident)
traceback.print_stack(sys._current_frames()[th.ident])
@hook("prompt_cmd", "netstat")
def netstat(data, toks, context, prompt):
"""Display sockets in use and many other things"""
@ -241,10 +260,14 @@ def netstat(data, toks, context, prompt):
lvl = 0
for hlvl in bot.hooks:
lvl += 1
for hook in hlvl.all_pre + hlvl.all_post + hlvl.cmd_rgxp + hlvl.cmd_default + hlvl.ask_rgxp + hlvl.ask_default + hlvl.msg_rgxp + hlvl.msg_default:
for hook in (hlvl.all_pre + hlvl.all_post + hlvl.cmd_rgxp +
hlvl.cmd_default + hlvl.ask_rgxp +
hlvl.ask_default + hlvl.msg_rgxp +
hlvl.msg_default):
print(" %s- %s" % (' ' * lvl * 2, hook))
for kind in [ "irc_hook", "cmd_hook", "ask_hook", "msg_hook" ]:
print(" %s- <%s> %s" % (' ' * lvl * 2, kind, ", ".join(hlvl.__dict__[kind].keys())))
for kind in ["irc_hook", "cmd_hook", "ask_hook", "msg_hook"]:
print(" %s- <%s> %s" % (' ' * lvl * 2, kind,
", ".join(hlvl.__dict__[kind].keys())))
print(" * My tag: %d" % bot.my_tag)
print(" * Tags in use (%d):" % bot.inc_tag)
for tag, (cmd, data) in bot.tags.items():

View File

@ -30,16 +30,19 @@ s = [('present', '0'), ('présent', '0'), ('pr', '0'),
d = defaultdict(list)
for k, v in s:
d[k].append(v)
d[k].append(v)
def help_full():
return "!conjugaison <tens> <verb>: give the conjugaison for <verb> in <tens>."
return ("!conjugaison <tens> <verb>: give the conjugaison for <verb> in "
"<tens>.")
@hook("cmd_hook", "conjugaison")
def cmd_conjug(msg):
if len(msg.cmds) < 3:
raise IRCException("donne moi un temps et un verbe, et je te donnerai sa conjugaison!")
raise IRCException("donne moi un temps et un verbe, et je te donnerai "
"sa conjugaison!")
tens = ' '.join(msg.cmds[1:-1])
print_debug(tens)
@ -58,31 +61,34 @@ def cmd_conjug(msg):
def get_conjug(verb, stringTens):
url = ("http://leconjugueur.lefigaro.fr/conjugaison/verbe/%s.html" %
quote(verb.encode("ISO-8859-1")))
print_debug (url)
print_debug(url)
page = web.getURLContent(url)
if page is not None:
for line in page.split("\n"):
if re.search('<div class="modeBloc">', line) is not None:
return compute_line(line, stringTens)
return compute_line(line, stringTens)
return list()
def compute_line(line, stringTens):
try:
idTemps = d[stringTens]
except:
raise IRCException("le temps demandé n'existe pas")
try:
idTemps = d[stringTens]
except:
raise IRCException("le temps demandé n'existe pas")
if len(idTemps) == 0:
raise IRCException("le temps demandé n'existe pas")
if len(idTemps) == 0:
raise IRCException("le temps demandé n'existe pas")
index = line.index('<div id="temps' + idTemps[0] + '\"')
endIndex = line[index:].index('<div class=\"conjugBloc\"')
index = line.index('<div id="temps' + idTemps[0] + '\"')
endIndex = line[index:].index('<div class=\"conjugBloc\"')
endIndex += index
newLine = line[index:endIndex]
endIndex += index
newLine = line[index:endIndex]
res = list()
for elt in re.finditer("[p|/]>([^/]*/b>)", newLine):
res.append(striphtml(elt.group(1).replace("<b>", "\x02").replace("</b>", "\x0F")))
return res
res = list()
for elt in re.finditer("[p|/]>([^/]*/b>)", newLine):
res.append(striphtml(elt.group(1)
.replace("<b>", "\x02")
.replace("</b>", "\x0F")))
return res

View File

@ -14,24 +14,30 @@ nemubotversion = 3.4
from more import Response
def help_full ():
return "!github /repo/: Display information about /repo/.\n!github_user /user/: Display information about /user/."
def help_full():
return ("!github /repo/: Display information about /repo/.\n"
"!github_user /user/: Display information about /user/.")
def info_repos(repo):
raw = urlopen("https://api.github.com/search/repositories?q=%s" % quote(repo), timeout=10)
raw = urlopen("https://api.github.com/search/repositories?q=%s" %
quote(repo), timeout=10)
return json.loads(raw.read().decode())
def info_user(username):
raw = urlopen("https://api.github.com/users/%s" % quote(username), timeout=10)
raw = urlopen("https://api.github.com/users/%s" % quote(username),
timeout=10)
user = json.loads(raw.read().decode())
raw = urlopen("https://api.github.com/users/%s/repos?sort=updated" % quote(username), timeout=10)
raw = urlopen("https://api.github.com/users/%s/repos?sort=updated" %
quote(username), timeout=10)
user["repos"] = json.loads(raw.read().decode())
return user
def info_issue(repo, issue=None):
rp = info_repos(repo)
if rp["items"]:
@ -41,14 +47,17 @@ def info_issue(repo, issue=None):
try:
if issue is not None:
raw = urlopen("https://api.github.com/repos/%s/issues/%s" % (quote(fullname), quote(issue)), timeout=10)
return [ json.loads(raw.read().decode()) ]
raw = urlopen("https://api.github.com/repos/%s/issues/%s" %
(quote(fullname), quote(issue)), timeout=10)
return [json.loads(raw.read().decode())]
else:
raw = urlopen("https://api.github.com/repos/%s/issues?sort=updated" % quote(fullname), timeout=10)
raw = urlopen("https://api.github.com/repos/%s/issues?sort=updated"
% quote(fullname), timeout=10)
return json.loads(raw.read().decode())
except urllib.error.HTTPError:
raise IRCException("Repository not found")
def info_commit(repo, commit=None):
rp = info_repos(repo)
if rp["items"]:
@ -58,10 +67,12 @@ def info_commit(repo, commit=None):
try:
if commit is not None:
raw = urlopen("https://api.github.com/repos/%s/commits/%s" % (quote(fullname), quote(commit)), timeout=10)
return [ json.loads(raw.read().decode()) ]
raw = urlopen("https://api.github.com/repos/%s/commits/%s" %
(quote(fullname), quote(commit)), timeout=10)
return [json.loads(raw.read().decode())]
else:
raw = urlopen("https://api.github.com/repos/%s/commits" % quote(fullname), timeout=10)
raw = urlopen("https://api.github.com/repos/%s/commits" %
quote(fullname), timeout=10)
return json.loads(raw.read().decode())
except urllib.error.HTTPError:
raise IRCException("Repository not found")
@ -74,16 +85,27 @@ def cmd_github(msg):
repos = info_repos(" ".join(msg.cmds[1:]))
res = Response(channel=msg.channel, nomore="No more repository", count=" (%d more repo)")
res = Response(channel=msg.channel,
nomore="No more repository",
count=" (%d more repo)")
for repo in repos["items"]:
homepage = ""
if repo["homepage"] is not None:
homepage = repo["homepage"] + " - "
res.append_message("Repository %s: %s%s Main language: %s; %d forks; %d stars; %d watchers; %d opened_issues; view it at %s" % (repo["full_name"], homepage, repo["description"], repo["language"], repo["forks"], repo["stargazers_count"], repo["watchers_count"], repo["open_issues_count"], repo["html_url"]))
res.append_message("Repository %s: %s%s Main language: %s; %d forks; %d stars; %d watchers; %d opened_issues; view it at %s" %
(repo["full_name"],
homepage,
repo["description"],
repo["language"], repo["forks"],
repo["stargazers_count"],
repo["watchers_count"],
repo["open_issues_count"],
repo["html_url"]))
return res
@hook("cmd_hook", "github_user")
def cmd_github(msg):
if len(msg.cmds) < 2:
@ -95,14 +117,22 @@ def cmd_github(msg):
if "login" in user:
if user["repos"]:
kf = " Known for: " + ", ".join([repo["name"] for repo in user["repos"]])
kf = (" Known for: " +
", ".join([repo["name"] for repo in user["repos"]]))
else:
kf = ""
if "name" in user:
name = user["name"]
else:
name = user["login"]
res.append_message("User %s: %d public repositories; %d public gists; %d followers; %d following; view it at %s.%s" % (name, user["public_repos"], user["public_gists"], user["followers"], user["following"], user["html_url"], kf))
res.append_message("User %s: %d public repositories; %d public gists; %d followers; %d following; view it at %s.%s" %
(name,
user["public_repos"],
user["public_gists"],
user["followers"],
user["following"],
user["html_url"],
kf))
else:
raise IRCException("User not found")
@ -166,9 +196,9 @@ def cmd_github(msg):
commits = info_commit(repo, commit)
for commit in commits:
res.append_message("Commit %s by %s on %s: %s" % (commit["sha"][:10],
commit["commit"]["author"]["name"],
commit["commit"]["author"]["date"],
commit["commit"]["message"].replace("\n", " ")))
res.append_message("Commit %s by %s on %s: %s" %
(commit["sha"][:10],
commit["commit"]["author"]["name"],
commit["commit"]["author"]["date"],
commit["commit"]["message"].replace("\n", " ")))
return res

View File

@ -1,5 +1,7 @@
# coding=utf-8
"Read manual pages on IRC"
import subprocess
import re
import os
@ -10,15 +12,13 @@ nemubotversion = 3.4
from more import Response
def help_tiny():
"""Line inserted in the response to the command !help"""
return "Read manual pages on IRC"
def help_full():
return "!man [0-9] /what/: gives informations about /what/."
RGXP_s = re.compile(b'\x1b\\[[0-9]+m')
@hook("cmd_hook", "MAN")
def cmd_man(msg):
args = ["man"]
@ -35,33 +35,40 @@ def cmd_man(msg):
os.unsetenv("LANG")
res = Response(channel=msg.channel)
with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
with subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as proc:
for line in proc.stdout.read().split(b"\n"):
(line, n) = RGXP_s.subn(b'', line)
res.append_message(line.decode())
if len(res.messages) <= 0:
if num is not None:
res.append_message("Il n'y a pas d'entrée %s dans la section %d du manuel." % (msg.cmds[1], num))
res.append_message("There is no entry %s in section %d." %
(msg.cmds[1], num))
else:
res.append_message("Il n'y a pas de page de manuel pour %s." % msg.cmds[1])
res.append_message("There is no man page for %s." % msg.cmds[1])
return res
@hook("cmd_hook", "man")
def cmd_whatis(msg):
args = ["whatis", " ".join(msg.cmds[1:])]
res = Response(channel=msg.channel)
with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
with subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as proc:
for line in proc.stdout.read().split(b"\n"):
(line, n) = RGXP_s.subn(b'', line)
res.append_message(" ".join(line.decode().split()))
if len(res.messages) <= 0:
if num is not None:
res.append_message("Il n'y a pas d'entrée %s dans la section %d du manuel." % (msg.cmds[1], num))
res.append_message("There is no entry %s in section %d." %
(msg.cmds[1], num))
else:
res.append_message("Il n'y a pas de page de manuel pour %s." % msg.cmds[1])
res.append_message("There is no man page for %s." % msg.cmds[1])
return res

View File

@ -14,6 +14,7 @@ nemubotversion = 3.4
from more import Response
def get_namespaces(site, ssl=False):
# Built URL
url = "http%s://%s/w/api.php?format=json&action=query&meta=siteinfo&siprop=namespaces" % (
@ -29,6 +30,7 @@ def get_namespaces(site, ssl=False):
namespaces[data["query"]["namespaces"][ns]["*"]] = data["query"]["namespaces"][ns]
return namespaces
def get_raw_page(site, term, ssl=False):
# Built URL
url = "http%s://%s/w/api.php?format=json&redirects&action=query&prop=revisions&rvprop=content&titles=%s" % (
@ -45,6 +47,7 @@ def get_raw_page(site, term, ssl=False):
except:
raise IRCException("article not found")
def get_unwikitextified(site, wikitext, ssl=False):
# Built URL
url = "http%s://%s/w/api.php?format=json&action=expandtemplates&text=%s" % (
@ -61,7 +64,6 @@ def get_unwikitextified(site, wikitext, ssl=False):
def strip_model(cnt):
# Strip models at begin and end: mostly useless
cnt = re.sub(r"^(({{([^{]|\s|({{(.|\s|{{.*?}})*?}})*?)*?}}|\[\[(.|\s|\[\[.*?\]\])*?\]\])\s*)+", "", cnt)
#cnt = re.sub(r"({{([^{]|\s|({{(.|\s|{{.*?}})*?}})*?)*?}}\s?)+$", "", cnt)
# Strip HTML comments
cnt = re.sub(r"<!--.*?-->", "", cnt)
@ -70,12 +72,13 @@ def strip_model(cnt):
cnt = re.sub(r"<ref.*?/ref>", "", cnt)
return cnt
def parse_wikitext(site, cnt, namespaces=dict(), ssl=False):
for i,_,_,_ in re.findall(r"({{([^{]|\s|({{(.|\s|{{.*?}})*?}})*?)*?}})", cnt):
for i, _, _, _ in re.findall(r"({{([^{]|\s|({{(.|\s|{{.*?}})*?}})*?)*?}})", cnt):
cnt = cnt.replace(i, get_unwikitextified(site, i, ssl), 1)
# Strip [[...]]
for full,args,lnk in re.findall(r"(\[\[(.*?|)?([^|]*?)\]\])", cnt):
for full, args, lnk in re.findall(r"(\[\[(.*?|)?([^|]*?)\]\])", cnt):
ns = lnk.find(":")
if lnk == "":
cnt = cnt.replace(full, args[:-1], 1)
@ -93,10 +96,12 @@ def parse_wikitext(site, cnt, namespaces=dict(), ssl=False):
return cnt
def irc_format(cnt):
cnt, _ = re.subn(r"(?P<title>==+)\s*(.*?)\s*(?P=title)\n*", "\x03\x16" + r"\2" + " :\x03\x16 ", cnt)
return cnt.replace("'''", "\x03\x02").replace("''", "\x03\x1f")
def get_page(site, term, ssl=False):
return strip_model(get_raw_page(site, term, ssl))

View File

@ -27,6 +27,7 @@ nemubotversion = 3.4
logger = logging.getLogger("nemubot.response")
class Response:
def __init__(self, message=None, channel=None, nick=None, server=None,
nomore="No more message", title=None, more="(suite) ",
@ -40,7 +41,7 @@ class Response:
self.alone = True
if message is not None:
self.append_message(message, shown_first_count=shown_first_count)
self.elt = 0 # Next element to display
self.elt = 0 # Next element to display
self.channel = channel
self.nick = nick
@ -50,12 +51,12 @@ class Response:
def receivers(self):
if self.channel is None:
if self.nick is not None:
return [ self.nick ]
return [self.nick]
return list()
elif isinstance(self.channel, list):
return self.channel
else:
return [ self.channel ]
return [self.channel]
def append_message(self, message, title=None, shown_first_count=-1):
if type(message) is str:
@ -110,17 +111,17 @@ class Response:
if len(self.rawtitle) <= 0:
self.rawtitle = None
def accept(self, visitor):
visitor.visit(self.next_response())
def next_response(self, maxlen=440):
if self.nick:
return DirectAsk(self.nick, self.get_message(maxlen - len(self.nick) - 2), server=None, to=self.receivers)
return DirectAsk(self.nick,
self.get_message(maxlen - len(self.nick) - 2),
server=None, to=self.receivers)
else:
return TextMessage(self.get_message(maxlen), server=None, to=self.receivers)
return TextMessage(self.get_message(maxlen),
server=None, to=self.receivers)
def get_message(self, maxlen):
if self.alone and len(self.messages) > 1:
@ -138,13 +139,15 @@ class Response:
elif isinstance(res, str):
self.messages.append(res)
else:
raise Exception("Type returned by nomore (%s) is not handled here." % type(res))
raise Exception("Type returned by nomore (%s) is not "
"handled here." % type(res))
return self.get_message()
else:
return self.nomore
if self.line_treat is not None and self.elt == 0:
self.messages[0] = self.line_treat(self.messages[0]).replace("\n", " ").strip()
self.messages[0] = (self.line_treat(self.messages[0])
.replace("\n", " ").strip())
msg = ""
if self.title is not None:
@ -198,6 +201,7 @@ class Response:
SERVERS = dict()
@hook("all_post")
def parseresponse(res):
# TODO: handle inter-bot communication NOMORE

View File

@ -11,11 +11,13 @@ nemubotversion = 3.4
from hooks import hook
from more import Response
def help_full():
return "!subreddit /subreddit/: Display information on the subreddit."
LAST_SUBS = dict()
@hook("cmd_hook", "subreddit")
def cmd_subreddit(msg):
global LAST_SUBS
@ -23,7 +25,8 @@ def cmd_subreddit(msg):
if msg.channel in LAST_SUBS and len(LAST_SUBS[msg.channel]) > 0:
subs = [LAST_SUBS[msg.channel].pop()]
else:
raise IRCException("Which subreddit? Need inspiration? type !horny or !bored")
raise IRCException("Which subreddit? Need inspiration? "
"type !horny or !bored")
else:
subs = msg.cmds[1:]
@ -36,30 +39,45 @@ def cmd_subreddit(msg):
else:
where = "r"
try:
req = urllib.request.Request("http://www.reddit.com/%s/%s/about.json" % (where, sub.group(2)), headers={ 'User-Agent' : "nemubot v3" })
req = urllib.request.Request(
"http://www.reddit.com/%s/%s/about.json" %
(where, sub.group(2)),
headers={'User-Agent': "nemubot v3"})
raw = urllib.request.urlopen(req, timeout=10)
except urllib.error.HTTPError as e:
raise IRCException("HTTP error occurs: %s %s" % (e.code, e.reason))
raise IRCException("HTTP error occurs: %s %s" %
(e.code, e.reason))
sbr = json.loads(raw.read().decode())
if "title" in sbr["data"]:
res = Response(channel=msg.channel, nomore="No more information")
res.append_message(("[NSFW] " if sbr["data"]["over18"] else "") + sbr["data"]["url"] + " " + sbr["data"]["title"] + ": " + sbr["data"]["public_description" if sbr["data"]["public_description"] != "" else "description"].replace("\n", " ") + " %s subscriber(s)" % sbr["data"]["subscribers"])
res = Response(channel=msg.channel,
nomore="No more information")
res.append_message(
("[NSFW] " if sbr["data"]["over18"] else "") +
sbr["data"]["url"] + " " + sbr["data"]["title"] + ": " +
sbr["data"]["public_description" if sbr["data"]["public_description"] != "" else "description"].replace("\n", " ") +
" %s subscriber(s)" % sbr["data"]["subscribers"])
if sbr["data"]["public_description"] != "":
res.append_message(sbr["data"]["description"].replace("\n", " "))
res.append_message(
sbr["data"]["description"].replace("\n", " "))
all_res.append(res)
else:
all_res.append(Response("/%s/%s doesn't exist" % (where, sub.group(2)), channel=msg.channel))
all_res.append(Response("/%s/%s doesn't exist" %
(where, sub.group(2)),
channel=msg.channel))
else:
all_res.append(Response("%s is not a valid subreddit" % osub, channel=msg.channel, nick=msg.nick))
all_res.append(Response("%s is not a valid subreddit" % osub,
channel=msg.channel, nick=msg.nick))
return all_res
@hook("msg_default")
def parselisten(msg):
parseresponse(msg)
return None
@hook("all_post")
def parseresponse(msg):
global LAST_SUBS

View File

@ -10,9 +10,12 @@ nemubotversion = 3.4
from more import Response
@hook("cmd_hook", "choice")
def cmd_choice(msg):
if len(msg.cmds) > 1:
return Response(random.choice(msg.cmds[1:]), channel=msg.channel, nick=msg.nick)
return Response(random.choice(msg.cmds[1:]),
channel=msg.channel,
nick=msg.nick)
else:
raise IRCException("indicate some terms to pick!")

View File

@ -14,25 +14,32 @@ nemubotversion = 3.4
from more import Response
def help_full ():
return "!tcode <transaction code|keywords>"
def help_full():
return "!tcode <transaction code|keywords>"
@hook("cmd_hook", "tcode")
def cmd_tcode(msg):
if len(msg.cmds) != 2:
raise IRCException("indicate a transaction code or a keyword to search!")
if len(msg.cmds) != 2:
raise IRCException("indicate a transaction code or "
"a keyword to search!")
url = "http://www.tcodesearch.com/tcodes/search?q=%s" % urllib.parse.quote(msg.cmds[1])
page = web.getURLContent(url)
url = ("http://www.tcodesearch.com/tcodes/search?q=%s" %
urllib.parse.quote(msg.cmds[1]))
page = web.getURLContent(url)
res = Response(channel=msg.channel,
nomore="No more transaction code", count=" (%d more tcodes)")
res = Response(channel=msg.channel,
nomore="No more transaction code",
count=" (%d more tcodes)")
if page is not None:
index = page.index('<div id="searchresults">') + len('<div id="searchresults">')
end = page[index:].index('</div>')+index
strscope = page[index:end]
for tcode in re.finditer('<strong> ([a-zA-Z0-9_]*)</strong> - ([^\n]*)\n', strscope):
res.append_message("\x02%s\x0F - %s" % (tcode.group(1), striphtml(tcode.group(2))))
if page is not None:
index = (page.index('<div id="searchresults">') +
len('<div id="searchresults">'))
end = page[index:].index('</div>')+index
strscope = page[index:end]
for tcode in re.finditer('<strong> ([a-zA-Z0-9_]*)</strong> - ([^\n]*)\n', strscope):
res.append_message("\x02%s\x0F - %s" % (tcode.group(1),
striphtml(tcode.group(2))))
return res
return res

View File

@ -12,12 +12,16 @@ nemubotversion = 3.4
from more import Response
def help_full():
return "If you would like to sleep soon, use !sleepytime to know the best time to wake up; use !sleepytime hh:mm if you want to wake up at hh:mm"
return ("If you would like to sleep soon, use !sleepytime to know the best"
" time to wake up; use !sleepytime hh:mm if you want to wake up at"
" hh:mm")
@hook("cmd_hook", "sleepytime")
def cmd_sleep(msg):
if len (msg.cmds) > 1 and re.match("[0-9]{1,2}[h':.,-]([0-9]{1,2})?[m'\":.,-]?",
if len(msg.cmds) > 1 and re.match("[0-9]{1,2}[h':.,-]([0-9]{1,2})?[m'\":.,-]?",
msg.cmds[1]) is not None:
# First, parse the hour
p = re.match("([0-9]{1,2})[h':.,-]([0-9]{1,2})?[m':.,-]?", msg.cmds[1])
@ -26,10 +30,10 @@ def cmd_sleep(msg):
datetime.now(timezone.utc).day,
hour=int(p.group(1)))]
if p.group(2) is not None:
f[0] += timedelta(minutes=int(p.group(2)))
f[0] += timedelta(minutes=int(p.group(2)))
g = list()
for i in range(0,6):
f.append(f[i] - timedelta(hours=1,minutes=30))
for i in range(6):
f.append(f[i] - timedelta(hours=1, minutes=30))
g.append(f[i+1].strftime("%H:%M"))
return Response("You should try to fall asleep at one of the following"
" times: %s" % ', '.join(g), channel=msg.channel)
@ -38,8 +42,8 @@ def cmd_sleep(msg):
else:
f = [datetime.now(timezone.utc) + timedelta(minutes=15)]
g = list()
for i in range(0,6):
f.append(f[i] + timedelta(hours=1,minutes=30))
for i in range(6):
f.append(f[i] + timedelta(hours=1, minutes=30))
g.append(f[i+1].strftime("%H:%M"))
return Response("If you head to bed right now, you should try to wake"
" up at one of the following times: %s" %

View File

@ -11,6 +11,7 @@ nemubotversion = 3.4
from more import Response
def load(context):
global DATAS
DATAS.setIndex("name", "station")
@ -20,8 +21,10 @@ def load(context):
# station_status)
# context.add_event(evt)
def help_full ():
return "!velib /number/ ...: gives available bikes and slots at the station /number/."
def help_full():
return ("!velib /number/ ...: gives available bikes and slots at "
"the station /number/.")
def station_status(station):
@ -42,11 +45,13 @@ def station_status(station):
else:
return (None, None)
def station_available(station):
"""Gets available velib at a given velib station"""
(a, f) = station_status(station)
return a
def station_free(station):
"""Gets free slots at a given velib station"""
(a, f) = station_status(station)
@ -62,6 +67,7 @@ def print_station_status(msg, station):
channel=msg.channel, nick=msg.nick)
raise IRCException("station %s inconnue." % station)
@hook("cmd_hook", "velib")
def ask_stations(msg):
"""Hook entry from !velib"""
@ -74,7 +80,8 @@ def ask_stations(msg):
if re.match("^[0-9]{4,5}$", station):
return print_station_status(msg, station)
elif station in DATAS.index:
return print_station_status(msg, DATAS.index[station]["number"])
return print_station_status(msg,
DATAS.index[station]["number"])
else:
raise IRCException("numéro de station invalide.")

View File

@ -12,19 +12,25 @@ from message import TextMessage
nemubotversion = 3.4
def help_full():
return "!ycc [<url>]: with an argument, reduce the given <url> thanks to ycc.fr; without argument, reduce the last URL said on the current channel."
return ("!ycc [<url>]: with an argument, reduce the given <url> thanks to "
"ycc.fr; without argument, reduce the last URL said on the current"
" channel.")
LAST_URLS = dict()
def gen_response(res, msg, srv):
if res is None:
raise IRCException("la situation est embarassante, il semblerait que YCC soit down :(")
elif isinstance(res, str):
return TextMessage("URL pour %s : %s" % (srv, res), server=None, to=msg.to_response)
return TextMessage("URL pour %s : %s" % (srv, res), server=None,
to=msg.to_response)
else:
raise IRCException("mauvaise URL : %s" % srv)
@hook("cmd_hook", "ycc")
def cmd_ycc(msg):
minify = list()
@ -45,7 +51,8 @@ def cmd_ycc(msg):
for url in minify:
o = urlparse(url, "http")
if o.scheme != "":
snd_url = "http://ycc.fr/redirection/create/" + quote(url, "/:%@&=?")
snd_url = "http://ycc.fr/redirection/create/" + quote(url,
"/:%@&=?")
print_debug(snd_url)
raw = urlopen(snd_url, timeout=10)
if o.netloc == "":
@ -56,24 +63,27 @@ def cmd_ycc(msg):
res.append(gen_response(False, msg, url))
return res
@hook("msg_default")
def parselisten(msg):
parseresponse(msg)
return None
@hook("all_post")
def parseresponse(msg):
global LAST_URLS
try:
urls = re.findall("([a-zA-Z0-9+.-]+:(?://)?[^ ]+)", msg.text)
for url in urls:
o = urlparse(url)
if o.scheme != "":
if o.netloc == "ycc.fr" or (o.netloc == "" and len(o.path) < 10):
continue
if msg.channel not in LAST_URLS:
LAST_URLS[msg.channel] = list()
LAST_URLS[msg.channel].append(url)
urls = re.findall("([a-zA-Z0-9+.-]+:(?://)?[^ ]+)", msg.text)
for url in urls:
o = urlparse(url)
if o.scheme != "":
if o.netloc == "ycc.fr" or (o.netloc == "" and
len(o.path) < 10):
continue
if msg.channel not in LAST_URLS:
LAST_URLS[msg.channel] = list()
LAST_URLS[msg.channel].append(url)
except:
pass
return msg