Reformat
This commit is contained in:
parent
bc5e08ead3
commit
abed9cf4ea
60 changed files with 1347 additions and 817 deletions
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("invite").hook(
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("changenickname"
|
||||
).hook(self.change_nickname, permission="changenickname",
|
||||
min_args=1, help="Change my nickname", usage="<nickname>")
|
||||
).hook(self.change_nickname,
|
||||
permission="changenickname",
|
||||
min_args=1,
|
||||
help="Change my nickname",
|
||||
usage="<nickname>")
|
||||
bot.events.on("received").on("command").on("raw"
|
||||
).hook(self.raw, permission="raw", min_args=1,
|
||||
).hook(self.raw,
|
||||
permission="raw",
|
||||
min_args=1,
|
||||
help="Send a raw IRC line through the bot",
|
||||
usage="<raw line>")
|
||||
bot.events.on("received").on("command").on("part"
|
||||
).hook(self.part, permission="part", min_args=1,
|
||||
).hook(self.part,
|
||||
permission="part",
|
||||
min_args=1,
|
||||
help="Part from a channel",
|
||||
usage="<#channel>")
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "BTC"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("btc").hook(
|
||||
|
@ -17,7 +19,8 @@ class Module(object):
|
|||
conversion = page[currency]
|
||||
buy, sell = conversion["buy"], conversion["sell"]
|
||||
event["stdout"].write("1 BTC = %.2f %s (buy) %.2f %s "
|
||||
"(sell)" % (buy, currency, sell, currency))
|
||||
"(sell)" % (
|
||||
buy, currency, sell, currency))
|
||||
else:
|
||||
event["stderr"].write("Unknown currency, available "
|
||||
"currencies: %s" % ", ".join(page.keys()))
|
||||
|
|
|
@ -6,12 +6,15 @@ import Utils
|
|||
URL_BITLYSHORTEN = "https://api-ssl.bitly.com/v3/shorten"
|
||||
REGEX_URL = re.compile("https?://", re.I)
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("get").on("shortlink").hook(self.shortlink)
|
||||
bot.events.on("received").on("command").on("shorten"
|
||||
).hook(self.shorten, min_args=1, help="Shorten a URL.",
|
||||
).hook(self.shorten,
|
||||
min_args=1,
|
||||
help="Shorten a URL.",
|
||||
usage="<url>")
|
||||
|
||||
def shortlink(self, event):
|
||||
|
|
|
@ -5,8 +5,10 @@ URL_GOOGLEBOOKS = "https://www.googleapis.com/books/v1/volumes"
|
|||
URL_BOOKINFO = "https://books.google.co.uk/books?id=%s"
|
||||
REGEX_BOOKID = re.compile("id=([\w\-]+)")
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "ISBN"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("isbn").hook(
|
||||
|
|
|
@ -1,41 +1,67 @@
|
|||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "Channel Op"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("kick", "k"
|
||||
).hook(self.kick, channel_only=True, require_mode="o",
|
||||
min_args=1, help="Kick a user from the channel",
|
||||
).hook(self.kick,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
min_args=1,
|
||||
help="Kick a user from the channel",
|
||||
usage="<nickname> [reason]")
|
||||
|
||||
bot.events.on("received").on("command").on("ban"
|
||||
).hook(self.ban, channel_only=True, require_mode="o",
|
||||
min_args=1, help="Ban a user/hostmask from the channel",
|
||||
).hook(self.ban,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
min_args=1,
|
||||
help="Ban a user/hostmask from the channel",
|
||||
usage="<nickname/hostmask>")
|
||||
bot.events.on("received").on("command").on("unban"
|
||||
).hook(self.unban, channel_only=True, require_mode="o",
|
||||
min_args=1, help="Unban a user/hostmask from the channel",
|
||||
).hook(self.unban,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
min_args=1,
|
||||
help="Unban a user/hostmask from the channel",
|
||||
usage="<nickname/hostmask>")
|
||||
|
||||
bot.events.on("received").on("command").on("kickban", "kb"
|
||||
).hook(self.kickban, channel_only=True, require_mode="o",
|
||||
min_args=1, help="Kickban a user from the channel",
|
||||
).hook(self.kickban,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
min_args=1,
|
||||
help="Kickban a user from the channel",
|
||||
usage="<nickanme> [reason]")
|
||||
|
||||
bot.events.on("received").on("command").on("op"
|
||||
).hook(self.op, channel_only=True, require_mode="o",
|
||||
help="Give +o to a user", usage="[nickname]")
|
||||
).hook(self.op,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
help="Give +o to a user",
|
||||
usage="[nickname]")
|
||||
bot.events.on("received").on("command").on("deop"
|
||||
).hook(self.deop, channel_only=True, require_mode="o",
|
||||
help="Take +o from a user", usage="[nickname]")
|
||||
).hook(self.deop,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
help="Take +o from a user",
|
||||
usage="[nickname]")
|
||||
|
||||
bot.events.on("received").on("command").on("voice"
|
||||
).hook(self.voice, channel_only=True, require_mode="o",
|
||||
help="Give +v to a user", usage="[nickname]")
|
||||
).hook(self.voice,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
help="Give +v to a user",
|
||||
usage="[nickname]")
|
||||
bot.events.on("received").on("command").on("devoice"
|
||||
).hook(self.devoice, channel_only=True, require_mode="o",
|
||||
help="Take +v from a user", usage="[nickname]")
|
||||
).hook(self.devoice,
|
||||
channel_only=True,
|
||||
require_mode="o",
|
||||
help="Take +v from a user",
|
||||
usage="[nickname]")
|
||||
|
||||
bot.events.on("received").on("message").on("channel").hook(
|
||||
self.highlight_spam)
|
||||
|
@ -43,7 +69,8 @@ class Module(object):
|
|||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="highlight-spam-threshold",
|
||||
help="Set the number of nicknames in a message that "
|
||||
"qualifies as spam", validate=Utils.int_or_none)
|
||||
"qualifies as spam",
|
||||
validate=Utils.int_or_none)
|
||||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="highlight-spam-protection",
|
||||
help="Enable/Disable highlight spam protection",
|
||||
|
@ -51,7 +78,8 @@ class Module(object):
|
|||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="highlight-spam-ban",
|
||||
help="Enable/Disable banning highlight spammers "
|
||||
"instead of just kicking", validate=Utils.bool_or_none)
|
||||
"instead of just kicking",
|
||||
validate=Utils.bool_or_none)
|
||||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="ban-format",
|
||||
help="Set ban format ($n = nick, $u = username, $h = hostname)")
|
||||
|
@ -74,7 +102,9 @@ class Module(object):
|
|||
|
||||
def _ban_format(self, user, s):
|
||||
return s.replace("$n", user.nickname).replace("$u", user.username
|
||||
).replace("$h", user.hostname)
|
||||
).replace("$h",
|
||||
user.hostname)
|
||||
|
||||
def _ban(self, channel, ban, user):
|
||||
format = channel.get_setting("ban-format", "*!$u@$h")
|
||||
hostmask_split = format.split("$$")
|
||||
|
@ -84,12 +114,14 @@ class Module(object):
|
|||
channel.send_ban(hostmask)
|
||||
else:
|
||||
channel.send_unban(hostmask)
|
||||
|
||||
def ban(self, event):
|
||||
target_user = event["server"].get_user(event["args_split"][0])
|
||||
if event["target"].has_user(target_user):
|
||||
self._ban(event["target"], True, target_user)
|
||||
else:
|
||||
event["target"].send_ban(event["args_split"][0])
|
||||
|
||||
def unban(self, event):
|
||||
target_user = event["server"].get_user(event["args_split"][0])
|
||||
if event["target"].has_user(target_user):
|
||||
|
@ -108,14 +140,17 @@ class Module(object):
|
|||
target = event["user"].nickname if not event["args_split"] else event[
|
||||
"args_split"][0]
|
||||
event["target"].send_mode("+o", target)
|
||||
|
||||
def deop(self, event):
|
||||
target = event["user"].nickname if not event["args_split"] else event[
|
||||
"args_split"][0]
|
||||
event["target"].send_mode("-o", target)
|
||||
|
||||
def voice(self, event):
|
||||
target = event["user"].nickname if not event["args_split"] else event[
|
||||
"args_split"][0]
|
||||
event["target"].send_mode("+v", target)
|
||||
|
||||
def devoice(self, event):
|
||||
target = event["user"].nickname if not event["args_split"] else event[
|
||||
"args_split"][0]
|
||||
|
@ -124,7 +159,8 @@ class Module(object):
|
|||
def highlight_spam(self, event):
|
||||
if event["channel"].get_setting("highlight-spam-protection", False):
|
||||
nicknames = list(map(lambda user: user.nickname,
|
||||
event["channel"].users)) + [event["server"].nickname]
|
||||
event["channel"].users)) + [
|
||||
event["server"].nickname]
|
||||
|
||||
highlights = set(nicknames) & set(event["message_split"])
|
||||
if len(highlights) > 1 and len(highlights) >= event["channel"
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received.numeric.001").hook(
|
||||
|
@ -15,7 +13,8 @@ class Module(object):
|
|||
|
||||
keys_sorted = list(map(lambda x: x[1],
|
||||
sorted(chan_keys.items(),
|
||||
key=lambda x: channels_sorted.index(x[0]))))
|
||||
key=lambda x: channels_sorted.index(
|
||||
x[0]))))
|
||||
|
||||
for i in range(len(channels_sorted)):
|
||||
channel = channels_sorted[i]
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
|
|
@ -25,6 +25,7 @@ THIRD_COLUMN = list(range(1, 37))[2::3]
|
|||
|
||||
REGEX_STREET = re.compile("street([1-9]|1[0-2])$")
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -40,8 +41,11 @@ class Module(object):
|
|||
bot.events.on("received.command.redeemcoins").hook(
|
||||
self.redeem_coins, help="Redeem free coins")
|
||||
bot.events.on("received.command.flip").hook(self.flip,
|
||||
help="Bet coins on a coin flip", usage=
|
||||
"heads|tails <coin amount>", min_args=2, protect_registered=True)
|
||||
help="Bet coins on a coin flip",
|
||||
usage=
|
||||
"heads|tails <coin amount>",
|
||||
min_args=2,
|
||||
protect_registered=True)
|
||||
bot.events.on("received.command.sendcoins").hook(
|
||||
self.send, min_args=2, help="Send coins to a user",
|
||||
usage="<nickname> <amount>", authenticated=True)
|
||||
|
@ -64,7 +68,8 @@ class Module(object):
|
|||
target = event["user"]
|
||||
coins = decimal.Decimal(target.get_setting("coins", "0.0"))
|
||||
event["stdout"].write("%s has %s coin%s" % (target.nickname,
|
||||
"{0:.2f}".format(coins), "" if coins == 1 else "s"))
|
||||
"{0:.2f}".format(coins),
|
||||
"" if coins == 1 else "s"))
|
||||
|
||||
def reset_coins(self, event):
|
||||
target = event["server"].get_user(event["args_split"][0])
|
||||
|
@ -76,7 +81,6 @@ class Module(object):
|
|||
target.del_setting("coins")
|
||||
event["stdout"].write("Reset coins for %s" % target.nickname)
|
||||
|
||||
|
||||
def richest(self, event):
|
||||
all_coins = event["server"].get_all_user_settings("coins", [])
|
||||
all_coins = list(filter(lambda coin: decimal.Decimal(coin[1]),
|
||||
|
@ -87,7 +91,8 @@ class Module(object):
|
|||
top_10 = sorted(all_coins.keys())
|
||||
top_10 = sorted(top_10, key=all_coins.get, reverse=True)[:10]
|
||||
top_10 = ", ".join("%s (%s)" % (Utils.prevent_highlight(event[
|
||||
"server"].get_user(nickname).nickname), "{0:.2f}".format(
|
||||
"server"].get_user(
|
||||
nickname).nickname), "{0:.2f}".format(
|
||||
all_coins[nickname])) for nickname in top_10)
|
||||
event["stdout"].write("Richest users: %s" % top_10)
|
||||
|
||||
|
@ -102,7 +107,8 @@ class Module(object):
|
|||
if last_redeem == None or (time.time() - last_redeem
|
||||
) >= redeem_delay:
|
||||
redeem_amount = decimal.Decimal(event["server"
|
||||
].get_setting("redeem-amount", DEFAULT_REDEEM_AMOUNT))
|
||||
].get_setting("redeem-amount",
|
||||
DEFAULT_REDEEM_AMOUNT))
|
||||
event["user"].set_setting("coins", str(
|
||||
user_coins + redeem_amount))
|
||||
event["stdout"].write("Redeemed %s coins" % "{0:.2f}".format(
|
||||
|
@ -111,7 +117,8 @@ class Module(object):
|
|||
else:
|
||||
time_left = (last_redeem + redeem_delay) - time.time()
|
||||
event["stderr"].write("Please wait %s before redeeming" %
|
||||
Utils.to_pretty_time(math.ceil(time_left)))
|
||||
Utils.to_pretty_time(
|
||||
math.ceil(time_left)))
|
||||
else:
|
||||
event["stderr"].write(
|
||||
"You can only redeem coins when you have none")
|
||||
|
@ -304,7 +311,8 @@ class Module(object):
|
|||
return
|
||||
|
||||
winnings_str = ["%s for %s (%d to 1)" % (winnings[bet][1], bet,
|
||||
winnings[bet][0]) for bet in winnings.keys()]
|
||||
winnings[bet][0]) for bet in
|
||||
winnings.keys()]
|
||||
|
||||
coin_winnings = sum(bet[1] for bet in winnings.values())
|
||||
coin_losses = sum([loss for loss in losses.values()])
|
||||
|
@ -317,14 +325,22 @@ class Module(object):
|
|||
choice = "%d %s" % (choice, colour)
|
||||
if not losses and winnings:
|
||||
event["stdout"].write("Roulette spin lands on %s, "
|
||||
"%s wins %s%s" % (choice, event["user"].nickname,
|
||||
", ".join(winnings_str), str(total_winnings_str)))
|
||||
"%s wins %s%s" % (
|
||||
choice, event["user"].nickname,
|
||||
", ".join(winnings_str),
|
||||
str(total_winnings_str)))
|
||||
elif losses and winnings:
|
||||
event["stdout"].write("Roulette spin lands on %s, "
|
||||
"%s wins %s%s; loses %s" % (choice,
|
||||
event["user"].nickname, ", ".join(winnings_str),
|
||||
str(total_winnings_str), str(coin_losses)))
|
||||
event[
|
||||
"user"].nickname,
|
||||
", ".join(
|
||||
winnings_str),
|
||||
str(
|
||||
total_winnings_str),
|
||||
str(coin_losses)))
|
||||
else:
|
||||
event["stdout"].write("Roulette spin lands on %s, "
|
||||
"%s loses %s" % (choice, event["user"].nickname,
|
||||
"%s loses %s" % (
|
||||
choice, event["user"].nickname,
|
||||
str(coin_losses)))
|
||||
|
|
|
@ -8,42 +8,52 @@ OUT_CUTOFF = 400
|
|||
|
||||
REGEX_CUTOFF = re.compile("^.{1,%d}(?:\s|$)" % OUT_CUTOFF)
|
||||
|
||||
|
||||
class Out(object):
|
||||
def __init__(self, module_name, target):
|
||||
self.module_name = module_name
|
||||
self.target = target
|
||||
self._text = ""
|
||||
self.written = False
|
||||
|
||||
def write(self, text):
|
||||
self._text += text
|
||||
self.written = True
|
||||
return self
|
||||
|
||||
def send(self):
|
||||
if self.has_text():
|
||||
text = self._text
|
||||
text_encoded = text.encode("utf8")
|
||||
if len(text_encoded) > OUT_CUTOFF:
|
||||
text = "%s%s" % (text_encoded[:OUT_CUTOFF].decode("utf8"
|
||||
).rstrip(), STR_MORE)
|
||||
).rstrip(),
|
||||
STR_MORE)
|
||||
self._text = "%s%s" % (STR_CONTINUED, text_encoded[OUT_CUTOFF:
|
||||
].decode("utf8").lstrip())
|
||||
else:
|
||||
self._text = ""
|
||||
self.target.send_message(text, prefix="[%s] " % self.prefix())
|
||||
|
||||
def set_prefix(self, prefix):
|
||||
self.module_name = prefix
|
||||
|
||||
def has_text(self):
|
||||
return bool(self._text)
|
||||
|
||||
|
||||
class StdOut(Out):
|
||||
def prefix(self):
|
||||
return "%s%s%s" % (Utils.color(Utils.COLOR_GREEN),
|
||||
self.module_name, Utils.FONT_RESET)
|
||||
|
||||
|
||||
class StdErr(Out):
|
||||
def prefix(self):
|
||||
return "%s!%s%s" % (Utils.color(Utils.COLOR_RED),
|
||||
self.module_name, Utils.FONT_RESET)
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -52,12 +62,15 @@ class Module(object):
|
|||
bot.events.on("received").on("message").on("private").hook(
|
||||
self.private_message)
|
||||
bot.events.on("received").on("command").on("help").hook(self.help,
|
||||
help="Show help for commands", usage="<command>")
|
||||
help="Show help for commands",
|
||||
usage="<command>")
|
||||
bot.events.on("received").on("command").on("usage").hook(self.usage,
|
||||
help="Show usage help for commands", min_args=1,
|
||||
help="Show usage help for commands",
|
||||
min_args=1,
|
||||
usage="<command>")
|
||||
bot.events.on("received").on("command").on("more").hook(self.more,
|
||||
help="Get more output from the last command", skip_out=True)
|
||||
help="Get more output from the last command",
|
||||
skip_out=True)
|
||||
|
||||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="command-prefix",
|
||||
|
@ -78,6 +91,7 @@ class Module(object):
|
|||
def has_command(self, command):
|
||||
return command.lower() in self.bot.events.on("received").on(
|
||||
"command").get_children()
|
||||
|
||||
def get_hook(self, command):
|
||||
return self.bot.events.on("received").on("command").on(command
|
||||
).get_hooks()[0]
|
||||
|
@ -85,7 +99,8 @@ class Module(object):
|
|||
def is_highlight(self, server, s):
|
||||
return s.lower() == server.nickname_lower or (s.lower().startswith(
|
||||
server.nickname_lower) and len(s) == len(server.nickname_lower
|
||||
)+1 and s[-1] in [":", ","])
|
||||
) + 1 and s[-1] in [":",
|
||||
","])
|
||||
|
||||
def message(self, event, command, args_index=1):
|
||||
if self.has_command(command):
|
||||
|
@ -109,8 +124,13 @@ class Module(object):
|
|||
target)
|
||||
|
||||
returns = self.bot.events.on("preprocess").on("command"
|
||||
).call(hook=hook, user=event["user"], server=event["server"],
|
||||
target=target, is_channel=is_channel)
|
||||
).call(hook=hook,
|
||||
user=event[
|
||||
"user"],
|
||||
server=event[
|
||||
"server"],
|
||||
target=target,
|
||||
is_channel=is_channel)
|
||||
for returned in returns:
|
||||
if returned:
|
||||
stderr.write(returned).send()
|
||||
|
@ -130,7 +150,8 @@ class Module(object):
|
|||
server = event["server"]
|
||||
user = event["user"]
|
||||
self.bot.events.on("received").on("command").on(command
|
||||
).call_limited(1, user=user, server=server,
|
||||
).call_limited(
|
||||
1, user=user, server=server,
|
||||
target=target, buffer=buffer, args=args,
|
||||
args_split=args_split, stdout=stdout, stderr=stderr,
|
||||
command=command.lower(), is_channel=is_channel)
|
||||
|
@ -141,10 +162,12 @@ class Module(object):
|
|||
target.last_stderr = stderr
|
||||
buffer.skip_next()
|
||||
|
||||
|
||||
def channel_message(self, event):
|
||||
command_prefix = event["channel"].get_setting("command-prefix",
|
||||
event["server"].get_setting("command-prefix", "!"))
|
||||
event[
|
||||
"server"].get_setting(
|
||||
"command-prefix",
|
||||
"!"))
|
||||
if event["message_split"][0].startswith(command_prefix):
|
||||
command = event["message_split"][0].replace(
|
||||
command_prefix, "", 1).lower()
|
||||
|
@ -164,17 +187,21 @@ class Module(object):
|
|||
command = event["args_split"][0].lower()
|
||||
if command in self.bot.events.on("received").on(
|
||||
"command").get_children():
|
||||
hooks = self.bot.events.on("received").on("command").on(command).get_hooks()
|
||||
hooks = self.bot.events.on("received").on("command").on(
|
||||
command).get_hooks()
|
||||
if hooks and "help" in hooks[0].kwargs:
|
||||
event["stdout"].write("%s: %s" % (command, hooks[0].kwargs["help"]))
|
||||
event["stdout"].write(
|
||||
"%s: %s" % (command, hooks[0].kwargs["help"]))
|
||||
else:
|
||||
event["stderr"].write("No help available for %s" % command)
|
||||
else:
|
||||
event["stderr"].write("Unknown command '%s'" % command)
|
||||
else:
|
||||
help_available = []
|
||||
for child in self.bot.events.on("received").on("command").get_children():
|
||||
hooks = self.bot.events.on("received").on("command").on(child).get_hooks()
|
||||
for child in self.bot.events.on("received").on(
|
||||
"command").get_children():
|
||||
hooks = self.bot.events.on("received").on("command").on(
|
||||
child).get_hooks()
|
||||
if hooks and "help" in hooks[0].kwargs:
|
||||
help_available.append(child)
|
||||
help_available = sorted(help_available)
|
||||
|
@ -184,16 +211,20 @@ class Module(object):
|
|||
command = event["args_split"][0].lower()
|
||||
if command in self.bot.events.on("received").on(
|
||||
"command").get_children():
|
||||
hooks = self.bot.events.on("received").on("command").on(command).get_hooks()
|
||||
hooks = self.bot.events.on("received").on("command").on(
|
||||
command).get_hooks()
|
||||
if hooks and "usage" in hooks[0].kwargs:
|
||||
event["stdout"].write("Usage: %s %s" % (command, hooks[0].kwargs["usage"]))
|
||||
event["stdout"].write(
|
||||
"Usage: %s %s" % (command, hooks[0].kwargs["usage"]))
|
||||
else:
|
||||
event["stderr"].write("No usage help available for %s" % command)
|
||||
event["stderr"].write(
|
||||
"No usage help available for %s" % command)
|
||||
else:
|
||||
event["stderr"].write("Unknown command '%s'" % command)
|
||||
|
||||
def more(self, event):
|
||||
if event["target"].last_stdout and event["target"].last_stdout.has_text():
|
||||
if event["target"].last_stdout and event[
|
||||
"target"].last_stdout.has_text():
|
||||
event["target"].last_stdout.send()
|
||||
|
||||
def send_stdout(self, event):
|
||||
|
@ -201,6 +232,7 @@ class Module(object):
|
|||
stdout.write(event["message"]).send()
|
||||
if stdout.has_text():
|
||||
event["target"].last_stdout = stdout
|
||||
|
||||
def send_stderr(self, event):
|
||||
stderr = StdErr(event["module_name"], event["target"])
|
||||
stderr.write(event["message"]).send()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import datetime
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("message").on("private").hook(
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
|
||||
URL_WORDNIK = "http://api.wordnik.com:80/v4/word.json/%s/definitions"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import socket
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "DNS"
|
||||
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("dns").hook(
|
||||
self.dns, min_args=1,
|
||||
|
|
|
@ -56,7 +56,8 @@ class Module(object):
|
|||
for server in self.bot.servers.values():
|
||||
for channel in server.channels.values():
|
||||
ducks_enabled = channel.get_setting("ducks-enabled", 0)
|
||||
ducks_enabled = int(ducks_enabled) if isinstance(ducks_enabled, str) else ducks_enabled
|
||||
ducks_enabled = int(ducks_enabled) if isinstance(ducks_enabled,
|
||||
str) else ducks_enabled
|
||||
|
||||
min_time = "min-duck-time-%s" % channel.name
|
||||
max_time = "max-duck-time-%s" % channel.name
|
||||
|
@ -64,8 +65,10 @@ class Module(object):
|
|||
min_duck_time = channel.get_setting("min-duck-time", 240)
|
||||
max_duck_time = channel.get_setting("max-duck-time", 1200)
|
||||
|
||||
min_duck_time = int(min_duck_time) if isinstance(min_duck_time, str) else min_duck_time
|
||||
max_duck_time = int(max_duck_time) if isinstance(max_duck_time, str) else max_duck_time
|
||||
min_duck_time = int(min_duck_time) if isinstance(min_duck_time,
|
||||
str) else min_duck_time
|
||||
max_duck_time = int(max_duck_time) if isinstance(max_duck_time,
|
||||
str) else max_duck_time
|
||||
|
||||
self.duck_times[min_time] = min_duck_time
|
||||
self.duck_times[max_time] = max_duck_time
|
||||
|
@ -84,25 +87,28 @@ class Module(object):
|
|||
min = "min-duck-time-%s" % (channel_name)
|
||||
max = "max-duck-time-%s" % (channel_name)
|
||||
|
||||
self.bot.log.debug("Attempting to set %s to %s", [str(min), str(self.duck_times[min])]);
|
||||
self.bot.log.debug("Attempting to set %s to %s", [str(max), str(self.duck_times[max])]);
|
||||
self.bot.log.debug("Attempting to set %s to %s",
|
||||
[str(min), str(self.duck_times[min])]);
|
||||
self.bot.log.debug("Attempting to set %s to %s",
|
||||
[str(max), str(self.duck_times[max])]);
|
||||
|
||||
return random.randint(self.duck_times[min], self.duck_times[max])
|
||||
|
||||
def decoy_time(self):
|
||||
return random.randint(300, 700)
|
||||
|
||||
return random.randint(10, 20)
|
||||
|
||||
def duck_bef(self, event):
|
||||
target = event["user"].nickname
|
||||
active_duck = event["target"].get_setting("active-duck", 0)
|
||||
active_duck = int(active_duck) if isinstance(active_duck, str) else active_duck
|
||||
active_duck = int(active_duck) if isinstance(active_duck,
|
||||
str) else active_duck
|
||||
|
||||
if active_duck == 0:
|
||||
event["stderr"].set_prefix("Kick")
|
||||
if event["server"].has_user(target):
|
||||
if not event["server"].is_own_nickname(target):
|
||||
event["target"].send_kick(target, "You tried befriending a non-existent duck. Creepy!")
|
||||
event["target"].send_kick(target,
|
||||
"You tried befriending a non-existent duck. Creepy!")
|
||||
else:
|
||||
event["stderr"].write("Nope.")
|
||||
else:
|
||||
|
@ -116,8 +122,9 @@ class Module(object):
|
|||
grammar = "" if befriended_ducks == 0 else "s"
|
||||
|
||||
event["stdout"].write(
|
||||
target + ", you've befriended " + str(befriended_ducks + 1) + " duck" + grammar + " in " + event[
|
||||
"target"].name);
|
||||
target + ", you've befriended " + str(
|
||||
befriended_ducks + 1) + " duck" + grammar + " in " + event[
|
||||
"target"].name)
|
||||
|
||||
next_duck_time = self.duck_time(event)
|
||||
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
||||
|
@ -128,7 +135,8 @@ class Module(object):
|
|||
event["stderr"].set_prefix("Kick")
|
||||
if event["server"].has_user(target):
|
||||
if not event["server"].is_own_nickname(target):
|
||||
event["target"].send_kick(target, "You tried shooting a non-existent duck. Creepy!")
|
||||
event["target"].send_kick(target,
|
||||
"You tried shooting a non-existent duck. Creepy!")
|
||||
else:
|
||||
event["stderr"].write("Nope.")
|
||||
else:
|
||||
|
@ -142,7 +150,9 @@ class Module(object):
|
|||
grammar = "" if shot_ducks == 0 else "s"
|
||||
|
||||
event["stdout"].write(
|
||||
target + ", you've shot " + str(shot_ducks + 1) + " duck" + grammar + " in " + event["target"].name);
|
||||
target + ", you've shot " + str(
|
||||
shot_ducks + 1) + " duck" + grammar + " in " + event[
|
||||
"target"].name);
|
||||
|
||||
next_duck_time = self.duck_time(event)
|
||||
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
||||
|
@ -151,13 +161,16 @@ class Module(object):
|
|||
for server in self.bot.servers.values():
|
||||
for channel in server.channels.values():
|
||||
ducks_enabled = channel.get_setting("ducks-enabled", 0)
|
||||
ducks_enabled = int(ducks_enabled) if isinstance(ducks_enabled, str) else ducks_enabled
|
||||
ducks_enabled = int(ducks_enabled) if isinstance(ducks_enabled,
|
||||
str) else ducks_enabled
|
||||
if ducks_enabled == 0:
|
||||
continue
|
||||
|
||||
self.bot.log.info("Ducks enabled for %s: %s", [str(channel.name), str(ducks_enabled)])
|
||||
self.bot.log.info("Ducks enabled for %s: %s",
|
||||
[str(channel.name), str(ducks_enabled)])
|
||||
active_duck = channel.get_setting("active-duck", 0)
|
||||
active_duck = int(active_duck) if isinstance(active_duck, str) else active_duck
|
||||
active_duck = int(active_duck) if isinstance(active_duck,
|
||||
str) else active_duck
|
||||
|
||||
if ducks_enabled == 1 and active_duck == 0:
|
||||
ducks = [
|
||||
|
@ -181,7 +194,8 @@ class Module(object):
|
|||
channel.set_setting("active-duck", 0)
|
||||
|
||||
next_duck_time = self.duck_time(channel.name)
|
||||
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
||||
self.bot.add_timer("duck-appear", next_duck_time,
|
||||
persist=False)
|
||||
|
||||
def duck_decoy(self, event):
|
||||
ducks = [
|
||||
|
@ -194,12 +208,15 @@ class Module(object):
|
|||
"・ ゜・。 。・゜゜ \_ó< beep beep!"
|
||||
]
|
||||
|
||||
event["target"].send_message(random.choice(ducks))
|
||||
event["channel"].send_message(random.choice(ducks))
|
||||
|
||||
def set_decoy(self, event):
|
||||
|
||||
channel = event["target"]
|
||||
next_decoy_time = self.decoy_time()
|
||||
self.bot.events.on("timer").on("duck-decoy").hook(self.duck_decoy)
|
||||
self.bot.add_timer("duck-decoy", next_decoy_time, persist=False)
|
||||
self.bot.add_timer("duck-decoy", next_decoy_time, None, None, False,
|
||||
channel=channel)
|
||||
|
||||
# def coins(self, event):
|
||||
# if event["args_split"]:
|
||||
|
|
|
@ -2,8 +2,10 @@ import Utils
|
|||
|
||||
URL_GEOIP = "http://ip-api.com/json/%s"
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "GeoIP"
|
||||
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("geoip").hook(
|
||||
self.geoip, min_args=1,
|
||||
|
|
|
@ -5,11 +5,13 @@ import Utils
|
|||
|
||||
URL_GOOGLESEARCH = "https://www.googleapis.com/customsearch/v1"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("google",
|
||||
"g").hook(self.google, help="Google feeling lucky",
|
||||
"g").hook(self.google,
|
||||
help="Google feeling lucky",
|
||||
usage="[search term]")
|
||||
|
||||
def google(self, event):
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import hashlib
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("hash"
|
||||
).hook(self.hash, min_args=2, help="Hash a string",
|
||||
).hook(self.hash, min_args=2,
|
||||
help="Hash a string",
|
||||
usage="<algo> <string>")
|
||||
|
||||
def hash(self, event):
|
||||
|
|
|
@ -3,6 +3,7 @@ import Utils
|
|||
URL_HAVEIBEENPWNEDAPI = "https://haveibeenpwned.com/api/v2/breachedaccount/%s"
|
||||
URL_HAVEIBEENPWNED = "https://haveibeenpwned.com/"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("beenpwned").hook(
|
||||
|
@ -17,7 +18,8 @@ class Module(object):
|
|||
code, page = page
|
||||
if code == 200:
|
||||
event["stdout"].write(
|
||||
"It seems '%s' has been pwned. check on %s." % (event["args"],
|
||||
"It seems '%s' has been pwned. check on %s." % (
|
||||
event["args"],
|
||||
URL_HAVEIBEENPWNED))
|
||||
else:
|
||||
event["stdout"].write("It seems '%s' has not been pwned" % (
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
_name = "IDs"
|
||||
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received.command.myid").hook(self.my_id,
|
||||
help="Show your user ID")
|
||||
|
|
|
@ -6,8 +6,10 @@ import Utils
|
|||
URL_OMDB = "http://www.omdbapi.com/"
|
||||
URL_IMDBTITLE = "http://imdb.com/title/%s"
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "IMDb"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("imdb").hook(
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
SECONDS_MAX = Utils.SECONDS_WEEKS * 8
|
||||
SECONDS_MAX_DESCRIPTION = "8 weeks"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -20,8 +21,10 @@ class Module(object):
|
|||
due_time = int(time.time()) + seconds
|
||||
|
||||
self.bot.add_timer("in", seconds,
|
||||
target=event["target"].name, due_time=due_time,
|
||||
server_id=event["server"].id, nickname=event["user"].nickname,
|
||||
target=event["target"].name,
|
||||
due_time=due_time,
|
||||
server_id=event["server"].id,
|
||||
nickname=event["user"].nickname,
|
||||
message=message)
|
||||
event["stdout"].write("Saved")
|
||||
else:
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("numeric").on("001").hook(self.do_join)
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
REGEX_KARMA = re.compile("(.*)(\+{2,}|\-{2,})$")
|
||||
KARMA_DELAY_SECONDS = 3
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -52,10 +53,13 @@ class Module(object):
|
|||
event["user"].last_karma = time.time()
|
||||
elif verbose:
|
||||
if target:
|
||||
self.bot.events.on("send").on("stderr").call(module_name="Karma",
|
||||
target=event["channel"], message="You cannot change your own karma")
|
||||
self.bot.events.on("send").on("stderr").call(
|
||||
module_name="Karma",
|
||||
target=event["channel"],
|
||||
message="You cannot change your own karma")
|
||||
elif verbose:
|
||||
event["stderr"].write("Try again in a couple of seconds")
|
||||
|
||||
def karma(self, event):
|
||||
if event["args"]:
|
||||
target = event["args"]
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
|
||||
URL_SCROBBLER = "http://ws.audioscrobbler.com/2.0/"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -13,7 +14,8 @@ class Module(object):
|
|||
help="Set username on last.fm")
|
||||
|
||||
bot.events.on("received").on("command").on("np",
|
||||
"listening", "nowplaying").hook(self.np,
|
||||
"listening",
|
||||
"nowplaying").hook(self.np,
|
||||
help="Get the last listened to track from a user",
|
||||
usage="[username]")
|
||||
|
||||
|
|
|
@ -1,27 +1,38 @@
|
|||
# --ignore
|
||||
import types, json
|
||||
|
||||
|
||||
def get_target(user):
|
||||
return user.alias or user.nickname
|
||||
|
||||
|
||||
def set_setting(user, setting, value):
|
||||
target = get_target(user)
|
||||
user.bot.database.set_user_setting(user.server.id, target,
|
||||
setting, value)
|
||||
|
||||
|
||||
def get_setting(user, setting, default=None):
|
||||
target = get_target(user)
|
||||
return user.bot.database.get_user_setting(user.server.id,
|
||||
target, setting, default)
|
||||
|
||||
|
||||
def find_settings(user, pattern, default=[]):
|
||||
target = get_target(user)
|
||||
return user.bot.databse.find_user_settings(user.server.id,
|
||||
target, pattern, default)
|
||||
|
||||
|
||||
def del_setting(user, setting):
|
||||
target = get_target(user)
|
||||
user.bot.database.del_user_setting(user.server.id, target,
|
||||
setting)
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "Aliases"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("new").on("user").hook(self.new_user)
|
||||
|
@ -60,6 +71,7 @@ class Module(object):
|
|||
FROM user_settings WHERE setting='alias' AND value=?
|
||||
AND server_id=?""", [json.dumps(target.lower()),
|
||||
server.id]).fetchall()
|
||||
|
||||
def _change_nick(self, old_nickname, new_nickname):
|
||||
self.bot.database.cursor().execute("""UPDATE user_settings
|
||||
SET nickname=? WHERE nickname=?""", [new_nickname.lower(),
|
||||
|
@ -76,7 +88,9 @@ class Module(object):
|
|||
aliases = self._get_aliases(target, event["server"])
|
||||
if any(aliases):
|
||||
event["stdout"].write("Aliases for %s: %s" % (target,
|
||||
", ".join([a[0] for a in aliases])))
|
||||
", ".join(
|
||||
[a[0] for a in
|
||||
aliases])))
|
||||
else:
|
||||
event["stderr"].write("%s has no aliases" % target)
|
||||
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
import base64
|
||||
import EventManager
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("numeric").on("001"
|
||||
).hook(self.on_connect, priority=EventManager.PRIORITY_URGENT)
|
||||
).hook(self.on_connect,
|
||||
priority=EventManager.PRIORITY_URGENT)
|
||||
bot.events.on("received").on("command").on("setnickserv"
|
||||
).hook(self.set_nickserv, min_args=1, permission="setnickserv",
|
||||
help="Set bot's nickserv password", usage="<password>",
|
||||
).hook(self.set_nickserv,
|
||||
min_args=1,
|
||||
permission="setnickserv",
|
||||
help="Set bot's nickserv password",
|
||||
usage="<password>",
|
||||
private_only=True)
|
||||
|
||||
def on_connect(self, event):
|
||||
|
|
461
modules/nr.py
461
modules/nr.py
|
@ -14,21 +14,25 @@ from suds import WebFault
|
|||
|
||||
URL = 'https://lite.realtime.nationalrail.co.uk/OpenLDBSVWS/wsdl.aspx?ver=2016-02-16'
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "NR"
|
||||
|
||||
PASSENGER_ACTIVITIES = ["U", "P", "R"]
|
||||
COLOURS = [Utils.COLOR_LIGHTBLUE, Utils.COLOR_GREEN, Utils.COLOR_RED, Utils.COLOR_CYAN, Utils.COLOR_LIGHTGREY, Utils.COLOR_ORANGE]
|
||||
COLOURS = [Utils.COLOR_LIGHTBLUE, Utils.COLOR_GREEN, Utils.COLOR_RED,
|
||||
Utils.COLOR_CYAN, Utils.COLOR_LIGHTGREY, Utils.COLOR_ORANGE]
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self._client = None
|
||||
bot.events.on("received").on("command").on("nrtrains"
|
||||
).hook(self.trains, min_args=1,
|
||||
).hook(self.trains,
|
||||
min_args=1,
|
||||
help="Get train/bus services for a station (Powered by NRE)",
|
||||
usage="<crs_id>")
|
||||
bot.events.on("received").on("command").on("nrservice"
|
||||
).hook(self.service, min_args=1,
|
||||
).hook(self.service,
|
||||
min_args=1,
|
||||
help="Get train service information for a UID, headcode or RID (Powered by NRE)",
|
||||
usage="<service_id>")
|
||||
bot.events.on("received").on("command").on("nrhead"
|
||||
|
@ -36,13 +40,16 @@ class Module(object):
|
|||
help="Get information for a given headcode/UID/RID (Powered by NRE)",
|
||||
usage="<headcode>")
|
||||
bot.events.on("received").on("command").on("nrcode"
|
||||
).hook(self.service_code, min_args=1,
|
||||
).hook(self.service_code,
|
||||
min_args=1,
|
||||
help="Get the text for a given delay/cancellation code (Powered by NRE)",
|
||||
usage="<code>")
|
||||
bot.events.on("telegram").on("command").on("nrtrains").hook(self.trains)
|
||||
bot.events.on("telegram").on("command").on("nrcode").hook(self.service_code)
|
||||
bot.events.on("telegram").on("command").on("nrcode").hook(
|
||||
self.service_code)
|
||||
bot.events.on("telegram").on("command").on("nrhead").hook(self.head)
|
||||
bot.events.on("telegram").on("command").on("nrservice").hook(self.service)
|
||||
bot.events.on("telegram").on("command").on("nrservice").hook(
|
||||
self.service)
|
||||
|
||||
@property
|
||||
def client(self):
|
||||
|
@ -83,7 +90,8 @@ class Module(object):
|
|||
continue
|
||||
ret["default"] = False
|
||||
ret[k] = v if len(defaults[k]) == 2 else defaults[k][2](v)
|
||||
ret["errors_summary"] = ", ".join(['"%s": %s' % (a[0], a[1]) for a in ret["errors"]])
|
||||
ret["errors_summary"] = ", ".join(
|
||||
['"%s": %s' % (a[0], a[1]) for a in ret["errors"]])
|
||||
return ret
|
||||
|
||||
def process(self, service):
|
||||
|
@ -100,10 +108,12 @@ class Module(object):
|
|||
times[a] = {"orig": service[a]}
|
||||
|
||||
if len(service[a]) > 5:
|
||||
times[a]["datetime"] = datetime.strptime(service[a], "%Y-%m-%dT%H:%M:%S")
|
||||
times[a]["datetime"] = datetime.strptime(service[a],
|
||||
"%Y-%m-%dT%H:%M:%S")
|
||||
else:
|
||||
times[a]["datetime"] = datetime.strptime(
|
||||
datetime.now().date().isoformat() + "T" + service[a][:4],
|
||||
datetime.now().date().isoformat() + "T" + service[a][
|
||||
:4],
|
||||
"%Y-%m-%dT%H%M"
|
||||
)
|
||||
times[a]["ut"] = times[a]["datetime"].timestamp()
|
||||
|
@ -112,8 +122,10 @@ class Module(object):
|
|||
|
||||
for k, a in times.items():
|
||||
if not a["orig"]: continue
|
||||
a["short"] = a["datetime"].strftime("%H%M") if len(a["orig"]) > 5 else a["orig"]
|
||||
a["shortest"] = "%02d" % a["datetime"].minute if -300 < a["ut"]-ut_now < 1800 else a["short"]
|
||||
a["short"] = a["datetime"].strftime("%H%M") if len(
|
||||
a["orig"]) > 5 else a["orig"]
|
||||
a["shortest"] = "%02d" % a["datetime"].minute if -300 < a[
|
||||
"ut"] - ut_now < 1800 else a["short"]
|
||||
a["prefix"] = k[2] + ("s" if k[0] == "s" else "")
|
||||
a["estimate"] = k[0] == "e"
|
||||
a["schedule"] = k[0] == "s"
|
||||
|
@ -122,7 +134,10 @@ class Module(object):
|
|||
if "a" + k[1:] in service: a["status"] = {"d": 0, "a": 3}[k[2]]
|
||||
if k[0] == "s": a["status"] = 4
|
||||
|
||||
arr, dep = [times[a] for a in a_types if times[a]["ut"]], [times[a] for a in d_types if times[a]["ut"]]
|
||||
arr, dep = [times[a] for a in a_types if times[a]["ut"]], [times[a] for
|
||||
a in d_types
|
||||
if times[a][
|
||||
"ut"]]
|
||||
times["arrival"] = (arr + dep + [nonetime])[0]
|
||||
times["departure"] = (dep + arr + [nonetime])[0]
|
||||
times["a"], times["d"] = (arr + [nonetime])[0], (dep + [nonetime])[0]
|
||||
|
@ -130,9 +145,13 @@ class Module(object):
|
|||
times["max_sched"] = {"ut": max(times["sta"]["ut"], times["std"]["ut"])}
|
||||
return times
|
||||
|
||||
def activities(self, string): return [a+b.strip() for a,b in list(zip(*[iter(string)]*2)) if (a+b).strip()]
|
||||
def activities(self, string):
|
||||
return [a + b.strip() for a, b in list(zip(*[iter(string)] * 2)) if
|
||||
(a + b).strip()]
|
||||
|
||||
def reduced_activities(self, string): return [a for a in self.activities(string) if a in self.PASSENGER_ACTIVITIES]
|
||||
def reduced_activities(self, string):
|
||||
return [a for a in self.activities(string) if
|
||||
a in self.PASSENGER_ACTIVITIES]
|
||||
|
||||
def trains(self, event):
|
||||
client = self.client
|
||||
|
@ -143,22 +162,42 @@ class Module(object):
|
|||
schedule = {}
|
||||
|
||||
location_code = event["args_split"][0].upper()
|
||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(event["args_split"]) > 1 else "", {
|
||||
"dest": ('', lambda x: x.isalpha() and len(x)==3),
|
||||
"origin":('', lambda x: x.isalpha() and len(x)==3),
|
||||
"inter": ('', lambda x: x.isalpha() and len(x)==3, lambda x: x.upper()),
|
||||
"toc": ('', lambda x: x.isalpha() and len(x) == 2),
|
||||
"dedup": (False, lambda x: type(x)==type(True)),
|
||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(
|
||||
event["args_split"]) > 1 else "", {
|
||||
"dest": (
|
||||
'', lambda x: x.isalpha() and len(x) == 3),
|
||||
"origin": (
|
||||
'', lambda x: x.isalpha() and len(x) == 3),
|
||||
"inter": (
|
||||
'', lambda x: x.isalpha() and len(x) == 3,
|
||||
lambda x: x.upper()),
|
||||
"toc": (
|
||||
'', lambda x: x.isalpha() and len(x) == 2),
|
||||
"dedup": (
|
||||
False, lambda x: type(x) == type(True)),
|
||||
"plat": ('', lambda x: len(x) <= 3),
|
||||
"type": ("departure", lambda x: x in ["departure", "arrival", "both"]),
|
||||
"terminating": (False, lambda x: type(x)==type(True)),
|
||||
"period": (120, lambda x: x.isdigit() and 1 <= int(x) <= 480, lambda x: int(x)),
|
||||
"nonpassenger": (False, lambda x: type(x)==type(True)),
|
||||
"time": ("", lambda x: len(x)==4 and x.isdigit()),
|
||||
"type": ("departure",
|
||||
lambda x: x in ["departure",
|
||||
"arrival", "both"]),
|
||||
"terminating": (
|
||||
False, lambda x: type(x) == type(True)),
|
||||
"period": (120,
|
||||
lambda x: x.isdigit() and 1 <= int(
|
||||
x) <= 480, lambda x: int(x)),
|
||||
"nonpassenger": (
|
||||
False, lambda x: type(x) == type(True)),
|
||||
"time": (
|
||||
"", lambda x: len(x) == 4 and x.isdigit()),
|
||||
"date": ("", lambda x: len(x) == 10),
|
||||
"tops": (None, lambda x: len(x)<4 and x.isdigit()),
|
||||
"power": (None, lambda x: x.upper() in ["EMU", "DMU", "HST", "D", "E"], lambda x: x.upper()),
|
||||
"crs": (False, lambda x: type(x)==type(True)),
|
||||
"tops": (
|
||||
None, lambda x: len(x) < 4 and x.isdigit()),
|
||||
"power": (None,
|
||||
lambda x: x.upper() in ["EMU", "DMU",
|
||||
"HST", "D",
|
||||
"E"],
|
||||
lambda x: x.upper()),
|
||||
"crs": (
|
||||
False, lambda x: type(x) == type(True)),
|
||||
"st": (False, lambda x: type(x) == type(True))
|
||||
})
|
||||
|
||||
|
@ -166,7 +205,8 @@ class Module(object):
|
|||
return event["stderr"].write("Filter: " + filter["errors_summary"])
|
||||
|
||||
if filter["inter"] and filter["type"] != "departure":
|
||||
return event["stderr"].write("Filtering by intermediate stations is only supported for departures.")
|
||||
return event["stderr"].write(
|
||||
"Filtering by intermediate stations is only supported for departures.")
|
||||
|
||||
nr_filterlist = client.factory.create("filterList")
|
||||
if filter["inter"]: nr_filterlist.crs.append(filter["inter"])
|
||||
|
@ -177,29 +217,40 @@ class Module(object):
|
|||
now = now.replace(minute=int(filter["time"][2:]))
|
||||
if filter["date"]:
|
||||
newdate = datetime.strptime(filter["date"], "%Y-%m-%d").date()
|
||||
now = now.replace(day=newdate.day, month=newdate.month, year=newdate.year)
|
||||
now = now.replace(day=newdate.day, month=newdate.month,
|
||||
year=newdate.year)
|
||||
|
||||
method = client.service.GetArrivalDepartureBoardByCRS if len(location_code) == 3 else client.service.GetArrivalDepartureBoardByTIPLOC
|
||||
method = client.service.GetArrivalDepartureBoardByCRS if len(
|
||||
location_code) == 3 else client.service.GetArrivalDepartureBoardByTIPLOC
|
||||
try:
|
||||
query = method(100, location_code, now.isoformat().split(".")[0], filter["period"],
|
||||
nr_filterlist, "to", '', "PBS", filter["nonpassenger"])
|
||||
query = method(100, location_code, now.isoformat().split(".")[0],
|
||||
filter["period"],
|
||||
nr_filterlist, "to", '', "PBS",
|
||||
filter["nonpassenger"])
|
||||
except WebFault as detail:
|
||||
if str(detail) == "Server raised fault: 'Invalid crs code supplied'":
|
||||
if str(
|
||||
detail) == "Server raised fault: 'Invalid crs code supplied'":
|
||||
return event["stderr"].write("Invalid CRS code.")
|
||||
else:
|
||||
return event["stderr"].write("An error occurred.")
|
||||
|
||||
nrcc_severe = len([a for a in query["nrccMessages"][0] if a["severity"] == "Major"]) if "nrccMessages" in query else 0
|
||||
nrcc_severe = len([a for a in query["nrccMessages"][0] if a[
|
||||
"severity"] == "Major"]) if "nrccMessages" in query else 0
|
||||
if event.get("external"):
|
||||
station_summary = "%s (%s) - %s (%s):\n" % (query["locationName"], query["crs"], query["stationManager"],
|
||||
station_summary = "%s (%s) - %s (%s):\n" % (
|
||||
query["locationName"], query["crs"], query["stationManager"],
|
||||
query["stationManagerCode"])
|
||||
else:
|
||||
station_summary = "%s (%s, %s%s)" % (query["locationName"], query["crs"], query["stationManagerCode"],
|
||||
", %s%s severe messages%s" % (Utils.color(Utils.COLOR_RED), nrcc_severe, Utils.color(Utils.FONT_RESET)) if nrcc_severe else ""
|
||||
station_summary = "%s (%s, %s%s)" % (
|
||||
query["locationName"], query["crs"], query["stationManagerCode"],
|
||||
", %s%s severe messages%s" % (
|
||||
Utils.color(Utils.COLOR_RED), nrcc_severe,
|
||||
Utils.color(Utils.FONT_RESET)) if nrcc_severe else ""
|
||||
)
|
||||
|
||||
if not "trainServices" in query and not "busServices" in query and not "ferryServices" in query:
|
||||
return event["stdout"].write("%s: No services for the next %s minutes" % (
|
||||
return event["stdout"].write(
|
||||
"%s: No services for the next %s minutes" % (
|
||||
station_summary, filter["period"]))
|
||||
|
||||
trains = []
|
||||
|
@ -213,103 +264,148 @@ class Module(object):
|
|||
"uid": t["uid"],
|
||||
"head": t["trainid"],
|
||||
"platform": '?' if not "platform" in t else t["platform"],
|
||||
"platform_hidden": "platformIsHidden" in t and t["platformIsHidden"],
|
||||
"platform_hidden": "platformIsHidden" in t and t[
|
||||
"platformIsHidden"],
|
||||
"platform_prefix": "",
|
||||
"toc": t["operatorCode"],
|
||||
"cancelled": t["isCancelled"] if "isCancelled" in t else False,
|
||||
"delayed" : t["departureType"]=="Delayed" if "departureType" in t else None,
|
||||
"cancel_reason" : t["cancelReason"]["value"] if "cancelReason" in t else "",
|
||||
"delay_reason" : t["delayReason"]["value"] if "delayReason" in t else "",
|
||||
"delayed": t[
|
||||
"departureType"] == "Delayed" if "departureType" in t else None,
|
||||
"cancel_reason": t["cancelReason"][
|
||||
"value"] if "cancelReason" in t else "",
|
||||
"delay_reason": t["delayReason"][
|
||||
"value"] if "delayReason" in t else "",
|
||||
"terminating": not "std" in t and not "etd" in t and not "atd" in t,
|
||||
"bus": t["trainid"] == "0B00",
|
||||
"times": self.process(t),
|
||||
"activity": self.reduced_activities(t["activities"]),
|
||||
}
|
||||
parsed["destinations"] = [{"name": a["locationName"], "tiploc": a["tiploc"],
|
||||
"crs": a["crs"] if "crs" in a else '', "code": a["crs"] if "crs"
|
||||
in a else a["tiploc"], "via": a["via"] if "via" in a else ''}
|
||||
parsed["destinations"] = [
|
||||
{"name": a["locationName"], "tiploc": a["tiploc"],
|
||||
"crs": a["crs"] if "crs" in a else '',
|
||||
"code": a["crs"] if "crs"
|
||||
in a else a["tiploc"],
|
||||
"via": a["via"] if "via" in a else ''}
|
||||
for a in t["destination"][0]]
|
||||
|
||||
parsed["origins"] = [{"name": a["locationName"], "tiploc": a["tiploc"],
|
||||
"crs": a["crs"] if "crs" in a else '', "code": a["crs"] if "crs"
|
||||
in a else a["tiploc"], "via": a["via"] if "via" in a else ''}
|
||||
parsed["origins"] = [
|
||||
{"name": a["locationName"], "tiploc": a["tiploc"],
|
||||
"crs": a["crs"] if "crs" in a else '',
|
||||
"code": a["crs"] if "crs"
|
||||
in a else a["tiploc"],
|
||||
"via": a["via"] if "via" in a else ''}
|
||||
for a in t["origin"][0]]
|
||||
|
||||
parsed["departure_only"] = location_code in [a["code"] for a in parsed["origins"]]
|
||||
parsed["departure_only"] = location_code in [a["code"] for a in
|
||||
parsed["origins"]]
|
||||
|
||||
if parsed["cancelled"] or parsed["delayed"]:
|
||||
for k, time in parsed["times"].items():
|
||||
time["short"], time["on_time"], time["status"], time["prefix"] = (
|
||||
"%s:%s" % ("C" if parsed["cancel_reason"] else "D", parsed["cancel_reason"] or parsed["delay_reason"] or "?"),
|
||||
time["short"], time["on_time"], time["status"], time[
|
||||
"prefix"] = (
|
||||
"%s:%s" % ("C" if parsed["cancel_reason"] else "D",
|
||||
parsed["cancel_reason"] or parsed[
|
||||
"delay_reason"] or "?"),
|
||||
False, 2, ""
|
||||
)
|
||||
|
||||
trains.append(parsed)
|
||||
|
||||
if eagle_url:
|
||||
summary_query = Utils.get_url("%s/json/summaries/%s?uids=%s" % (eagle_url, now.date().isoformat(), "%20".join([a["uid"] for a in trains])), json=True, headers={"x-eagle-key": self.bot.config["eagle-api-key"]})
|
||||
summary_query = Utils.get_url("%s/json/summaries/%s?uids=%s" % (
|
||||
eagle_url, now.date().isoformat(),
|
||||
"%20".join([a["uid"] for a in trains])), json=True, headers={
|
||||
"x-eagle-key": self.bot.config["eagle-api-key"]})
|
||||
if summary_query:
|
||||
for t in trains:
|
||||
summary = summary_query[t["uid"]]
|
||||
t.update(summary)
|
||||
summary_plat = summary.get("platforms", {}).get(query["crs"])
|
||||
summary_plat = summary.get("platforms", {}).get(
|
||||
query["crs"])
|
||||
if summary_plat and t["platform"] == "?":
|
||||
t["platform"], t["platform_prefix"] = summary_plat, "s"
|
||||
|
||||
for t in trains:
|
||||
t["dest_summary"] = "/".join(["%s%s" %(a["code"]*filter["crs"] or a["name"], " " + a["via"]
|
||||
t["dest_summary"] = "/".join(["%s%s" % (
|
||||
a["code"] * filter["crs"] or a["name"], " " + a["via"]
|
||||
if a["via"] else '') for a in t["destinations"]])
|
||||
t["origin_summary"] = "/".join(["%s%s" %(a["code"]*filter["crs"] or a["name"], " " + a["via"]
|
||||
t["origin_summary"] = "/".join(["%s%s" % (
|
||||
a["code"] * filter["crs"] or a["name"], " " + a["via"]
|
||||
if a["via"] else '') for a in t["origins"]])
|
||||
|
||||
trains = sorted(trains, key=lambda t: t["times"]["max_sched"]["ut"] if filter["type"]=="both" else t["times"]["st" + filter["type"][0]]["ut"])
|
||||
trains = sorted(trains,
|
||||
key=lambda t: t["times"]["max_sched"]["ut"] if filter[
|
||||
"type"] == "both" else
|
||||
t["times"]["st" + filter["type"][0]]["ut"])
|
||||
|
||||
trains_filtered = []
|
||||
train_locs_toc = []
|
||||
|
||||
for train in trains:
|
||||
if not True in [
|
||||
(train["destinations"], train["toc"]) in train_locs_toc and (filter["dedup"] or filter["default"]),
|
||||
filter["dest"] and not filter["dest"].upper() in [a["code"] for a in train["destinations"]],
|
||||
filter["origin"] and not filter["origin"].upper() in [a["code"] for a in train["origins"]],
|
||||
(train["destinations"], train["toc"]) in train_locs_toc and (
|
||||
filter["dedup"] or filter["default"]),
|
||||
filter["dest"] and not filter["dest"].upper() in [a["code"] for
|
||||
a in train[
|
||||
"destinations"]],
|
||||
filter["origin"] and not filter["origin"].upper() in [a["code"]
|
||||
for a in
|
||||
train[
|
||||
"origins"]],
|
||||
filter["toc"] and not filter["toc"].upper() == train["toc"],
|
||||
filter["plat"] and not filter["plat"] == train["platform"],
|
||||
filter["type"] == "departure" and train["terminating"],
|
||||
filter["type"] == "arrival" and train["departure_only"],
|
||||
filter["terminating"] and not train["terminating"],
|
||||
filter["tops"] and not filter["tops"] in train.get("tops_possible", []),
|
||||
filter["power"] and not filter["power"]==train.get("power_type", None),
|
||||
filter["tops"] and not filter["tops"] in train.get(
|
||||
"tops_possible", []),
|
||||
filter["power"] and not filter["power"] == train.get(
|
||||
"power_type", None),
|
||||
]:
|
||||
train_locs_toc.append((train["destinations"], train["toc"]))
|
||||
trains_filtered.append(train)
|
||||
if event.get("external"):
|
||||
trains_string = "\n".join(["%-6s %-4s %-2s %-3s %1s%-6s %1s %s" % (
|
||||
t["uid"], t["head"], t["toc"], "bus" if t["bus"] else t["platform"],
|
||||
t["uid"], t["head"], t["toc"],
|
||||
"bus" if t["bus"] else t["platform"],
|
||||
"~" if t["times"]["both"]["estimate"] else '',
|
||||
t["times"]["both"]["prefix"] + t["times"]["both"]["short"],
|
||||
"←" if t["terminating"] or filter["type"] == "arrival" else "→",
|
||||
t["origin_summary"] if t["terminating"] or filter["type"]=="arrival" else t["dest_summary"]
|
||||
t["origin_summary"] if t["terminating"] or filter[
|
||||
"type"] == "arrival" else t["dest_summary"]
|
||||
) for t in trains_filtered])
|
||||
else:
|
||||
trains_string = ", ".join(["%s%s (%s, %s%s%s%s, %s%s%s%s%s)" % (
|
||||
"from " if not filter["type"][0] in "ad" and t["terminating"] else '',
|
||||
t["origin_summary"] if t["terminating"] or filter["type"]=="arrival" else t["dest_summary"],
|
||||
"from " if not filter["type"][0] in "ad" and t[
|
||||
"terminating"] else '',
|
||||
t["origin_summary"] if t["terminating"] or filter[
|
||||
"type"] == "arrival" else t["dest_summary"],
|
||||
t["uid"],
|
||||
t["platform_prefix"],
|
||||
"bus" if t["bus"] else t["platform"],
|
||||
"*" if t["platform_hidden"] else '',
|
||||
"?" if "platformsAreUnreliable" in query and query["platformsAreUnreliable"] else '',
|
||||
t["times"][filter["type"]]["prefix"].replace(filter["type"][0], '') if not t["cancelled"] else "",
|
||||
"?" if "platformsAreUnreliable" in query and query[
|
||||
"platformsAreUnreliable"] else '',
|
||||
t["times"][filter["type"]]["prefix"].replace(filter["type"][0],
|
||||
'') if not t[
|
||||
"cancelled"] else "",
|
||||
Utils.color(colours[t["times"][filter["type"]]["status"]]),
|
||||
t["times"][filter["type"]]["shortest"*filter["st"] or "short"],
|
||||
t["times"][filter["type"]][
|
||||
"shortest" * filter["st"] or "short"],
|
||||
Utils.color(Utils.FONT_RESET),
|
||||
bool(t["activity"]) * ", " + "+".join(t["activity"]),
|
||||
) for t in trains_filtered])
|
||||
if event.get("external"):
|
||||
event["stdout"].write("%s%s\n%s" % (
|
||||
station_summary, "\n calling at %s" % filter["inter"] if filter["inter"] else '', trains_string))
|
||||
station_summary,
|
||||
"\n calling at %s" % filter["inter"] if filter["inter"] else '',
|
||||
trains_string))
|
||||
else:
|
||||
event["stdout"].write("%s%s: %s" % (station_summary, " departures calling at %s" % filter["inter"] if filter["inter"] else '', trains_string))
|
||||
event["stdout"].write("%s%s: %s" % (station_summary,
|
||||
" departures calling at %s" %
|
||||
filter["inter"] if filter[
|
||||
"inter"] else '',
|
||||
trains_string))
|
||||
|
||||
def service(self, event):
|
||||
client = self.client
|
||||
|
@ -317,7 +413,8 @@ class Module(object):
|
|||
external = event.get("external", False)
|
||||
|
||||
SCHEDULE_STATUS = {"B": "perm bus", "F": "freight train", "P": "train",
|
||||
"S": "ship", "T": "trip", "1": "train", "2": "freight",
|
||||
"S": "ship", "T": "trip", "1": "train",
|
||||
"2": "freight",
|
||||
"3": "trip", "4": "ship", "5": "bus"}
|
||||
|
||||
eagle_key = self.bot.config["eagle-api-key"]
|
||||
|
@ -327,9 +424,12 @@ class Module(object):
|
|||
|
||||
service_id = event["args_split"][0]
|
||||
|
||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(event["args_split"]) > 1 else "", {
|
||||
"passing": (False, lambda x: type(x)==type(True)),
|
||||
"type": ("arrival", lambda x: x in ["arrival", "departure"])
|
||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(
|
||||
event["args_split"]) > 1 else "", {
|
||||
"passing": (
|
||||
False, lambda x: type(x) == type(True)),
|
||||
"type": ("arrival", lambda x: x in ["arrival",
|
||||
"departure"])
|
||||
})
|
||||
|
||||
if filter["errors"]:
|
||||
|
@ -338,18 +438,27 @@ class Module(object):
|
|||
|
||||
rid = service_id
|
||||
if len(service_id) <= 8:
|
||||
query = client.service.QueryServices(service_id, datetime.utcnow().date().isoformat(),
|
||||
datetime.utcnow().time().strftime("%H:%M:%S+0000"))
|
||||
query = client.service.QueryServices(service_id,
|
||||
datetime.utcnow().date().isoformat(),
|
||||
datetime.utcnow().time().strftime(
|
||||
"%H:%M:%S+0000"))
|
||||
if eagle_url:
|
||||
schedule_query = Utils.get_url("%s/json/schedule/%s/%s" % (eagle_url, service_id, datetime.now().date().isoformat()), json=True, headers={"x-eagle-key": eagle_key})
|
||||
schedule_query = Utils.get_url("%s/json/schedule/%s/%s" % (
|
||||
eagle_url, service_id, datetime.now().date().isoformat()),
|
||||
json=True, headers={
|
||||
"x-eagle-key": eagle_key})
|
||||
if schedule_query:
|
||||
schedule = schedule_query["current"]
|
||||
if not query and not schedule:
|
||||
return event["stdout"].write("No service information is available for this identifier.")
|
||||
return event["stdout"].write(
|
||||
"No service information is available for this identifier.")
|
||||
|
||||
if query and len(query["serviceList"][0]) > 1:
|
||||
return event["stdout"].write("Identifier refers to multiple services: " +
|
||||
", ".join(["%s (%s->%s)" % (a["uid"], a["originCrs"], a["destinationCrs"]) for a in query["serviceList"][0]]))
|
||||
return event["stdout"].write(
|
||||
"Identifier refers to multiple services: " +
|
||||
", ".join(["%s (%s->%s)" % (
|
||||
a["uid"], a["originCrs"], a["destinationCrs"]) for a in
|
||||
query["serviceList"][0]]))
|
||||
if query: rid = query["serviceList"][0][0]["rid"]
|
||||
|
||||
if query:
|
||||
|
@ -357,70 +466,109 @@ class Module(object):
|
|||
query = client.service.GetServiceDetailsByRID(rid)
|
||||
if schedule:
|
||||
sources.append("Eagle/SCHEDULE")
|
||||
if not query: query = {"trainid": schedule["signalling_id"] or "0000", "operator": schedule["operator_name"] or schedule["atoc_code"]}
|
||||
stype = "class %s %s" % (schedule_query["tops_inferred"], schedule["power_type"]) if schedule_query["tops_inferred"] else schedule["power_type"]
|
||||
if not query: query = {
|
||||
"trainid": schedule["signalling_id"] or "0000",
|
||||
"operator": schedule["operator_name"] or schedule[
|
||||
"atoc_code"]}
|
||||
stype = "class %s %s" % (
|
||||
schedule_query["tops_inferred"], schedule["power_type"]) if \
|
||||
schedule_query["tops_inferred"] else schedule["power_type"]
|
||||
for k, v in {
|
||||
"operatorCode": schedule["atoc_code"],
|
||||
"serviceType": stype if stype else SCHEDULE_STATUS[schedule["status"]],
|
||||
"serviceType": stype if stype else SCHEDULE_STATUS[
|
||||
schedule["status"]],
|
||||
}.items():
|
||||
query[k] = v
|
||||
|
||||
disruptions = []
|
||||
if "cancelReason" in query:
|
||||
disruptions.append("Cancelled (%s%s)" % (query["cancelReason"]["value"], " at " + query["cancelReason"]["_tiploc"] if query["cancelReason"]["_tiploc"] else ""))
|
||||
disruptions.append("Cancelled (%s%s)" % (
|
||||
query["cancelReason"]["value"],
|
||||
" at " + query["cancelReason"]["_tiploc"] if query["cancelReason"][
|
||||
"_tiploc"] else ""))
|
||||
if "delayReason" in query:
|
||||
disruptions.append("Delayed (%s%s)" % (query["delayReason"]["value"], " at " + query["delayReason"]["_tiploc"] if query["delayReason"]["_tiploc"] else ""))
|
||||
disruptions.append("Delayed (%s%s)" % (
|
||||
query["delayReason"]["value"],
|
||||
" at " + query["delayReason"]["_tiploc"] if query["delayReason"][
|
||||
"_tiploc"] else ""))
|
||||
if disruptions and not external:
|
||||
disruptions = Utils.color(Utils.COLOR_RED) + ", ".join(disruptions) + Utils.color(Utils.FONT_RESET) + " "
|
||||
disruptions = Utils.color(Utils.COLOR_RED) + ", ".join(
|
||||
disruptions) + Utils.color(Utils.FONT_RESET) + " "
|
||||
elif disruptions and external:
|
||||
disruptions = ", ".join(disruptions)
|
||||
else: disruptions = ""
|
||||
else:
|
||||
disruptions = ""
|
||||
|
||||
stations = []
|
||||
for station in query["locations"][0] if "locations" in query else schedule["locations"]:
|
||||
for station in query["locations"][0] if "locations" in query else \
|
||||
schedule["locations"]:
|
||||
if "locations" in query:
|
||||
parsed = {"name": station["locationName"],
|
||||
"crs": (station["crs"] if "crs" in station else station["tiploc"]).rstrip(),
|
||||
"crs": (
|
||||
station["crs"] if "crs" in station else station[
|
||||
"tiploc"]).rstrip(),
|
||||
"tiploc": station["tiploc"].rstrip(),
|
||||
"called": "atd" in station,
|
||||
"passing": station["isPass"] if "isPass" in station else False,
|
||||
"passing": station[
|
||||
"isPass"] if "isPass" in station else False,
|
||||
"first": len(stations) == 0,
|
||||
"last": False,
|
||||
"cancelled" : station["isCancelled"] if "isCancelled" in station else False,
|
||||
"cancelled": station[
|
||||
"isCancelled"] if "isCancelled" in station else False,
|
||||
"associations": [],
|
||||
"length": station["length"] if "length" in station else None,
|
||||
"length": station[
|
||||
"length"] if "length" in station else None,
|
||||
"times": self.process(station),
|
||||
"platform": station["platform"] if "platform" in station else None,
|
||||
"activity": self.activities(station["activities"]) if "activities" in station else [],
|
||||
"activity_p": self.reduced_activities(station["activities"]) if "activities" in station else [],
|
||||
"platform": station[
|
||||
"platform"] if "platform" in station else None,
|
||||
"activity": self.activities(station[
|
||||
"activities"]) if "activities" in station else [],
|
||||
"activity_p": self.reduced_activities(station[
|
||||
"activities"]) if "activities" in station else [],
|
||||
}
|
||||
|
||||
if parsed["cancelled"]:
|
||||
parsed["times"]["arrival"].update({"short": "Cancelled", "on_time": False, "status": 2})
|
||||
parsed["times"]["departure"].update({"short": "Cancelled", "on_time": False, "status": 2})
|
||||
parsed["times"]["arrival"].update(
|
||||
{"short": "Cancelled", "on_time": False, "status": 2})
|
||||
parsed["times"]["departure"].update(
|
||||
{"short": "Cancelled", "on_time": False, "status": 2})
|
||||
|
||||
associations = station["associations"][0] if "associations" in station else []
|
||||
associations = station["associations"][
|
||||
0] if "associations" in station else []
|
||||
for assoc in associations:
|
||||
parsed_assoc = {
|
||||
"uid_assoc": assoc.uid,
|
||||
"category": {"divide": "VV", "join": "JJ", "next": "NP"}[assoc["category"]],
|
||||
"from": parsed["first"], "direction": assoc["destTiploc"].rstrip()==parsed["tiploc"],
|
||||
"origin_name": assoc["origin"], "origin_tiploc": assoc["originTiploc"],
|
||||
"origin_crs": assoc["originCRS"] if "originCRS" in assoc else None,
|
||||
"category":
|
||||
{"divide": "VV", "join": "JJ", "next": "NP"}[
|
||||
assoc["category"]],
|
||||
"from": parsed["first"],
|
||||
"direction": assoc["destTiploc"].rstrip() == parsed[
|
||||
"tiploc"],
|
||||
"origin_name": assoc["origin"],
|
||||
"origin_tiploc": assoc["originTiploc"],
|
||||
"origin_crs": assoc[
|
||||
"originCRS"] if "originCRS" in assoc else None,
|
||||
|
||||
"dest_name": assoc["destination"], "dest_tiploc": assoc["destTiploc"],
|
||||
"dest_crs": assoc["destCRS"] if "destCRS" in assoc else None,
|
||||
"dest_name": assoc["destination"],
|
||||
"dest_tiploc": assoc["destTiploc"],
|
||||
"dest_crs": assoc[
|
||||
"destCRS"] if "destCRS" in assoc else None,
|
||||
|
||||
"far_name": assoc["destination"], "far_tiploc": assoc["destTiploc"],
|
||||
"far_crs": assoc["destCRS"] if "destCRS" in assoc else None,
|
||||
"far_name": assoc["destination"],
|
||||
"far_tiploc": assoc["destTiploc"],
|
||||
"far_crs": assoc[
|
||||
"destCRS"] if "destCRS" in assoc else None,
|
||||
}
|
||||
if parsed_assoc["direction"]:
|
||||
parsed_assoc.update({"far_name": parsed_assoc["origin_name"],
|
||||
"far_tiploc": parsed_assoc["origin_tiploc"], "far_crs": parsed_assoc["origin_crs"]})
|
||||
parsed_assoc.update(
|
||||
{"far_name": parsed_assoc["origin_name"],
|
||||
"far_tiploc": parsed_assoc["origin_tiploc"],
|
||||
"far_crs": parsed_assoc["origin_crs"]})
|
||||
parsed["associations"].append(parsed_assoc)
|
||||
else:
|
||||
parsed = {"name": (station["name"] or "none"),
|
||||
"crs": station["crs"] if station["crs"] else station["tiploc"],
|
||||
"crs": station["crs"] if station["crs"] else station[
|
||||
"tiploc"],
|
||||
"tiploc": station["tiploc"],
|
||||
"called": False,
|
||||
"passing": bool(station.get("pass")),
|
||||
|
@ -432,47 +580,66 @@ class Module(object):
|
|||
"platform": station["platform"],
|
||||
"associations": station["associations"] or [],
|
||||
"activity": self.activities(station["activity"]),
|
||||
"activity_p": self.reduced_activities(station["activity"]),
|
||||
"activity_p": self.reduced_activities(
|
||||
station["activity"]),
|
||||
}
|
||||
stations.append(parsed)
|
||||
|
||||
[a for a in stations if a["called"] or a["first"]][-1]["last"] = True
|
||||
|
||||
for station in stations[0:[k for k,v in enumerate(stations) if v["last"]][0]]:
|
||||
for station in stations[
|
||||
0:[k for k, v in enumerate(stations) if v["last"]][0]]:
|
||||
if not station["first"]: station["called"] = True
|
||||
|
||||
for station in stations:
|
||||
for assoc in station["associations"]:
|
||||
assoc["summary"] = "{arrow} {assoc[category]} {assoc[uid_assoc]} {dir_arrow} {assoc[far_name]} ({code})".format(assoc=assoc, arrow=assoc["from"]*"<-" or "->", dir_arrow=(assoc["direction"])*"<-" or "->", code=assoc["far_crs"] or assoc["far_tiploc"])
|
||||
assoc[
|
||||
"summary"] = "{arrow} {assoc[category]} {assoc[uid_assoc]} {dir_arrow} {assoc[far_name]} ({code})".format(
|
||||
assoc=assoc, arrow=assoc["from"] * "<-" or "->",
|
||||
dir_arrow=(assoc["direction"]) * "<-" or "->",
|
||||
code=assoc["far_crs"] or assoc["far_tiploc"])
|
||||
|
||||
if station["passing"]:
|
||||
station["times"]["arrival"]["status"], station["times"]["departure"]["status"] = 5, 5
|
||||
station["times"]["arrival"]["status"], \
|
||||
station["times"]["departure"]["status"] = 5, 5
|
||||
elif station["called"]:
|
||||
station["times"]["arrival"]["status"], station["times"]["departure"]["status"] = 0, 0
|
||||
station["times"]["arrival"]["status"], \
|
||||
station["times"]["departure"]["status"] = 0, 0
|
||||
|
||||
station["summary"] = "%s%s (%s%s%s%s%s%s%s)%s" % (
|
||||
"*" * station["passing"],
|
||||
station["name"],
|
||||
station["crs"] + ", " if station["name"] != station["crs"] else '',
|
||||
station["length"] + " cars, " if station["length"] and (station["first"] or (station["last"]) or station["associations"]) else '',
|
||||
station["crs"] + ", " if station["name"] != station[
|
||||
"crs"] else '',
|
||||
station["length"] + " cars, " if station["length"] and (
|
||||
station["first"] or (station["last"]) or station[
|
||||
"associations"]) else '',
|
||||
("~" if station["times"][filter["type"]]["estimate"] else '') +
|
||||
station["times"][filter["type"]]["prefix"].replace(filter["type"][0], ""),
|
||||
Utils.color(colours[station["times"][filter["type"]]["status"]]),
|
||||
station["times"][filter["type"]]["prefix"].replace(
|
||||
filter["type"][0], ""),
|
||||
Utils.color(
|
||||
colours[station["times"][filter["type"]]["status"]]),
|
||||
station["times"][filter["type"]]["short"],
|
||||
Utils.color(Utils.FONT_RESET),
|
||||
", "*bool(station["activity_p"]) + "+".join(station["activity_p"]),
|
||||
", " * bool(station["activity_p"]) + "+".join(
|
||||
station["activity_p"]),
|
||||
", ".join([a["summary"] for a in station["associations"]]),
|
||||
)
|
||||
station["summary_external"] = "%1s%-5s %1s%-5s %-3s %-3s %-3s %s%s" % (
|
||||
"~"*station["times"]["a"]["estimate"] + "s"*(station["times"]["a"]["schedule"]),
|
||||
station[
|
||||
"summary_external"] = "%1s%-5s %1s%-5s %-3s %-3s %-3s %s%s" % (
|
||||
"~" * station["times"]["a"]["estimate"] + "s" * (
|
||||
station["times"]["a"]["schedule"]),
|
||||
station["times"]["a"]["short"],
|
||||
"~"*station["times"]["d"]["estimate"] + "s"*(station["times"]["d"]["schedule"]),
|
||||
"~" * station["times"]["d"]["estimate"] + "s" * (
|
||||
station["times"]["d"]["schedule"]),
|
||||
station["times"]["d"]["short"],
|
||||
station["platform"] or '',
|
||||
",".join(station["activity"]) or '',
|
||||
station["crs"] or station["tiploc"],
|
||||
station["name"],
|
||||
"\n" + "\n".join([a["summary"] for a in station["associations"]]) if station["associations"] else "",
|
||||
"\n" + "\n".join(
|
||||
[a["summary"] for a in station["associations"]]) if station[
|
||||
"associations"] else "",
|
||||
)
|
||||
|
||||
stations_filtered = []
|
||||
|
@ -483,8 +650,10 @@ class Module(object):
|
|||
continue
|
||||
|
||||
stations_filtered.append(station)
|
||||
if station["first"] and not station["last"] and filter["default"] and not external:
|
||||
stations_filtered.append({"summary": "(...)", "summary_external": "(...)"})
|
||||
if station["first"] and not station["last"] and filter[
|
||||
"default"] and not external:
|
||||
stations_filtered.append(
|
||||
{"summary": "(...)", "summary_external": "(...)"})
|
||||
|
||||
done_count = len([s for s in stations if s["called"]])
|
||||
total_count = len(stations)
|
||||
|
@ -492,13 +661,16 @@ class Module(object):
|
|||
event["stdout"].write("%s: %s\n%s%s (%s) %s %s\n\n%s" % (
|
||||
service_id, ", ".join(sources),
|
||||
disruptions + "\n" if disruptions else '',
|
||||
query["operator"], query["operatorCode"], query["trainid"], query["serviceType"],
|
||||
query["operator"], query["operatorCode"], query["trainid"],
|
||||
query["serviceType"],
|
||||
"\n".join([s["summary_external"] for s in stations_filtered])
|
||||
))
|
||||
else:
|
||||
event["stdout"].write("%s%s %s %s (%s%s%s/%s/%s): %s" % (disruptions, query["operatorCode"],
|
||||
event["stdout"].write("%s%s %s %s (%s%s%s/%s/%s): %s" % (
|
||||
disruptions, query["operatorCode"],
|
||||
query["trainid"], query["serviceType"],
|
||||
Utils.color(Utils.COLOR_LIGHTBLUE), done_count, Utils.color(Utils.FONT_RESET),
|
||||
Utils.color(Utils.COLOR_LIGHTBLUE), done_count,
|
||||
Utils.color(Utils.FONT_RESET),
|
||||
len(stations_filtered), total_count,
|
||||
", ".join([s["summary"] for s in stations_filtered])))
|
||||
|
||||
|
@ -506,25 +678,40 @@ class Module(object):
|
|||
client = self.client
|
||||
service_id = event["args_split"][0]
|
||||
|
||||
query = client.service.QueryServices(service_id, datetime.utcnow().date().isoformat(),
|
||||
datetime.utcnow().time().strftime("%H:%M:%S+0000"))
|
||||
query = client.service.QueryServices(service_id,
|
||||
datetime.utcnow().date().isoformat(),
|
||||
datetime.utcnow().time().strftime(
|
||||
"%H:%M:%S+0000"))
|
||||
|
||||
if not query:
|
||||
return event["stderr"].write("No currently running services match this identifier")
|
||||
return event["stderr"].write(
|
||||
"No currently running services match this identifier")
|
||||
|
||||
services = query["serviceList"][0]
|
||||
if event.get("external"):
|
||||
event["stdout"].write("\n".join(["{a.uid:6} {a.trainid:4} {a.originName} ({a.originCrs}) → {a.destinationName} ({a.destinationCrs})".format(a=a) for a in services]))
|
||||
event["stdout"].write("\n".join([
|
||||
"{a.uid:6} {a.trainid:4} {a.originName} ({a.originCrs}) → {a.destinationName} ({a.destinationCrs})".format(
|
||||
a=a) for a in services]))
|
||||
else:
|
||||
event["stdout"].write(", ".join(["h/%s r/%s u/%s rs/%s %s (%s) -> %s (%s)" % (a["trainid"], a["rid"], a["uid"], a["rsid"], a["originName"], a["originCrs"], a["destinationName"], a["destinationCrs"]) for a in services]))
|
||||
event["stdout"].write(", ".join([
|
||||
"h/%s r/%s u/%s rs/%s %s (%s) -> %s (%s)" % (
|
||||
a["trainid"], a["rid"],
|
||||
a["uid"], a["rsid"],
|
||||
a["originName"], a["originCrs"],
|
||||
a["destinationName"],
|
||||
a["destinationCrs"]) for a in
|
||||
services]))
|
||||
|
||||
def service_code(self, event):
|
||||
client = self.client
|
||||
|
||||
if not event["args"].isnumeric():
|
||||
return event["stderr"].write("The delay/cancellation code must be a number")
|
||||
reasons = {a["code"]:(a["lateReason"], a["cancReason"]) for a in client.service.GetReasonCodeList()[0]}
|
||||
return event["stderr"].write(
|
||||
"The delay/cancellation code must be a number")
|
||||
reasons = {a["code"]: (a["lateReason"], a["cancReason"]) for a in
|
||||
client.service.GetReasonCodeList()[0]}
|
||||
if event["args"] in reasons:
|
||||
event["stdout"].write("%s: %s" % (event["args"], " / ".join(reasons[event["args"]])))
|
||||
event["stdout"].write(
|
||||
"%s: %s" % (event["args"], " / ".join(reasons[event["args"]])))
|
||||
else:
|
||||
event["stdout"].write("This doesn't seem to be a valid reason code")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import EventManager
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("numeric").on("001").hook(
|
||||
|
|
|
@ -4,6 +4,7 @@ import scrypt
|
|||
REQUIRES_IDENTIFY = ("You need to be identified to use that command "
|
||||
"(/msg %s register | /msg %s identify)")
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -12,13 +13,20 @@ class Module(object):
|
|||
self.preprocess_command)
|
||||
bot.events.on("received").on("part").hook(self.on_part)
|
||||
bot.events.on("received").on("command").on("identify"
|
||||
).hook(self.identify, private_only=True, min_args=1,
|
||||
usage="<password>", help="Identify yourself")
|
||||
).hook(self.identify,
|
||||
private_only=True,
|
||||
min_args=1,
|
||||
usage="<password>",
|
||||
help="Identify yourself")
|
||||
bot.events.on("received").on("command").on("register"
|
||||
).hook(self.register, private_only=True, min_args=1,
|
||||
usage="<password>", help="Register your nickname")
|
||||
).hook(self.register,
|
||||
private_only=True,
|
||||
min_args=1,
|
||||
usage="<password>",
|
||||
help="Register your nickname")
|
||||
bot.events.on("received.command.logout").hook(self.logout,
|
||||
private_only=True, help="Sign out from the bot")
|
||||
private_only=True,
|
||||
help="Sign out from the bot")
|
||||
|
||||
bot.events.on("received.command.mypermissions").hook(
|
||||
self.my_permissions, authenticated=True)
|
||||
|
@ -142,6 +150,7 @@ class Module(object):
|
|||
target.set_setting("permissions", permissions)
|
||||
event["stdout"].write("Gave permission '%s' to %s" % (
|
||||
permission, target.nickname))
|
||||
|
||||
def remove_permission(self, event):
|
||||
permission = event["args_split"][1].lower()
|
||||
target, registered, permissions = self._get_user_details(
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received.command.ping").hook(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import datetime
|
||||
import EventManager
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -51,18 +52,23 @@ class Module(object):
|
|||
self.print_line(event, "<%s> %s" % (
|
||||
nickname, event["message"]),
|
||||
channel=event["channel"].name)
|
||||
|
||||
def channel_message(self, event):
|
||||
self._on_message(event, event["user"].nickname)
|
||||
|
||||
def self_channel_message(self, event):
|
||||
self._on_message(event, event["server"].nickname)
|
||||
|
||||
def _on_notice(self, event, target):
|
||||
self.print_line(event, "(notice->%s) <%s> %s" % (
|
||||
target, event["user"].nickname, event["message"]))
|
||||
|
||||
def channel_notice(self, event):
|
||||
self._on_notice(event, event["channel"].name)
|
||||
|
||||
def private_notice(self, event):
|
||||
self._on_notice(event, event["server"].nickname)
|
||||
|
||||
def server_notice(self, event):
|
||||
self.print_line(event, "(server notice) %s" % event["message"])
|
||||
|
||||
|
@ -70,18 +76,25 @@ class Module(object):
|
|||
if not self.bot.args.verbose:
|
||||
self.print_line(event, "%s joined %s" % (nickname,
|
||||
event["channel"].name))
|
||||
|
||||
def join(self, event):
|
||||
self._on_join(event, event["user"].nickname)
|
||||
|
||||
def self_join(self, event):
|
||||
self._on_join(event, event["server"].nickname)
|
||||
|
||||
def _on_part(self, event, nickname):
|
||||
if not self.bot.args.verbose:
|
||||
self.print_line(event, "%s left %s%s" % (nickname,
|
||||
event["channel"].name, "" if not event[
|
||||
"reason"] else " (%s)" % event["reason"]))
|
||||
event["channel"].name,
|
||||
"" if not event[
|
||||
"reason"] else " (%s)" %
|
||||
event[
|
||||
"reason"]))
|
||||
|
||||
def part(self, event):
|
||||
self._on_part(event, event["user"].nickname)
|
||||
|
||||
def self_part(self, event):
|
||||
self._on_part(event, event["server"].nickname)
|
||||
|
||||
|
@ -93,24 +106,32 @@ class Module(object):
|
|||
def on_quit(self, event):
|
||||
if not self.bot.args.verbose:
|
||||
self.print_line(event, "%s quit%s" % (event["user"].nickname,
|
||||
"" if not event["reason"] else " (%s)" % event["reason"]))
|
||||
"" if not event[
|
||||
"reason"] else " (%s)" %
|
||||
event[
|
||||
"reason"]))
|
||||
|
||||
def _on_kick(self, event, nickname):
|
||||
if not self.bot.args.verbose:
|
||||
self.print_line(event, "%s kicked %s from %s%s" % (
|
||||
event["user"].nickname, nickname, event["channel"].name,
|
||||
"" if not event["reason"] else " (%s)" % event["reason"]))
|
||||
|
||||
def kick(self, event):
|
||||
self._on_kick(event, event["target_user"].nickname)
|
||||
|
||||
def self_kick(self, event):
|
||||
self._on_kick(event, event["server"].nickname)
|
||||
|
||||
def _on_topic(self, event, setter, action, topic, channel):
|
||||
self.print_line(event, "topic %s by %s: %s" % (action, setter,
|
||||
topic), channel=channel.name)
|
||||
topic),
|
||||
channel=channel.name)
|
||||
|
||||
def on_topic(self, event):
|
||||
self._on_topic(event, event["user"].nickname, "changed",
|
||||
event["topic"], event["channel"])
|
||||
|
||||
def on_333(self, event):
|
||||
self._on_topic(event, event["setter"], "set",
|
||||
event["channel"].topic, event["channel"])
|
||||
|
|
|
@ -54,6 +54,7 @@ QUOTES = {
|
|||
"I don’t need to understand how encryption works": "Amber Rudd",
|
||||
}
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("get.quit-quote").hook(self.quote)
|
||||
|
@ -61,4 +62,3 @@ class Module(object):
|
|||
def quote(self, event):
|
||||
quote = random.choice(list(QUOTES.items()))
|
||||
return (" - " if quote[1] else "").join(quote)
|
||||
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
import random, time
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("quoteadd",
|
||||
"qadd").hook(self.quote_add, min_args=1,
|
||||
"qadd").hook(self.quote_add,
|
||||
min_args=1,
|
||||
help="Added a quote to a category",
|
||||
usage="<category> = <quote>")
|
||||
bot.events.on("received").on("command").on("quoteget",
|
||||
"qget").hook(self.quote_get, min_args=1,
|
||||
"qget").hook(self.quote_get,
|
||||
min_args=1,
|
||||
help="Find a quote within a category",
|
||||
usage="<category> = <search>")
|
||||
bot.events.on("received").on("command").on("quotedel",
|
||||
"qdel").hook(self.quote_del, min_args=1,
|
||||
"qdel").hook(self.quote_del,
|
||||
min_args=1,
|
||||
help="Delete a quote from a category",
|
||||
usage="<category> = <quote>")
|
||||
bot.events.on("received").on("command").on("quote",
|
||||
"q").hook(self.quote, min_args=1,
|
||||
"q").hook(self.quote,
|
||||
min_args=1,
|
||||
help="Get a random quote from a category",
|
||||
usage="<category>")
|
||||
|
||||
|
@ -47,7 +52,9 @@ class Module(object):
|
|||
found.append(quote)
|
||||
if found:
|
||||
event["stdout"].write("%d quote%s found: %s" % (len(found),
|
||||
"s" if len(found) > 1 else "", found[0]))
|
||||
"s" if len(
|
||||
found) > 1 else "",
|
||||
found[0]))
|
||||
else:
|
||||
event["stderr"].write("No quotes found")
|
||||
else:
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import random, uuid
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "Random"
|
||||
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("random",
|
||||
"rand").hook(self.random, help="Get a random number",
|
||||
"rand").hook(self.random,
|
||||
help="Get a random number",
|
||||
usage="[start] [end]")
|
||||
bot.events.on("received").on("command").on("guid"
|
||||
).hook(self.guid, help="Get a random guid")
|
||||
).hook(self.guid,
|
||||
help="Get a random guid")
|
||||
|
||||
def random(self, event):
|
||||
start, end = "1", "100"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import base64
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -36,4 +37,3 @@ class Module(object):
|
|||
|
||||
def on_90x(self, event):
|
||||
event["server"].send_capability_end()
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
REGEX_SPLIT = re.compile("(?<!\\\\)/")
|
||||
REGEX_SED = re.compile("^s/")
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -17,7 +18,8 @@ class Module(object):
|
|||
bot.events.on("postboot").on("configure").on(
|
||||
"channelset").assure_call(setting="sed-sender-only",
|
||||
help="Disable/Enable sed only looking at the messages "
|
||||
"sent by the user", validate=Utils.bool_or_none)
|
||||
"sent by the user",
|
||||
validate=Utils.bool_or_none)
|
||||
|
||||
def channel_message(self, event):
|
||||
sed_split = re.split(REGEX_SPLIT, event["message"], 3)
|
||||
|
@ -59,7 +61,8 @@ class Module(object):
|
|||
event, "sed-sender-only", False
|
||||
) else None
|
||||
line = event["channel"].buffer.find(pattern, from_self=False,
|
||||
for_user=for_user, not_pattern=REGEX_SED)
|
||||
for_user=for_user,
|
||||
not_pattern=REGEX_SED)
|
||||
if line:
|
||||
new_message = re.sub(pattern, replace, line.message, count)
|
||||
if line.action:
|
||||
|
@ -68,4 +71,6 @@ class Module(object):
|
|||
prefix = "<%s>" % line.sender
|
||||
self.bot.events.on("send").on("stdout").call(target=event[
|
||||
"channel"], module_name="Sed", server=event["server"],
|
||||
message="%s %s" % (prefix, new_message))
|
||||
message="%s %s" % (
|
||||
prefix,
|
||||
new_message))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import time
|
||||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("message").on("channel"
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -8,7 +6,8 @@ class Module(object):
|
|||
bot.events.on("postboot").on("configure").on("set").hook(
|
||||
self.postboot_set, replay=True)
|
||||
bot.events.on("postboot").on("configure").on("channelset"
|
||||
).hook(self.postboot_channelset, replay=True)
|
||||
).hook(
|
||||
self.postboot_channelset, replay=True)
|
||||
|
||||
bot.events.on("received").on("command").on("set").hook(
|
||||
self.set, help="Set a specified user setting",
|
||||
|
@ -18,17 +17,24 @@ class Module(object):
|
|||
usage="<setting>", min_args=1)
|
||||
|
||||
bot.events.on("received").on("command").on("channelset"
|
||||
).hook(self.channel_set, channel_only=True,
|
||||
).hook(self.channel_set,
|
||||
channel_only=True,
|
||||
help="Set a specified setting for the current channel",
|
||||
usage="<setting> <value>", require_mode="o")
|
||||
usage="<setting> <value>",
|
||||
require_mode="o")
|
||||
bot.events.on("received").on("command").on("channelsetoverride"
|
||||
).hook(self.channel_set, channel_only=True,
|
||||
).hook(self.channel_set,
|
||||
channel_only=True,
|
||||
help="Set a specified setting for the current channel",
|
||||
usage="<setting> <value>", permission="channelsetoverride")
|
||||
usage="<setting> <value>",
|
||||
permission="channelsetoverride")
|
||||
bot.events.on("received").on("command").on("channelget"
|
||||
).hook(self.channel_get, channel_only=True,
|
||||
).hook(self.channel_get,
|
||||
channel_only=True,
|
||||
help="Get a specified setting for the current channel",
|
||||
usage="<setting>", min_args=1, require_mode="o")
|
||||
usage="<setting>",
|
||||
min_args=1,
|
||||
require_mode="o")
|
||||
|
||||
def _postboot_set(self, settings, event):
|
||||
settings[event["setting"]] = {}
|
||||
|
@ -36,8 +42,10 @@ class Module(object):
|
|||
"validate", lambda s: s)
|
||||
settings[event["setting"]]["help"] = event.get("help",
|
||||
"")
|
||||
|
||||
def postboot_set(self, event):
|
||||
self._postboot_set(self.settings, event)
|
||||
|
||||
def postboot_channelset(self, event):
|
||||
self._postboot_set(self.channel_settings, event)
|
||||
|
||||
|
@ -59,6 +67,7 @@ class Module(object):
|
|||
else:
|
||||
event["stdout"].write("Available settings: %s" % (
|
||||
", ".join(settings.keys())))
|
||||
|
||||
def set(self, event):
|
||||
self._set(self.settings, event, event["user"])
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import signal
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -8,7 +9,8 @@ class Module(object):
|
|||
|
||||
def SIGINT(self, signum, frame):
|
||||
print()
|
||||
self.bot.events.on("signal").on("interrupt").call(signum=signum, frame=frame)
|
||||
self.bot.events.on("signal").on("interrupt").call(signum=signum,
|
||||
frame=frame)
|
||||
|
||||
for server in self.bot.servers.values():
|
||||
reason = "Leaving"
|
||||
|
|
|
@ -7,12 +7,15 @@ URL_SOUNDCLOUD_TRACK = "http://api.soundcloud.com/tracks"
|
|||
URL_SOUNDCLOUD_RESOLVE = "http://api.soundcloud.com/resolve"
|
||||
REGEX_SOUNDCLOUD = "https?://soundcloud.com/([^/]+)/([^/]+)"
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "SoundCloud"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("soundcloud", "sc"
|
||||
).hook(self.soundcloud, help="Search SoundCloud")
|
||||
).hook(self.soundcloud,
|
||||
help="Search SoundCloud")
|
||||
|
||||
def soundcloud(self, event):
|
||||
query = None
|
||||
|
@ -56,6 +59,7 @@ class Module(object):
|
|||
duration = duration[3:]
|
||||
link = page["permalink_url"]
|
||||
event["stdout"].write("%s [%s] (posted by %s) %s" % (title,
|
||||
duration, user, link))
|
||||
duration, user,
|
||||
link))
|
||||
else:
|
||||
event["stderr"].write("Failed to load results")
|
||||
|
|
|
@ -3,6 +3,7 @@ import Utils
|
|||
|
||||
URL_SPOTIFY = "https://api.spotify.com/v1/search"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("spotify").hook(
|
||||
|
@ -11,7 +12,9 @@ class Module(object):
|
|||
|
||||
def spotify(self, event):
|
||||
page = Utils.get_url(URL_SPOTIFY, get_params={"type": "track",
|
||||
"limit": 1, "q": event["args"]}, json=True)
|
||||
"limit": 1,
|
||||
"q": event["args"]},
|
||||
json=True)
|
||||
if page:
|
||||
if len(page["tracks"]["items"]):
|
||||
item = page["tracks"]["items"][0]
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import time
|
||||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.boot_time = time.time()
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("uptime"
|
||||
).hook(self.uptime, help="Show my uptime")
|
||||
).hook(self.uptime,
|
||||
help="Show my uptime")
|
||||
bot.events.on("received").on("command").on("stats"
|
||||
).hook(self.stats, help="Show my network/channel/user stats")
|
||||
).hook(self.stats,
|
||||
help="Show my network/channel/user stats")
|
||||
|
||||
def uptime(self, event):
|
||||
seconds = int(time.time() - self.boot_time)
|
||||
|
@ -23,7 +26,6 @@ class Module(object):
|
|||
channels += len(server.channels)
|
||||
users += len(server.users)
|
||||
|
||||
|
||||
response = "I currently have %d network" % networks
|
||||
if networks > 1:
|
||||
response += "s"
|
||||
|
|
|
@ -4,41 +4,64 @@ import random
|
|||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received.command.strax").hook(
|
||||
self.strax, help="Suggests a glorious method of battle for the glory of the Sontaran Empire, through IRC!")
|
||||
self.strax,
|
||||
help="Suggests a glorious method of battle for the glory of the Sontaran Empire, through IRC!")
|
||||
|
||||
def strax(self, event):
|
||||
suggestion_greeting = ["Might I suggest", "Can I suggest", "Should we attack immediately with"]
|
||||
command_greeting = ["We should attack now with", "We must attack now with", "I suggest attacking with",
|
||||
suggestion_greeting = ["Might I suggest", "Can I suggest",
|
||||
"Should we attack immediately with"]
|
||||
command_greeting = ["We should attack now with",
|
||||
"We must attack now with",
|
||||
"I suggest attacking with",
|
||||
"We should coordinate an attack with"]
|
||||
method_of_attack_a = ["full-frontal", "pincer", "surprise", "brutally excessive", "multi-pronged", "glorious",
|
||||
"violent", "devastating", "superior", "fast-paced", "fleet-wide", "stealth",
|
||||
"diversionary", "exceptional", "point-blank", "night time"]
|
||||
method_of_attack_an = ["acid-heavy", "immediate", "overwhelming", "unstoppable", "underground", "arial",
|
||||
method_of_attack_a = ["full-frontal", "pincer", "surprise",
|
||||
"brutally excessive", "multi-pronged", "glorious",
|
||||
"violent", "devastating", "superior",
|
||||
"fast-paced", "fleet-wide", "stealth",
|
||||
"diversionary", "exceptional", "point-blank",
|
||||
"night time"]
|
||||
method_of_attack_an = ["acid-heavy", "immediate", "overwhelming",
|
||||
"unstoppable", "underground", "arial",
|
||||
"naval", "amphibious", "full-scale"]
|
||||
type_of_attack = ["assault", "attack", "bombardment", "offensive", "barrage", "charge", "strike", "operation",
|
||||
type_of_attack = ["assault", "attack", "bombardment", "offensive",
|
||||
"barrage", "charge", "strike", "operation",
|
||||
"manoeuvre", "blitzkrieg", "ambush", "massacre"]
|
||||
attack_adjective = ["laser", "berserker", "acid", "armoured attack", "proton",
|
||||
attack_adjective = ["laser", "berserker", "acid", "armoured attack",
|
||||
"proton",
|
||||
"three kinds of", "atomic", "toxic", "explosive",
|
||||
"red-hot", "thermal", "automated fire", "cluster",
|
||||
"enhanced germ", "energy-drink-fueled", "battle ready", "Sontaran", "military"]
|
||||
attack_object = ["bees", "chainsaws", "marmots", "acid", "monkeys", "mines", "bombs", "snakes", "spiders",
|
||||
"knives", "rockets", "sharks", "owls", "repurposed cybermats", "cannons", "alligators", "ants",
|
||||
"gorillas", "genetically enhanced cyber-elephants", "mechanoids", "KGB agents",
|
||||
"enhanced germ", "energy-drink-fueled",
|
||||
"battle ready", "Sontaran", "military"]
|
||||
attack_object = ["bees", "chainsaws", "marmots", "acid", "monkeys",
|
||||
"mines", "bombs", "snakes", "spiders",
|
||||
"knives", "rockets", "sharks", "owls",
|
||||
"repurposed cybermats", "cannons", "alligators",
|
||||
"ants",
|
||||
"gorillas", "genetically enhanced cyber-elephants",
|
||||
"mechanoids", "KGB agents",
|
||||
"MI5 operatives", "thermonuclear missiles"]
|
||||
attack_object_two = ["robots", "ninjas", "grenades", "a dolphin full of napalm", "dynamite",
|
||||
"xenomorphs", "lots and lots of C4", "tactical nukes", "bio-weapons",
|
||||
"rocket launchers", "an elephant", "a memory worm for afterwards", "this pencil"]
|
||||
attack_object_two = ["robots", "ninjas", "grenades",
|
||||
"a dolphin full of napalm", "dynamite",
|
||||
"xenomorphs", "lots and lots of C4",
|
||||
"tactical nukes", "bio-weapons",
|
||||
"rocket launchers", "an elephant",
|
||||
"a memory worm for afterwards", "this pencil"]
|
||||
|
||||
method_of_attack = " an " + random.choice(method_of_attack_an) if random.choice([1,
|
||||
method_of_attack = " an " + random.choice(
|
||||
method_of_attack_an) if random.choice([1,
|
||||
2]) == 1 else " a " + random.choice(
|
||||
method_of_attack_a)
|
||||
|
||||
greeting_choice = random.choice([1, 2])
|
||||
greeting = random.choice(suggestion_greeting) if greeting_choice == 1 else random.choice(command_greeting)
|
||||
greeting = random.choice(
|
||||
suggestion_greeting) if greeting_choice == 1 else random.choice(
|
||||
command_greeting)
|
||||
exclamation = "?" if greeting_choice == 1 else "!"
|
||||
|
||||
suggestion = greeting + method_of_attack + " " + random.choice(type_of_attack) + " with " + random.choice(
|
||||
attack_adjective) + " " + random.choice(attack_object) + " and " + random.choice(
|
||||
suggestion = greeting + method_of_attack + " " + random.choice(
|
||||
type_of_attack) + " with " + random.choice(
|
||||
attack_adjective) + " " + random.choice(
|
||||
attack_object) + " and " + random.choice(
|
||||
attack_object_two) + exclamation
|
||||
|
||||
event["stdout"].write(suggestion)
|
||||
|
|
|
@ -5,6 +5,7 @@ import json
|
|||
from datetime import datetime
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class Module(Thread):
|
||||
_name = "telegram"
|
||||
|
||||
|
@ -26,7 +27,8 @@ class Module(Thread):
|
|||
dolphin.events.on("signal").on("interrupt").hook(self.sigint)
|
||||
|
||||
def start(self, bot, update):
|
||||
bot.send_message(chat_id=update.message.chat_id, text="`Dolphin, but Telegram`", parse_mode="Markdown")
|
||||
bot.send_message(chat_id=update.message.chat_id,
|
||||
text="`Dolphin, but Telegram`", parse_mode="Markdown")
|
||||
|
||||
def handle(self, bot, update):
|
||||
message, text = update.message, update.message.text
|
||||
|
@ -45,18 +47,23 @@ class Module(Thread):
|
|||
"stderr": IOWrapper(bot, message.chat_id, message.message_id),
|
||||
"external": True,
|
||||
}
|
||||
self.dolphin.events.on("telegram").on("command").on(command).call(**data)
|
||||
self.dolphin.events.on("telegram").on("command").on(command).call(
|
||||
**data)
|
||||
|
||||
def sigint(self, event):
|
||||
self.updater.stop()
|
||||
|
||||
|
||||
class IOWrapper:
|
||||
def __init__(self, bot, chat_id, message_id):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
self.message_id = message_id
|
||||
|
||||
def write(self, text):
|
||||
if len(text) > 4096 - 10:
|
||||
text = text[:4086] + "…"
|
||||
self.bot.send_message(chat_id=self.chat_id, text="```\n" + text + "\n```",
|
||||
reply_to_message_id=self.message_id, parse_mode="Markdown")
|
||||
self.bot.send_message(chat_id=self.chat_id,
|
||||
text="```\n" + text + "\n```",
|
||||
reply_to_message_id=self.message_id,
|
||||
parse_mode="Markdown")
|
||||
|
|
101
modules/tfl.py
101
modules/tfl.py
|
@ -7,7 +7,9 @@ URL_BUS_SEARCH = "https://api.tfl.gov.uk/StopPoint/Search/%s"
|
|||
URL_LINE_ARRIVALS = "https://api.tfl.gov.uk/Line/%s/Arrivals"
|
||||
|
||||
URL_LINE = "https://api.tfl.gov.uk/Line/Mode/tube/Status"
|
||||
LINE_NAMES = ["bakerloo", "central", "circle", "district", "hammersmith and city", "jubilee", "metropolitan", "piccadilly", "victoria", "waterloo and city"]
|
||||
LINE_NAMES = ["bakerloo", "central", "circle", "district",
|
||||
"hammersmith and city", "jubilee", "metropolitan", "piccadilly",
|
||||
"victoria", "waterloo and city"]
|
||||
|
||||
URL_STOP = "https://api.tfl.gov.uk/StopPoint/%s"
|
||||
URL_STOP_SEARCH = "https://api.tfl.gov.uk/StopPoint/Search/%s"
|
||||
|
@ -16,10 +18,13 @@ URL_VEHICLE = "https://api.tfl.gov.uk/Vehicle/%s/Arrivals"
|
|||
|
||||
URL_ROUTE = "https://api.tfl.gov.uk/Line/%s/Route/Sequence/all?excludeCrowding=True"
|
||||
|
||||
PLATFORM_TYPES = ["Northbound", "Southbound", "Eastbound", "Westbound", "Inner Rail", "Outer Rail"]
|
||||
PLATFORM_TYPES = ["Northbound", "Southbound", "Eastbound", "Westbound",
|
||||
"Inner Rail", "Outer Rail"]
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "TFL"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.result_map = {}
|
||||
|
@ -32,11 +37,13 @@ class Module(object):
|
|||
help="Get line status for TfL underground lines",
|
||||
usage="<line_name>")
|
||||
bot.events.on("received").on("command").on("tflsearch"
|
||||
).hook(self.search, min_args=1,
|
||||
).hook(self.search,
|
||||
min_args=1,
|
||||
help="Get a list of TfL stop IDs for a given name",
|
||||
usage="<name>")
|
||||
bot.events.on("received").on("command").on("tflvehicle"
|
||||
).hook(self.vehicle, min_args=1,
|
||||
).hook(self.vehicle,
|
||||
min_args=1,
|
||||
help="Get information for a given vehicle",
|
||||
usage="<ID>")
|
||||
bot.events.on("received").on("command").on("tflstop"
|
||||
|
@ -44,7 +51,8 @@ class Module(object):
|
|||
help="Get information for a given stop",
|
||||
usage="<stop_id>")
|
||||
bot.events.on("received").on("command").on("tflservice"
|
||||
).hook(self.service, min_args=1,
|
||||
).hook(self.service,
|
||||
min_args=1,
|
||||
help="Get service information and arrival estimates",
|
||||
usage="<service index>")
|
||||
|
||||
|
@ -57,11 +65,15 @@ class Module(object):
|
|||
time_until = vehicle_due - datetime.datetime.utcnow()
|
||||
time_until = int(time_until.total_seconds() / 60)
|
||||
|
||||
if time_until == 0: human_time = "due"
|
||||
else: human_time = "in %s min" % time_until
|
||||
if time_until == 0:
|
||||
human_time = "due"
|
||||
else:
|
||||
human_time = "in %s min" % time_until
|
||||
|
||||
if human: return human_time
|
||||
else: return time_until
|
||||
if human:
|
||||
return human_time
|
||||
else:
|
||||
return time_until
|
||||
|
||||
def platform(self, platform, short=False):
|
||||
p = re.compile("(?:(.*) - Platform (\\d+)|(.*bound) Platform (\\d+))")
|
||||
|
@ -103,16 +115,23 @@ class Module(object):
|
|||
for bus in bus_stop:
|
||||
bus_number = bus["lineName"]
|
||||
human_time = self.vehicle_span(bus["expectedArrival"])
|
||||
time_until = self.vehicle_span(bus["expectedArrival"], human=False)
|
||||
time_until = self.vehicle_span(bus["expectedArrival"],
|
||||
human=False)
|
||||
|
||||
# If the mode is "tube", "Underground Station" is redundant
|
||||
destination = bus.get("destinationName", "?")
|
||||
if (bus["modeName"] == "tube"): destination = destination.replace(" Underground Station", "")
|
||||
if (bus[
|
||||
"modeName"] == "tube"): destination = destination.replace(
|
||||
" Underground Station", "")
|
||||
|
||||
busses.append({"route": bus_number, "time": time_until, "id": bus["vehicleId"],
|
||||
"destination": destination, "human_time": human_time, "mode": bus["modeName"],
|
||||
busses.append({"route": bus_number, "time": time_until,
|
||||
"id": bus["vehicleId"],
|
||||
"destination": destination,
|
||||
"human_time": human_time,
|
||||
"mode": bus["modeName"],
|
||||
"platform": bus["platformName"],
|
||||
"platform_short" : self.platform(bus["platformName"], short=True)})
|
||||
"platform_short": self.platform(
|
||||
bus["platformName"], short=True)})
|
||||
if busses:
|
||||
busses = sorted(busses, key=lambda b: b["time"])
|
||||
busses_filtered = []
|
||||
|
@ -122,11 +141,14 @@ class Module(object):
|
|||
# dedup if target route isn't "*", filter if target route isn't None or "*"
|
||||
for b in busses:
|
||||
if target_bus_route != "*":
|
||||
if (b["route"], b["destination"]) in bus_route_dest: continue
|
||||
if bus_route_plat.count((b["route"], b["platform"])) >= 2: continue
|
||||
if (b["route"],
|
||||
b["destination"]) in bus_route_dest: continue
|
||||
if bus_route_plat.count(
|
||||
(b["route"], b["platform"])) >= 2: continue
|
||||
bus_route_plat.append((b["route"], b["platform"]))
|
||||
bus_route_dest.append((b["route"], b["destination"]))
|
||||
if b["route"] == target_bus_route or not target_bus_route:
|
||||
if b[
|
||||
"route"] == target_bus_route or not target_bus_route:
|
||||
busses_filtered.append(b)
|
||||
else:
|
||||
busses_filtered.append(b)
|
||||
|
@ -134,7 +156,8 @@ class Module(object):
|
|||
self.result_map[event["target"].id] = busses_filtered
|
||||
|
||||
# do the magic formatty things!
|
||||
busses_string = ", ".join(["%s (%s, %s)" % (b["destination"], b["route"], b["human_time"],
|
||||
busses_string = ", ".join(["%s (%s, %s)" % (
|
||||
b["destination"], b["route"], b["human_time"],
|
||||
) for b in busses_filtered])
|
||||
|
||||
event["stdout"].write("%s (%s): %s" % (stop_name, stop_id,
|
||||
|
@ -177,7 +200,9 @@ class Module(object):
|
|||
for status in statuses:
|
||||
for arg in event["args_split"]:
|
||||
if arg.lower() in status["name"].lower():
|
||||
result += "%s: %s (%d) '%s'; " % (status["name"], status["description"], status["severity"], status["reason"])
|
||||
result += "%s: %s (%d) '%s'; " % (
|
||||
status["name"], status["description"],
|
||||
status["severity"], status["reason"])
|
||||
if result:
|
||||
event["stdout"].write(result[:-2])
|
||||
else:
|
||||
|
@ -191,12 +216,16 @@ class Module(object):
|
|||
stop_name = event["args"].replace(" ", "%20")
|
||||
|
||||
stop_search = Utils.get_url(URL_STOP_SEARCH % stop_name, get_params={
|
||||
"app_id": app_id, "app_key": app_key, "maxResults": "6", "faresOnly": "False"}, json=True)
|
||||
"app_id": app_id, "app_key": app_key, "maxResults": "6",
|
||||
"faresOnly": "False"}, json=True)
|
||||
if stop_search:
|
||||
for stop in stop_search["matches"]:
|
||||
pass
|
||||
results = ["%s (%s): %s" % (stop["name"], ", ".join(stop["modes"]), stop["id"]) for stop in stop_search["matches"]]
|
||||
event["stdout"].write("[%s results] %s" % (stop_search["total"], "; ".join(results)))
|
||||
results = ["%s (%s): %s" % (
|
||||
stop["name"], ", ".join(stop["modes"]), stop["id"]) for stop in
|
||||
stop_search["matches"]]
|
||||
event["stdout"].write(
|
||||
"[%s results] %s" % (stop_search["total"], "; ".join(results)))
|
||||
else:
|
||||
event["stderr"].write("No results")
|
||||
|
||||
|
@ -209,12 +238,16 @@ class Module(object):
|
|||
vehicle = Utils.get_url(URL_VEHICLE % vehicle_id, get_params={
|
||||
"app_id": app_id, "app_key": app_key}, json=True)[0]
|
||||
|
||||
arrival_time = self.vehicle_span(vehicle["expectedArrival"], human=False)
|
||||
arrival_time = self.vehicle_span(vehicle["expectedArrival"],
|
||||
human=False)
|
||||
platform = self.platform(vehicle["platformName"])
|
||||
|
||||
event["stdout"].write("%s (%s) to %s. %s. Arrival at %s (%s) in %s minutes on %s" % (
|
||||
vehicle["vehicleId"], vehicle["lineName"], vehicle["destinationName"], vehicle["currentLocation"],
|
||||
vehicle["stationName"], vehicle["naptanId"], arrival_time, platform))
|
||||
event["stdout"].write(
|
||||
"%s (%s) to %s. %s. Arrival at %s (%s) in %s minutes on %s" % (
|
||||
vehicle["vehicleId"], vehicle["lineName"],
|
||||
vehicle["destinationName"], vehicle["currentLocation"],
|
||||
vehicle["stationName"], vehicle["naptanId"], arrival_time,
|
||||
platform))
|
||||
|
||||
def service(self, event):
|
||||
app_id = self.bot.config["tfl-api-id"]
|
||||
|
@ -228,19 +261,25 @@ class Module(object):
|
|||
return
|
||||
results = self.result_map[event["target"].id]
|
||||
if int(service_id) >= len(results):
|
||||
event["stdout"].write("%s is too high. Remember that the first arrival is 0" % service_id)
|
||||
event["stdout"].write(
|
||||
"%s is too high. Remember that the first arrival is 0" % service_id)
|
||||
return
|
||||
service = results[int(service_id)]
|
||||
arrivals = Utils.get_url(URL_LINE_ARRIVALS % service["route"], get_params={
|
||||
"app_id": app_id, "app_key": app_key}, json=True)
|
||||
arrivals = Utils.get_url(URL_LINE_ARRIVALS % service["route"],
|
||||
get_params={
|
||||
"app_id": app_id, "app_key": app_key},
|
||||
json=True)
|
||||
|
||||
arrivals = [a for a in arrivals if a["vehicleId"] == service["id"]]
|
||||
arrivals = sorted(arrivals, key=lambda b: b["timeToStation"])
|
||||
|
||||
event["stdout"].write(
|
||||
"%s (%s) to %s: " % (arrivals[0]["vehicleId"], arrivals[0]["lineName"], arrivals[0]["destinationName"]) +
|
||||
"%s (%s) to %s: " % (
|
||||
arrivals[0]["vehicleId"], arrivals[0]["lineName"],
|
||||
arrivals[0]["destinationName"]) +
|
||||
", ".join(["%s (%s, %s)" %
|
||||
(a["stationName"], self.platform(a.get("platformName", "?"), True),
|
||||
(a["stationName"],
|
||||
self.platform(a.get("platformName", "?"), True),
|
||||
a["expectedArrival"][11:16]
|
||||
) for a in arrivals]))
|
||||
|
||||
|
|
|
@ -4,18 +4,21 @@ import Utils
|
|||
|
||||
URL_THESAURUS = "http://words.bighugelabs.com/api/2/%s/%s/json"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("synonym",
|
||||
"antonym").hook(self.thesaurus, min_args=1,
|
||||
"antonym").hook(
|
||||
self.thesaurus, min_args=1,
|
||||
help="Get synonyms/antonyms for a provided phrase",
|
||||
usage="<word> [type]")
|
||||
|
||||
def thesaurus(self, event):
|
||||
phrase = event["args_split"][0]
|
||||
page = Utils.get_url(URL_THESAURUS % (self.bot.config[
|
||||
"bighugethesaurus-api-key"], phrase), json=True)
|
||||
"bighugethesaurus-api-key"],
|
||||
phrase), json=True)
|
||||
syn_ant = event["command"][:3]
|
||||
if page:
|
||||
if not len(event["args_split"]) > 1:
|
||||
|
|
|
@ -3,6 +3,7 @@ import Utils
|
|||
|
||||
REGEX_URL = re.compile("https?://\S+", re.I)
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("title", "t").hook(
|
||||
|
@ -27,7 +28,8 @@ class Module(object):
|
|||
title = soup.title
|
||||
if title:
|
||||
title = title.text.replace("\n", " ").replace("\r", ""
|
||||
).replace(" ", " ").strip()
|
||||
).replace(" ",
|
||||
" ").strip()
|
||||
event["stdout"].write(title)
|
||||
else:
|
||||
event["stderr"].write("No title found.")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import EventManager
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("message").on("channel"
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -16,17 +14,21 @@ class Module(object):
|
|||
def todo(self, event):
|
||||
todo = event["user"].get_setting("todo", [])
|
||||
if event["args"]:
|
||||
if event["args_split"][0].isdigit() and int(event["args_split"][0]) > 0:
|
||||
if event["args_split"][0].isdigit() and int(
|
||||
event["args_split"][0]) > 0:
|
||||
index = int(event["args_split"][0])
|
||||
if len(todo) >= index:
|
||||
event["stdout"].write("Todo %d: %s" % (index, todo[index-1]))
|
||||
event["stdout"].write(
|
||||
"Todo %d: %s" % (index, todo[index - 1]))
|
||||
else:
|
||||
event["stderr"].write("You do not have that many things in your todo")
|
||||
event["stderr"].write(
|
||||
"You do not have that many things in your todo")
|
||||
else:
|
||||
event["stderr"].write("Please provide a number")
|
||||
else:
|
||||
todo_count = len(todo)
|
||||
event["stdout"].write("There are %d items in your todo" % todo_count)
|
||||
event["stdout"].write(
|
||||
"There are %d items in your todo" % todo_count)
|
||||
|
||||
def todo_add(self, event):
|
||||
arg_lower = event["args"].lower()
|
||||
|
@ -52,4 +54,5 @@ class Module(object):
|
|||
event["stderr"].write("You do not have that many things in "
|
||||
"your todo")
|
||||
else:
|
||||
event["stderr"].write("Please provided a todo item number to remove")
|
||||
event["stderr"].write(
|
||||
"Please provided a todo item number to remove")
|
||||
|
|
|
@ -5,16 +5,19 @@ import Utils
|
|||
URL_TRAKT = "https://api-v2launch.trakt.tv/users/%s/watching"
|
||||
URL_TRAKTSLUG = "https://trakt.tv/%s/%s"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("nowwatching",
|
||||
"nw").hook(self.now_watching,
|
||||
help="Get what you or another user is now watching "
|
||||
"on trakt.tv", usage="[username]")
|
||||
"on trakt.tv",
|
||||
usage="[username]")
|
||||
|
||||
bot.events.on("postboot").on("configure").on("set"
|
||||
).assure_call(setting="trakt", help="Set username on trakt.tv")
|
||||
).assure_call(
|
||||
setting="trakt", help="Set username on trakt.tv")
|
||||
|
||||
def now_watching(self, event):
|
||||
if event["args"]:
|
||||
|
|
|
@ -5,6 +5,7 @@ URL_TRANSLATE = "http://translate.googleapis.com/translate_a/single"
|
|||
URL_LANGUAGES = "https://cloud.google.com/translate/docs/languages"
|
||||
REGEX_LANGUAGES = re.compile("(\w+)?:(\w+)? ")
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("translate", "tr").hook(
|
||||
|
@ -47,4 +48,3 @@ class Module(object):
|
|||
else:
|
||||
event["stderr"].write("Failed to translate, try checking "
|
||||
"source/target languages (" + URL_LANGUAGES + ")")
|
||||
|
||||
|
|
|
@ -10,11 +10,13 @@ import Utils
|
|||
REGEX_TWITTERURL = re.compile(
|
||||
"https?://(?:www\.)?twitter.com/[^/]+/status/(\d+)", re.I)
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("twitter", "tw"
|
||||
).hook(self.twitter, help="Find a tweet",
|
||||
).hook(self.twitter,
|
||||
help="Find a tweet",
|
||||
usage="[@username/URL/ID]")
|
||||
|
||||
def make_timestamp(self, s):
|
||||
|
@ -64,13 +66,17 @@ class Module(object):
|
|||
retweet_timestamp = self.make_timestamp(tweet[
|
||||
"created_at"])
|
||||
original_timestamp = self.make_timestamp(tweet[
|
||||
"retweeted_status"]["created_at"])
|
||||
"retweeted_status"][
|
||||
"created_at"])
|
||||
event["stdout"].write("(%s (%s) retweeted %s (%s)) %s" % (
|
||||
username, retweet_timestamp,
|
||||
original_username, original_timestamp, original_text))
|
||||
else:
|
||||
event["stdout"].write("(%s, %s) %s" % (username,
|
||||
self.make_timestamp(tweet["created_at"]), tweet["text"]))
|
||||
self.make_timestamp(
|
||||
tweet[
|
||||
"created_at"]),
|
||||
tweet["text"]))
|
||||
else:
|
||||
event["stderr"].write("Invalid tweet identifiers provided")
|
||||
else:
|
||||
|
|
|
@ -2,8 +2,10 @@ import Utils
|
|||
|
||||
UPCITEMDB_URL = "https://api.upcitemdb.com/prod/trial/lookup"
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "UPC"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on(
|
||||
|
@ -48,6 +50,7 @@ class Module(object):
|
|||
|
||||
event["stdout"].write("%s%s%s(weight: %s"
|
||||
", size: %s, price: %s)" % (
|
||||
brand, title, description, weight, size, pricing))
|
||||
brand, title, description, weight, size,
|
||||
pricing))
|
||||
else:
|
||||
event["stderr"].write("Failed to load results")
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
URL_URBANDICTIONARY = "http://api.urbandictionary.com/v0/define"
|
||||
REGEX_DEFNUMBER = re.compile("-n(\d+) \S+")
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("urbandictionary", "ud"
|
||||
|
@ -25,8 +26,11 @@ class Module(object):
|
|||
if number > 0 and len(page["list"]) > number - 1:
|
||||
definition = page["list"][number - 1]
|
||||
event["stdout"].write("%s: %s" % (definition["word"],
|
||||
definition["definition"].replace("\n", " ").replace(
|
||||
"\r", "").replace(" ", " ")))
|
||||
definition[
|
||||
"definition"].replace(
|
||||
"\n", " ").replace(
|
||||
"\r", "").replace(
|
||||
" ", " ")))
|
||||
else:
|
||||
event["stderr"].write("Definition number does not exist")
|
||||
else:
|
||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
|||
|
||||
URL_WEATHER = "http://api.openweathermap.org/data/2.5/weather"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -33,6 +34,7 @@ class Module(object):
|
|||
location, celsius, fahrenheit, description, humidity,
|
||||
wind_speed))
|
||||
else:
|
||||
event["stderr"].write("No weather information for this location")
|
||||
event["stderr"].write(
|
||||
"No weather information for this location")
|
||||
else:
|
||||
event["stderr"].write("Failed to load results")
|
||||
|
|
|
@ -2,11 +2,13 @@ import Utils
|
|||
|
||||
URL_WIKIPEDIA = "https://en.wikipedia.org/w/api.php"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("wiki", "wi"
|
||||
).hook(self.wikipedia, min_args=1)
|
||||
).hook(self.wikipedia,
|
||||
min_args=1)
|
||||
|
||||
def wikipedia(self, event):
|
||||
page = Utils.get_url(URL_WIKIPEDIA, get_params={
|
||||
|
@ -25,4 +27,3 @@ class Module(object):
|
|||
event["stderr"].write("No results found")
|
||||
else:
|
||||
event["stderr"].write("Failed to load results")
|
||||
|
||||
|
|
|
@ -6,19 +6,25 @@ import Utils
|
|||
URL_WA = "http://api.wolframalpha.com/v2/query"
|
||||
REGEX_CHARHEX = re.compile("\\\\:(\S{4})")
|
||||
|
||||
|
||||
class Module(object):
|
||||
_name = "Wolfram|Alpha"
|
||||
|
||||
def __init__(self, bot):
|
||||
bot.events.on("received").on("command").on("wolframalpha", "wa"
|
||||
).hook(self.wa, min_args=1, help=
|
||||
).hook(self.wa, min_args=1,
|
||||
help=
|
||||
"Evauate a given string on Wolfram|Alpha",
|
||||
usage="<query>")
|
||||
self.bot = bot
|
||||
|
||||
def wa(self, event):
|
||||
soup = Utils.get_url(URL_WA, get_params={"input": event["args"],
|
||||
"appid": self.bot.config["wolframalpha-api-key"],
|
||||
"format": "plaintext", "reinterpret": "true"}, soup=True)
|
||||
"appid": self.bot.config[
|
||||
"wolframalpha-api-key"],
|
||||
"format": "plaintext",
|
||||
"reinterpret": "true"},
|
||||
soup=True)
|
||||
|
||||
if soup:
|
||||
if int(soup.find("queryresult").get("numpods")) > 0:
|
||||
|
@ -29,8 +35,10 @@ class Module(object):
|
|||
if pod.get("primary") == "true":
|
||||
answer = pod.find("subpod").find("plaintext")
|
||||
text = "(%s) %s" % (input.replace(" | ", ": "),
|
||||
answer.text.strip().replace(" | ", ": "
|
||||
).replace("\n", " | ").replace("\r", ""))
|
||||
answer.text.strip().replace(" | ",
|
||||
": "
|
||||
).replace(
|
||||
"\n", " | ").replace("\r", ""))
|
||||
while True:
|
||||
match = re.search(REGEX_CHARHEX, text)
|
||||
if match:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import time
|
||||
import Utils
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
@ -9,15 +10,20 @@ class Module(object):
|
|||
bot.events.on("self").on("message").on("channel"
|
||||
).hook(self.self_channel_message)
|
||||
bot.events.on("received").on("command").on("words"
|
||||
).hook(self.words, channel_only=True,
|
||||
usage="<nickname>", help=
|
||||
).hook(self.words,
|
||||
channel_only=True,
|
||||
usage="<nickname>",
|
||||
help=
|
||||
"See how many words you or the given nickname have used")
|
||||
bot.events.on("received").on("command").on("trackword"
|
||||
).hook(self.track_word, min_args=1,
|
||||
help="Start tracking a word", usage="<word>",
|
||||
).hook(self.track_word,
|
||||
min_args=1,
|
||||
help="Start tracking a word",
|
||||
usage="<word>",
|
||||
permission="track-word")
|
||||
bot.events.on("received").on("command").on("wordusers"
|
||||
).hook(self.word_users, min_args=1,
|
||||
).hook(self.word_users,
|
||||
min_args=1,
|
||||
help="Show who has used a tracked word the most",
|
||||
usage="<word>")
|
||||
|
||||
|
@ -43,8 +49,10 @@ class Module(object):
|
|||
word_count = user.get_setting(setting, 0)
|
||||
word_count += 1
|
||||
user.set_setting(setting, word_count)
|
||||
|
||||
def channel_message(self, event):
|
||||
self._channel_message(event["user"], event)
|
||||
|
||||
def self_channel_message(self, event):
|
||||
self._channel_message(event["server"].get_user(
|
||||
event["server"].nickname), event)
|
||||
|
@ -86,7 +94,8 @@ class Module(object):
|
|||
top_10 = sorted(word_users.keys())
|
||||
top_10 = sorted(top_10, key=word_users.get, reverse=True)[:10]
|
||||
top_10 = ", ".join("%s (%d)" % (Utils.prevent_highlight(event[
|
||||
"server"].get_user(nickname).nickname), word_users[nickname]
|
||||
"server"].get_user(
|
||||
nickname).nickname), word_users[nickname]
|
||||
) for nickname in top_10)
|
||||
event["stdout"].write("Top '%s' users: %s" % (word, top_10))
|
||||
else:
|
||||
|
|
|
@ -16,12 +16,14 @@ URL_YOUTUBESHORT = "https://youtu.be/%s"
|
|||
ARROW_UP = "▲"
|
||||
ARROW_DOWN = "▼"
|
||||
|
||||
|
||||
class Module(object):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
bot.events.on("received").on("command").on("yt", "youtube"
|
||||
).hook(self.yt,
|
||||
help="Find a video on youtube", usage="[query]")
|
||||
help="Find a video on youtube",
|
||||
usage="[query]")
|
||||
bot.events.on("received").on("message").on("channel").hook(
|
||||
self.channel_message)
|
||||
|
||||
|
@ -30,11 +32,14 @@ class Module(object):
|
|||
help="Disable/Enable automatically getting info from youtube URLs",
|
||||
validate=Utils.bool_or_none)
|
||||
|
||||
|
||||
def get_video_page(self, video_id, part):
|
||||
return Utils.get_url(URL_YOUTUBEVIDEO, get_params={"part": part,
|
||||
"id": video_id, "key": self.bot.config["google-api-key"]},
|
||||
"id": video_id,
|
||||
"key":
|
||||
self.bot.config[
|
||||
"google-api-key"]},
|
||||
json=True)
|
||||
|
||||
def video_details(self, video_id):
|
||||
snippet = self.get_video_page(video_id, "snippet")
|
||||
if snippet["items"]:
|
||||
|
@ -57,14 +62,18 @@ class Module(object):
|
|||
match = re.match(REGEX_ISO8601, video_duration)
|
||||
video_duration = ""
|
||||
video_duration += "%s:" % match.group(1)[:-1].zfill(2
|
||||
) if match.group(1) else ""
|
||||
) if match.group(
|
||||
1) else ""
|
||||
video_duration += "%s:" % match.group(2)[:-1].zfill(2
|
||||
) if match.group(2) else "00:"
|
||||
) if match.group(
|
||||
2) else "00:"
|
||||
video_duration += "%s" % match.group(3)[:-1].zfill(2
|
||||
) if match.group(3) else "00"
|
||||
) if match.group(
|
||||
3) else "00"
|
||||
return "%s (%s) uploaded by %s, %s views%s %s" % (
|
||||
video_title, video_duration, video_uploader, "{:,}".format(
|
||||
int(video_views)), video_opinions, URL_YOUTUBESHORT % video_id)
|
||||
int(video_views)), video_opinions,
|
||||
URL_YOUTUBESHORT % video_id)
|
||||
|
||||
def yt(self, event):
|
||||
video_id = None
|
||||
|
@ -74,13 +83,17 @@ class Module(object):
|
|||
else:
|
||||
last_youtube = event["buffer"].find(REGEX_YOUTUBE)
|
||||
if last_youtube:
|
||||
video_id = re.search(REGEX_YOUTUBE, last_youtube.message).group(1)
|
||||
video_id = re.search(REGEX_YOUTUBE, last_youtube.message).group(
|
||||
1)
|
||||
if search or video_id:
|
||||
if not video_id:
|
||||
search_page = Utils.get_url(URL_YOUTUBESEARCH,
|
||||
get_params={"q": search, "part": "snippet",
|
||||
"maxResults": "1", "type": "video",
|
||||
"key": self.bot.config["google-api-key"]},
|
||||
get_params={"q": search,
|
||||
"part": "snippet",
|
||||
"maxResults": "1",
|
||||
"type": "video",
|
||||
"key": self.bot.config[
|
||||
"google-api-key"]},
|
||||
json=True)
|
||||
if search_page:
|
||||
if search_page["pageInfo"]["totalResults"] > 0:
|
||||
|
@ -104,4 +117,5 @@ class Module(object):
|
|||
if video_details:
|
||||
self.bot.events.on("send").on("stdout").call(target=event[
|
||||
"channel"], message=video_details, module_name="Youtube",
|
||||
server=event["server"])
|
||||
server=event[
|
||||
"server"])
|
||||
|
|
Loading…
Reference in a new issue