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):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("invite").hook(
|
bot.events.on("received").on("invite").hook(
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("changenickname"
|
bot.events.on("received").on("command").on("changenickname"
|
||||||
).hook(self.change_nickname, permission="changenickname",
|
).hook(self.change_nickname,
|
||||||
min_args=1, help="Change my nickname", usage="<nickname>")
|
permission="changenickname",
|
||||||
|
min_args=1,
|
||||||
|
help="Change my nickname",
|
||||||
|
usage="<nickname>")
|
||||||
bot.events.on("received").on("command").on("raw"
|
bot.events.on("received").on("command").on("raw"
|
||||||
).hook(self.raw, permission="raw", min_args=1,
|
).hook(self.raw,
|
||||||
help="Send a raw IRC line through the bot",
|
permission="raw",
|
||||||
usage="<raw line>")
|
min_args=1,
|
||||||
|
help="Send a raw IRC line through the bot",
|
||||||
|
usage="<raw line>")
|
||||||
bot.events.on("received").on("command").on("part"
|
bot.events.on("received").on("command").on("part"
|
||||||
).hook(self.part, permission="part", min_args=1,
|
).hook(self.part,
|
||||||
help="Part from a channel",
|
permission="part",
|
||||||
usage="<#channel>")
|
min_args=1,
|
||||||
|
help="Part from a channel",
|
||||||
|
usage="<#channel>")
|
||||||
|
|
||||||
def change_nickname(self, event):
|
def change_nickname(self, event):
|
||||||
nickname = event["args_split"][0]
|
nickname = event["args_split"][0]
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="automode",
|
"channelset").assure_call(setting="automode",
|
||||||
help="Disable/Enable automode",
|
help="Disable/Enable automode",
|
||||||
validate=Utils.bool_or_none)
|
validate=Utils.bool_or_none)
|
||||||
|
|
||||||
bot.events.on("channel").on("mode").hook(self.on_mode)
|
bot.events.on("channel").on("mode").hook(self.on_mode)
|
||||||
bot.events.on("received").on("join").hook(self.on_join)
|
bot.events.on("received").on("join").hook(self.on_join)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "BTC"
|
_name = "BTC"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("btc").hook(
|
bot.events.on("received").on("command").on("btc").hook(
|
||||||
|
@ -11,15 +13,16 @@ class Module(object):
|
||||||
def btc(self, event):
|
def btc(self, event):
|
||||||
currency = (event["args"] or "USD").upper()
|
currency = (event["args"] or "USD").upper()
|
||||||
page = Utils.get_url("https://blockchain.info/ticker",
|
page = Utils.get_url("https://blockchain.info/ticker",
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if currency in page:
|
if currency in page:
|
||||||
conversion = page[currency]
|
conversion = page[currency]
|
||||||
buy, sell = conversion["buy"], conversion["sell"]
|
buy, sell = conversion["buy"], conversion["sell"]
|
||||||
event["stdout"].write("1 BTC = %.2f %s (buy) %.2f %s "
|
event["stdout"].write("1 BTC = %.2f %s (buy) %.2f %s "
|
||||||
"(sell)" % (buy, currency, sell, currency))
|
"(sell)" % (
|
||||||
|
buy, currency, sell, currency))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Unknown currency, available "
|
event["stderr"].write("Unknown currency, available "
|
||||||
"currencies: %s" % ", ".join(page.keys()))
|
"currencies: %s" % ", ".join(page.keys()))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#--require-config bitly-api-key
|
# --require-config bitly-api-key
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import Utils
|
import Utils
|
||||||
|
@ -6,13 +6,16 @@ import Utils
|
||||||
URL_BITLYSHORTEN = "https://api-ssl.bitly.com/v3/shorten"
|
URL_BITLYSHORTEN = "https://api-ssl.bitly.com/v3/shorten"
|
||||||
REGEX_URL = re.compile("https?://", re.I)
|
REGEX_URL = re.compile("https?://", re.I)
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("get").on("shortlink").hook(self.shortlink)
|
bot.events.on("get").on("shortlink").hook(self.shortlink)
|
||||||
bot.events.on("received").on("command").on("shorten"
|
bot.events.on("received").on("command").on("shorten"
|
||||||
).hook(self.shorten, min_args=1, help="Shorten a URL.",
|
).hook(self.shorten,
|
||||||
usage="<url>")
|
min_args=1,
|
||||||
|
help="Shorten a URL.",
|
||||||
|
usage="<url>")
|
||||||
|
|
||||||
def shortlink(self, event):
|
def shortlink(self, event):
|
||||||
url = event["url"]
|
url = event["url"]
|
||||||
|
@ -26,7 +29,7 @@ class Module(object):
|
||||||
|
|
||||||
def shorten(self, event):
|
def shorten(self, event):
|
||||||
link = self.bot.events.on("get").on("shortlink"
|
link = self.bot.events.on("get").on("shortlink"
|
||||||
).call_for_result(url=event["args"])
|
).call_for_result(url=event["args"])
|
||||||
if link:
|
if link:
|
||||||
event["stdout"].write("Short URL: %s" % link)
|
event["stdout"].write("Short URL: %s" % link)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -5,8 +5,10 @@ URL_GOOGLEBOOKS = "https://www.googleapis.com/books/v1/volumes"
|
||||||
URL_BOOKINFO = "https://books.google.co.uk/books?id=%s"
|
URL_BOOKINFO = "https://books.google.co.uk/books?id=%s"
|
||||||
REGEX_BOOKID = re.compile("id=([\w\-]+)")
|
REGEX_BOOKID = re.compile("id=([\w\-]+)")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "ISBN"
|
_name = "ISBN"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("isbn").hook(
|
bot.events.on("received").on("command").on("isbn").hook(
|
||||||
|
@ -24,7 +26,7 @@ class Module(object):
|
||||||
book = page["items"][0]["volumeInfo"]
|
book = page["items"][0]["volumeInfo"]
|
||||||
title = book["title"]
|
title = book["title"]
|
||||||
sub_title = (", %s" % book.get("subtitle")
|
sub_title = (", %s" % book.get("subtitle")
|
||||||
) if book.get("subtitle") else ""
|
) if book.get("subtitle") else ""
|
||||||
|
|
||||||
authors = ", ".join(book.get("authors", []))
|
authors = ", ".join(book.get("authors", []))
|
||||||
authors = " - %s" % authors if authors else ""
|
authors = " - %s" % authors if authors else ""
|
||||||
|
|
|
@ -1,60 +1,88 @@
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "Channel Op"
|
_name = "Channel Op"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("kick", "k"
|
bot.events.on("received").on("command").on("kick", "k"
|
||||||
).hook(self.kick, channel_only=True, require_mode="o",
|
).hook(self.kick,
|
||||||
min_args=1, help="Kick a user from the channel",
|
channel_only=True,
|
||||||
usage="<nickname> [reason]")
|
require_mode="o",
|
||||||
|
min_args=1,
|
||||||
|
help="Kick a user from the channel",
|
||||||
|
usage="<nickname> [reason]")
|
||||||
|
|
||||||
bot.events.on("received").on("command").on("ban"
|
bot.events.on("received").on("command").on("ban"
|
||||||
).hook(self.ban, channel_only=True, require_mode="o",
|
).hook(self.ban,
|
||||||
min_args=1, help="Ban a user/hostmask from the channel",
|
channel_only=True,
|
||||||
usage="<nickname/hostmask>")
|
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"
|
bot.events.on("received").on("command").on("unban"
|
||||||
).hook(self.unban, channel_only=True, require_mode="o",
|
).hook(self.unban,
|
||||||
min_args=1, help="Unban a user/hostmask from the channel",
|
channel_only=True,
|
||||||
usage="<nickname/hostmask>")
|
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"
|
bot.events.on("received").on("command").on("kickban", "kb"
|
||||||
).hook(self.kickban, channel_only=True, require_mode="o",
|
).hook(self.kickban,
|
||||||
min_args=1, help="Kickban a user from the channel",
|
channel_only=True,
|
||||||
usage="<nickanme> [reason]")
|
require_mode="o",
|
||||||
|
min_args=1,
|
||||||
|
help="Kickban a user from the channel",
|
||||||
|
usage="<nickanme> [reason]")
|
||||||
|
|
||||||
bot.events.on("received").on("command").on("op"
|
bot.events.on("received").on("command").on("op"
|
||||||
).hook(self.op, channel_only=True, require_mode="o",
|
).hook(self.op,
|
||||||
help="Give +o to a user", usage="[nickname]")
|
channel_only=True,
|
||||||
|
require_mode="o",
|
||||||
|
help="Give +o to a user",
|
||||||
|
usage="[nickname]")
|
||||||
bot.events.on("received").on("command").on("deop"
|
bot.events.on("received").on("command").on("deop"
|
||||||
).hook(self.deop, channel_only=True, require_mode="o",
|
).hook(self.deop,
|
||||||
help="Take +o from a user", usage="[nickname]")
|
channel_only=True,
|
||||||
|
require_mode="o",
|
||||||
|
help="Take +o from a user",
|
||||||
|
usage="[nickname]")
|
||||||
|
|
||||||
bot.events.on("received").on("command").on("voice"
|
bot.events.on("received").on("command").on("voice"
|
||||||
).hook(self.voice, channel_only=True, require_mode="o",
|
).hook(self.voice,
|
||||||
help="Give +v to a user", usage="[nickname]")
|
channel_only=True,
|
||||||
|
require_mode="o",
|
||||||
|
help="Give +v to a user",
|
||||||
|
usage="[nickname]")
|
||||||
bot.events.on("received").on("command").on("devoice"
|
bot.events.on("received").on("command").on("devoice"
|
||||||
).hook(self.devoice, channel_only=True, require_mode="o",
|
).hook(self.devoice,
|
||||||
help="Take +v from a user", usage="[nickname]")
|
channel_only=True,
|
||||||
|
require_mode="o",
|
||||||
|
help="Take +v from a user",
|
||||||
|
usage="[nickname]")
|
||||||
|
|
||||||
bot.events.on("received").on("message").on("channel").hook(
|
bot.events.on("received").on("message").on("channel").hook(
|
||||||
self.highlight_spam)
|
self.highlight_spam)
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="highlight-spam-threshold",
|
"channelset").assure_call(setting="highlight-spam-threshold",
|
||||||
help="Set the number of nicknames in a message that "
|
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(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="highlight-spam-protection",
|
"channelset").assure_call(setting="highlight-spam-protection",
|
||||||
help="Enable/Disable highlight spam protection",
|
help="Enable/Disable highlight spam protection",
|
||||||
validate=Utils.bool_or_none)
|
validate=Utils.bool_or_none)
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="highlight-spam-ban",
|
"channelset").assure_call(setting="highlight-spam-ban",
|
||||||
help="Enable/Disable banning highlight spammers "
|
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(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="ban-format",
|
"channelset").assure_call(setting="ban-format",
|
||||||
help="Set ban format ($n = nick, $u = username, $h = hostname)")
|
help="Set ban format ($n = nick, $u = username, $h = hostname)")
|
||||||
|
|
||||||
def kick(self, event):
|
def kick(self, event):
|
||||||
target = event["args_split"][0]
|
target = event["args_split"][0]
|
||||||
|
@ -74,7 +102,9 @@ class Module(object):
|
||||||
|
|
||||||
def _ban_format(self, user, s):
|
def _ban_format(self, user, s):
|
||||||
return s.replace("$n", user.nickname).replace("$u", user.username
|
return s.replace("$n", user.nickname).replace("$u", user.username
|
||||||
).replace("$h", user.hostname)
|
).replace("$h",
|
||||||
|
user.hostname)
|
||||||
|
|
||||||
def _ban(self, channel, ban, user):
|
def _ban(self, channel, ban, user):
|
||||||
format = channel.get_setting("ban-format", "*!$u@$h")
|
format = channel.get_setting("ban-format", "*!$u@$h")
|
||||||
hostmask_split = format.split("$$")
|
hostmask_split = format.split("$$")
|
||||||
|
@ -84,12 +114,14 @@ class Module(object):
|
||||||
channel.send_ban(hostmask)
|
channel.send_ban(hostmask)
|
||||||
else:
|
else:
|
||||||
channel.send_unban(hostmask)
|
channel.send_unban(hostmask)
|
||||||
|
|
||||||
def ban(self, event):
|
def ban(self, event):
|
||||||
target_user = event["server"].get_user(event["args_split"][0])
|
target_user = event["server"].get_user(event["args_split"][0])
|
||||||
if event["target"].has_user(target_user):
|
if event["target"].has_user(target_user):
|
||||||
self._ban(event["target"], True, target_user)
|
self._ban(event["target"], True, target_user)
|
||||||
else:
|
else:
|
||||||
event["target"].send_ban(event["args_split"][0])
|
event["target"].send_ban(event["args_split"][0])
|
||||||
|
|
||||||
def unban(self, event):
|
def unban(self, event):
|
||||||
target_user = event["server"].get_user(event["args_split"][0])
|
target_user = event["server"].get_user(event["args_split"][0])
|
||||||
if event["target"].has_user(target_user):
|
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[
|
target = event["user"].nickname if not event["args_split"] else event[
|
||||||
"args_split"][0]
|
"args_split"][0]
|
||||||
event["target"].send_mode("+o", target)
|
event["target"].send_mode("+o", target)
|
||||||
|
|
||||||
def deop(self, event):
|
def deop(self, event):
|
||||||
target = event["user"].nickname if not event["args_split"] else event[
|
target = event["user"].nickname if not event["args_split"] else event[
|
||||||
"args_split"][0]
|
"args_split"][0]
|
||||||
event["target"].send_mode("-o", target)
|
event["target"].send_mode("-o", target)
|
||||||
|
|
||||||
def voice(self, event):
|
def voice(self, event):
|
||||||
target = event["user"].nickname if not event["args_split"] else event[
|
target = event["user"].nickname if not event["args_split"] else event[
|
||||||
"args_split"][0]
|
"args_split"][0]
|
||||||
event["target"].send_mode("+v", target)
|
event["target"].send_mode("+v", target)
|
||||||
|
|
||||||
def devoice(self, event):
|
def devoice(self, event):
|
||||||
target = event["user"].nickname if not event["args_split"] else event[
|
target = event["user"].nickname if not event["args_split"] else event[
|
||||||
"args_split"][0]
|
"args_split"][0]
|
||||||
|
@ -124,17 +159,18 @@ class Module(object):
|
||||||
def highlight_spam(self, event):
|
def highlight_spam(self, event):
|
||||||
if event["channel"].get_setting("highlight-spam-protection", False):
|
if event["channel"].get_setting("highlight-spam-protection", False):
|
||||||
nicknames = list(map(lambda user: user.nickname,
|
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"])
|
highlights = set(nicknames) & set(event["message_split"])
|
||||||
if len(highlights) > 1 and len(highlights) >= event["channel"
|
if len(highlights) > 1 and len(highlights) >= event["channel"
|
||||||
].get_setting("highlight-spam-threshold", 10):
|
].get_setting("highlight-spam-threshold", 10):
|
||||||
has_mode = event["channel"].mode_or_above(event["user"], "v")
|
has_mode = event["channel"].mode_or_above(event["user"], "v")
|
||||||
should_ban = event["channel"].get_setting("highlight-spam-ban",
|
should_ban = event["channel"].get_setting("highlight-spam-ban",
|
||||||
False)
|
False)
|
||||||
if not has_mode:
|
if not has_mode:
|
||||||
if should_ban:
|
if should_ban:
|
||||||
event["channel"].send_ban("*!%s@%s" % (
|
event["channel"].send_ban("*!%s@%s" % (
|
||||||
event["user"].username, event["user"].hostname))
|
event["user"].username, event["user"].hostname))
|
||||||
event["channel"].send_kick(event["user"].nickname,
|
event["channel"].send_kick(event["user"].nickname,
|
||||||
"highlight spam detected")
|
"highlight spam detected")
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received.numeric.001").hook(
|
bot.events.on("received.numeric.001").hook(
|
||||||
|
@ -8,14 +6,15 @@ class Module(object):
|
||||||
bot.events.on("self.kick").hook(self.on_kick)
|
bot.events.on("self.kick").hook(self.on_kick)
|
||||||
|
|
||||||
def on_connect(self, event):
|
def on_connect(self, event):
|
||||||
channels = event["server"].get_setting("autojoin", [])
|
channels = event["server"].get_setting("autojoin", [])
|
||||||
chan_keys = event["server"].get_setting("channel_keys", {})
|
chan_keys = event["server"].get_setting("channel_keys", {})
|
||||||
channels_sorted = sorted(channels,
|
channels_sorted = sorted(channels,
|
||||||
key=lambda x: 0 if x in chan_keys else 1)
|
key=lambda x: 0 if x in chan_keys else 1)
|
||||||
|
|
||||||
keys_sorted = list(map(lambda x: x[1],
|
keys_sorted = list(map(lambda x: x[1],
|
||||||
sorted(chan_keys.items(),
|
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)):
|
for i in range(len(channels_sorted)):
|
||||||
channel = channels_sorted[i]
|
channel = channels_sorted[i]
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -11,5 +9,5 @@ class Module(object):
|
||||||
"require_mode"):
|
"require_mode"):
|
||||||
required_mode = event["hook"].kwargs.get("require_mode")[0]
|
required_mode = event["hook"].kwargs.get("require_mode")[0]
|
||||||
if not event["target"].mode_or_above(event["user"],
|
if not event["target"].mode_or_above(event["user"],
|
||||||
required_mode):
|
required_mode):
|
||||||
return "You do not have permission to do this"
|
return "You do not have permission to do this"
|
||||||
|
|
130
modules/coins.py
130
modules/coins.py
|
@ -2,10 +2,10 @@ import datetime, decimal, math, random, re, time
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
SIDES = {"heads": 0, "tails": 1}
|
SIDES = {"heads": 0, "tails": 1}
|
||||||
DEFAULT_REDEEM_DELAY = 600 # 600 seconds, 10 minutes
|
DEFAULT_REDEEM_DELAY = 600 # 600 seconds, 10 minutes
|
||||||
DEFAULT_REDEEM_AMOUNT = "100.0"
|
DEFAULT_REDEEM_AMOUNT = "100.0"
|
||||||
DEFAULT_INTEREST_RATE = "0.01"
|
DEFAULT_INTEREST_RATE = "0.01"
|
||||||
INTEREST_INTERVAL = 60*60 # 1 hour
|
INTEREST_INTERVAL = 60 * 60 # 1 hour
|
||||||
DECIMAL_ZERO = decimal.Decimal("0")
|
DECIMAL_ZERO = decimal.Decimal("0")
|
||||||
REGEX_FLOAT = re.compile("\d+(?:\.\d{1,2}|$)")
|
REGEX_FLOAT = re.compile("\d+(?:\.\d{1,2}|$)")
|
||||||
|
|
||||||
|
@ -25,11 +25,12 @@ THIRD_COLUMN = list(range(1, 37))[2::3]
|
||||||
|
|
||||||
REGEX_STREET = re.compile("street([1-9]|1[0-2])$")
|
REGEX_STREET = re.compile("street([1-9]|1[0-2])$")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received.command.coins").hook(self.coins,
|
bot.events.on("received.command.coins").hook(self.coins,
|
||||||
help="Show how many coins you have")
|
help="Show how many coins you have")
|
||||||
bot.events.on("received").on("command").on("resetcoins").hook(
|
bot.events.on("received").on("command").on("resetcoins").hook(
|
||||||
self.reset_coins, permission="resetcoins",
|
self.reset_coins, permission="resetcoins",
|
||||||
min_args=1, help=
|
min_args=1, help=
|
||||||
|
@ -40,8 +41,11 @@ class Module(object):
|
||||||
bot.events.on("received.command.redeemcoins").hook(
|
bot.events.on("received.command.redeemcoins").hook(
|
||||||
self.redeem_coins, help="Redeem free coins")
|
self.redeem_coins, help="Redeem free coins")
|
||||||
bot.events.on("received.command.flip").hook(self.flip,
|
bot.events.on("received.command.flip").hook(self.flip,
|
||||||
help="Bet coins on a coin flip", usage=
|
help="Bet coins on a coin flip",
|
||||||
"heads|tails <coin amount>", min_args=2, protect_registered=True)
|
usage=
|
||||||
|
"heads|tails <coin amount>",
|
||||||
|
min_args=2,
|
||||||
|
protect_registered=True)
|
||||||
bot.events.on("received.command.sendcoins").hook(
|
bot.events.on("received.command.sendcoins").hook(
|
||||||
self.send, min_args=2, help="Send coins to a user",
|
self.send, min_args=2, help="Send coins to a user",
|
||||||
usage="<nickname> <amount>", authenticated=True)
|
usage="<nickname> <amount>", authenticated=True)
|
||||||
|
@ -50,12 +54,12 @@ class Module(object):
|
||||||
usage="<type> <amount>", protect_registered=True)
|
usage="<type> <amount>", protect_registered=True)
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
until_next_hour = 60-now.second
|
until_next_hour = 60 - now.second
|
||||||
until_next_hour += ((60-(now.minute+1))*60)
|
until_next_hour += ((60 - (now.minute + 1)) * 60)
|
||||||
|
|
||||||
bot.events.on("timer").on("coin-interest").hook(self.interest)
|
bot.events.on("timer").on("coin-interest").hook(self.interest)
|
||||||
bot.add_timer("coin-interest", INTEREST_INTERVAL, persist=False,
|
bot.add_timer("coin-interest", INTEREST_INTERVAL, persist=False,
|
||||||
next_due=time.time()+until_next_hour)
|
next_due=time.time() + until_next_hour)
|
||||||
|
|
||||||
def coins(self, event):
|
def coins(self, event):
|
||||||
if event["args_split"]:
|
if event["args_split"]:
|
||||||
|
@ -64,7 +68,8 @@ class Module(object):
|
||||||
target = event["user"]
|
target = event["user"]
|
||||||
coins = decimal.Decimal(target.get_setting("coins", "0.0"))
|
coins = decimal.Decimal(target.get_setting("coins", "0.0"))
|
||||||
event["stdout"].write("%s has %s coin%s" % (target.nickname,
|
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):
|
def reset_coins(self, event):
|
||||||
target = event["server"].get_user(event["args_split"][0])
|
target = event["server"].get_user(event["args_split"][0])
|
||||||
|
@ -76,18 +81,18 @@ class Module(object):
|
||||||
target.del_setting("coins")
|
target.del_setting("coins")
|
||||||
event["stdout"].write("Reset coins for %s" % target.nickname)
|
event["stdout"].write("Reset coins for %s" % target.nickname)
|
||||||
|
|
||||||
|
|
||||||
def richest(self, event):
|
def richest(self, event):
|
||||||
all_coins = event["server"].get_all_user_settings("coins", [])
|
all_coins = event["server"].get_all_user_settings("coins", [])
|
||||||
all_coins = list(filter(lambda coin: decimal.Decimal(coin[1]),
|
all_coins = list(filter(lambda coin: decimal.Decimal(coin[1]),
|
||||||
all_coins))
|
all_coins))
|
||||||
items = [(coin[0], decimal.Decimal(coin[1])) for coin in all_coins]
|
items = [(coin[0], decimal.Decimal(coin[1])) for coin in all_coins]
|
||||||
all_coins = dict(items)
|
all_coins = dict(items)
|
||||||
|
|
||||||
top_10 = sorted(all_coins.keys())
|
top_10 = sorted(all_coins.keys())
|
||||||
top_10 = sorted(top_10, key=all_coins.get, reverse=True)[:10]
|
top_10 = sorted(top_10, key=all_coins.get, reverse=True)[:10]
|
||||||
top_10 = ", ".join("%s (%s)" % (Utils.prevent_highlight(event[
|
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)
|
all_coins[nickname])) for nickname in top_10)
|
||||||
event["stdout"].write("Richest users: %s" % top_10)
|
event["stdout"].write("Richest users: %s" % top_10)
|
||||||
|
|
||||||
|
@ -97,21 +102,23 @@ class Module(object):
|
||||||
if user_coins == DECIMAL_ZERO:
|
if user_coins == DECIMAL_ZERO:
|
||||||
last_redeem = event["user"].get_setting("last-redeem", None)
|
last_redeem = event["user"].get_setting("last-redeem", None)
|
||||||
redeem_delay = event["server"].get_setting("redeem-delay",
|
redeem_delay = event["server"].get_setting("redeem-delay",
|
||||||
DEFAULT_REDEEM_DELAY)
|
DEFAULT_REDEEM_DELAY)
|
||||||
|
|
||||||
if last_redeem == None or (time.time()-last_redeem
|
if last_redeem == None or (time.time() - last_redeem
|
||||||
) >= redeem_delay:
|
) >= redeem_delay:
|
||||||
redeem_amount = decimal.Decimal(event["server"
|
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(
|
event["user"].set_setting("coins", str(
|
||||||
user_coins+redeem_amount))
|
user_coins + redeem_amount))
|
||||||
event["stdout"].write("Redeemed %s coins" % "{0:.2f}".format(
|
event["stdout"].write("Redeemed %s coins" % "{0:.2f}".format(
|
||||||
redeem_amount))
|
redeem_amount))
|
||||||
event["user"].set_setting("last-redeem", time.time())
|
event["user"].set_setting("last-redeem", time.time())
|
||||||
else:
|
else:
|
||||||
time_left = (last_redeem+redeem_delay)-time.time()
|
time_left = (last_redeem + redeem_delay) - time.time()
|
||||||
event["stderr"].write("Please wait %s before redeeming" %
|
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:
|
else:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"You can only redeem coins when you have none")
|
"You can only redeem coins when you have none")
|
||||||
|
@ -145,12 +152,12 @@ class Module(object):
|
||||||
win = side_name == chosen_side
|
win = side_name == chosen_side
|
||||||
|
|
||||||
if win:
|
if win:
|
||||||
event["user"].set_setting("coins", str(user_coins+coin_bet))
|
event["user"].set_setting("coins", str(user_coins + coin_bet))
|
||||||
event["stdout"].write("%s flips %s and wins %s coin%s!" % (
|
event["stdout"].write("%s flips %s and wins %s coin%s!" % (
|
||||||
event["user"].nickname, side_name, coin_bet_str,
|
event["user"].nickname, side_name, coin_bet_str,
|
||||||
"" if coin_bet == 1 else "s"))
|
"" if coin_bet == 1 else "s"))
|
||||||
else:
|
else:
|
||||||
event["user"].set_setting("coins", str(user_coins-coin_bet))
|
event["user"].set_setting("coins", str(user_coins - coin_bet))
|
||||||
event["stdout"].write("%s flips %s and loses %s coin%s!" % (
|
event["stdout"].write("%s flips %s and loses %s coin%s!" % (
|
||||||
event["user"].nickname, side_name, coin_bet_str,
|
event["user"].nickname, side_name, coin_bet_str,
|
||||||
"" if coin_bet == 1 else "s"))
|
"" if coin_bet == 1 else "s"))
|
||||||
|
@ -162,17 +169,17 @@ class Module(object):
|
||||||
send_amount = event["args_split"][1]
|
send_amount = event["args_split"][1]
|
||||||
match = REGEX_FLOAT.match(send_amount)
|
match = REGEX_FLOAT.match(send_amount)
|
||||||
if not match or round(decimal.Decimal(send_amount), 2
|
if not match or round(decimal.Decimal(send_amount), 2
|
||||||
) <= DECIMAL_ZERO:
|
) <= DECIMAL_ZERO:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"Please provide a positive number of coins to send")
|
"Please provide a positive number of coins to send")
|
||||||
return
|
return
|
||||||
send_amount = decimal.Decimal(match.group(0))
|
send_amount = decimal.Decimal(match.group(0))
|
||||||
|
|
||||||
user_coins = decimal.Decimal(event["user"].get_setting("coins",
|
user_coins = decimal.Decimal(event["user"].get_setting("coins",
|
||||||
"0.0"))
|
"0.0"))
|
||||||
redeem_amount = decimal.Decimal(event["server"].get_setting(
|
redeem_amount = decimal.Decimal(event["server"].get_setting(
|
||||||
"redeem-amount", DEFAULT_REDEEM_AMOUNT))
|
"redeem-amount", DEFAULT_REDEEM_AMOUNT))
|
||||||
new_user_coins = user_coins-send_amount
|
new_user_coins = user_coins - send_amount
|
||||||
|
|
||||||
if new_user_coins == DECIMAL_ZERO:
|
if new_user_coins == DECIMAL_ZERO:
|
||||||
event["stderr"].write("You have no coins")
|
event["stderr"].write("You have no coins")
|
||||||
|
@ -186,12 +193,12 @@ class Module(object):
|
||||||
target_user_coins = target_user.get_setting("coins", None)
|
target_user_coins = target_user.get_setting("coins", None)
|
||||||
if target_user_coins == None:
|
if target_user_coins == None:
|
||||||
event["stderr"].write("You can only send coins to users that "
|
event["stderr"].write("You can only send coins to users that "
|
||||||
"have had coins before")
|
"have had coins before")
|
||||||
return
|
return
|
||||||
target_user_coins = decimal.Decimal(target_user_coins)
|
target_user_coins = decimal.Decimal(target_user_coins)
|
||||||
|
|
||||||
event["user"].set_setting("coins", str(new_user_coins))
|
event["user"].set_setting("coins", str(new_user_coins))
|
||||||
target_user.set_setting("coins", str(target_user_coins+send_amount))
|
target_user.set_setting("coins", str(target_user_coins + send_amount))
|
||||||
|
|
||||||
event["stdout"].write("%s sent %s coins to %s" % (
|
event["stdout"].write("%s sent %s coins to %s" % (
|
||||||
event["user"].nickname, "{0:.2f}".format(send_amount),
|
event["user"].nickname, "{0:.2f}".format(send_amount),
|
||||||
|
@ -208,9 +215,9 @@ class Module(object):
|
||||||
for nickname, coins in all_coins:
|
for nickname, coins in all_coins:
|
||||||
coins = decimal.Decimal(coins)
|
coins = decimal.Decimal(coins)
|
||||||
if coins > redeem_amount:
|
if coins > redeem_amount:
|
||||||
coins += round(coins*interest_rate, 2)
|
coins += round(coins * interest_rate, 2)
|
||||||
server.get_user(nickname).set_setting("coins",
|
server.get_user(nickname).set_setting("coins",
|
||||||
str(coins))
|
str(coins))
|
||||||
event["timer"].redo()
|
event["timer"].redo()
|
||||||
|
|
||||||
def roulette(self, event):
|
def roulette(self, event):
|
||||||
|
@ -231,7 +238,7 @@ class Module(object):
|
||||||
for i, bet_amount in enumerate(bet_amounts):
|
for i, bet_amount in enumerate(bet_amounts):
|
||||||
match = REGEX_FLOAT.match(bet_amount)
|
match = REGEX_FLOAT.match(bet_amount)
|
||||||
if not match or round(decimal.Decimal(bet_amount), 2
|
if not match or round(decimal.Decimal(bet_amount), 2
|
||||||
) <= DECIMAL_ZERO:
|
) <= DECIMAL_ZERO:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"Please provide a positive number of coins to bet")
|
"Please provide a positive number of coins to bet")
|
||||||
return
|
return
|
||||||
|
@ -239,7 +246,7 @@ class Module(object):
|
||||||
bet_amount_total = sum(bet_amounts)
|
bet_amount_total = sum(bet_amounts)
|
||||||
|
|
||||||
user_coins = decimal.Decimal(event["user"].get_setting("coins",
|
user_coins = decimal.Decimal(event["user"].get_setting("coins",
|
||||||
"0.0"))
|
"0.0"))
|
||||||
if bet_amount_total > user_coins:
|
if bet_amount_total > user_coins:
|
||||||
event["stderr"].write("You don't have enough coins to bet")
|
event["stderr"].write("You don't have enough coins to bet")
|
||||||
return
|
return
|
||||||
|
@ -252,10 +259,10 @@ class Module(object):
|
||||||
losses = {}
|
losses = {}
|
||||||
if choice == 0:
|
if choice == 0:
|
||||||
loss = sum(bet_amounts)
|
loss = sum(bet_amounts)
|
||||||
event["user"].set_setting("coins", str(user_coins-loss))
|
event["user"].set_setting("coins", str(user_coins - loss))
|
||||||
event["stdout"].write("Roulette spin lands on 0, "
|
event["stdout"].write("Roulette spin lands on 0, "
|
||||||
"the house wins, %s loses %s" % (
|
"the house wins, %s loses %s" % (
|
||||||
event["user"].nickname, loss))
|
event["user"].nickname, loss))
|
||||||
return
|
return
|
||||||
|
|
||||||
failed = False
|
failed = False
|
||||||
|
@ -264,34 +271,34 @@ class Module(object):
|
||||||
street_match = REGEX_STREET.match(bet)
|
street_match = REGEX_STREET.match(bet)
|
||||||
odds = 0
|
odds = 0
|
||||||
if bet == "even":
|
if bet == "even":
|
||||||
odds = 1*((choice % 2) == 0)
|
odds = 1 * ((choice % 2) == 0)
|
||||||
elif bet == "odd":
|
elif bet == "odd":
|
||||||
odds = 1*((choice % 2) == 1)
|
odds = 1 * ((choice % 2) == 1)
|
||||||
elif bet == "red":
|
elif bet == "red":
|
||||||
odds = 1*(choice in RED)
|
odds = 1 * (choice in RED)
|
||||||
elif bet == "black":
|
elif bet == "black":
|
||||||
odds = 1*(choice in BLACK)
|
odds = 1 * (choice in BLACK)
|
||||||
elif bet == "small" or bet == "low":
|
elif bet == "small" or bet == "low":
|
||||||
odds = 1*(choice in SMALL)
|
odds = 1 * (choice in SMALL)
|
||||||
elif bet == "big" or bet == "high":
|
elif bet == "big" or bet == "high":
|
||||||
odds = 1*(choice in BIG)
|
odds = 1 * (choice in BIG)
|
||||||
elif bet == "dozen1":
|
elif bet == "dozen1":
|
||||||
odds = 2*(choice in FIRST_DOZEN)
|
odds = 2 * (choice in FIRST_DOZEN)
|
||||||
elif bet == "dozen2":
|
elif bet == "dozen2":
|
||||||
odds = 2*(choice in SECOND_DOZEN)
|
odds = 2 * (choice in SECOND_DOZEN)
|
||||||
elif bet == "dozen3":
|
elif bet == "dozen3":
|
||||||
odds = 2*(choice in THIRD_DOZEN)
|
odds = 2 * (choice in THIRD_DOZEN)
|
||||||
elif bet == "column1":
|
elif bet == "column1":
|
||||||
odds = 2*(choice in FIRST_COLUMN)
|
odds = 2 * (choice in FIRST_COLUMN)
|
||||||
elif bet == "column2":
|
elif bet == "column2":
|
||||||
odds = 2*(choice in SECOND_COLUMN)
|
odds = 2 * (choice in SECOND_COLUMN)
|
||||||
elif bet == "column3":
|
elif bet == "column3":
|
||||||
odds = 2*(choice in THIRD_COLUMN)
|
odds = 2 * (choice in THIRD_COLUMN)
|
||||||
elif street_match:
|
elif street_match:
|
||||||
row = int(street_match.group(1))
|
row = int(street_match.group(1))
|
||||||
odds = 11*(((row*3)-2) <= choice <= (row*3))
|
odds = 11 * (((row * 3) - 2) <= choice <= (row * 3))
|
||||||
elif bet.isdigit() and (1 <= int(bet) <= 36):
|
elif bet.isdigit() and (1 <= int(bet) <= 36):
|
||||||
odds = 35*(choice == int(bet))
|
odds = 35 * (choice == int(bet))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Unknown bet")
|
event["stderr"].write("Unknown bet")
|
||||||
failed = True
|
failed = True
|
||||||
|
@ -299,32 +306,41 @@ class Module(object):
|
||||||
if odds == 0:
|
if odds == 0:
|
||||||
losses[bet] = bet_amounts[i]
|
losses[bet] = bet_amounts[i]
|
||||||
else:
|
else:
|
||||||
winnings[bet] = [odds, bet_amounts[i]*odds]
|
winnings[bet] = [odds, bet_amounts[i] * odds]
|
||||||
if failed:
|
if failed:
|
||||||
return
|
return
|
||||||
|
|
||||||
winnings_str = ["%s for %s (%d to 1)" % (winnings[bet][1], bet,
|
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_winnings = sum(bet[1] for bet in winnings.values())
|
||||||
coin_losses = sum([loss for loss in losses.values()])
|
coin_losses = sum([loss for loss in losses.values()])
|
||||||
total_winnings_str = " (%s total)" % coin_winnings if len(
|
total_winnings_str = " (%s total)" % coin_winnings if len(
|
||||||
winnings.keys()) > 1 else ""
|
winnings.keys()) > 1 else ""
|
||||||
|
|
||||||
new_user_coins = (user_coins-coin_losses)+coin_winnings
|
new_user_coins = (user_coins - coin_losses) + coin_winnings
|
||||||
event["user"].set_setting("coins", str(new_user_coins))
|
event["user"].set_setting("coins", str(new_user_coins))
|
||||||
|
|
||||||
choice = "%d %s" % (choice, colour)
|
choice = "%d %s" % (choice, colour)
|
||||||
if not losses and winnings:
|
if not losses and winnings:
|
||||||
event["stdout"].write("Roulette spin lands on %s, "
|
event["stdout"].write("Roulette spin lands on %s, "
|
||||||
"%s wins %s%s" % (choice, event["user"].nickname,
|
"%s wins %s%s" % (
|
||||||
", ".join(winnings_str), str(total_winnings_str)))
|
choice, event["user"].nickname,
|
||||||
|
", ".join(winnings_str),
|
||||||
|
str(total_winnings_str)))
|
||||||
elif losses and winnings:
|
elif losses and winnings:
|
||||||
event["stdout"].write("Roulette spin lands on %s, "
|
event["stdout"].write("Roulette spin lands on %s, "
|
||||||
"%s wins %s%s; loses %s" % (choice,
|
"%s wins %s%s; loses %s" % (choice,
|
||||||
event["user"].nickname, ", ".join(winnings_str),
|
event[
|
||||||
str(total_winnings_str), str(coin_losses)))
|
"user"].nickname,
|
||||||
|
", ".join(
|
||||||
|
winnings_str),
|
||||||
|
str(
|
||||||
|
total_winnings_str),
|
||||||
|
str(coin_losses)))
|
||||||
else:
|
else:
|
||||||
event["stdout"].write("Roulette spin lands on %s, "
|
event["stdout"].write("Roulette spin lands on %s, "
|
||||||
"%s loses %s" % (choice, event["user"].nickname,
|
"%s loses %s" % (
|
||||||
str(coin_losses)))
|
choice, event["user"].nickname,
|
||||||
|
str(coin_losses)))
|
||||||
|
|
|
@ -8,41 +8,51 @@ OUT_CUTOFF = 400
|
||||||
|
|
||||||
REGEX_CUTOFF = re.compile("^.{1,%d}(?:\s|$)" % OUT_CUTOFF)
|
REGEX_CUTOFF = re.compile("^.{1,%d}(?:\s|$)" % OUT_CUTOFF)
|
||||||
|
|
||||||
|
|
||||||
class Out(object):
|
class Out(object):
|
||||||
def __init__(self, module_name, target):
|
def __init__(self, module_name, target):
|
||||||
self.module_name = module_name
|
self.module_name = module_name
|
||||||
self.target = target
|
self.target = target
|
||||||
self._text = ""
|
self._text = ""
|
||||||
self.written = False
|
self.written = False
|
||||||
|
|
||||||
def write(self, text):
|
def write(self, text):
|
||||||
self._text += text
|
self._text += text
|
||||||
self.written = True
|
self.written = True
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def send(self):
|
def send(self):
|
||||||
if self.has_text():
|
if self.has_text():
|
||||||
text = self._text
|
text = self._text
|
||||||
text_encoded = text.encode("utf8")
|
text_encoded = text.encode("utf8")
|
||||||
if len(text_encoded) > OUT_CUTOFF:
|
if len(text_encoded) > OUT_CUTOFF:
|
||||||
text = "%s%s" % (text_encoded[:OUT_CUTOFF].decode("utf8"
|
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:
|
self._text = "%s%s" % (STR_CONTINUED, text_encoded[OUT_CUTOFF:
|
||||||
].decode("utf8").lstrip())
|
].decode("utf8").lstrip())
|
||||||
else:
|
else:
|
||||||
self._text = ""
|
self._text = ""
|
||||||
self.target.send_message(text, prefix="[%s] " % self.prefix())
|
self.target.send_message(text, prefix="[%s] " % self.prefix())
|
||||||
|
|
||||||
def set_prefix(self, prefix):
|
def set_prefix(self, prefix):
|
||||||
self.module_name = prefix
|
self.module_name = prefix
|
||||||
|
|
||||||
def has_text(self):
|
def has_text(self):
|
||||||
return bool(self._text)
|
return bool(self._text)
|
||||||
|
|
||||||
|
|
||||||
class StdOut(Out):
|
class StdOut(Out):
|
||||||
def prefix(self):
|
def prefix(self):
|
||||||
return "%s%s%s" % (Utils.color(Utils.COLOR_GREEN),
|
return "%s%s%s" % (Utils.color(Utils.COLOR_GREEN),
|
||||||
self.module_name, Utils.FONT_RESET)
|
self.module_name, Utils.FONT_RESET)
|
||||||
|
|
||||||
|
|
||||||
class StdErr(Out):
|
class StdErr(Out):
|
||||||
def prefix(self):
|
def prefix(self):
|
||||||
return "%s!%s%s" % (Utils.color(Utils.COLOR_RED),
|
return "%s!%s%s" % (Utils.color(Utils.COLOR_RED),
|
||||||
self.module_name, Utils.FONT_RESET)
|
self.module_name, Utils.FONT_RESET)
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -52,16 +62,19 @@ class Module(object):
|
||||||
bot.events.on("received").on("message").on("private").hook(
|
bot.events.on("received").on("message").on("private").hook(
|
||||||
self.private_message)
|
self.private_message)
|
||||||
bot.events.on("received").on("command").on("help").hook(self.help,
|
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,
|
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",
|
||||||
usage="<command>")
|
min_args=1,
|
||||||
|
usage="<command>")
|
||||||
bot.events.on("received").on("command").on("more").hook(self.more,
|
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(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="command-prefix",
|
"channelset").assure_call(setting="command-prefix",
|
||||||
help="Set the command prefix used in this channel")
|
help="Set the command prefix used in this channel")
|
||||||
|
|
||||||
bot.events.on("new").on("user", "channel").hook(self.new)
|
bot.events.on("new").on("user", "channel").hook(self.new)
|
||||||
bot.events.on("send").on("stdout").hook(self.send_stdout)
|
bot.events.on("send").on("stdout").hook(self.send_stdout)
|
||||||
|
@ -78,14 +91,16 @@ class Module(object):
|
||||||
def has_command(self, command):
|
def has_command(self, command):
|
||||||
return command.lower() in self.bot.events.on("received").on(
|
return command.lower() in self.bot.events.on("received").on(
|
||||||
"command").get_children()
|
"command").get_children()
|
||||||
|
|
||||||
def get_hook(self, command):
|
def get_hook(self, command):
|
||||||
return self.bot.events.on("received").on("command").on(command
|
return self.bot.events.on("received").on("command").on(command
|
||||||
).get_hooks()[0]
|
).get_hooks()[0]
|
||||||
|
|
||||||
def is_highlight(self, server, s):
|
def is_highlight(self, server, s):
|
||||||
return s.lower() == server.nickname_lower or (s.lower().startswith(
|
return s.lower() == server.nickname_lower or (s.lower().startswith(
|
||||||
server.nickname_lower) and len(s) == len(server.nickname_lower
|
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):
|
def message(self, event, command, args_index=1):
|
||||||
if self.has_command(command):
|
if self.has_command(command):
|
||||||
|
@ -106,11 +121,16 @@ class Module(object):
|
||||||
|
|
||||||
module_name = hook.function.__self__._name
|
module_name = hook.function.__self__._name
|
||||||
stdout, stderr = StdOut(module_name, target), StdErr(module_name,
|
stdout, stderr = StdOut(module_name, target), StdErr(module_name,
|
||||||
target)
|
target)
|
||||||
|
|
||||||
returns = self.bot.events.on("preprocess").on("command"
|
returns = self.bot.events.on("preprocess").on("command"
|
||||||
).call(hook=hook, user=event["user"], server=event["server"],
|
).call(hook=hook,
|
||||||
target=target, is_channel=is_channel)
|
user=event[
|
||||||
|
"user"],
|
||||||
|
server=event[
|
||||||
|
"server"],
|
||||||
|
target=target,
|
||||||
|
is_channel=is_channel)
|
||||||
for returned in returns:
|
for returned in returns:
|
||||||
if returned:
|
if returned:
|
||||||
stderr.write(returned).send()
|
stderr.write(returned).send()
|
||||||
|
@ -124,13 +144,14 @@ class Module(object):
|
||||||
command, hook.kwargs["usage"])).send()
|
command, hook.kwargs["usage"])).send()
|
||||||
else:
|
else:
|
||||||
stderr.write("Not enough arguments (minimum: %d)" % min_args
|
stderr.write("Not enough arguments (minimum: %d)" % min_args
|
||||||
).send()
|
).send()
|
||||||
else:
|
else:
|
||||||
args = " ".join(args_split)
|
args = " ".join(args_split)
|
||||||
server = event["server"]
|
server = event["server"]
|
||||||
user = event["user"]
|
user = event["user"]
|
||||||
self.bot.events.on("received").on("command").on(command
|
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,
|
target=target, buffer=buffer, args=args,
|
||||||
args_split=args_split, stdout=stdout, stderr=stderr,
|
args_split=args_split, stdout=stdout, stderr=stderr,
|
||||||
command=command.lower(), is_channel=is_channel)
|
command=command.lower(), is_channel=is_channel)
|
||||||
|
@ -141,10 +162,12 @@ class Module(object):
|
||||||
target.last_stderr = stderr
|
target.last_stderr = stderr
|
||||||
buffer.skip_next()
|
buffer.skip_next()
|
||||||
|
|
||||||
|
|
||||||
def channel_message(self, event):
|
def channel_message(self, event):
|
||||||
command_prefix = event["channel"].get_setting("command-prefix",
|
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):
|
if event["message_split"][0].startswith(command_prefix):
|
||||||
command = event["message_split"][0].replace(
|
command = event["message_split"][0].replace(
|
||||||
command_prefix, "", 1).lower()
|
command_prefix, "", 1).lower()
|
||||||
|
@ -164,17 +187,21 @@ class Module(object):
|
||||||
command = event["args_split"][0].lower()
|
command = event["args_split"][0].lower()
|
||||||
if command in self.bot.events.on("received").on(
|
if command in self.bot.events.on("received").on(
|
||||||
"command").get_children():
|
"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:
|
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:
|
else:
|
||||||
event["stderr"].write("No help available for %s" % command)
|
event["stderr"].write("No help available for %s" % command)
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Unknown command '%s'" % command)
|
event["stderr"].write("Unknown command '%s'" % command)
|
||||||
else:
|
else:
|
||||||
help_available = []
|
help_available = []
|
||||||
for child in self.bot.events.on("received").on("command").get_children():
|
for child in self.bot.events.on("received").on(
|
||||||
hooks = self.bot.events.on("received").on("command").on(child).get_hooks()
|
"command").get_children():
|
||||||
|
hooks = self.bot.events.on("received").on("command").on(
|
||||||
|
child).get_hooks()
|
||||||
if hooks and "help" in hooks[0].kwargs:
|
if hooks and "help" in hooks[0].kwargs:
|
||||||
help_available.append(child)
|
help_available.append(child)
|
||||||
help_available = sorted(help_available)
|
help_available = sorted(help_available)
|
||||||
|
@ -184,16 +211,20 @@ class Module(object):
|
||||||
command = event["args_split"][0].lower()
|
command = event["args_split"][0].lower()
|
||||||
if command in self.bot.events.on("received").on(
|
if command in self.bot.events.on("received").on(
|
||||||
"command").get_children():
|
"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:
|
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:
|
else:
|
||||||
event["stderr"].write("No usage help available for %s" % command)
|
event["stderr"].write(
|
||||||
|
"No usage help available for %s" % command)
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Unknown command '%s'" % command)
|
event["stderr"].write("Unknown command '%s'" % command)
|
||||||
|
|
||||||
def more(self, event):
|
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()
|
event["target"].last_stdout.send()
|
||||||
|
|
||||||
def send_stdout(self, event):
|
def send_stdout(self, event):
|
||||||
|
@ -201,6 +232,7 @@ class Module(object):
|
||||||
stdout.write(event["message"]).send()
|
stdout.write(event["message"]).send()
|
||||||
if stdout.has_text():
|
if stdout.has_text():
|
||||||
event["target"].last_stdout = stdout
|
event["target"].last_stdout = stdout
|
||||||
|
|
||||||
def send_stderr(self, event):
|
def send_stderr(self, event):
|
||||||
stderr = StdErr(event["module_name"], event["target"])
|
stderr = StdErr(event["module_name"], event["target"])
|
||||||
stderr.write(event["message"]).send()
|
stderr.write(event["message"]).send()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("message").on("private").hook(
|
bot.events.on("received").on("message").on("private").hook(
|
||||||
|
@ -18,10 +19,10 @@ class Module(object):
|
||||||
ctcp_response = None
|
ctcp_response = None
|
||||||
if ctcp_command == "VERSION":
|
if ctcp_command == "VERSION":
|
||||||
ctcp_response = self.bot.config.get("ctcp-version",
|
ctcp_response = self.bot.config.get("ctcp-version",
|
||||||
"BitBot (https://github.com/jesopo/bitbot)")
|
"BitBot (https://github.com/jesopo/bitbot)")
|
||||||
elif ctcp_command == "SOURCE":
|
elif ctcp_command == "SOURCE":
|
||||||
ctcp_response = self.bot.config.get("ctcp-source",
|
ctcp_response = self.bot.config.get("ctcp-source",
|
||||||
"https://github.com/jesopo/bitbot")
|
"https://github.com/jesopo/bitbot")
|
||||||
elif ctcp_command == "PING":
|
elif ctcp_command == "PING":
|
||||||
ctcp_response = " ".join(ctcp_args_split)
|
ctcp_response = " ".join(ctcp_args_split)
|
||||||
elif ctcp_command == "TIME":
|
elif ctcp_command == "TIME":
|
||||||
|
@ -29,4 +30,4 @@ class Module(object):
|
||||||
|
|
||||||
if ctcp_response:
|
if ctcp_response:
|
||||||
event["user"].send_ctcp_response(ctcp_command,
|
event["user"].send_ctcp_response(ctcp_command,
|
||||||
ctcp_response)
|
ctcp_response)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#--require-config wordnik-api-key
|
# --require-config wordnik-api-key
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_WORDNIK = "http://api.wordnik.com:80/v4/word.json/%s/definitions"
|
URL_WORDNIK = "http://api.wordnik.com:80/v4/word.json/%s/definitions"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -23,7 +24,7 @@ class Module(object):
|
||||||
if page:
|
if page:
|
||||||
if len(page):
|
if len(page):
|
||||||
event["stdout"].write("%s: %s" % (page[0]["word"],
|
event["stdout"].write("%s: %s" % (page[0]["word"],
|
||||||
page[0]["text"]))
|
page[0]["text"]))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No definitions found")
|
event["stderr"].write("No definitions found")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "DNS"
|
_name = "DNS"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("dns").hook(
|
bot.events.on("received").on("command").on("dns").hook(
|
||||||
self.dns, min_args=1,
|
self.dns, min_args=1,
|
||||||
|
@ -12,7 +14,7 @@ class Module(object):
|
||||||
hostname = event["args_split"][0]
|
hostname = event["args_split"][0]
|
||||||
try:
|
try:
|
||||||
address_info = socket.getaddrinfo(hostname, 1, 0,
|
address_info = socket.getaddrinfo(hostname, 1, 0,
|
||||||
socket.SOCK_DGRAM)
|
socket.SOCK_DGRAM)
|
||||||
except socket.gaierror:
|
except socket.gaierror:
|
||||||
event["stderr"].write("Failed to find hostname")
|
event["stderr"].write("Failed to find hostname")
|
||||||
return
|
return
|
||||||
|
|
|
@ -56,7 +56,8 @@ class Module(object):
|
||||||
for server in self.bot.servers.values():
|
for server in self.bot.servers.values():
|
||||||
for channel in server.channels.values():
|
for channel in server.channels.values():
|
||||||
ducks_enabled = channel.get_setting("ducks-enabled", 0)
|
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
|
min_time = "min-duck-time-%s" % channel.name
|
||||||
max_time = "max-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)
|
min_duck_time = channel.get_setting("min-duck-time", 240)
|
||||||
max_duck_time = channel.get_setting("max-duck-time", 1200)
|
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
|
min_duck_time = int(min_duck_time) if isinstance(min_duck_time,
|
||||||
max_duck_time = int(max_duck_time) if isinstance(max_duck_time, str) else max_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[min_time] = min_duck_time
|
||||||
self.duck_times[max_time] = max_duck_time
|
self.duck_times[max_time] = max_duck_time
|
||||||
|
@ -84,25 +87,28 @@ class Module(object):
|
||||||
min = "min-duck-time-%s" % (channel_name)
|
min = "min-duck-time-%s" % (channel_name)
|
||||||
max = "max-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",
|
||||||
self.bot.log.debug("Attempting to set %s to %s", [str(max), str(self.duck_times[max])]);
|
[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])
|
return random.randint(self.duck_times[min], self.duck_times[max])
|
||||||
|
|
||||||
def decoy_time(self):
|
def decoy_time(self):
|
||||||
return random.randint(300, 700)
|
return random.randint(10, 20)
|
||||||
|
|
||||||
|
|
||||||
def duck_bef(self, event):
|
def duck_bef(self, event):
|
||||||
target = event["user"].nickname
|
target = event["user"].nickname
|
||||||
active_duck = event["target"].get_setting("active-duck", 0)
|
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:
|
if active_duck == 0:
|
||||||
event["stderr"].set_prefix("Kick")
|
event["stderr"].set_prefix("Kick")
|
||||||
if event["server"].has_user(target):
|
if event["server"].has_user(target):
|
||||||
if not event["server"].is_own_nickname(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:
|
else:
|
||||||
event["stderr"].write("Nope.")
|
event["stderr"].write("Nope.")
|
||||||
else:
|
else:
|
||||||
|
@ -116,8 +122,9 @@ class Module(object):
|
||||||
grammar = "" if befriended_ducks == 0 else "s"
|
grammar = "" if befriended_ducks == 0 else "s"
|
||||||
|
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
target + ", you've befriended " + str(befriended_ducks + 1) + " duck" + grammar + " in " + event[
|
target + ", you've befriended " + str(
|
||||||
"target"].name);
|
befriended_ducks + 1) + " duck" + grammar + " in " + event[
|
||||||
|
"target"].name)
|
||||||
|
|
||||||
next_duck_time = self.duck_time(event)
|
next_duck_time = self.duck_time(event)
|
||||||
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
||||||
|
@ -128,7 +135,8 @@ class Module(object):
|
||||||
event["stderr"].set_prefix("Kick")
|
event["stderr"].set_prefix("Kick")
|
||||||
if event["server"].has_user(target):
|
if event["server"].has_user(target):
|
||||||
if not event["server"].is_own_nickname(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:
|
else:
|
||||||
event["stderr"].write("Nope.")
|
event["stderr"].write("Nope.")
|
||||||
else:
|
else:
|
||||||
|
@ -142,7 +150,9 @@ class Module(object):
|
||||||
grammar = "" if shot_ducks == 0 else "s"
|
grammar = "" if shot_ducks == 0 else "s"
|
||||||
|
|
||||||
event["stdout"].write(
|
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)
|
next_duck_time = self.duck_time(event)
|
||||||
self.bot.add_timer("duck-appear", next_duck_time, persist=False)
|
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 server in self.bot.servers.values():
|
||||||
for channel in server.channels.values():
|
for channel in server.channels.values():
|
||||||
ducks_enabled = channel.get_setting("ducks-enabled", 0)
|
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:
|
if ducks_enabled == 0:
|
||||||
continue
|
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 = 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:
|
if ducks_enabled == 1 and active_duck == 0:
|
||||||
ducks = [
|
ducks = [
|
||||||
|
@ -181,7 +194,8 @@ class Module(object):
|
||||||
channel.set_setting("active-duck", 0)
|
channel.set_setting("active-duck", 0)
|
||||||
|
|
||||||
next_duck_time = self.duck_time(channel.name)
|
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):
|
def duck_decoy(self, event):
|
||||||
ducks = [
|
ducks = [
|
||||||
|
@ -194,12 +208,15 @@ class Module(object):
|
||||||
"・ ゜・。 。・゜゜ \_ó< beep beep!"
|
"・ ゜・。 。・゜゜ \_ó< beep beep!"
|
||||||
]
|
]
|
||||||
|
|
||||||
event["target"].send_message(random.choice(ducks))
|
event["channel"].send_message(random.choice(ducks))
|
||||||
|
|
||||||
def set_decoy(self, event):
|
def set_decoy(self, event):
|
||||||
|
|
||||||
|
channel = event["target"]
|
||||||
next_decoy_time = self.decoy_time()
|
next_decoy_time = self.decoy_time()
|
||||||
self.bot.events.on("timer").on("duck-decoy").hook(self.duck_decoy)
|
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):
|
# def coins(self, event):
|
||||||
# if event["args_split"]:
|
# if event["args_split"]:
|
||||||
|
|
|
@ -2,8 +2,10 @@ import Utils
|
||||||
|
|
||||||
URL_GEOIP = "http://ip-api.com/json/%s"
|
URL_GEOIP = "http://ip-api.com/json/%s"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "GeoIP"
|
_name = "GeoIP"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("geoip").hook(
|
bot.events.on("received").on("command").on("geoip").hook(
|
||||||
self.geoip, min_args=1,
|
self.geoip, min_args=1,
|
||||||
|
@ -12,17 +14,17 @@ class Module(object):
|
||||||
|
|
||||||
def geoip(self, event):
|
def geoip(self, event):
|
||||||
page = Utils.get_url(URL_GEOIP % event["args_split"][0],
|
page = Utils.get_url(URL_GEOIP % event["args_split"][0],
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if page["status"] == "success":
|
if page["status"] == "success":
|
||||||
data = page["query"]
|
data = page["query"]
|
||||||
data += " | Organisation: %s" % page["org"]
|
data += " | Organisation: %s" % page["org"]
|
||||||
data += " | City: %s" % page["city"]
|
data += " | City: %s" % page["city"]
|
||||||
data += " | Region: %s (%s)" % (page["regionName"],
|
data += " | Region: %s (%s)" % (page["regionName"],
|
||||||
page["countryCode"])
|
page["countryCode"])
|
||||||
data += " | ISP: %s" % page["isp"]
|
data += " | ISP: %s" % page["isp"]
|
||||||
data += " | Lon/Lat: %s/%s" % (page["lon"],
|
data += " | Lon/Lat: %s/%s" % (page["lon"],
|
||||||
page["lat"])
|
page["lat"])
|
||||||
data += " | Timezone: %s" % page["timezone"]
|
data += " | Timezone: %s" % page["timezone"]
|
||||||
event["stdout"].write(data)
|
event["stdout"].write(data)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
#--require-config google-api-key
|
# --require-config google-api-key
|
||||||
#--require-config google-search-id
|
# --require-config google-search-id
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_GOOGLESEARCH = "https://www.googleapis.com/customsearch/v1"
|
URL_GOOGLESEARCH = "https://www.googleapis.com/customsearch/v1"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("google",
|
bot.events.on("received").on("command").on("google",
|
||||||
"g").hook(self.google, help="Google feeling lucky",
|
"g").hook(self.google,
|
||||||
usage="[search term]")
|
help="Google feeling lucky",
|
||||||
|
usage="[search term]")
|
||||||
|
|
||||||
def google(self, event):
|
def google(self, event):
|
||||||
phrase = event["args"] or event["buffer"].get()
|
phrase = event["args"] or event["buffer"].get()
|
||||||
if phrase:
|
if phrase:
|
||||||
page = Utils.get_url(URL_GOOGLESEARCH, get_params={
|
page = Utils.get_url(URL_GOOGLESEARCH, get_params={
|
||||||
"q": phrase, "key": self.bot.config[
|
"q": phrase, "key": self.bot.config[
|
||||||
"google-api-key"], "cx": self.bot.config[
|
"google-api-key"], "cx": self.bot.config[
|
||||||
"google-search-id"], "prettyPrint": "true",
|
"google-search-id"], "prettyPrint": "true",
|
||||||
"num": 1, "gl": "gb"}, json=True)
|
"num": 1, "gl": "gb"}, json=True)
|
||||||
if page:
|
if page:
|
||||||
if "items" in page and len(page["items"]):
|
if "items" in page and len(page["items"]):
|
||||||
event["stdout"].write(page["items"][0][
|
event["stdout"].write(page["items"][0][
|
||||||
"link"])
|
"link"])
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No results found")
|
event["stderr"].write("No results found")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("hash"
|
bot.events.on("received").on("command").on("hash"
|
||||||
).hook(self.hash, min_args=2, help="Hash a string",
|
).hook(self.hash, min_args=2,
|
||||||
usage="<algo> <string>")
|
help="Hash a string",
|
||||||
|
usage="<algo> <string>")
|
||||||
|
|
||||||
def hash(self, event):
|
def hash(self, event):
|
||||||
algorithm = event["args_split"][0].lower()
|
algorithm = event["args_split"][0].lower()
|
||||||
if algorithm in hashlib.algorithms_available:
|
if algorithm in hashlib.algorithms_available:
|
||||||
phrase = " ".join(event["args_split"][1:])
|
phrase = " ".join(event["args_split"][1:])
|
||||||
cipher_text = hashlib.new(algorithm, phrase.encode("utf8")
|
cipher_text = hashlib.new(algorithm, phrase.encode("utf8")
|
||||||
).hexdigest()
|
).hexdigest()
|
||||||
event["stdout"].write("%s -> %s" % (phrase, cipher_text))
|
event["stdout"].write("%s -> %s" % (phrase, cipher_text))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Unknown algorithm provided")
|
event["stderr"].write("Unknown algorithm provided")
|
||||||
|
|
|
@ -3,21 +3,23 @@ import Utils
|
||||||
URL_HAVEIBEENPWNEDAPI = "https://haveibeenpwned.com/api/v2/breachedaccount/%s"
|
URL_HAVEIBEENPWNEDAPI = "https://haveibeenpwned.com/api/v2/breachedaccount/%s"
|
||||||
URL_HAVEIBEENPWNED = "https://haveibeenpwned.com/"
|
URL_HAVEIBEENPWNED = "https://haveibeenpwned.com/"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("beenpwned").hook(
|
bot.events.on("received").on("command").on("beenpwned").hook(
|
||||||
self.beenpwned, min_args=1,
|
self.beenpwned, min_args=1,
|
||||||
help="Find out if a username, email or similar has appeared "
|
help="Find out if a username, email or similar has appeared "
|
||||||
"in any hacked databases", usage="<username/email>")
|
"in any hacked databases", usage="<username/email>")
|
||||||
|
|
||||||
def beenpwned(self, event):
|
def beenpwned(self, event):
|
||||||
page = Utils.get_url(URL_HAVEIBEENPWNEDAPI % event["args"], json=True,
|
page = Utils.get_url(URL_HAVEIBEENPWNEDAPI % event["args"], json=True,
|
||||||
code=True)
|
code=True)
|
||||||
if page:
|
if page:
|
||||||
code, page = page
|
code, page = page
|
||||||
if code == 200:
|
if code == 200:
|
||||||
event["stdout"].write(
|
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))
|
URL_HAVEIBEENPWNED))
|
||||||
else:
|
else:
|
||||||
event["stdout"].write("It seems '%s' has not been pwned" % (
|
event["stdout"].write("It seems '%s' has not been pwned" % (
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "IDs"
|
_name = "IDs"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received.command.myid").hook(self.my_id,
|
bot.events.on("received.command.myid").hook(self.my_id,
|
||||||
help="Show your user ID")
|
help="Show your user ID")
|
||||||
bot.events.on("received.command.channelid").hook(
|
bot.events.on("received.command.channelid").hook(
|
||||||
self.channel_id, channel_only=True,
|
self.channel_id, channel_only=True,
|
||||||
help="Show the current channel's ID")
|
help="Show the current channel's ID")
|
||||||
|
|
||||||
def my_id(self, event):
|
def my_id(self, event):
|
||||||
event["stdout"].write("%s: %d" % (event["user"].nickname,
|
event["stdout"].write("%s: %d" % (event["user"].nickname,
|
||||||
event["user"].id))
|
event["user"].id))
|
||||||
|
|
||||||
def channel_id(self, event):
|
def channel_id(self, event):
|
||||||
event["stdout"].write("%s: %d" % (event["target"].name,
|
event["stdout"].write("%s: %d" % (event["target"].name,
|
||||||
event["target"].id))
|
event["target"].id))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#--require-config omdbapi-api-key
|
# --require-config omdbapi-api-key
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import Utils
|
import Utils
|
||||||
|
@ -6,8 +6,10 @@ import Utils
|
||||||
URL_OMDB = "http://www.omdbapi.com/"
|
URL_OMDB = "http://www.omdbapi.com/"
|
||||||
URL_IMDBTITLE = "http://imdb.com/title/%s"
|
URL_IMDBTITLE = "http://imdb.com/title/%s"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "IMDb"
|
_name = "IMDb"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("imdb").hook(
|
bot.events.on("received").on("command").on("imdb").hook(
|
||||||
|
@ -19,7 +21,7 @@ class Module(object):
|
||||||
page = Utils.get_url(URL_OMDB, get_params={
|
page = Utils.get_url(URL_OMDB, get_params={
|
||||||
"t": event["args"],
|
"t": event["args"],
|
||||||
"apikey": self.bot.config["omdbapi-api-key"]},
|
"apikey": self.bot.config["omdbapi-api-key"]},
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if "Title" in page:
|
if "Title" in page:
|
||||||
event["stdout"].write("%s, %s (%s) %s (%s/10.0) %s" % (
|
event["stdout"].write("%s, %s (%s) %s (%s/10.0) %s" % (
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import time
|
import time
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
SECONDS_MAX = Utils.SECONDS_WEEKS*8
|
SECONDS_MAX = Utils.SECONDS_WEEKS * 8
|
||||||
SECONDS_MAX_DESCRIPTION = "8 weeks"
|
SECONDS_MAX_DESCRIPTION = "8 weeks"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -17,17 +18,19 @@ class Module(object):
|
||||||
message = " ".join(event["args_split"][1:])
|
message = " ".join(event["args_split"][1:])
|
||||||
if seconds:
|
if seconds:
|
||||||
if seconds <= SECONDS_MAX:
|
if seconds <= SECONDS_MAX:
|
||||||
due_time = int(time.time())+seconds
|
due_time = int(time.time()) + seconds
|
||||||
|
|
||||||
self.bot.add_timer("in", seconds,
|
self.bot.add_timer("in", seconds,
|
||||||
target=event["target"].name, due_time=due_time,
|
target=event["target"].name,
|
||||||
server_id=event["server"].id, nickname=event["user"].nickname,
|
due_time=due_time,
|
||||||
message=message)
|
server_id=event["server"].id,
|
||||||
|
nickname=event["user"].nickname,
|
||||||
|
message=message)
|
||||||
event["stdout"].write("Saved")
|
event["stdout"].write("Saved")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"The given time is above the max (%s)" % (
|
"The given time is above the max (%s)" % (
|
||||||
SECONDS_MAX_DESCRIPTION))
|
SECONDS_MAX_DESCRIPTION))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"Please provided a valid time above 0 seconds")
|
"Please provided a valid time above 0 seconds")
|
||||||
|
@ -36,6 +39,6 @@ class Module(object):
|
||||||
for server in self.bot.servers.values():
|
for server in self.bot.servers.values():
|
||||||
if event["server_id"] == server.id:
|
if event["server_id"] == server.id:
|
||||||
server.send_message(event["target"],
|
server.send_message(event["target"],
|
||||||
"%s, this is your reminder: %s" % (
|
"%s, this is your reminder: %s" % (
|
||||||
event["nickname"], event["message"]))
|
event["nickname"], event["message"]))
|
||||||
break
|
break
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("numeric").on("001").hook(self.do_join)
|
bot.events.on("received").on("numeric").on("001").hook(self.do_join)
|
||||||
|
|
||||||
def do_join(self, event):
|
def do_join(self, event):
|
||||||
event["server"].send_join("#bitbot")
|
event["server"].send_join("#bitbot")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
||||||
REGEX_KARMA = re.compile("(.*)(\+{2,}|\-{2,})$")
|
REGEX_KARMA = re.compile("(.*)(\+{2,}|\-{2,})$")
|
||||||
KARMA_DELAY_SECONDS = 3
|
KARMA_DELAY_SECONDS = 3
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -20,8 +21,8 @@ class Module(object):
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="karma-verbose",
|
"channelset").assure_call(setting="karma-verbose",
|
||||||
help="Disable/Enable automatically responding to karma changes",
|
help="Disable/Enable automatically responding to karma changes",
|
||||||
validate=Utils.bool_or_none)
|
validate=Utils.bool_or_none)
|
||||||
|
|
||||||
def new_user(self, event):
|
def new_user(self, event):
|
||||||
event["user"].last_karma = None
|
event["user"].last_karma = None
|
||||||
|
@ -30,8 +31,8 @@ class Module(object):
|
||||||
match = re.match(REGEX_KARMA, event["message"].strip())
|
match = re.match(REGEX_KARMA, event["message"].strip())
|
||||||
if match and not event["action"]:
|
if match and not event["action"]:
|
||||||
verbose = event["channel"].get_setting("karma-verbose", False)
|
verbose = event["channel"].get_setting("karma-verbose", False)
|
||||||
if not event["user"].last_karma or (time.time()-event["user"
|
if not event["user"].last_karma or (time.time() - event["user"
|
||||||
].last_karma) >= KARMA_DELAY_SECONDS:
|
].last_karma) >= KARMA_DELAY_SECONDS:
|
||||||
target = match.group(1).lower().strip()
|
target = match.group(1).lower().strip()
|
||||||
if not target == event["user"].name and target:
|
if not target == event["user"].name and target:
|
||||||
positive = match.group(2)[0] == "+"
|
positive = match.group(2)[0] == "+"
|
||||||
|
@ -52,10 +53,13 @@ class Module(object):
|
||||||
event["user"].last_karma = time.time()
|
event["user"].last_karma = time.time()
|
||||||
elif verbose:
|
elif verbose:
|
||||||
if target:
|
if target:
|
||||||
self.bot.events.on("send").on("stderr").call(module_name="Karma",
|
self.bot.events.on("send").on("stderr").call(
|
||||||
target=event["channel"], message="You cannot change your own karma")
|
module_name="Karma",
|
||||||
|
target=event["channel"],
|
||||||
|
message="You cannot change your own karma")
|
||||||
elif verbose:
|
elif verbose:
|
||||||
event["stderr"].write("Try again in a couple of seconds")
|
event["stderr"].write("Try again in a couple of seconds")
|
||||||
|
|
||||||
def karma(self, event):
|
def karma(self, event):
|
||||||
if event["args"]:
|
if event["args"]:
|
||||||
target = event["args"]
|
target = event["args"]
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
#--require-config lastfm-api-key
|
# --require-config lastfm-api-key
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_SCROBBLER = "http://ws.audioscrobbler.com/2.0/"
|
URL_SCROBBLER = "http://ws.audioscrobbler.com/2.0/"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"set").assure_call(setting="lastfm",
|
"set").assure_call(setting="lastfm",
|
||||||
help="Set username on last.fm")
|
help="Set username on last.fm")
|
||||||
|
|
||||||
bot.events.on("received").on("command").on("np",
|
bot.events.on("received").on("command").on("np",
|
||||||
"listening", "nowplaying").hook(self.np,
|
"listening",
|
||||||
help="Get the last listened to track from a user",
|
"nowplaying").hook(self.np,
|
||||||
usage="[username]")
|
help="Get the last listened to track from a user",
|
||||||
|
usage="[username]")
|
||||||
|
|
||||||
def np(self, event):
|
def np(self, event):
|
||||||
if event["args_split"]:
|
if event["args_split"]:
|
||||||
|
@ -23,7 +25,7 @@ class Module(object):
|
||||||
shown_username = lastfm_username
|
shown_username = lastfm_username
|
||||||
else:
|
else:
|
||||||
lastfm_username = event["user"].get_setting("lastfm",
|
lastfm_username = event["user"].get_setting("lastfm",
|
||||||
event["user"].nickname)
|
event["user"].nickname)
|
||||||
shown_username = event["user"].nickname
|
shown_username = event["user"].nickname
|
||||||
page = Utils.get_url(URL_SCROBBLER, get_params={
|
page = Utils.get_url(URL_SCROBBLER, get_params={
|
||||||
"method": "user.getrecenttracks", "user": lastfm_username,
|
"method": "user.getrecenttracks", "user": lastfm_username,
|
||||||
|
@ -31,7 +33,7 @@ class Module(object):
|
||||||
"format": "json", "limit": "1"}, json=True)
|
"format": "json", "limit": "1"}, json=True)
|
||||||
if page:
|
if page:
|
||||||
if "recenttracks" in page and len(page["recenttracks"
|
if "recenttracks" in page and len(page["recenttracks"
|
||||||
]["track"]):
|
]["track"]):
|
||||||
now_playing = page["recenttracks"]["track"][0]
|
now_playing = page["recenttracks"]["track"][0]
|
||||||
track_name = now_playing["name"]
|
track_name = now_playing["name"]
|
||||||
artist = now_playing["artist"]["#text"]
|
artist = now_playing["artist"]["#text"]
|
||||||
|
@ -54,14 +56,14 @@ class Module(object):
|
||||||
if "userplaycount" in info_page.get("track", []):
|
if "userplaycount" in info_page.get("track", []):
|
||||||
play_count = int(info_page["track"]["userplaycount"])
|
play_count = int(info_page["track"]["userplaycount"])
|
||||||
play_count = " (%d play%s)" % (play_count,
|
play_count = " (%d play%s)" % (play_count,
|
||||||
"s" if play_count > 1 else "")
|
"s" if play_count > 1 else "")
|
||||||
|
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
"%s is now playing: %s - %s%s%s" % (
|
"%s is now playing: %s - %s%s%s" % (
|
||||||
shown_username, artist, track_name, play_count, tags))
|
shown_username, artist, track_name, play_count, tags))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"The user '%s' has never scrobbled before" % (
|
"The user '%s' has never scrobbled before" % (
|
||||||
shown_username))
|
shown_username))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
|
@ -1,34 +1,45 @@
|
||||||
#--ignore
|
# --ignore
|
||||||
import types, json
|
import types, json
|
||||||
|
|
||||||
|
|
||||||
def get_target(user):
|
def get_target(user):
|
||||||
return user.alias or user.nickname
|
return user.alias or user.nickname
|
||||||
|
|
||||||
|
|
||||||
def set_setting(user, setting, value):
|
def set_setting(user, setting, value):
|
||||||
target = get_target(user)
|
target = get_target(user)
|
||||||
user.bot.database.set_user_setting(user.server.id, target,
|
user.bot.database.set_user_setting(user.server.id, target,
|
||||||
setting, value)
|
setting, value)
|
||||||
|
|
||||||
|
|
||||||
def get_setting(user, setting, default=None):
|
def get_setting(user, setting, default=None):
|
||||||
target = get_target(user)
|
target = get_target(user)
|
||||||
return user.bot.database.get_user_setting(user.server.id,
|
return user.bot.database.get_user_setting(user.server.id,
|
||||||
target, setting, default)
|
target, setting, default)
|
||||||
|
|
||||||
|
|
||||||
def find_settings(user, pattern, default=[]):
|
def find_settings(user, pattern, default=[]):
|
||||||
target = get_target(user)
|
target = get_target(user)
|
||||||
return user.bot.databse.find_user_settings(user.server.id,
|
return user.bot.databse.find_user_settings(user.server.id,
|
||||||
target, pattern, default)
|
target, pattern, default)
|
||||||
|
|
||||||
|
|
||||||
def del_setting(user, setting):
|
def del_setting(user, setting):
|
||||||
target = get_target(user)
|
target = get_target(user)
|
||||||
user.bot.database.del_user_setting(user.server.id, target,
|
user.bot.database.del_user_setting(user.server.id, target,
|
||||||
setting)
|
setting)
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "Aliases"
|
_name = "Aliases"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("new").on("user").hook(self.new_user)
|
bot.events.on("new").on("user").hook(self.new_user)
|
||||||
bot.events.on("received").on("nick").hook(self.nickname_change)
|
bot.events.on("received").on("nick").hook(self.nickname_change)
|
||||||
bot.events.on("received").on("command").on("alias").hook(
|
bot.events.on("received").on("command").on("alias").hook(
|
||||||
self.alias)
|
self.alias)
|
||||||
#bot.events.on("received").on("command").on("mainalias").hook(
|
# bot.events.on("received").on("command").on("mainalias").hook(
|
||||||
# self.main_alias)
|
# self.main_alias)
|
||||||
|
|
||||||
def new_user(self, event):
|
def new_user(self, event):
|
||||||
|
@ -59,11 +70,12 @@ class Module(object):
|
||||||
return self.bot.database.cursor().execute("""SELECT nickname
|
return self.bot.database.cursor().execute("""SELECT nickname
|
||||||
FROM user_settings WHERE setting='alias' AND value=?
|
FROM user_settings WHERE setting='alias' AND value=?
|
||||||
AND server_id=?""", [json.dumps(target.lower()),
|
AND server_id=?""", [json.dumps(target.lower()),
|
||||||
server.id]).fetchall()
|
server.id]).fetchall()
|
||||||
|
|
||||||
def _change_nick(self, old_nickname, new_nickname):
|
def _change_nick(self, old_nickname, new_nickname):
|
||||||
self.bot.database.cursor().execute("""UPDATE user_settings
|
self.bot.database.cursor().execute("""UPDATE user_settings
|
||||||
SET nickname=? WHERE nickname=?""", [new_nickname.lower(),
|
SET nickname=? WHERE nickname=?""", [new_nickname.lower(),
|
||||||
old_nickname.lower()])
|
old_nickname.lower()])
|
||||||
|
|
||||||
def alias(self, event):
|
def alias(self, event):
|
||||||
if event["args"]:
|
if event["args"]:
|
||||||
|
@ -76,7 +88,9 @@ class Module(object):
|
||||||
aliases = self._get_aliases(target, event["server"])
|
aliases = self._get_aliases(target, event["server"])
|
||||||
if any(aliases):
|
if any(aliases):
|
||||||
event["stdout"].write("Aliases for %s: %s" % (target,
|
event["stdout"].write("Aliases for %s: %s" % (target,
|
||||||
", ".join([a[0] for a in aliases])))
|
", ".join(
|
||||||
|
[a[0] for a in
|
||||||
|
aliases])))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("%s has no aliases" % target)
|
event["stderr"].write("%s has no aliases" % target)
|
||||||
|
|
||||||
|
@ -91,6 +105,6 @@ class Module(object):
|
||||||
"alias", alias)
|
"alias", alias)
|
||||||
self._change_nick()
|
self._change_nick()
|
||||||
event["stdout"].write("This nickname has been set as the "
|
event["stdout"].write("This nickname has been set as the "
|
||||||
"main alias for it's group of aliases")
|
"main alias for it's group of aliases")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("This nickname is already a main alias")
|
event["stderr"].write("This nickname is already a main alias")
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
import base64
|
import base64
|
||||||
import EventManager
|
import EventManager
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("numeric").on("001"
|
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"
|
bot.events.on("received").on("command").on("setnickserv"
|
||||||
).hook(self.set_nickserv, min_args=1, permission="setnickserv",
|
).hook(self.set_nickserv,
|
||||||
help="Set bot's nickserv password", usage="<password>",
|
min_args=1,
|
||||||
private_only=True)
|
permission="setnickserv",
|
||||||
|
help="Set bot's nickserv password",
|
||||||
|
usage="<password>",
|
||||||
|
private_only=True)
|
||||||
|
|
||||||
def on_connect(self, event):
|
def on_connect(self, event):
|
||||||
nickserv_password = event["server"].get_setting(
|
nickserv_password = event["server"].get_setting(
|
||||||
|
@ -16,7 +21,7 @@ class Module(object):
|
||||||
if nickserv_password:
|
if nickserv_password:
|
||||||
event["server"].attempted_auth = True
|
event["server"].attempted_auth = True
|
||||||
event["server"].send_message("nickserv",
|
event["server"].send_message("nickserv",
|
||||||
"identify %s" % nickserv_password)
|
"identify %s" % nickserv_password)
|
||||||
|
|
||||||
def set_nickserv(self, event):
|
def set_nickserv(self, event):
|
||||||
nickserv_password = event["args"]
|
nickserv_password = event["args"]
|
||||||
|
|
593
modules/nr.py
593
modules/nr.py
|
@ -14,35 +14,42 @@ from suds import WebFault
|
||||||
|
|
||||||
URL = 'https://lite.realtime.nationalrail.co.uk/OpenLDBSVWS/wsdl.aspx?ver=2016-02-16'
|
URL = 'https://lite.realtime.nationalrail.co.uk/OpenLDBSVWS/wsdl.aspx?ver=2016-02-16'
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "NR"
|
_name = "NR"
|
||||||
|
|
||||||
PASSENGER_ACTIVITIES = ["U", "P", "R"]
|
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):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self._client = None
|
self._client = None
|
||||||
bot.events.on("received").on("command").on("nrtrains"
|
bot.events.on("received").on("command").on("nrtrains"
|
||||||
).hook(self.trains, min_args=1,
|
).hook(self.trains,
|
||||||
help="Get train/bus services for a station (Powered by NRE)",
|
min_args=1,
|
||||||
usage="<crs_id>")
|
help="Get train/bus services for a station (Powered by NRE)",
|
||||||
|
usage="<crs_id>")
|
||||||
bot.events.on("received").on("command").on("nrservice"
|
bot.events.on("received").on("command").on("nrservice"
|
||||||
).hook(self.service, min_args=1,
|
).hook(self.service,
|
||||||
help="Get train service information for a UID, headcode or RID (Powered by NRE)",
|
min_args=1,
|
||||||
usage="<service_id>")
|
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"
|
bot.events.on("received").on("command").on("nrhead"
|
||||||
).hook(self.head, min_args=1,
|
).hook(self.head, min_args=1,
|
||||||
help="Get information for a given headcode/UID/RID (Powered by NRE)",
|
help="Get information for a given headcode/UID/RID (Powered by NRE)",
|
||||||
usage="<headcode>")
|
usage="<headcode>")
|
||||||
bot.events.on("received").on("command").on("nrcode"
|
bot.events.on("received").on("command").on("nrcode"
|
||||||
).hook(self.service_code, min_args=1,
|
).hook(self.service_code,
|
||||||
help="Get the text for a given delay/cancellation code (Powered by NRE)",
|
min_args=1,
|
||||||
usage="<code>")
|
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("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("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
|
@property
|
||||||
def client(self):
|
def client(self):
|
||||||
|
@ -70,11 +77,11 @@ class Module(object):
|
||||||
else:
|
else:
|
||||||
params[arg.replace("!", "")] = '!' not in arg
|
params[arg.replace("!", "")] = '!' not in arg
|
||||||
|
|
||||||
ret = {k: v[0] for k,v in defaults.items()}
|
ret = {k: v[0] for k, v in defaults.items()}
|
||||||
ret["default"] = True
|
ret["default"] = True
|
||||||
ret["errors"] = []
|
ret["errors"] = []
|
||||||
|
|
||||||
for k,v in params.items():
|
for k, v in params.items():
|
||||||
if not k in defaults.keys():
|
if not k in defaults.keys():
|
||||||
ret["errors"].append((k, "Invalid parameter"))
|
ret["errors"].append((k, "Invalid parameter"))
|
||||||
continue
|
continue
|
||||||
|
@ -83,7 +90,8 @@ class Module(object):
|
||||||
continue
|
continue
|
||||||
ret["default"] = False
|
ret["default"] = False
|
||||||
ret[k] = v if len(defaults[k]) == 2 else defaults[k][2](v)
|
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
|
return ret
|
||||||
|
|
||||||
def process(self, service):
|
def process(self, service):
|
||||||
|
@ -100,10 +108,12 @@ class Module(object):
|
||||||
times[a] = {"orig": service[a]}
|
times[a] = {"orig": service[a]}
|
||||||
|
|
||||||
if len(service[a]) > 5:
|
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:
|
else:
|
||||||
times[a]["datetime"] = datetime.strptime(
|
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"
|
"%Y-%m-%dT%H%M"
|
||||||
)
|
)
|
||||||
times[a]["ut"] = times[a]["datetime"].timestamp()
|
times[a]["ut"] = times[a]["datetime"].timestamp()
|
||||||
|
@ -112,17 +122,22 @@ class Module(object):
|
||||||
|
|
||||||
for k, a in times.items():
|
for k, a in times.items():
|
||||||
if not a["orig"]: continue
|
if not a["orig"]: continue
|
||||||
a["short"] = a["datetime"].strftime("%H%M") if len(a["orig"]) > 5 else a["orig"]
|
a["short"] = a["datetime"].strftime("%H%M") if len(
|
||||||
a["shortest"] = "%02d" % a["datetime"].minute if -300 < a["ut"]-ut_now < 1800 else a["short"]
|
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["prefix"] = k[2] + ("s" if k[0] == "s" else "")
|
||||||
a["estimate"] = k[0] == "e"
|
a["estimate"] = k[0] == "e"
|
||||||
a["schedule"] = k[0] == "s"
|
a["schedule"] = k[0] == "s"
|
||||||
a["on_time"] = a["ut"] - times["s"+ k[1:]]["ut"] < 300
|
a["on_time"] = a["ut"] - times["s" + k[1:]]["ut"] < 300
|
||||||
a["status"] = 1 if a["on_time"] else 2
|
a["status"] = 1 if a["on_time"] else 2
|
||||||
if "a" + k[1:] in service: a["status"] = {"d": 0, "a": 3}[k[2]]
|
if "a" + k[1:] in service: a["status"] = {"d": 0, "a": 3}[k[2]]
|
||||||
if k[0] == "s": a["status"] = 4
|
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["arrival"] = (arr + dep + [nonetime])[0]
|
||||||
times["departure"] = (dep + arr + [nonetime])[0]
|
times["departure"] = (dep + arr + [nonetime])[0]
|
||||||
times["a"], times["d"] = (arr + [nonetime])[0], (dep + [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"])}
|
times["max_sched"] = {"ut": max(times["sta"]["ut"], times["std"]["ut"])}
|
||||||
return times
|
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):
|
def trains(self, event):
|
||||||
client = self.client
|
client = self.client
|
||||||
|
@ -143,30 +162,51 @@ class Module(object):
|
||||||
schedule = {}
|
schedule = {}
|
||||||
|
|
||||||
location_code = event["args_split"][0].upper()
|
location_code = event["args_split"][0].upper()
|
||||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(event["args_split"]) > 1 else "", {
|
filter = self.filter(' '.join(event["args_split"][1:]) if len(
|
||||||
"dest": ('', lambda x: x.isalpha() and len(x)==3),
|
event["args_split"]) > 1 else "", {
|
||||||
"origin":('', lambda x: x.isalpha() and len(x)==3),
|
"dest": (
|
||||||
"inter": ('', lambda x: x.isalpha() and len(x)==3, lambda x: x.upper()),
|
'', lambda x: x.isalpha() and len(x) == 3),
|
||||||
"toc": ('', lambda x: x.isalpha() and len(x) == 2),
|
"origin": (
|
||||||
"dedup": (False, lambda x: type(x)==type(True)),
|
'', lambda x: x.isalpha() and len(x) == 3),
|
||||||
"plat": ('', lambda x: len(x) <= 3),
|
"inter": (
|
||||||
"type": ("departure", lambda x: x in ["departure", "arrival", "both"]),
|
'', lambda x: x.isalpha() and len(x) == 3,
|
||||||
"terminating": (False, lambda x: type(x)==type(True)),
|
lambda x: x.upper()),
|
||||||
"period": (120, lambda x: x.isdigit() and 1 <= int(x) <= 480, lambda x: int(x)),
|
"toc": (
|
||||||
"nonpassenger": (False, lambda x: type(x)==type(True)),
|
'', lambda x: x.isalpha() and len(x) == 2),
|
||||||
"time": ("", lambda x: len(x)==4 and x.isdigit()),
|
"dedup": (
|
||||||
"date": ("", lambda x: len(x)==10),
|
False, lambda x: type(x) == type(True)),
|
||||||
"tops": (None, lambda x: len(x)<4 and x.isdigit()),
|
"plat": ('', lambda x: len(x) <= 3),
|
||||||
"power": (None, lambda x: x.upper() in ["EMU", "DMU", "HST", "D", "E"], lambda x: x.upper()),
|
"type": ("departure",
|
||||||
"crs": (False, lambda x: type(x)==type(True)),
|
lambda x: x in ["departure",
|
||||||
"st": (False, lambda x: type(x)==type(True))
|
"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)),
|
||||||
|
"st": (False, lambda x: type(x) == type(True))
|
||||||
|
})
|
||||||
|
|
||||||
if filter["errors"]:
|
if filter["errors"]:
|
||||||
return event["stderr"].write("Filter: " + filter["errors_summary"])
|
return event["stderr"].write("Filter: " + filter["errors_summary"])
|
||||||
|
|
||||||
if filter["inter"] and filter["type"]!="departure":
|
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")
|
nr_filterlist = client.factory.create("filterList")
|
||||||
if filter["inter"]: nr_filterlist.crs.append(filter["inter"])
|
if filter["inter"]: nr_filterlist.crs.append(filter["inter"])
|
||||||
|
@ -177,30 +217,41 @@ class Module(object):
|
||||||
now = now.replace(minute=int(filter["time"][2:]))
|
now = now.replace(minute=int(filter["time"][2:]))
|
||||||
if filter["date"]:
|
if filter["date"]:
|
||||||
newdate = datetime.strptime(filter["date"], "%Y-%m-%d").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:
|
try:
|
||||||
query = method(100, location_code, now.isoformat().split(".")[0], filter["period"],
|
query = method(100, location_code, now.isoformat().split(".")[0],
|
||||||
nr_filterlist, "to", '', "PBS", filter["nonpassenger"])
|
filter["period"],
|
||||||
|
nr_filterlist, "to", '', "PBS",
|
||||||
|
filter["nonpassenger"])
|
||||||
except WebFault as detail:
|
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.")
|
return event["stderr"].write("Invalid CRS code.")
|
||||||
else:
|
else:
|
||||||
return event["stderr"].write("An error occurred.")
|
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"):
|
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["stationManagerCode"])
|
query["locationName"], query["crs"], query["stationManager"],
|
||||||
|
query["stationManagerCode"])
|
||||||
else:
|
else:
|
||||||
station_summary = "%s (%s, %s%s)" % (query["locationName"], query["crs"], query["stationManagerCode"],
|
station_summary = "%s (%s, %s%s)" % (
|
||||||
", %s%s severe messages%s" % (Utils.color(Utils.COLOR_RED), nrcc_severe, Utils.color(Utils.FONT_RESET)) if nrcc_severe else ""
|
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:
|
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(
|
||||||
station_summary, filter["period"]))
|
"%s: No services for the next %s minutes" % (
|
||||||
|
station_summary, filter["period"]))
|
||||||
|
|
||||||
trains = []
|
trains = []
|
||||||
services = []
|
services = []
|
||||||
|
@ -209,107 +260,152 @@ class Module(object):
|
||||||
if "ferryServices" in query: services += query["ferryServices"][0]
|
if "ferryServices" in query: services += query["ferryServices"][0]
|
||||||
for t in services:
|
for t in services:
|
||||||
parsed = {
|
parsed = {
|
||||||
"rid" : t["rid"],
|
"rid": t["rid"],
|
||||||
"uid" : t["uid"],
|
"uid": t["uid"],
|
||||||
"head" : t["trainid"],
|
"head": t["trainid"],
|
||||||
"platform": '?' if not "platform" in t else t["platform"],
|
"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": "",
|
"platform_prefix": "",
|
||||||
"toc": t["operatorCode"],
|
"toc": t["operatorCode"],
|
||||||
"cancelled" : t["isCancelled"] if "isCancelled" in t else False,
|
"cancelled": t["isCancelled"] if "isCancelled" in t else False,
|
||||||
"delayed" : t["departureType"]=="Delayed" if "departureType" in t else None,
|
"delayed": t[
|
||||||
"cancel_reason" : t["cancelReason"]["value"] if "cancelReason" in t else "",
|
"departureType"] == "Delayed" if "departureType" in t else None,
|
||||||
"delay_reason" : t["delayReason"]["value"] if "delayReason" in t else "",
|
"cancel_reason": t["cancelReason"][
|
||||||
"terminating" : not "std" in t and not "etd" in t and not "atd" in t,
|
"value"] if "cancelReason" in t else "",
|
||||||
"bus" : t["trainid"]=="0B00",
|
"delay_reason": t["delayReason"][
|
||||||
"times" : self.process(t),
|
"value"] if "delayReason" in t else "",
|
||||||
"activity" : self.reduced_activities(t["activities"]),
|
"terminating": not "std" in t and not "etd" in t and not "atd" in t,
|
||||||
}
|
"bus": t["trainid"] == "0B00",
|
||||||
parsed["destinations"] = [{"name": a["locationName"], "tiploc": a["tiploc"],
|
"times": self.process(t),
|
||||||
"crs": a["crs"] if "crs" in a else '', "code": a["crs"] if "crs"
|
"activity": self.reduced_activities(t["activities"]),
|
||||||
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]]
|
for a in t["destination"][0]]
|
||||||
|
|
||||||
parsed["origins"] = [{"name": a["locationName"], "tiploc": a["tiploc"],
|
parsed["origins"] = [
|
||||||
"crs": a["crs"] if "crs" in a else '', "code": a["crs"] if "crs"
|
{"name": a["locationName"], "tiploc": a["tiploc"],
|
||||||
in a else a["tiploc"], "via": a["via"] if "via" in a else ''}
|
"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]]
|
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"]:
|
if parsed["cancelled"] or parsed["delayed"]:
|
||||||
for k, time in parsed["times"].items():
|
for k, time in parsed["times"].items():
|
||||||
time["short"], time["on_time"], time["status"], time["prefix"] = (
|
time["short"], time["on_time"], time["status"], time[
|
||||||
"%s:%s" % ("C" if parsed["cancel_reason"] else "D", parsed["cancel_reason"] or parsed["delay_reason"] or "?"),
|
"prefix"] = (
|
||||||
|
"%s:%s" % ("C" if parsed["cancel_reason"] else "D",
|
||||||
|
parsed["cancel_reason"] or parsed[
|
||||||
|
"delay_reason"] or "?"),
|
||||||
False, 2, ""
|
False, 2, ""
|
||||||
)
|
)
|
||||||
|
|
||||||
trains.append(parsed)
|
trains.append(parsed)
|
||||||
|
|
||||||
if eagle_url:
|
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:
|
if summary_query:
|
||||||
for t in trains:
|
for t in trains:
|
||||||
summary = summary_query[t["uid"]]
|
summary = summary_query[t["uid"]]
|
||||||
t.update(summary)
|
t.update(summary)
|
||||||
summary_plat = summary.get("platforms", {}).get(query["crs"])
|
summary_plat = summary.get("platforms", {}).get(
|
||||||
if summary_plat and t["platform"]=="?":
|
query["crs"])
|
||||||
|
if summary_plat and t["platform"] == "?":
|
||||||
t["platform"], t["platform_prefix"] = summary_plat, "s"
|
t["platform"], t["platform_prefix"] = summary_plat, "s"
|
||||||
|
|
||||||
for t in trains:
|
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" % (
|
||||||
if a["via"] else '') for a in t["destinations"]])
|
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["destinations"]])
|
||||||
if a["via"] else '') for a in t["origins"]])
|
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 = []
|
trains_filtered = []
|
||||||
train_locs_toc = []
|
train_locs_toc = []
|
||||||
|
|
||||||
for train in trains:
|
for train in trains:
|
||||||
if not True in [
|
if not True in [
|
||||||
(train["destinations"], train["toc"]) in train_locs_toc and (filter["dedup"] or filter["default"]),
|
(train["destinations"], train["toc"]) in train_locs_toc and (
|
||||||
filter["dest"] and not filter["dest"].upper() in [a["code"] for a in train["destinations"]],
|
filter["dedup"] or filter["default"]),
|
||||||
filter["origin"] and not filter["origin"].upper() in [a["code"] for a in train["origins"]],
|
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["toc"] and not filter["toc"].upper() == train["toc"],
|
||||||
filter["plat"] and not filter["plat"] == train["platform"],
|
filter["plat"] and not filter["plat"] == train["platform"],
|
||||||
filter["type"] == "departure" and train["terminating"],
|
filter["type"] == "departure" and train["terminating"],
|
||||||
filter["type"] == "arrival" and train["departure_only"],
|
filter["type"] == "arrival" and train["departure_only"],
|
||||||
filter["terminating"] and not train["terminating"],
|
filter["terminating"] and not train["terminating"],
|
||||||
filter["tops"] and not filter["tops"] in train.get("tops_possible", []),
|
filter["tops"] and not filter["tops"] in train.get(
|
||||||
filter["power"] and not filter["power"]==train.get("power_type", None),
|
"tops_possible", []),
|
||||||
|
filter["power"] and not filter["power"] == train.get(
|
||||||
|
"power_type", None),
|
||||||
]:
|
]:
|
||||||
train_locs_toc.append((train["destinations"], train["toc"]))
|
train_locs_toc.append((train["destinations"], train["toc"]))
|
||||||
trains_filtered.append(train)
|
trains_filtered.append(train)
|
||||||
if event.get("external"):
|
if event.get("external"):
|
||||||
trains_string = "\n".join(["%-6s %-4s %-2s %-3s %1s%-6s %1s %s" % (
|
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 '',
|
"~" if t["times"]["both"]["estimate"] else '',
|
||||||
t["times"]["both"]["prefix"] + t["times"]["both"]["short"],
|
t["times"]["both"]["prefix"] + t["times"]["both"]["short"],
|
||||||
"←" if t["terminating"] or filter["type"]=="arrival" else "→",
|
"←" 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[
|
||||||
) for t in trains_filtered])
|
"type"] == "arrival" else t["dest_summary"]
|
||||||
|
) for t in trains_filtered])
|
||||||
else:
|
else:
|
||||||
trains_string = ", ".join(["%s%s (%s, %s%s%s%s, %s%s%s%s%s)" % (
|
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 '',
|
"from " if not filter["type"][0] in "ad" and t[
|
||||||
t["origin_summary"] if t["terminating"] or filter["type"]=="arrival" else t["dest_summary"],
|
"terminating"] else '',
|
||||||
|
t["origin_summary"] if t["terminating"] or filter[
|
||||||
|
"type"] == "arrival" else t["dest_summary"],
|
||||||
t["uid"],
|
t["uid"],
|
||||||
t["platform_prefix"],
|
t["platform_prefix"],
|
||||||
"bus" if t["bus"] else t["platform"],
|
"bus" if t["bus"] else t["platform"],
|
||||||
"*" if t["platform_hidden"] else '',
|
"*" if t["platform_hidden"] else '',
|
||||||
"?" if "platformsAreUnreliable" in query and query["platformsAreUnreliable"] else '',
|
"?" if "platformsAreUnreliable" in query and query[
|
||||||
t["times"][filter["type"]]["prefix"].replace(filter["type"][0], '') if not t["cancelled"] else "",
|
"platformsAreUnreliable"] else '',
|
||||||
|
t["times"][filter["type"]]["prefix"].replace(filter["type"][0],
|
||||||
|
'') if not t[
|
||||||
|
"cancelled"] else "",
|
||||||
Utils.color(colours[t["times"][filter["type"]]["status"]]),
|
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),
|
Utils.color(Utils.FONT_RESET),
|
||||||
bool(t["activity"])*", " + "+".join(t["activity"]),
|
bool(t["activity"]) * ", " + "+".join(t["activity"]),
|
||||||
) for t in trains_filtered])
|
) for t in trains_filtered])
|
||||||
if event.get("external"):
|
if event.get("external"):
|
||||||
event["stdout"].write("%s%s\n%s" % (
|
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:
|
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):
|
def service(self, event):
|
||||||
client = self.client
|
client = self.client
|
||||||
|
@ -317,8 +413,9 @@ class Module(object):
|
||||||
external = event.get("external", False)
|
external = event.get("external", False)
|
||||||
|
|
||||||
SCHEDULE_STATUS = {"B": "perm bus", "F": "freight train", "P": "train",
|
SCHEDULE_STATUS = {"B": "perm bus", "F": "freight train", "P": "train",
|
||||||
"S": "ship", "T": "trip", "1": "train", "2": "freight",
|
"S": "ship", "T": "trip", "1": "train",
|
||||||
"3": "trip", "4": "ship", "5": "bus"}
|
"2": "freight",
|
||||||
|
"3": "trip", "4": "ship", "5": "bus"}
|
||||||
|
|
||||||
eagle_key = self.bot.config["eagle-api-key"]
|
eagle_key = self.bot.config["eagle-api-key"]
|
||||||
eagle_url = self.bot.config["eagle-api-url"]
|
eagle_url = self.bot.config["eagle-api-url"]
|
||||||
|
@ -327,10 +424,13 @@ class Module(object):
|
||||||
|
|
||||||
service_id = event["args_split"][0]
|
service_id = event["args_split"][0]
|
||||||
|
|
||||||
filter = self.filter(' '.join(event["args_split"][1:]) if len(event["args_split"]) > 1 else "", {
|
filter = self.filter(' '.join(event["args_split"][1:]) if len(
|
||||||
"passing": (False, lambda x: type(x)==type(True)),
|
event["args_split"]) > 1 else "", {
|
||||||
"type": ("arrival", lambda x: x in ["arrival", "departure"])
|
"passing": (
|
||||||
})
|
False, lambda x: type(x) == type(True)),
|
||||||
|
"type": ("arrival", lambda x: x in ["arrival",
|
||||||
|
"departure"])
|
||||||
|
})
|
||||||
|
|
||||||
if filter["errors"]:
|
if filter["errors"]:
|
||||||
event["stderr"].write("Filter: " + filter["errors_summary"])
|
event["stderr"].write("Filter: " + filter["errors_summary"])
|
||||||
|
@ -338,18 +438,27 @@ class Module(object):
|
||||||
|
|
||||||
rid = service_id
|
rid = service_id
|
||||||
if len(service_id) <= 8:
|
if len(service_id) <= 8:
|
||||||
query = client.service.QueryServices(service_id, datetime.utcnow().date().isoformat(),
|
query = client.service.QueryServices(service_id,
|
||||||
datetime.utcnow().time().strftime("%H:%M:%S+0000"))
|
datetime.utcnow().date().isoformat(),
|
||||||
|
datetime.utcnow().time().strftime(
|
||||||
|
"%H:%M:%S+0000"))
|
||||||
if eagle_url:
|
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:
|
if schedule_query:
|
||||||
schedule = schedule_query["current"]
|
schedule = schedule_query["current"]
|
||||||
if not query and not schedule:
|
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:
|
if query and len(query["serviceList"][0]) > 1:
|
||||||
return event["stdout"].write("Identifier refers to multiple services: " +
|
return event["stdout"].write(
|
||||||
", ".join(["%s (%s->%s)" % (a["uid"], a["originCrs"], a["destinationCrs"]) for a in query["serviceList"][0]]))
|
"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: rid = query["serviceList"][0][0]["rid"]
|
||||||
|
|
||||||
if query:
|
if query:
|
||||||
|
@ -357,123 +466,181 @@ class Module(object):
|
||||||
query = client.service.GetServiceDetailsByRID(rid)
|
query = client.service.GetServiceDetailsByRID(rid)
|
||||||
if schedule:
|
if schedule:
|
||||||
sources.append("Eagle/SCHEDULE")
|
sources.append("Eagle/SCHEDULE")
|
||||||
if not query: query = {"trainid": schedule["signalling_id"] or "0000", "operator": schedule["operator_name"] or schedule["atoc_code"]}
|
if not query: query = {
|
||||||
stype = "class %s %s" % (schedule_query["tops_inferred"], schedule["power_type"]) if schedule_query["tops_inferred"] else schedule["power_type"]
|
"trainid": schedule["signalling_id"] or "0000",
|
||||||
for k,v in {
|
"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"],
|
"operatorCode": schedule["atoc_code"],
|
||||||
"serviceType": stype if stype else SCHEDULE_STATUS[schedule["status"]],
|
"serviceType": stype if stype else SCHEDULE_STATUS[
|
||||||
|
schedule["status"]],
|
||||||
}.items():
|
}.items():
|
||||||
query[k] = v
|
query[k] = v
|
||||||
|
|
||||||
disruptions = []
|
disruptions = []
|
||||||
if "cancelReason" in query:
|
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:
|
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:
|
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:
|
elif disruptions and external:
|
||||||
disruptions = ", ".join(disruptions)
|
disruptions = ", ".join(disruptions)
|
||||||
else: disruptions = ""
|
else:
|
||||||
|
disruptions = ""
|
||||||
|
|
||||||
stations = []
|
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:
|
if "locations" in query:
|
||||||
parsed = {"name": station["locationName"],
|
parsed = {"name": station["locationName"],
|
||||||
"crs": (station["crs"] if "crs" in station else station["tiploc"]).rstrip(),
|
"crs": (
|
||||||
"tiploc": station["tiploc"].rstrip(),
|
station["crs"] if "crs" in station else station[
|
||||||
"called": "atd" in station,
|
"tiploc"]).rstrip(),
|
||||||
"passing": station["isPass"] if "isPass" in station else False,
|
"tiploc": station["tiploc"].rstrip(),
|
||||||
"first": len(stations) == 0,
|
"called": "atd" in station,
|
||||||
"last" : False,
|
"passing": station[
|
||||||
"cancelled" : station["isCancelled"] if "isCancelled" in station else False,
|
"isPass"] if "isPass" in station else False,
|
||||||
"associations": [],
|
"first": len(stations) == 0,
|
||||||
"length": station["length"] if "length" in station else None,
|
"last": False,
|
||||||
"times": self.process(station),
|
"cancelled": station[
|
||||||
"platform": station["platform"] if "platform" in station else None,
|
"isCancelled"] if "isCancelled" in station else False,
|
||||||
"activity": self.activities(station["activities"]) if "activities" in station else [],
|
"associations": [],
|
||||||
"activity_p": self.reduced_activities(station["activities"]) if "activities" in station else [],
|
"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 [],
|
||||||
|
}
|
||||||
|
|
||||||
if parsed["cancelled"]:
|
if parsed["cancelled"]:
|
||||||
parsed["times"]["arrival"].update({"short": "Cancelled", "on_time": False, "status": 2})
|
parsed["times"]["arrival"].update(
|
||||||
parsed["times"]["departure"].update({"short": "Cancelled", "on_time": False, "status": 2})
|
{"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:
|
for assoc in associations:
|
||||||
parsed_assoc = {
|
parsed_assoc = {
|
||||||
"uid_assoc": assoc.uid,
|
"uid_assoc": assoc.uid,
|
||||||
"category": {"divide": "VV", "join": "JJ", "next": "NP"}[assoc["category"]],
|
"category":
|
||||||
"from": parsed["first"], "direction": assoc["destTiploc"].rstrip()==parsed["tiploc"],
|
{"divide": "VV", "join": "JJ", "next": "NP"}[
|
||||||
"origin_name": assoc["origin"], "origin_tiploc": assoc["originTiploc"],
|
assoc["category"]],
|
||||||
"origin_crs": assoc["originCRS"] if "originCRS" in assoc else None,
|
"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_name": assoc["destination"],
|
||||||
"dest_crs": assoc["destCRS"] if "destCRS" in assoc else None,
|
"dest_tiploc": assoc["destTiploc"],
|
||||||
|
"dest_crs": assoc[
|
||||||
|
"destCRS"] if "destCRS" in assoc else None,
|
||||||
|
|
||||||
"far_name": assoc["destination"], "far_tiploc": assoc["destTiploc"],
|
"far_name": assoc["destination"],
|
||||||
"far_crs": assoc["destCRS"] if "destCRS" in assoc else None,
|
"far_tiploc": assoc["destTiploc"],
|
||||||
}
|
"far_crs": assoc[
|
||||||
|
"destCRS"] if "destCRS" in assoc else None,
|
||||||
|
}
|
||||||
if parsed_assoc["direction"]:
|
if parsed_assoc["direction"]:
|
||||||
parsed_assoc.update({"far_name": parsed_assoc["origin_name"],
|
parsed_assoc.update(
|
||||||
"far_tiploc": parsed_assoc["origin_tiploc"], "far_crs": parsed_assoc["origin_crs"]})
|
{"far_name": parsed_assoc["origin_name"],
|
||||||
|
"far_tiploc": parsed_assoc["origin_tiploc"],
|
||||||
|
"far_crs": parsed_assoc["origin_crs"]})
|
||||||
parsed["associations"].append(parsed_assoc)
|
parsed["associations"].append(parsed_assoc)
|
||||||
else:
|
else:
|
||||||
parsed = {"name": (station["name"] or "none"),
|
parsed = {"name": (station["name"] or "none"),
|
||||||
"crs": station["crs"] if station["crs"] else station["tiploc"],
|
"crs": station["crs"] if station["crs"] else station[
|
||||||
"tiploc": station["tiploc"],
|
"tiploc"],
|
||||||
"called": False,
|
"tiploc": station["tiploc"],
|
||||||
"passing": bool(station.get("pass")),
|
"called": False,
|
||||||
"first": len(stations) == 0,
|
"passing": bool(station.get("pass")),
|
||||||
"last" : False,
|
"first": len(stations) == 0,
|
||||||
"cancelled" : False,
|
"last": False,
|
||||||
"length": None,
|
"cancelled": False,
|
||||||
"times": self.process(station["dolphin_times"]),
|
"length": None,
|
||||||
"platform": station["platform"],
|
"times": self.process(station["dolphin_times"]),
|
||||||
"associations": station["associations"] or [],
|
"platform": station["platform"],
|
||||||
"activity": self.activities(station["activity"]),
|
"associations": station["associations"] or [],
|
||||||
"activity_p": self.reduced_activities(station["activity"]),
|
"activity": self.activities(station["activity"]),
|
||||||
}
|
"activity_p": self.reduced_activities(
|
||||||
|
station["activity"]),
|
||||||
|
}
|
||||||
stations.append(parsed)
|
stations.append(parsed)
|
||||||
|
|
||||||
[a for a in stations if a["called"] or a["first"]][-1]["last"] = True
|
[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
|
if not station["first"]: station["called"] = True
|
||||||
|
|
||||||
for station in stations:
|
for station in stations:
|
||||||
for assoc in station["associations"]:
|
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"]:
|
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"]:
|
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["summary"] = "%s%s (%s%s%s%s%s%s%s)%s" % (
|
||||||
"*" * station["passing"],
|
"*" * station["passing"],
|
||||||
station["name"],
|
station["name"],
|
||||||
station["crs"] + ", " if station["name"] != station["crs"] else '',
|
station["crs"] + ", " if station["name"] != station[
|
||||||
station["length"] + " cars, " if station["length"] and (station["first"] or (station["last"]) or station["associations"]) else '',
|
"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 '') +
|
("~" if station["times"][filter["type"]]["estimate"] else '') +
|
||||||
station["times"][filter["type"]]["prefix"].replace(filter["type"][0], ""),
|
station["times"][filter["type"]]["prefix"].replace(
|
||||||
Utils.color(colours[station["times"][filter["type"]]["status"]]),
|
filter["type"][0], ""),
|
||||||
|
Utils.color(
|
||||||
|
colours[station["times"][filter["type"]]["status"]]),
|
||||||
station["times"][filter["type"]]["short"],
|
station["times"][filter["type"]]["short"],
|
||||||
Utils.color(Utils.FONT_RESET),
|
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"]]),
|
", ".join([a["summary"] for a in station["associations"]]),
|
||||||
)
|
)
|
||||||
station["summary_external"] = "%1s%-5s %1s%-5s %-3s %-3s %-3s %s%s" % (
|
station[
|
||||||
"~"*station["times"]["a"]["estimate"] + "s"*(station["times"]["a"]["schedule"]),
|
"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"]["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["times"]["d"]["short"],
|
||||||
station["platform"] or '',
|
station["platform"] or '',
|
||||||
",".join(station["activity"]) or '',
|
",".join(station["activity"]) or '',
|
||||||
station["crs"] or station["tiploc"],
|
station["crs"] or station["tiploc"],
|
||||||
station["name"],
|
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 = []
|
stations_filtered = []
|
||||||
for station in stations:
|
for station in stations:
|
||||||
|
@ -483,8 +650,10 @@ class Module(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
stations_filtered.append(station)
|
stations_filtered.append(station)
|
||||||
if station["first"] and not station["last"] and filter["default"] and not external:
|
if station["first"] and not station["last"] and filter[
|
||||||
stations_filtered.append({"summary": "(...)", "summary_external": "(...)"})
|
"default"] and not external:
|
||||||
|
stations_filtered.append(
|
||||||
|
{"summary": "(...)", "summary_external": "(...)"})
|
||||||
|
|
||||||
done_count = len([s for s in stations if s["called"]])
|
done_count = len([s for s in stations if s["called"]])
|
||||||
total_count = len(stations)
|
total_count = len(stations)
|
||||||
|
@ -492,39 +661,57 @@ class Module(object):
|
||||||
event["stdout"].write("%s: %s\n%s%s (%s) %s %s\n\n%s" % (
|
event["stdout"].write("%s: %s\n%s%s (%s) %s %s\n\n%s" % (
|
||||||
service_id, ", ".join(sources),
|
service_id, ", ".join(sources),
|
||||||
disruptions + "\n" if disruptions else '',
|
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])
|
"\n".join([s["summary_external"] for s in stations_filtered])
|
||||||
))
|
))
|
||||||
else:
|
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" % (
|
||||||
query["trainid"], query["serviceType"],
|
disruptions, query["operatorCode"],
|
||||||
Utils.color(Utils.COLOR_LIGHTBLUE), done_count, Utils.color(Utils.FONT_RESET),
|
query["trainid"], query["serviceType"],
|
||||||
len(stations_filtered), total_count,
|
Utils.color(Utils.COLOR_LIGHTBLUE), done_count,
|
||||||
", ".join([s["summary"] for s in stations_filtered])))
|
Utils.color(Utils.FONT_RESET),
|
||||||
|
len(stations_filtered), total_count,
|
||||||
|
", ".join([s["summary"] for s in stations_filtered])))
|
||||||
|
|
||||||
def head(self, event):
|
def head(self, event):
|
||||||
client = self.client
|
client = self.client
|
||||||
service_id = event["args_split"][0]
|
service_id = event["args_split"][0]
|
||||||
|
|
||||||
query = client.service.QueryServices(service_id, datetime.utcnow().date().isoformat(),
|
query = client.service.QueryServices(service_id,
|
||||||
datetime.utcnow().time().strftime("%H:%M:%S+0000"))
|
datetime.utcnow().date().isoformat(),
|
||||||
|
datetime.utcnow().time().strftime(
|
||||||
|
"%H:%M:%S+0000"))
|
||||||
|
|
||||||
if not query:
|
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]
|
services = query["serviceList"][0]
|
||||||
if event.get("external"):
|
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:
|
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):
|
def service_code(self, event):
|
||||||
client = self.client
|
client = self.client
|
||||||
|
|
||||||
if not event["args"].isnumeric():
|
if not event["args"].isnumeric():
|
||||||
return event["stderr"].write("The delay/cancellation code must be a number")
|
return event["stderr"].write(
|
||||||
reasons = {a["code"]:(a["lateReason"], a["cancReason"]) for a in client.service.GetReasonCodeList()[0]}
|
"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:
|
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:
|
else:
|
||||||
event["stdout"].write("This doesn't seem to be a valid reason code")
|
event["stdout"].write("This doesn't seem to be a valid reason code")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import EventManager
|
import EventManager
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("numeric").on("001").hook(
|
bot.events.on("received").on("numeric").on("001").hook(
|
||||||
|
@ -11,6 +12,6 @@ class Module(object):
|
||||||
command = command.split("%%")
|
command = command.split("%%")
|
||||||
for j, part in enumerate(command[:]):
|
for j, part in enumerate(command[:]):
|
||||||
command[j] = part.replace("%nick%", event["server"
|
command[j] = part.replace("%nick%", event["server"
|
||||||
].original_nickname)
|
].original_nickname)
|
||||||
command = "%".join(command)
|
command = "%".join(command)
|
||||||
event["server"].send(command)
|
event["server"].send(command)
|
||||||
|
|
|
@ -2,7 +2,8 @@ import base64, os
|
||||||
import scrypt
|
import scrypt
|
||||||
|
|
||||||
REQUIRES_IDENTIFY = ("You need to be identified to use that command "
|
REQUIRES_IDENTIFY = ("You need to be identified to use that command "
|
||||||
"(/msg %s register | /msg %s identify)")
|
"(/msg %s register | /msg %s identify)")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -12,13 +13,20 @@ class Module(object):
|
||||||
self.preprocess_command)
|
self.preprocess_command)
|
||||||
bot.events.on("received").on("part").hook(self.on_part)
|
bot.events.on("received").on("part").hook(self.on_part)
|
||||||
bot.events.on("received").on("command").on("identify"
|
bot.events.on("received").on("command").on("identify"
|
||||||
).hook(self.identify, private_only=True, min_args=1,
|
).hook(self.identify,
|
||||||
usage="<password>", help="Identify yourself")
|
private_only=True,
|
||||||
|
min_args=1,
|
||||||
|
usage="<password>",
|
||||||
|
help="Identify yourself")
|
||||||
bot.events.on("received").on("command").on("register"
|
bot.events.on("received").on("command").on("register"
|
||||||
).hook(self.register, private_only=True, min_args=1,
|
).hook(self.register,
|
||||||
usage="<password>", help="Register your nickname")
|
private_only=True,
|
||||||
|
min_args=1,
|
||||||
|
usage="<password>",
|
||||||
|
help="Register your nickname")
|
||||||
bot.events.on("received.command.logout").hook(self.logout,
|
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(
|
bot.events.on("received.command.mypermissions").hook(
|
||||||
self.my_permissions, authenticated=True)
|
self.my_permissions, authenticated=True)
|
||||||
|
@ -33,7 +41,7 @@ class Module(object):
|
||||||
def on_part(self, event):
|
def on_part(self, event):
|
||||||
if len(event["user"].channels) == 1 and event["user"].identified:
|
if len(event["user"].channels) == 1 and event["user"].identified:
|
||||||
event["user"].send_notice("You no longer share any channels "
|
event["user"].send_notice("You no longer share any channels "
|
||||||
"with me so you have been signed out")
|
"with me so you have been signed out")
|
||||||
|
|
||||||
def _get_hash(self, user):
|
def _get_hash(self, user):
|
||||||
hash, salt = user.get_setting("authentication", (None, None))
|
hash, salt = user.get_setting("authentication", (None, None))
|
||||||
|
@ -56,7 +64,7 @@ class Module(object):
|
||||||
def identify(self, event):
|
def identify(self, event):
|
||||||
if not event["user"].channels:
|
if not event["user"].channels:
|
||||||
event["stderr"].write("You must share at least one channel "
|
event["stderr"].write("You must share at least one channel "
|
||||||
"with me before you can identify")
|
"with me before you can identify")
|
||||||
return
|
return
|
||||||
if not event["user"].identified:
|
if not event["user"].identified:
|
||||||
password = event["args_split"][0]
|
password = event["args_split"][0]
|
||||||
|
@ -66,7 +74,7 @@ class Module(object):
|
||||||
if attempt == hash:
|
if attempt == hash:
|
||||||
self._identified(event["user"])
|
self._identified(event["user"])
|
||||||
event["stdout"].write("Correct password, you have "
|
event["stdout"].write("Correct password, you have "
|
||||||
"been identified.")
|
"been identified.")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Incorrect password")
|
event["stderr"].write("Incorrect password")
|
||||||
else:
|
else:
|
||||||
|
@ -97,23 +105,23 @@ class Module(object):
|
||||||
permission = event["hook"].kwargs.get("permission", None)
|
permission = event["hook"].kwargs.get("permission", None)
|
||||||
authenticated = event["hook"].kwargs.get("authenticated", False)
|
authenticated = event["hook"].kwargs.get("authenticated", False)
|
||||||
protect_registered = event["hook"].kwargs.get("protect_registered",
|
protect_registered = event["hook"].kwargs.get("protect_registered",
|
||||||
False)
|
False)
|
||||||
|
|
||||||
if permission:
|
if permission:
|
||||||
identified = event["user"].identified
|
identified = event["user"].identified
|
||||||
user_permissions = event["user"].get_setting("permissions", [])
|
user_permissions = event["user"].get_setting("permissions", [])
|
||||||
has_permission = permission and (
|
has_permission = permission and (
|
||||||
permission in user_permissions or "*" in user_permissions)
|
permission in user_permissions or "*" in user_permissions)
|
||||||
if not identified or not has_permission:
|
if not identified or not has_permission:
|
||||||
return "You do not have permission to do that"
|
return "You do not have permission to do that"
|
||||||
elif authenticated:
|
elif authenticated:
|
||||||
if not event["user"].identified:
|
if not event["user"].identified:
|
||||||
return REQUIRES_IDENTIFY % (event["server"].nickname,
|
return REQUIRES_IDENTIFY % (event["server"].nickname,
|
||||||
event["server"].nickname)
|
event["server"].nickname)
|
||||||
elif protect_registered:
|
elif protect_registered:
|
||||||
if authentication and not event["user"].identified:
|
if authentication and not event["user"].identified:
|
||||||
return REQUIRES_IDENTIFY % (event["server"].nickname,
|
return REQUIRES_IDENTIFY % (event["server"].nickname,
|
||||||
event["server"].nickname)
|
event["server"].nickname)
|
||||||
|
|
||||||
def my_permissions(self, event):
|
def my_permissions(self, event):
|
||||||
permissions = event["user"].get_setting("permissions", [])
|
permissions = event["user"].get_setting("permissions", [])
|
||||||
|
@ -142,6 +150,7 @@ class Module(object):
|
||||||
target.set_setting("permissions", permissions)
|
target.set_setting("permissions", permissions)
|
||||||
event["stdout"].write("Gave permission '%s' to %s" % (
|
event["stdout"].write("Gave permission '%s' to %s" % (
|
||||||
permission, target.nickname))
|
permission, target.nickname))
|
||||||
|
|
||||||
def remove_permission(self, event):
|
def remove_permission(self, event):
|
||||||
permission = event["args_split"][1].lower()
|
permission = event["args_split"][1].lower()
|
||||||
target, registered, permissions = self._get_user_details(
|
target, registered, permissions = self._get_user_details(
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received.command.ping").hook(
|
bot.events.on("received.command.ping").hook(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
import EventManager
|
import EventManager
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -46,42 +47,54 @@ class Module(object):
|
||||||
if event["action"]:
|
if event["action"]:
|
||||||
self.print_line(event, "* %s %s" % (
|
self.print_line(event, "* %s %s" % (
|
||||||
nickname, event["message"]),
|
nickname, event["message"]),
|
||||||
channel=event["channel"].name)
|
channel=event["channel"].name)
|
||||||
else:
|
else:
|
||||||
self.print_line(event, "<%s> %s" % (
|
self.print_line(event, "<%s> %s" % (
|
||||||
nickname, event["message"]),
|
nickname, event["message"]),
|
||||||
channel=event["channel"].name)
|
channel=event["channel"].name)
|
||||||
|
|
||||||
def channel_message(self, event):
|
def channel_message(self, event):
|
||||||
self._on_message(event, event["user"].nickname)
|
self._on_message(event, event["user"].nickname)
|
||||||
|
|
||||||
def self_channel_message(self, event):
|
def self_channel_message(self, event):
|
||||||
self._on_message(event, event["server"].nickname)
|
self._on_message(event, event["server"].nickname)
|
||||||
|
|
||||||
def _on_notice(self, event, target):
|
def _on_notice(self, event, target):
|
||||||
self.print_line(event, "(notice->%s) <%s> %s" % (
|
self.print_line(event, "(notice->%s) <%s> %s" % (
|
||||||
target, event["user"].nickname, event["message"]))
|
target, event["user"].nickname, event["message"]))
|
||||||
|
|
||||||
def channel_notice(self, event):
|
def channel_notice(self, event):
|
||||||
self._on_notice(event, event["channel"].name)
|
self._on_notice(event, event["channel"].name)
|
||||||
|
|
||||||
def private_notice(self, event):
|
def private_notice(self, event):
|
||||||
self._on_notice(event, event["server"].nickname)
|
self._on_notice(event, event["server"].nickname)
|
||||||
|
|
||||||
def server_notice(self, event):
|
def server_notice(self, event):
|
||||||
self.print_line(event, "(server notice) %s" % event["message"])
|
self.print_line(event, "(server notice) %s" % event["message"])
|
||||||
|
|
||||||
def _on_join(self, event, nickname):
|
def _on_join(self, event, nickname):
|
||||||
if not self.bot.args.verbose:
|
if not self.bot.args.verbose:
|
||||||
self.print_line(event, "%s joined %s" % (nickname,
|
self.print_line(event, "%s joined %s" % (nickname,
|
||||||
event["channel"].name))
|
event["channel"].name))
|
||||||
|
|
||||||
def join(self, event):
|
def join(self, event):
|
||||||
self._on_join(event, event["user"].nickname)
|
self._on_join(event, event["user"].nickname)
|
||||||
|
|
||||||
def self_join(self, event):
|
def self_join(self, event):
|
||||||
self._on_join(event, event["server"].nickname)
|
self._on_join(event, event["server"].nickname)
|
||||||
|
|
||||||
def _on_part(self, event, nickname):
|
def _on_part(self, event, nickname):
|
||||||
if not self.bot.args.verbose:
|
if not self.bot.args.verbose:
|
||||||
self.print_line(event, "%s left %s%s" % (nickname,
|
self.print_line(event, "%s left %s%s" % (nickname,
|
||||||
event["channel"].name, "" if not event[
|
event["channel"].name,
|
||||||
"reason"] else " (%s)" % event["reason"]))
|
"" if not event[
|
||||||
|
"reason"] else " (%s)" %
|
||||||
|
event[
|
||||||
|
"reason"]))
|
||||||
|
|
||||||
def part(self, event):
|
def part(self, event):
|
||||||
self._on_part(event, event["user"].nickname)
|
self._on_part(event, event["user"].nickname)
|
||||||
|
|
||||||
def self_part(self, event):
|
def self_part(self, event):
|
||||||
self._on_part(event, event["server"].nickname)
|
self._on_part(event, event["server"].nickname)
|
||||||
|
|
||||||
|
@ -93,24 +106,32 @@ class Module(object):
|
||||||
def on_quit(self, event):
|
def on_quit(self, event):
|
||||||
if not self.bot.args.verbose:
|
if not self.bot.args.verbose:
|
||||||
self.print_line(event, "%s quit%s" % (event["user"].nickname,
|
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):
|
def _on_kick(self, event, nickname):
|
||||||
if not self.bot.args.verbose:
|
if not self.bot.args.verbose:
|
||||||
self.print_line(event, "%s kicked %s from %s%s" % (
|
self.print_line(event, "%s kicked %s from %s%s" % (
|
||||||
event["user"].nickname, nickname, event["channel"].name,
|
event["user"].nickname, nickname, event["channel"].name,
|
||||||
"" if not event["reason"] else " (%s)" % event["reason"]))
|
"" if not event["reason"] else " (%s)" % event["reason"]))
|
||||||
|
|
||||||
def kick(self, event):
|
def kick(self, event):
|
||||||
self._on_kick(event, event["target_user"].nickname)
|
self._on_kick(event, event["target_user"].nickname)
|
||||||
|
|
||||||
def self_kick(self, event):
|
def self_kick(self, event):
|
||||||
self._on_kick(event, event["server"].nickname)
|
self._on_kick(event, event["server"].nickname)
|
||||||
|
|
||||||
def _on_topic(self, event, setter, action, topic, channel):
|
def _on_topic(self, event, setter, action, topic, channel):
|
||||||
self.print_line(event, "topic %s by %s: %s" % (action, setter,
|
self.print_line(event, "topic %s by %s: %s" % (action, setter,
|
||||||
topic), channel=channel.name)
|
topic),
|
||||||
|
channel=channel.name)
|
||||||
|
|
||||||
def on_topic(self, event):
|
def on_topic(self, event):
|
||||||
self._on_topic(event, event["user"].nickname, "changed",
|
self._on_topic(event, event["user"].nickname, "changed",
|
||||||
event["topic"], event["channel"])
|
event["topic"], event["channel"])
|
||||||
|
|
||||||
def on_333(self, event):
|
def on_333(self, event):
|
||||||
self._on_topic(event, event["setter"], "set",
|
self._on_topic(event, event["setter"], "set",
|
||||||
event["channel"].topic, event["channel"])
|
event["channel"].topic, event["channel"])
|
||||||
|
|
104
modules/quit.py
104
modules/quit.py
|
@ -1,59 +1,60 @@
|
||||||
import random
|
import random
|
||||||
|
|
||||||
QUOTES = {
|
QUOTES = {
|
||||||
"You can build a throne with bayonets, but it's difficult to sit on it." : "Boris Yeltsin",
|
"You can build a throne with bayonets, but it's difficult to sit on it.": "Boris Yeltsin",
|
||||||
"We don't appreciate what we have until it's gone. Freedom is like that. It's like air. When you have it, you don't notice it." : "Boris Yeltsin",
|
"We don't appreciate what we have until it's gone. Freedom is like that. It's like air. When you have it, you don't notice it.": "Boris Yeltsin",
|
||||||
"They accused us of suppressing freedom of expression. This was a lie and we could not let them publish it." : "Nelba Blandon, as director of censorship, Nicaragua",
|
"They accused us of suppressing freedom of expression. This was a lie and we could not let them publish it.": "Nelba Blandon, as director of censorship, Nicaragua",
|
||||||
"Death solves all problems - no man, no problem." : "Anatoly Rybakov",
|
"Death solves all problems - no man, no problem.": "Anatoly Rybakov",
|
||||||
"If we don't end war, war will end us." : "H.G. Wells",
|
"If we don't end war, war will end us.": "H.G. Wells",
|
||||||
"All that is necessary for evil to succeed is for good men to do nothing." : "Edmund Burke",
|
"All that is necessary for evil to succeed is for good men to do nothing.": "Edmund Burke",
|
||||||
"Live well. It is the greatest revenge." : "The Talmud",
|
"Live well. It is the greatest revenge.": "The Talmud",
|
||||||
"To improve is to change, so to be perfect is to have changed often." : "Winston Churchill",
|
"To improve is to change, so to be perfect is to have changed often.": "Winston Churchill",
|
||||||
"I believe it is peace for our time." : "Neville Chamberlain",
|
"I believe it is peace for our time.": "Neville Chamberlain",
|
||||||
"Orbiting Earth in the spaceship, I saw how beautiful our planet is. People, let us preserve and increase this beauty, not destroy it!" : "Yuri Gagarin",
|
"Orbiting Earth in the spaceship, I saw how beautiful our planet is. People, let us preserve and increase this beauty, not destroy it!": "Yuri Gagarin",
|
||||||
"Science is not everything, but science is very beautiful." : "Robert Oppenheimer",
|
"Science is not everything, but science is very beautiful.": "Robert Oppenheimer",
|
||||||
"We choose to go to the Moon! We choose to go to the Moon in this decade and do the other things, not because they are easy, but because they are hard." : "",
|
"We choose to go to the Moon! We choose to go to the Moon in this decade and do the other things, not because they are easy, but because they are hard.": "",
|
||||||
"You teach a child to read, and he or her will be able to pass a literacy test." : "George W Bush",
|
"You teach a child to read, and he or her will be able to pass a literacy test.": "George W Bush",
|
||||||
"I know the human being and fish can coexist peacefully." : "George W Bush",
|
"I know the human being and fish can coexist peacefully.": "George W Bush",
|
||||||
"They misunderestimated me." : "George W Bush",
|
"They misunderestimated me.": "George W Bush",
|
||||||
"I'm an Internet expert too." : "Kim Jong Il",
|
"I'm an Internet expert too.": "Kim Jong Il",
|
||||||
"So long, and thanks for all the fish" : "",
|
"So long, and thanks for all the fish": "",
|
||||||
"It is a lie that I made the people starve." : "Nicolae Ceaușescu",
|
"It is a lie that I made the people starve.": "Nicolae Ceaușescu",
|
||||||
"As far as I know - effective immediately, without delay." : "Günter Schabowski",
|
"As far as I know - effective immediately, without delay.": "Günter Schabowski",
|
||||||
"Not all those who wander are lost." : "J.R.R. Tolkien",
|
"Not all those who wander are lost.": "J.R.R. Tolkien",
|
||||||
"Life would be tragic if it weren't funny." : "Stephen Hawking",
|
"Life would be tragic if it weren't funny.": "Stephen Hawking",
|
||||||
"We are such stuff as dreams are made on; and our little life is rounded with a sleep." : "",
|
"We are such stuff as dreams are made on; and our little life is rounded with a sleep.": "",
|
||||||
"Do androids dream of electric sheep?" : "",
|
"Do androids dream of electric sheep?": "",
|
||||||
"Love all, trust a few, do wrong to none." : "William Shakespeare",
|
"Love all, trust a few, do wrong to none.": "William Shakespeare",
|
||||||
"Patriotism is not enough. I must have no hatred or bitterness towards any one." : "Edith Cavell",
|
"Patriotism is not enough. I must have no hatred or bitterness towards any one.": "Edith Cavell",
|
||||||
"The monuments of wit survive the monuments of power." : "Francis Bacon",
|
"The monuments of wit survive the monuments of power.": "Francis Bacon",
|
||||||
"Human ingenuity cannot concoct a cipher which human ingenuity cannot resolve" : "Edgar Allan Poe",
|
"Human ingenuity cannot concoct a cipher which human ingenuity cannot resolve": "Edgar Allan Poe",
|
||||||
"Nobody has the intention to erect a wall" : "Walter Ulbricht",
|
"Nobody has the intention to erect a wall": "Walter Ulbricht",
|
||||||
"We're all completely fucked. I'm fucked. You're fucked. [...] It has been the biggest cock-up ever and we're all completely fucked" : "Richard Mottram",
|
"We're all completely fucked. I'm fucked. You're fucked. [...] It has been the biggest cock-up ever and we're all completely fucked": "Richard Mottram",
|
||||||
"The security aspect of cyber is very, very tough. And maybe it's hardly doable." : "Donald Trump",
|
"The security aspect of cyber is very, very tough. And maybe it's hardly doable.": "Donald Trump",
|
||||||
"The Internet. The hate machine, the love machine, the machine powered by many machines. We are all part of it, helping it grow, and helping it grow on us." : "Topiary",
|
"The Internet. The hate machine, the love machine, the machine powered by many machines. We are all part of it, helping it grow, and helping it grow on us.": "Topiary",
|
||||||
"Every great historical event began as a utopia and ended as a reality." : "Richard Nikolaus Eijiro",
|
"Every great historical event began as a utopia and ended as a reality.": "Richard Nikolaus Eijiro",
|
||||||
"Strange women lying in ponds distributing swords is no basis for a system of government!" : "",
|
"Strange women lying in ponds distributing swords is no basis for a system of government!": "",
|
||||||
"My hovercraft is full of eels." : "",
|
"My hovercraft is full of eels.": "",
|
||||||
"That was only a prelude; where they burn books, they will in the end also burn people" : "Heinrich Heine",
|
"That was only a prelude; where they burn books, they will in the end also burn people": "Heinrich Heine",
|
||||||
'Never, "for the sake of peace and quiet", deny your own experience or convictions.' : "Dag Hammarskjöld",
|
'Never, "for the sake of peace and quiet", deny your own experience or convictions.': "Dag Hammarskjöld",
|
||||||
"Quis custodiet ipsos custodes?" : "",
|
"Quis custodiet ipsos custodes?": "",
|
||||||
"Unless someone like you cares a whole awful lot, nothing is going to get better. It's not." : "Theodor Seuss Geisel",
|
"Unless someone like you cares a whole awful lot, nothing is going to get better. It's not.": "Theodor Seuss Geisel",
|
||||||
"Wer nichts zu verbergen hat, hat auch nichts zu befürchten" : "",
|
"Wer nichts zu verbergen hat, hat auch nichts zu befürchten": "",
|
||||||
"Words will always retain their power. Words offer the means to meaning, and for those who will listen, the enunciation of truth." : "Alan Moore",
|
"Words will always retain their power. Words offer the means to meaning, and for those who will listen, the enunciation of truth.": "Alan Moore",
|
||||||
"Сейчас я вам заявляю, что вы провалились!" : "",
|
"Сейчас я вам заявляю, что вы провалились!": "",
|
||||||
"Godhet är något så enkelt: att alltid finnas för andra, att aldrig söka sig själv." : "Dag Hammarskjöld",
|
"Godhet är något så enkelt: att alltid finnas för andra, att aldrig söka sig själv.": "Dag Hammarskjöld",
|
||||||
"Fire, water and government know nothing of mercy" : "",
|
"Fire, water and government know nothing of mercy": "",
|
||||||
"The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true. So I elect for neither label" : "James Branch Cabell",
|
"The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true. So I elect for neither label": "James Branch Cabell",
|
||||||
"微乎微乎,至于无形;神乎神乎,至于无声;故能为敌之司命" : "孫子",
|
"微乎微乎,至于无形;神乎神乎,至于无声;故能为敌之司命": "孫子",
|
||||||
"If you know your enemy and know yourself, one hundred battles will not defeat you" : "Sun Tzu",
|
"If you know your enemy and know yourself, one hundred battles will not defeat you": "Sun Tzu",
|
||||||
"Come here to this gate! Mr Gorbachev, open this gate! Mr Gorbachev, tear down this wall!" : "Ronald Reagan",
|
"Come here to this gate! Mr Gorbachev, open this gate! Mr Gorbachev, tear down this wall!": "Ronald Reagan",
|
||||||
"The lamps are going out all over Europe, we shall not see them lit again in our lifetime" : "Edward Grey",
|
"The lamps are going out all over Europe, we shall not see them lit again in our lifetime": "Edward Grey",
|
||||||
"The laws of mathematics are very commendable, but the only law that applies in Australia is the law of Australia" : "Malcolm Turnbull",
|
"The laws of mathematics are very commendable, but the only law that applies in Australia is the law of Australia": "Malcolm Turnbull",
|
||||||
"He had to download the entire iOS system on his computer, he had to decrypt it, he had to do all of these things I don't even understand" : "Glenn Moramarco, as assistant U.S. attorney",
|
"He had to download the entire iOS system on his computer, he had to decrypt it, he had to do all of these things I don't even understand": "Glenn Moramarco, as assistant U.S. attorney",
|
||||||
"I don’t need to understand how encryption works" : "Amber Rudd",
|
"I don’t need to understand how encryption works": "Amber Rudd",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("get.quit-quote").hook(self.quote)
|
bot.events.on("get.quit-quote").hook(self.quote)
|
||||||
|
@ -61,4 +62,3 @@ class Module(object):
|
||||||
def quote(self, event):
|
def quote(self, event):
|
||||||
quote = random.choice(list(QUOTES.items()))
|
quote = random.choice(list(QUOTES.items()))
|
||||||
return (" - " if quote[1] else "").join(quote)
|
return (" - " if quote[1] else "").join(quote)
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,29 @@
|
||||||
import random, time
|
import random, time
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("quoteadd",
|
bot.events.on("received").on("command").on("quoteadd",
|
||||||
"qadd").hook(self.quote_add, min_args=1,
|
"qadd").hook(self.quote_add,
|
||||||
help="Added a quote to a category",
|
min_args=1,
|
||||||
usage="<category> = <quote>")
|
help="Added a quote to a category",
|
||||||
|
usage="<category> = <quote>")
|
||||||
bot.events.on("received").on("command").on("quoteget",
|
bot.events.on("received").on("command").on("quoteget",
|
||||||
"qget").hook(self.quote_get, min_args=1,
|
"qget").hook(self.quote_get,
|
||||||
help="Find a quote within a category",
|
min_args=1,
|
||||||
usage="<category> = <search>")
|
help="Find a quote within a category",
|
||||||
|
usage="<category> = <search>")
|
||||||
bot.events.on("received").on("command").on("quotedel",
|
bot.events.on("received").on("command").on("quotedel",
|
||||||
"qdel").hook(self.quote_del, min_args=1,
|
"qdel").hook(self.quote_del,
|
||||||
help="Delete a quote from a category",
|
min_args=1,
|
||||||
usage="<category> = <quote>")
|
help="Delete a quote from a category",
|
||||||
|
usage="<category> = <quote>")
|
||||||
bot.events.on("received").on("command").on("quote",
|
bot.events.on("received").on("command").on("quote",
|
||||||
"q").hook(self.quote, min_args=1,
|
"q").hook(self.quote,
|
||||||
help="Get a random quote from a category",
|
min_args=1,
|
||||||
usage="<category>")
|
help="Get a random quote from a category",
|
||||||
|
usage="<category>")
|
||||||
|
|
||||||
def category_and_quote(self, s):
|
def category_and_quote(self, s):
|
||||||
if "=" in s:
|
if "=" in s:
|
||||||
|
@ -47,12 +52,14 @@ class Module(object):
|
||||||
found.append(quote)
|
found.append(quote)
|
||||||
if found:
|
if found:
|
||||||
event["stdout"].write("%d quote%s found: %s" % (len(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:
|
else:
|
||||||
event["stderr"].write("No quotes found")
|
event["stderr"].write("No quotes found")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Please provide a category and a "
|
event["stderr"].write("Please provide a category and a "
|
||||||
"part of a quote to find")
|
"part of a quote to find")
|
||||||
|
|
||||||
def quote_del(self, event):
|
def quote_del(self, event):
|
||||||
category, remove_quote = self.category_and_quote(event["args"])
|
category, remove_quote = self.category_and_quote(event["args"])
|
||||||
|
@ -72,13 +79,13 @@ class Module(object):
|
||||||
event["stderr"].write("Quote not found")
|
event["stderr"].write("Quote not found")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Please provide a category and a quote "
|
event["stderr"].write("Please provide a category and a quote "
|
||||||
"to remove")
|
"to remove")
|
||||||
|
|
||||||
def quote(self, event):
|
def quote(self, event):
|
||||||
category = event["args"].strip().lower()
|
category = event["args"].strip().lower()
|
||||||
quotes = event["server"].get_setting("quotes-%s" % category, [])
|
quotes = event["server"].get_setting("quotes-%s" % category, [])
|
||||||
if quotes:
|
if quotes:
|
||||||
index = random.randint(0, len(quotes)-1)
|
index = random.randint(0, len(quotes) - 1)
|
||||||
nickname, time_added, quote = quotes[index]
|
nickname, time_added, quote = quotes[index]
|
||||||
event["stdout"].write("%s: %s" % (category, quote))
|
event["stdout"].write("%s: %s" % (category, quote))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
import random, uuid
|
import random, uuid
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "Random"
|
_name = "Random"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("random",
|
bot.events.on("received").on("command").on("random",
|
||||||
"rand").hook(self.random, help="Get a random number",
|
"rand").hook(self.random,
|
||||||
usage="[start] [end]")
|
help="Get a random number",
|
||||||
|
usage="[start] [end]")
|
||||||
bot.events.on("received").on("command").on("guid"
|
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):
|
def random(self, event):
|
||||||
start, end = "1", "100"
|
start, end = "1", "100"
|
||||||
|
@ -20,7 +24,7 @@ class Module(object):
|
||||||
if end > start:
|
if end > start:
|
||||||
number = random.randint(start, end)
|
number = random.randint(start, end)
|
||||||
event["stdout"].write("(%d-%d) %d" % (start, end,
|
event["stdout"].write("(%d-%d) %d" % (start, end,
|
||||||
number))
|
number))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"End must be greater than start")
|
"End must be greater than start")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -36,4 +37,3 @@ class Module(object):
|
||||||
|
|
||||||
def on_90x(self, event):
|
def on_90x(self, event):
|
||||||
event["server"].send_capability_end()
|
event["server"].send_capability_end()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Utils
|
||||||
REGEX_SPLIT = re.compile("(?<!\\\\)/")
|
REGEX_SPLIT = re.compile("(?<!\\\\)/")
|
||||||
REGEX_SED = re.compile("^s/")
|
REGEX_SED = re.compile("^s/")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -12,12 +13,13 @@ class Module(object):
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="sed",
|
"channelset").assure_call(setting="sed",
|
||||||
help="Disable/Enable sed in a channel",
|
help="Disable/Enable sed in a channel",
|
||||||
validate=Utils.bool_or_none)
|
validate=Utils.bool_or_none)
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="sed-sender-only",
|
"channelset").assure_call(setting="sed-sender-only",
|
||||||
help="Disable/Enable sed only looking at the messages "
|
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):
|
def channel_message(self, event):
|
||||||
sed_split = re.split(REGEX_SPLIT, event["message"], 3)
|
sed_split = re.split(REGEX_SPLIT, event["message"], 3)
|
||||||
|
@ -51,7 +53,7 @@ class Module(object):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self.bot.events.on("send").on("stderr").call(target=event[
|
self.bot.events.on("send").on("stderr").call(target=event[
|
||||||
"channel"], module_name="Sed", server=event["server"],
|
"channel"], module_name="Sed", server=event["server"],
|
||||||
message="Invalid regex in pattern")
|
message="Invalid regex in pattern")
|
||||||
return
|
return
|
||||||
replace = sed_split[2].replace("\\/", "/")
|
replace = sed_split[2].replace("\\/", "/")
|
||||||
|
|
||||||
|
@ -59,7 +61,8 @@ class Module(object):
|
||||||
event, "sed-sender-only", False
|
event, "sed-sender-only", False
|
||||||
) else None
|
) else None
|
||||||
line = event["channel"].buffer.find(pattern, from_self=False,
|
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:
|
if line:
|
||||||
new_message = re.sub(pattern, replace, line.message, count)
|
new_message = re.sub(pattern, replace, line.message, count)
|
||||||
if line.action:
|
if line.action:
|
||||||
|
@ -68,4 +71,6 @@ class Module(object):
|
||||||
prefix = "<%s>" % line.sender
|
prefix = "<%s>" % line.sender
|
||||||
self.bot.events.on("send").on("stdout").call(target=event[
|
self.bot.events.on("send").on("stdout").call(target=event[
|
||||||
"channel"], module_name="Sed", server=event["server"],
|
"channel"], module_name="Sed", server=event["server"],
|
||||||
message="%s %s" % (prefix, new_message))
|
message="%s %s" % (
|
||||||
|
prefix,
|
||||||
|
new_message))
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import time
|
import time
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("message").on("channel"
|
bot.events.on("received").on("message").on("channel"
|
||||||
).hook(self.channel_message)
|
).hook(self.channel_message)
|
||||||
bot.events.on("received").on("command").on("seen").hook(
|
bot.events.on("received").on("command").on("seen").hook(
|
||||||
self.seen, min_args=1,
|
self.seen, min_args=1,
|
||||||
help="Find out when a user was last seen",
|
help="Find out when a user was last seen",
|
||||||
|
@ -16,10 +17,10 @@ class Module(object):
|
||||||
|
|
||||||
def seen(self, event):
|
def seen(self, event):
|
||||||
seen_seconds = event["server"].get_user(event["args_split"][0]
|
seen_seconds = event["server"].get_user(event["args_split"][0]
|
||||||
).get_setting("seen")
|
).get_setting("seen")
|
||||||
if seen_seconds:
|
if seen_seconds:
|
||||||
since = Utils.to_pretty_time(time.time()-seen_seconds,
|
since = Utils.to_pretty_time(time.time() - seen_seconds,
|
||||||
max_units=2)
|
max_units=2)
|
||||||
event["stdout"].write("%s was last seen %s ago" % (
|
event["stdout"].write("%s was last seen %s ago" % (
|
||||||
event["args_split"][0], since))
|
event["args_split"][0], since))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -8,7 +6,8 @@ class Module(object):
|
||||||
bot.events.on("postboot").on("configure").on("set").hook(
|
bot.events.on("postboot").on("configure").on("set").hook(
|
||||||
self.postboot_set, replay=True)
|
self.postboot_set, replay=True)
|
||||||
bot.events.on("postboot").on("configure").on("channelset"
|
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(
|
bot.events.on("received").on("command").on("set").hook(
|
||||||
self.set, help="Set a specified user setting",
|
self.set, help="Set a specified user setting",
|
||||||
|
@ -18,26 +17,35 @@ class Module(object):
|
||||||
usage="<setting>", min_args=1)
|
usage="<setting>", min_args=1)
|
||||||
|
|
||||||
bot.events.on("received").on("command").on("channelset"
|
bot.events.on("received").on("command").on("channelset"
|
||||||
).hook(self.channel_set, channel_only=True,
|
).hook(self.channel_set,
|
||||||
help="Set a specified setting for the current channel",
|
channel_only=True,
|
||||||
usage="<setting> <value>", require_mode="o")
|
help="Set a specified setting for the current channel",
|
||||||
|
usage="<setting> <value>",
|
||||||
|
require_mode="o")
|
||||||
bot.events.on("received").on("command").on("channelsetoverride"
|
bot.events.on("received").on("command").on("channelsetoverride"
|
||||||
).hook(self.channel_set, channel_only=True,
|
).hook(self.channel_set,
|
||||||
help="Set a specified setting for the current channel",
|
channel_only=True,
|
||||||
usage="<setting> <value>", permission="channelsetoverride")
|
help="Set a specified setting for the current channel",
|
||||||
|
usage="<setting> <value>",
|
||||||
|
permission="channelsetoverride")
|
||||||
bot.events.on("received").on("command").on("channelget"
|
bot.events.on("received").on("command").on("channelget"
|
||||||
).hook(self.channel_get, channel_only=True,
|
).hook(self.channel_get,
|
||||||
help="Get a specified setting for the current channel",
|
channel_only=True,
|
||||||
usage="<setting>", min_args=1, require_mode="o")
|
help="Get a specified setting for the current channel",
|
||||||
|
usage="<setting>",
|
||||||
|
min_args=1,
|
||||||
|
require_mode="o")
|
||||||
|
|
||||||
def _postboot_set(self, settings, event):
|
def _postboot_set(self, settings, event):
|
||||||
settings[event["setting"]] = {}
|
settings[event["setting"]] = {}
|
||||||
settings[event["setting"]]["validate"] = event.get(
|
settings[event["setting"]]["validate"] = event.get(
|
||||||
"validate", lambda s: s)
|
"validate", lambda s: s)
|
||||||
settings[event["setting"]]["help"] = event.get("help",
|
settings[event["setting"]]["help"] = event.get("help",
|
||||||
"")
|
"")
|
||||||
|
|
||||||
def postboot_set(self, event):
|
def postboot_set(self, event):
|
||||||
self._postboot_set(self.settings, event)
|
self._postboot_set(self.settings, event)
|
||||||
|
|
||||||
def postboot_channelset(self, event):
|
def postboot_channelset(self, event):
|
||||||
self._postboot_set(self.channel_settings, event)
|
self._postboot_set(self.channel_settings, event)
|
||||||
|
|
||||||
|
@ -59,6 +67,7 @@ class Module(object):
|
||||||
else:
|
else:
|
||||||
event["stdout"].write("Available settings: %s" % (
|
event["stdout"].write("Available settings: %s" % (
|
||||||
", ".join(settings.keys())))
|
", ".join(settings.keys())))
|
||||||
|
|
||||||
def set(self, event):
|
def set(self, event):
|
||||||
self._set(self.settings, event, event["user"])
|
self._set(self.settings, event, event["user"])
|
||||||
|
|
||||||
|
@ -68,14 +77,14 @@ class Module(object):
|
||||||
def _get(self, event, setting, qualifier, value):
|
def _get(self, event, setting, qualifier, value):
|
||||||
if not value == None:
|
if not value == None:
|
||||||
event["stdout"].write("'%s'%s: %s" % (setting,
|
event["stdout"].write("'%s'%s: %s" % (setting,
|
||||||
qualifier, str(value)))
|
qualifier, str(value)))
|
||||||
else:
|
else:
|
||||||
event["stdout"].write("'%s' has no value set" % setting)
|
event["stdout"].write("'%s' has no value set" % setting)
|
||||||
|
|
||||||
def channel_get(self, event):
|
def channel_get(self, event):
|
||||||
setting = event["args_split"][0]
|
setting = event["args_split"][0]
|
||||||
self._get(event, setting, " for %s" % event["target"].name,
|
self._get(event, setting, " for %s" % event["target"].name,
|
||||||
event["target"].get_setting(setting, None))
|
event["target"].get_setting(setting, None))
|
||||||
|
|
||||||
def get(self, event):
|
def get(self, event):
|
||||||
setting = event["args_split"][0]
|
setting = event["args_split"][0]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -8,13 +9,14 @@ class Module(object):
|
||||||
|
|
||||||
def SIGINT(self, signum, frame):
|
def SIGINT(self, signum, frame):
|
||||||
print()
|
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():
|
for server in self.bot.servers.values():
|
||||||
reason = "Leaving"
|
reason = "Leaving"
|
||||||
if server.get_setting("quit-quote", True):
|
if server.get_setting("quit-quote", True):
|
||||||
reason = self.bot.events.on("get.quit-quote"
|
reason = self.bot.events.on("get.quit-quote"
|
||||||
).call_for_result(default="Leaving")
|
).call_for_result(default="Leaving")
|
||||||
server.send_quit(reason)
|
server.send_quit(reason)
|
||||||
self.bot.register_write(server)
|
self.bot.register_write(server)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#--require-config soundcloud-api-key
|
# --require-config soundcloud-api-key
|
||||||
|
|
||||||
import json, re, time
|
import json, re, time
|
||||||
import Utils
|
import Utils
|
||||||
|
@ -7,12 +7,15 @@ URL_SOUNDCLOUD_TRACK = "http://api.soundcloud.com/tracks"
|
||||||
URL_SOUNDCLOUD_RESOLVE = "http://api.soundcloud.com/resolve"
|
URL_SOUNDCLOUD_RESOLVE = "http://api.soundcloud.com/resolve"
|
||||||
REGEX_SOUNDCLOUD = "https?://soundcloud.com/([^/]+)/([^/]+)"
|
REGEX_SOUNDCLOUD = "https?://soundcloud.com/([^/]+)/([^/]+)"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "SoundCloud"
|
_name = "SoundCloud"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("soundcloud", "sc"
|
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):
|
def soundcloud(self, event):
|
||||||
query = None
|
query = None
|
||||||
|
@ -28,14 +31,14 @@ class Module(object):
|
||||||
last_soundcloud = event["buffer"].find(REGEX_SOUNDCLOUD)
|
last_soundcloud = event["buffer"].find(REGEX_SOUNDCLOUD)
|
||||||
if last_soundcloud:
|
if last_soundcloud:
|
||||||
url = re.match(REGEX_SOUNDCLOUD,
|
url = re.match(REGEX_SOUNDCLOUD,
|
||||||
last_soundcloud.message).string
|
last_soundcloud.message).string
|
||||||
|
|
||||||
if not query and not url:
|
if not query and not url:
|
||||||
event["stderr"].write("no search phrase provided")
|
event["stderr"].write("no search phrase provided")
|
||||||
return
|
return
|
||||||
has_query = not query == None
|
has_query = not query == None
|
||||||
get_params = {"limit": 1,
|
get_params = {"limit": 1,
|
||||||
"client_id": self.bot.config["soundcloud-api-key"]}
|
"client_id": self.bot.config["soundcloud-api-key"]}
|
||||||
|
|
||||||
if query:
|
if query:
|
||||||
get_params["q"] = query
|
get_params["q"] = query
|
||||||
|
@ -51,11 +54,12 @@ class Module(object):
|
||||||
title = page["title"]
|
title = page["title"]
|
||||||
user = page["user"]["username"]
|
user = page["user"]["username"]
|
||||||
duration = time.strftime("%H:%M:%S", time.gmtime(page[
|
duration = time.strftime("%H:%M:%S", time.gmtime(page[
|
||||||
"duration"]/1000))
|
"duration"] / 1000))
|
||||||
if duration.startswith("00:"):
|
if duration.startswith("00:"):
|
||||||
duration = duration[3:]
|
duration = duration[3:]
|
||||||
link = page["permalink_url"]
|
link = page["permalink_url"]
|
||||||
event["stdout"].write("%s [%s] (posted by %s) %s" % (title,
|
event["stdout"].write("%s [%s] (posted by %s) %s" % (title,
|
||||||
duration, user, link))
|
duration, user,
|
||||||
|
link))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
|
@ -3,6 +3,7 @@ import Utils
|
||||||
|
|
||||||
URL_SPOTIFY = "https://api.spotify.com/v1/search"
|
URL_SPOTIFY = "https://api.spotify.com/v1/search"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("spotify").hook(
|
bot.events.on("received").on("command").on("spotify").hook(
|
||||||
|
@ -11,7 +12,9 @@ class Module(object):
|
||||||
|
|
||||||
def spotify(self, event):
|
def spotify(self, event):
|
||||||
page = Utils.get_url(URL_SPOTIFY, get_params={"type": "track",
|
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 page:
|
||||||
if len(page["tracks"]["items"]):
|
if len(page["tracks"]["items"]):
|
||||||
item = page["tracks"]["items"][0]
|
item = page["tracks"]["items"][0]
|
||||||
|
@ -19,7 +22,7 @@ class Module(object):
|
||||||
artist_name = item["artists"][0]["name"]
|
artist_name = item["artists"][0]["name"]
|
||||||
url = item["external_urls"]["spotify"]
|
url = item["external_urls"]["spotify"]
|
||||||
event["stdout"].write("%s (by %s) %s" % (title, artist_name,
|
event["stdout"].write("%s (by %s) %s" % (title, artist_name,
|
||||||
url))
|
url))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No results found")
|
event["stderr"].write("No results found")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import time
|
import time
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.boot_time = time.time()
|
self.boot_time = time.time()
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("uptime"
|
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"
|
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):
|
def uptime(self, event):
|
||||||
seconds = int(time.time()-self.boot_time)
|
seconds = int(time.time() - self.boot_time)
|
||||||
event["stdout"].write("Uptime: %s" % Utils.to_pretty_time(
|
event["stdout"].write("Uptime: %s" % Utils.to_pretty_time(
|
||||||
seconds))
|
seconds))
|
||||||
|
|
||||||
|
@ -23,7 +26,6 @@ class Module(object):
|
||||||
channels += len(server.channels)
|
channels += len(server.channels)
|
||||||
users += len(server.users)
|
users += len(server.users)
|
||||||
|
|
||||||
|
|
||||||
response = "I currently have %d network" % networks
|
response = "I currently have %d network" % networks
|
||||||
if networks > 1:
|
if networks > 1:
|
||||||
response += "s"
|
response += "s"
|
||||||
|
|
|
@ -4,41 +4,64 @@ import random
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received.command.strax").hook(
|
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):
|
def strax(self, event):
|
||||||
suggestion_greeting = ["Might I suggest", "Can I suggest", "Should we attack immediately with"]
|
suggestion_greeting = ["Might I suggest", "Can I suggest",
|
||||||
command_greeting = ["We should attack now with", "We must attack now with", "I suggest attacking with",
|
"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"]
|
"We should coordinate an attack with"]
|
||||||
method_of_attack_a = ["full-frontal", "pincer", "surprise", "brutally excessive", "multi-pronged", "glorious",
|
method_of_attack_a = ["full-frontal", "pincer", "surprise",
|
||||||
"violent", "devastating", "superior", "fast-paced", "fleet-wide", "stealth",
|
"brutally excessive", "multi-pronged", "glorious",
|
||||||
"diversionary", "exceptional", "point-blank", "night time"]
|
"violent", "devastating", "superior",
|
||||||
method_of_attack_an = ["acid-heavy", "immediate", "overwhelming", "unstoppable", "underground", "arial",
|
"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"]
|
"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"]
|
"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",
|
"three kinds of", "atomic", "toxic", "explosive",
|
||||||
"red-hot", "thermal", "automated fire", "cluster",
|
"red-hot", "thermal", "automated fire", "cluster",
|
||||||
"enhanced germ", "energy-drink-fueled", "battle ready", "Sontaran", "military"]
|
"enhanced germ", "energy-drink-fueled",
|
||||||
attack_object = ["bees", "chainsaws", "marmots", "acid", "monkeys", "mines", "bombs", "snakes", "spiders",
|
"battle ready", "Sontaran", "military"]
|
||||||
"knives", "rockets", "sharks", "owls", "repurposed cybermats", "cannons", "alligators", "ants",
|
attack_object = ["bees", "chainsaws", "marmots", "acid", "monkeys",
|
||||||
"gorillas", "genetically enhanced cyber-elephants", "mechanoids", "KGB agents",
|
"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"]
|
"MI5 operatives", "thermonuclear missiles"]
|
||||||
attack_object_two = ["robots", "ninjas", "grenades", "a dolphin full of napalm", "dynamite",
|
attack_object_two = ["robots", "ninjas", "grenades",
|
||||||
"xenomorphs", "lots and lots of C4", "tactical nukes", "bio-weapons",
|
"a dolphin full of napalm", "dynamite",
|
||||||
"rocket launchers", "an elephant", "a memory worm for afterwards", "this pencil"]
|
"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(
|
||||||
2]) == 1 else " a " + random.choice(
|
method_of_attack_an) if random.choice([1,
|
||||||
|
2]) == 1 else " a " + random.choice(
|
||||||
method_of_attack_a)
|
method_of_attack_a)
|
||||||
|
|
||||||
greeting_choice = random.choice([1, 2])
|
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 "!"
|
exclamation = "?" if greeting_choice == 1 else "!"
|
||||||
|
|
||||||
suggestion = greeting + method_of_attack + " " + random.choice(type_of_attack) + " with " + random.choice(
|
suggestion = greeting + method_of_attack + " " + random.choice(
|
||||||
attack_adjective) + " " + random.choice(attack_object) + " and " + random.choice(
|
type_of_attack) + " with " + random.choice(
|
||||||
|
attack_adjective) + " " + random.choice(
|
||||||
|
attack_object) + " and " + random.choice(
|
||||||
attack_object_two) + exclamation
|
attack_object_two) + exclamation
|
||||||
|
|
||||||
event["stdout"].write(suggestion)
|
event["stdout"].write(suggestion)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
|
|
||||||
class Module(Thread):
|
class Module(Thread):
|
||||||
_name = "telegram"
|
_name = "telegram"
|
||||||
|
|
||||||
|
@ -26,7 +27,8 @@ class Module(Thread):
|
||||||
dolphin.events.on("signal").on("interrupt").hook(self.sigint)
|
dolphin.events.on("signal").on("interrupt").hook(self.sigint)
|
||||||
|
|
||||||
def start(self, bot, update):
|
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):
|
def handle(self, bot, update):
|
||||||
message, text = update.message, update.message.text
|
message, text = update.message, update.message.text
|
||||||
|
@ -44,19 +46,24 @@ class Module(Thread):
|
||||||
"stdout": IOWrapper(bot, message.chat_id, message.message_id),
|
"stdout": IOWrapper(bot, message.chat_id, message.message_id),
|
||||||
"stderr": IOWrapper(bot, message.chat_id, message.message_id),
|
"stderr": IOWrapper(bot, message.chat_id, message.message_id),
|
||||||
"external": True,
|
"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):
|
def sigint(self, event):
|
||||||
self.updater.stop()
|
self.updater.stop()
|
||||||
|
|
||||||
|
|
||||||
class IOWrapper:
|
class IOWrapper:
|
||||||
def __init__(self, bot, chat_id, message_id):
|
def __init__(self, bot, chat_id, message_id):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.message_id = message_id
|
self.message_id = message_id
|
||||||
|
|
||||||
def write(self, text):
|
def write(self, text):
|
||||||
if len(text)>4096-10:
|
if len(text) > 4096 - 10:
|
||||||
text = text[:4086] + "…"
|
text = text[:4086] + "…"
|
||||||
self.bot.send_message(chat_id=self.chat_id, text="```\n" + text + "\n```",
|
self.bot.send_message(chat_id=self.chat_id,
|
||||||
reply_to_message_id=self.message_id, parse_mode="Markdown")
|
text="```\n" + text + "\n```",
|
||||||
|
reply_to_message_id=self.message_id,
|
||||||
|
parse_mode="Markdown")
|
||||||
|
|
169
modules/tfl.py
169
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_ARRIVALS = "https://api.tfl.gov.uk/Line/%s/Arrivals"
|
||||||
|
|
||||||
URL_LINE = "https://api.tfl.gov.uk/Line/Mode/tube/Status"
|
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 = "https://api.tfl.gov.uk/StopPoint/%s"
|
||||||
URL_STOP_SEARCH = "https://api.tfl.gov.uk/StopPoint/Search/%s"
|
URL_STOP_SEARCH = "https://api.tfl.gov.uk/StopPoint/Search/%s"
|
||||||
|
@ -16,52 +18,62 @@ URL_VEHICLE = "https://api.tfl.gov.uk/Vehicle/%s/Arrivals"
|
||||||
|
|
||||||
URL_ROUTE = "https://api.tfl.gov.uk/Line/%s/Route/Sequence/all?excludeCrowding=True"
|
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):
|
class Module(object):
|
||||||
_name = "TFL"
|
_name = "TFL"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.result_map = {}
|
self.result_map = {}
|
||||||
bot.events.on("received").on("command").on("tflbus"
|
bot.events.on("received").on("command").on("tflbus"
|
||||||
).hook(self.bus, min_args=1,
|
).hook(self.bus, min_args=1,
|
||||||
help="Get bus due times for a TfL bus stop",
|
help="Get bus due times for a TfL bus stop",
|
||||||
usage="<stop_id>")
|
usage="<stop_id>")
|
||||||
bot.events.on("received").on("command").on("tflline"
|
bot.events.on("received").on("command").on("tflline"
|
||||||
).hook(self.line,
|
).hook(self.line,
|
||||||
help="Get line status for TfL underground lines",
|
help="Get line status for TfL underground lines",
|
||||||
usage="<line_name>")
|
usage="<line_name>")
|
||||||
bot.events.on("received").on("command").on("tflsearch"
|
bot.events.on("received").on("command").on("tflsearch"
|
||||||
).hook(self.search, min_args=1,
|
).hook(self.search,
|
||||||
help="Get a list of TfL stop IDs for a given name",
|
min_args=1,
|
||||||
usage="<name>")
|
help="Get a list of TfL stop IDs for a given name",
|
||||||
|
usage="<name>")
|
||||||
bot.events.on("received").on("command").on("tflvehicle"
|
bot.events.on("received").on("command").on("tflvehicle"
|
||||||
).hook(self.vehicle, min_args=1,
|
).hook(self.vehicle,
|
||||||
help="Get information for a given vehicle",
|
min_args=1,
|
||||||
usage="<ID>")
|
help="Get information for a given vehicle",
|
||||||
|
usage="<ID>")
|
||||||
bot.events.on("received").on("command").on("tflstop"
|
bot.events.on("received").on("command").on("tflstop"
|
||||||
).hook(self.stop, min_args=1,
|
).hook(self.stop, min_args=1,
|
||||||
help="Get information for a given stop",
|
help="Get information for a given stop",
|
||||||
usage="<stop_id>")
|
usage="<stop_id>")
|
||||||
bot.events.on("received").on("command").on("tflservice"
|
bot.events.on("received").on("command").on("tflservice"
|
||||||
).hook(self.service, min_args=1,
|
).hook(self.service,
|
||||||
help="Get service information and arrival estimates",
|
min_args=1,
|
||||||
usage="<service index>")
|
help="Get service information and arrival estimates",
|
||||||
|
usage="<service index>")
|
||||||
|
|
||||||
def vehicle_span(self, arrival_time, human=True):
|
def vehicle_span(self, arrival_time, human=True):
|
||||||
vehicle_due_iso8601 = arrival_time
|
vehicle_due_iso8601 = arrival_time
|
||||||
if "." in vehicle_due_iso8601:
|
if "." in vehicle_due_iso8601:
|
||||||
vehicle_due_iso8601 = vehicle_due_iso8601.split(".")[0]+"Z"
|
vehicle_due_iso8601 = vehicle_due_iso8601.split(".")[0] + "Z"
|
||||||
vehicle_due = datetime.datetime.strptime(vehicle_due_iso8601,
|
vehicle_due = datetime.datetime.strptime(vehicle_due_iso8601,
|
||||||
"%Y-%m-%dT%H:%M:%SZ")
|
"%Y-%m-%dT%H:%M:%SZ")
|
||||||
time_until = vehicle_due-datetime.datetime.utcnow()
|
time_until = vehicle_due - datetime.datetime.utcnow()
|
||||||
time_until = int(time_until.total_seconds()/60)
|
time_until = int(time_until.total_seconds() / 60)
|
||||||
|
|
||||||
if time_until == 0: human_time = "due"
|
if time_until == 0:
|
||||||
else: human_time = "in %s min" % time_until
|
human_time = "due"
|
||||||
|
else:
|
||||||
|
human_time = "in %s min" % time_until
|
||||||
|
|
||||||
if human: return human_time
|
if human:
|
||||||
else: return time_until
|
return human_time
|
||||||
|
else:
|
||||||
|
return time_until
|
||||||
|
|
||||||
def platform(self, platform, short=False):
|
def platform(self, platform, short=False):
|
||||||
p = re.compile("(?:(.*) - Platform (\\d+)|(.*bound) Platform (\\d+))")
|
p = re.compile("(?:(.*) - Platform (\\d+)|(.*bound) Platform (\\d+))")
|
||||||
|
@ -103,16 +115,23 @@ class Module(object):
|
||||||
for bus in bus_stop:
|
for bus in bus_stop:
|
||||||
bus_number = bus["lineName"]
|
bus_number = bus["lineName"]
|
||||||
human_time = self.vehicle_span(bus["expectedArrival"])
|
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
|
# If the mode is "tube", "Underground Station" is redundant
|
||||||
destination = bus.get("destinationName", "?")
|
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"],
|
busses.append({"route": bus_number, "time": time_until,
|
||||||
"destination": destination, "human_time": human_time, "mode": bus["modeName"],
|
"id": bus["vehicleId"],
|
||||||
"platform": bus["platformName"],
|
"destination": destination,
|
||||||
"platform_short" : self.platform(bus["platformName"], short=True)})
|
"human_time": human_time,
|
||||||
|
"mode": bus["modeName"],
|
||||||
|
"platform": bus["platformName"],
|
||||||
|
"platform_short": self.platform(
|
||||||
|
bus["platformName"], short=True)})
|
||||||
if busses:
|
if busses:
|
||||||
busses = sorted(busses, key=lambda b: b["time"])
|
busses = sorted(busses, key=lambda b: b["time"])
|
||||||
busses_filtered = []
|
busses_filtered = []
|
||||||
|
@ -122,11 +141,14 @@ class Module(object):
|
||||||
# dedup if target route isn't "*", filter if target route isn't None or "*"
|
# dedup if target route isn't "*", filter if target route isn't None or "*"
|
||||||
for b in busses:
|
for b in busses:
|
||||||
if target_bus_route != "*":
|
if target_bus_route != "*":
|
||||||
if (b["route"], b["destination"]) in bus_route_dest: continue
|
if (b["route"],
|
||||||
if bus_route_plat.count((b["route"], b["platform"])) >= 2: continue
|
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_plat.append((b["route"], b["platform"]))
|
||||||
bus_route_dest.append((b["route"], b["destination"]))
|
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)
|
busses_filtered.append(b)
|
||||||
else:
|
else:
|
||||||
busses_filtered.append(b)
|
busses_filtered.append(b)
|
||||||
|
@ -134,32 +156,33 @@ class Module(object):
|
||||||
self.result_map[event["target"].id] = busses_filtered
|
self.result_map[event["target"].id] = busses_filtered
|
||||||
|
|
||||||
# do the magic formatty things!
|
# do the magic formatty things!
|
||||||
busses_string = ", ".join(["%s (%s, %s)" % (b["destination"], b["route"], b["human_time"],
|
busses_string = ", ".join(["%s (%s, %s)" % (
|
||||||
) for b in busses_filtered])
|
b["destination"], b["route"], b["human_time"],
|
||||||
|
) for b in busses_filtered])
|
||||||
|
|
||||||
event["stdout"].write("%s (%s): %s" % (stop_name, stop_id,
|
event["stdout"].write("%s (%s): %s" % (stop_name, stop_id,
|
||||||
busses_string))
|
busses_string))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("%s: No busses due" % stop_id)
|
event["stderr"].write("%s: No busses due" % stop_id)
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Bus ID '%s' unknown" % stop_id)
|
event["stderr"].write("Bus ID '%s' unknown" % stop_id)
|
||||||
|
|
||||||
def line(self, event):
|
def line(self, event):
|
||||||
app_id = self.bot.config["tfl-api-id"]
|
app_id = self.bot.config["tfl-api-id"]
|
||||||
app_key = self.bot.config["tfl-api-key"]
|
app_key = self.bot.config["tfl-api-key"]
|
||||||
|
|
||||||
lines = Utils.get_url(URL_LINE, get_params={
|
lines = Utils.get_url(URL_LINE, get_params={
|
||||||
"app_id": app_id, "app_key": app_key}, json=True)
|
"app_id": app_id, "app_key": app_key}, json=True)
|
||||||
statuses = []
|
statuses = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
for status in line["lineStatuses"]:
|
for status in line["lineStatuses"]:
|
||||||
entry = {
|
entry = {
|
||||||
"id": line["id"],
|
"id": line["id"],
|
||||||
"name": line["name"],
|
"name": line["name"],
|
||||||
"severity": status["statusSeverity"],
|
"severity": status["statusSeverity"],
|
||||||
"description": status["statusSeverityDescription"],
|
"description": status["statusSeverityDescription"],
|
||||||
"reason": status.get("reason")
|
"reason": status.get("reason")
|
||||||
}
|
}
|
||||||
statuses.append(entry)
|
statuses.append(entry)
|
||||||
statuses = sorted(statuses, key=lambda line: line["severity"])
|
statuses = sorted(statuses, key=lambda line: line["severity"])
|
||||||
combined = collections.OrderedDict()
|
combined = collections.OrderedDict()
|
||||||
|
@ -177,7 +200,9 @@ class Module(object):
|
||||||
for status in statuses:
|
for status in statuses:
|
||||||
for arg in event["args_split"]:
|
for arg in event["args_split"]:
|
||||||
if arg.lower() in status["name"].lower():
|
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:
|
if result:
|
||||||
event["stdout"].write(result[:-2])
|
event["stdout"].write(result[:-2])
|
||||||
else:
|
else:
|
||||||
|
@ -187,16 +212,20 @@ class Module(object):
|
||||||
app_id = self.bot.config["tfl-api-id"]
|
app_id = self.bot.config["tfl-api-id"]
|
||||||
app_key = self.bot.config["tfl-api-key"]
|
app_key = self.bot.config["tfl-api-key"]
|
||||||
|
|
||||||
#As awful as this is, it also makes it ~work~.
|
# As awful as this is, it also makes it ~work~.
|
||||||
stop_name = event["args"].replace(" ", "%20")
|
stop_name = event["args"].replace(" ", "%20")
|
||||||
|
|
||||||
stop_search = Utils.get_url(URL_STOP_SEARCH % stop_name, get_params={
|
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:
|
if stop_search:
|
||||||
for stop in stop_search["matches"]:
|
for stop in stop_search["matches"]:
|
||||||
pass
|
pass
|
||||||
results = ["%s (%s): %s" % (stop["name"], ", ".join(stop["modes"]), stop["id"]) for stop in stop_search["matches"]]
|
results = ["%s (%s): %s" % (
|
||||||
event["stdout"].write("[%s results] %s" % (stop_search["total"], "; ".join(results)))
|
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:
|
else:
|
||||||
event["stderr"].write("No results")
|
event["stderr"].write("No results")
|
||||||
|
|
||||||
|
@ -207,14 +236,18 @@ class Module(object):
|
||||||
vehicle_id = event["args_split"][0]
|
vehicle_id = event["args_split"][0]
|
||||||
|
|
||||||
vehicle = Utils.get_url(URL_VEHICLE % vehicle_id, get_params={
|
vehicle = Utils.get_url(URL_VEHICLE % vehicle_id, get_params={
|
||||||
"app_id": app_id, "app_key": app_key}, json=True)[0]
|
"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"])
|
platform = self.platform(vehicle["platformName"])
|
||||||
|
|
||||||
event["stdout"].write("%s (%s) to %s. %s. Arrival at %s (%s) in %s minutes on %s" % (
|
event["stdout"].write(
|
||||||
vehicle["vehicleId"], vehicle["lineName"], vehicle["destinationName"], vehicle["currentLocation"],
|
"%s (%s) to %s. %s. Arrival at %s (%s) in %s minutes on %s" % (
|
||||||
vehicle["stationName"], vehicle["naptanId"], arrival_time, platform))
|
vehicle["vehicleId"], vehicle["lineName"],
|
||||||
|
vehicle["destinationName"], vehicle["currentLocation"],
|
||||||
|
vehicle["stationName"], vehicle["naptanId"], arrival_time,
|
||||||
|
platform))
|
||||||
|
|
||||||
def service(self, event):
|
def service(self, event):
|
||||||
app_id = self.bot.config["tfl-api-id"]
|
app_id = self.bot.config["tfl-api-id"]
|
||||||
|
@ -228,21 +261,27 @@ class Module(object):
|
||||||
return
|
return
|
||||||
results = self.result_map[event["target"].id]
|
results = self.result_map[event["target"].id]
|
||||||
if int(service_id) >= len(results):
|
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
|
return
|
||||||
service = results[int(service_id)]
|
service = results[int(service_id)]
|
||||||
arrivals = Utils.get_url(URL_LINE_ARRIVALS % service["route"], get_params={
|
arrivals = Utils.get_url(URL_LINE_ARRIVALS % service["route"],
|
||||||
"app_id": app_id, "app_key": app_key}, json=True)
|
get_params={
|
||||||
|
"app_id": app_id, "app_key": app_key},
|
||||||
|
json=True)
|
||||||
|
|
||||||
arrivals = [a for a in arrivals if a["vehicleId"] == service["id"]]
|
arrivals = [a for a in arrivals if a["vehicleId"] == service["id"]]
|
||||||
arrivals = sorted(arrivals, key=lambda b: b["timeToStation"])
|
arrivals = sorted(arrivals, key=lambda b: b["timeToStation"])
|
||||||
|
|
||||||
event["stdout"].write(
|
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)" %
|
", ".join(["%s (%s, %s)" %
|
||||||
(a["stationName"], self.platform(a.get("platformName", "?"), True),
|
(a["stationName"],
|
||||||
a["expectedArrival"][11:16]
|
self.platform(a.get("platformName", "?"), True),
|
||||||
) for a in arrivals]))
|
a["expectedArrival"][11:16]
|
||||||
|
) for a in arrivals]))
|
||||||
|
|
||||||
def stop(self, event):
|
def stop(self, event):
|
||||||
app_id = self.bot.config["tfl-api-id"]
|
app_id = self.bot.config["tfl-api-id"]
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
#--require-config bighugethesaurus-api-key
|
# --require-config bighugethesaurus-api-key
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_THESAURUS = "http://words.bighugelabs.com/api/2/%s/%s/json"
|
URL_THESAURUS = "http://words.bighugelabs.com/api/2/%s/%s/json"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("synonym",
|
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",
|
help="Get synonyms/antonyms for a provided phrase",
|
||||||
usage="<word> [type]")
|
usage="<word> [type]")
|
||||||
|
|
||||||
def thesaurus(self, event):
|
def thesaurus(self, event):
|
||||||
phrase = event["args_split"][0]
|
phrase = event["args_split"][0]
|
||||||
page = Utils.get_url(URL_THESAURUS % (self.bot.config[
|
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]
|
syn_ant = event["command"][:3]
|
||||||
if page:
|
if page:
|
||||||
if not len(event["args_split"]) > 1:
|
if not len(event["args_split"]) > 1:
|
||||||
|
@ -27,7 +30,7 @@ class Module(object):
|
||||||
word_types = sorted(word_types)
|
word_types = sorted(word_types)
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
"Available categories for %s: %s" % (
|
"Available categories for %s: %s" % (
|
||||||
phrase, ", ".join(word_types)))
|
phrase, ", ".join(word_types)))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No categories available")
|
event["stderr"].write("No categories available")
|
||||||
else:
|
else:
|
||||||
|
@ -36,7 +39,7 @@ class Module(object):
|
||||||
if syn_ant in page[category]:
|
if syn_ant in page[category]:
|
||||||
event["stdout"].write("%ss for %s: %s" % (
|
event["stdout"].write("%ss for %s: %s" % (
|
||||||
event["command"].title(), phrase, ", ".join(
|
event["command"].title(), phrase, ", ".join(
|
||||||
page[category][syn_ant])))
|
page[category][syn_ant])))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No %ss for %s" % (
|
event["stderr"].write("No %ss for %s" % (
|
||||||
event["command"], phrase))
|
event["command"], phrase))
|
||||||
|
|
|
@ -3,31 +3,33 @@ import Utils
|
||||||
|
|
||||||
REGEX_URL = re.compile("https?://\S+", re.I)
|
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(
|
|
||||||
self.title, help="Get the title of the provided or most "
|
|
||||||
"recent URL.", usage="[URL]")
|
|
||||||
|
|
||||||
def title(self, event):
|
class Module(object):
|
||||||
url = None
|
def __init__(self, bot):
|
||||||
if len(event["args"]) > 0:
|
bot.events.on("received").on("command").on("title", "t").hook(
|
||||||
url = event["args_split"][0]
|
self.title, help="Get the title of the provided or most "
|
||||||
else:
|
"recent URL.", usage="[URL]")
|
||||||
url = event["buffer"].find(REGEX_URL)
|
|
||||||
if url:
|
def title(self, event):
|
||||||
url = re.search(REGEX_URL, url.message).group(0)
|
url = None
|
||||||
if not url:
|
if len(event["args"]) > 0:
|
||||||
event["stderr"].write("No URL provided/found.")
|
url = event["args_split"][0]
|
||||||
return
|
else:
|
||||||
soup = Utils.get_url(url, soup=True)
|
url = event["buffer"].find(REGEX_URL)
|
||||||
if not soup:
|
if url:
|
||||||
event["stderr"].write("Failed to get URL.")
|
url = re.search(REGEX_URL, url.message).group(0)
|
||||||
return
|
if not url:
|
||||||
title = soup.title
|
event["stderr"].write("No URL provided/found.")
|
||||||
if title:
|
return
|
||||||
title = title.text.replace("\n", " ").replace("\r", ""
|
soup = Utils.get_url(url, soup=True)
|
||||||
).replace(" ", " ").strip()
|
if not soup:
|
||||||
event["stdout"].write(title)
|
event["stderr"].write("Failed to get URL.")
|
||||||
else:
|
return
|
||||||
event["stderr"].write("No title found.")
|
title = soup.title
|
||||||
|
if title:
|
||||||
|
title = title.text.replace("\n", " ").replace("\r", ""
|
||||||
|
).replace(" ",
|
||||||
|
" ").strip()
|
||||||
|
event["stdout"].write(title)
|
||||||
|
else:
|
||||||
|
event["stderr"].write("No title found.")
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import EventManager
|
import EventManager
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("message").on("channel"
|
bot.events.on("received").on("message").on("channel"
|
||||||
).hook(self.channel_message,
|
).hook(self.channel_message,
|
||||||
priority=EventManager.PRIORITY_MEDIUM)
|
priority=EventManager.PRIORITY_MEDIUM)
|
||||||
bot.events.on("received").on("command").on("to").hook(
|
bot.events.on("received").on("command").on("to").hook(
|
||||||
self.to, min_args=2, help=("Relay a message to a "
|
self.to, min_args=2, help=("Relay a message to a "
|
||||||
"user the next time they talk in a channel"),
|
"user the next time they talk in a channel"),
|
||||||
channel_only=True, usage="<username> <message>")
|
channel_only=True, usage="<username> <message>")
|
||||||
|
|
||||||
def channel_message(self, event):
|
def channel_message(self, event):
|
||||||
messages = event["channel"].get_user_setting(event["user"].id,
|
messages = event["channel"].get_user_setting(event["user"].id,
|
||||||
"to", [])
|
"to", [])
|
||||||
for nickname, message in messages:
|
for nickname, message in messages:
|
||||||
event["channel"].send_message("%s: <%s> %s" % (
|
event["channel"].send_message("%s: <%s> %s" % (
|
||||||
event["user"].nickname, nickname, message))
|
event["user"].nickname, nickname, message))
|
||||||
|
@ -22,9 +23,9 @@ class Module(object):
|
||||||
def to(self, event):
|
def to(self, event):
|
||||||
target_user = event["server"].get_user(event["args_split"][0])
|
target_user = event["server"].get_user(event["args_split"][0])
|
||||||
messages = event["target"].get_user_setting(target_user.id,
|
messages = event["target"].get_user_setting(target_user.id,
|
||||||
"to", [])
|
"to", [])
|
||||||
messages.append([event["user"].nickname,
|
messages.append([event["user"].nickname,
|
||||||
" ".join(event["args_split"][1:])])
|
" ".join(event["args_split"][1:])])
|
||||||
event["target"].set_user_setting(target_user.id,
|
event["target"].set_user_setting(target_user.id,
|
||||||
"to", messages)
|
"to", messages)
|
||||||
event["stdout"].write("Message saved")
|
event["stdout"].write("Message saved")
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -11,22 +9,26 @@ class Module(object):
|
||||||
usage="<description>")
|
usage="<description>")
|
||||||
bot.events.on("received").on("command").on("tododel").hook(
|
bot.events.on("received").on("command").on("tododel").hook(
|
||||||
self.todo_del, min_args=1, help="Remove something from your "
|
self.todo_del, min_args=1, help="Remove something from your "
|
||||||
"todo list", usage="<item number>")
|
"todo list", usage="<item number>")
|
||||||
|
|
||||||
def todo(self, event):
|
def todo(self, event):
|
||||||
todo = event["user"].get_setting("todo", [])
|
todo = event["user"].get_setting("todo", [])
|
||||||
if event["args"]:
|
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])
|
index = int(event["args_split"][0])
|
||||||
if len(todo) >= index:
|
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:
|
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:
|
else:
|
||||||
event["stderr"].write("Please provide a number")
|
event["stderr"].write("Please provide a number")
|
||||||
else:
|
else:
|
||||||
todo_count = len(todo)
|
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):
|
def todo_add(self, event):
|
||||||
arg_lower = event["args"].lower()
|
arg_lower = event["args"].lower()
|
||||||
|
@ -34,7 +36,7 @@ class Module(object):
|
||||||
for item in todo:
|
for item in todo:
|
||||||
if item.lower() == arg_lower:
|
if item.lower() == arg_lower:
|
||||||
event["stderr"].write(
|
event["stderr"].write(
|
||||||
"That is already in your todo")
|
"That is already in your todo")
|
||||||
return
|
return
|
||||||
todo.append(event["args"])
|
todo.append(event["args"])
|
||||||
event["user"].set_setting("todo", todo)
|
event["user"].set_setting("todo", todo)
|
||||||
|
@ -45,11 +47,12 @@ class Module(object):
|
||||||
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])
|
index = int(event["args_split"][0])
|
||||||
if len(todo) >= index:
|
if len(todo) >= index:
|
||||||
todo.pop(index-1)
|
todo.pop(index - 1)
|
||||||
event["user"].set_setting("todo", todo)
|
event["user"].set_setting("todo", todo)
|
||||||
event["stdout"].write("Todo item removed")
|
event["stdout"].write("Todo item removed")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("You do not have that many things in "
|
event["stderr"].write("You do not have that many things in "
|
||||||
"your todo")
|
"your todo")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Please provided a todo item number to remove")
|
event["stderr"].write(
|
||||||
|
"Please provided a todo item number to remove")
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
#--require-config trakt-api-key
|
# --require-config trakt-api-key
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_TRAKT = "https://api-v2launch.trakt.tv/users/%s/watching"
|
URL_TRAKT = "https://api-v2launch.trakt.tv/users/%s/watching"
|
||||||
URL_TRAKTSLUG = "https://trakt.tv/%s/%s"
|
URL_TRAKTSLUG = "https://trakt.tv/%s/%s"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("nowwatching",
|
bot.events.on("received").on("command").on("nowwatching",
|
||||||
"nw").hook(self.now_watching,
|
"nw").hook(self.now_watching,
|
||||||
help="Get what you or another user is 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"
|
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):
|
def now_watching(self, event):
|
||||||
if event["args"]:
|
if event["args"]:
|
||||||
username = event["args_split"][0]
|
username = event["args_split"][0]
|
||||||
else:
|
else:
|
||||||
username = event["user"].get_setting("trakt",
|
username = event["user"].get_setting("trakt",
|
||||||
event["user"].nickname)
|
event["user"].nickname)
|
||||||
page = Utils.get_url(URL_TRAKT % username, headers={
|
page = Utils.get_url(URL_TRAKT % username, headers={
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"trakt-api-version": "2", "trakt-api-key":
|
"trakt-api-version": "2", "trakt-api-key":
|
||||||
self.bot.config["trakt-api-key"]}, json=True,
|
self.bot.config["trakt-api-key"]}, json=True,
|
||||||
code=True)
|
code=True)
|
||||||
if page[0]:
|
if page[0]:
|
||||||
code, page = page
|
code, page = page
|
||||||
if code == 200:
|
if code == 200:
|
||||||
|
@ -37,8 +40,8 @@ class Module(object):
|
||||||
slug = page["movie"]["ids"]["slug"]
|
slug = page["movie"]["ids"]["slug"]
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
"%s is now watching %s (%s) %s" % (
|
"%s is now watching %s (%s) %s" % (
|
||||||
username, title, year,
|
username, title, year,
|
||||||
URL_TRAKTSLUG % ("movie", slug)))
|
URL_TRAKTSLUG % ("movie", slug)))
|
||||||
elif type == "episode":
|
elif type == "episode":
|
||||||
season = page["episode"]["season"]
|
season = page["episode"]["season"]
|
||||||
episode_number = page["episode"]["number"]
|
episode_number = page["episode"]["number"]
|
||||||
|
@ -48,9 +51,9 @@ class Module(object):
|
||||||
slug = page["show"]["ids"]["slug"]
|
slug = page["show"]["ids"]["slug"]
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
"%s is now watching %s s%se%s - %s %s" % (
|
"%s is now watching %s s%se%s - %s %s" % (
|
||||||
username, show_title, str(season).zfill(2),
|
username, show_title, str(season).zfill(2),
|
||||||
str(episode_number).zfill(2), episode_title,
|
str(episode_number).zfill(2), episode_title,
|
||||||
URL_TRAKTSLUG % ("shows", slug)))
|
URL_TRAKTSLUG % ("shows", slug)))
|
||||||
else:
|
else:
|
||||||
print("ack! unknown trakt media type!")
|
print("ack! unknown trakt media type!")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -5,11 +5,12 @@ URL_TRANSLATE = "http://translate.googleapis.com/translate_a/single"
|
||||||
URL_LANGUAGES = "https://cloud.google.com/translate/docs/languages"
|
URL_LANGUAGES = "https://cloud.google.com/translate/docs/languages"
|
||||||
REGEX_LANGUAGES = re.compile("(\w+)?:(\w+)? ")
|
REGEX_LANGUAGES = re.compile("(\w+)?:(\w+)? ")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("translate", "tr").hook(
|
bot.events.on("received").on("command").on("translate", "tr").hook(
|
||||||
self.translate, help="Translate the provided phrase or the "
|
self.translate, help="Translate the provided phrase or the "
|
||||||
"last line seen.", usage="[phrase]")
|
"last line seen.", usage="[phrase]")
|
||||||
|
|
||||||
def translate(self, event):
|
def translate(self, event):
|
||||||
phrase = event["args"]
|
phrase = event["args"]
|
||||||
|
@ -46,5 +47,4 @@ class Module(object):
|
||||||
data_json[0][0][0]))
|
data_json[0][0][0]))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to translate, try checking "
|
event["stderr"].write("Failed to translate, try checking "
|
||||||
"source/target languages (" + URL_LANGUAGES + ")")
|
"source/target languages (" + URL_LANGUAGES + ")")
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#--require-config twitter-api-key
|
# --require-config twitter-api-key
|
||||||
#--require-config twitter-api-secret
|
# --require-config twitter-api-secret
|
||||||
#--require-config twitter-access-token
|
# --require-config twitter-access-token
|
||||||
#--require-config twitter-access-secret
|
# --require-config twitter-access-secret
|
||||||
|
|
||||||
import datetime, re, time, traceback
|
import datetime, re, time, traceback
|
||||||
import twitter
|
import twitter
|
||||||
|
@ -10,16 +10,18 @@ import Utils
|
||||||
REGEX_TWITTERURL = re.compile(
|
REGEX_TWITTERURL = re.compile(
|
||||||
"https?://(?:www\.)?twitter.com/[^/]+/status/(\d+)", re.I)
|
"https?://(?:www\.)?twitter.com/[^/]+/status/(\d+)", re.I)
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("twitter", "tw"
|
bot.events.on("received").on("command").on("twitter", "tw"
|
||||||
).hook(self.twitter, help="Find a tweet",
|
).hook(self.twitter,
|
||||||
usage="[@username/URL/ID]")
|
help="Find a tweet",
|
||||||
|
usage="[@username/URL/ID]")
|
||||||
|
|
||||||
def make_timestamp(self, s):
|
def make_timestamp(self, s):
|
||||||
seconds_since = time.time()-datetime.datetime.strptime(s,
|
seconds_since = time.time() - datetime.datetime.strptime(s,
|
||||||
"%a %b %d %H:%M:%S %z %Y").timestamp()
|
"%a %b %d %H:%M:%S %z %Y").timestamp()
|
||||||
since, unit = Utils.time_unit(seconds_since)
|
since, unit = Utils.time_unit(seconds_since)
|
||||||
return "%s %s ago" % (since, unit)
|
return "%s %s ago" % (since, unit)
|
||||||
|
|
||||||
|
@ -59,18 +61,22 @@ class Module(object):
|
||||||
username = "@%s" % tweet["user"]["screen_name"]
|
username = "@%s" % tweet["user"]["screen_name"]
|
||||||
if "retweeted_status" in tweet:
|
if "retweeted_status" in tweet:
|
||||||
original_username = "@%s" % tweet["retweeted_status"
|
original_username = "@%s" % tweet["retweeted_status"
|
||||||
]["user"]["screen_name"]
|
]["user"]["screen_name"]
|
||||||
original_text = tweet["retweeted_status"]["text"]
|
original_text = tweet["retweeted_status"]["text"]
|
||||||
retweet_timestamp = self.make_timestamp(tweet[
|
retweet_timestamp = self.make_timestamp(tweet[
|
||||||
"created_at"])
|
"created_at"])
|
||||||
original_timestamp = self.make_timestamp(tweet[
|
original_timestamp = self.make_timestamp(tweet[
|
||||||
"retweeted_status"]["created_at"])
|
"retweeted_status"][
|
||||||
|
"created_at"])
|
||||||
event["stdout"].write("(%s (%s) retweeted %s (%s)) %s" % (
|
event["stdout"].write("(%s (%s) retweeted %s (%s)) %s" % (
|
||||||
username, retweet_timestamp,
|
username, retweet_timestamp,
|
||||||
original_username, original_timestamp, original_text))
|
original_username, original_timestamp, original_text))
|
||||||
else:
|
else:
|
||||||
event["stdout"].write("(%s, %s) %s" % (username,
|
event["stdout"].write("(%s, %s) %s" % (username,
|
||||||
self.make_timestamp(tweet["created_at"]), tweet["text"]))
|
self.make_timestamp(
|
||||||
|
tweet[
|
||||||
|
"created_at"]),
|
||||||
|
tweet["text"]))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Invalid tweet identifiers provided")
|
event["stderr"].write("Invalid tweet identifiers provided")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -2,8 +2,10 @@ import Utils
|
||||||
|
|
||||||
UPCITEMDB_URL = "https://api.upcitemdb.com/prod/trial/lookup"
|
UPCITEMDB_URL = "https://api.upcitemdb.com/prod/trial/lookup"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "UPC"
|
_name = "UPC"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on(
|
bot.events.on("received").on("command").on(
|
||||||
|
@ -18,8 +20,8 @@ class Module(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
page = Utils.get_url(UPCITEMDB_URL,
|
page = Utils.get_url(UPCITEMDB_URL,
|
||||||
get_params={"upc": event["args_split"][0]},
|
get_params={"upc": event["args_split"][0]},
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if not len(page["items"]):
|
if not len(page["items"]):
|
||||||
event["stderr"].write("UPC/EAN not found")
|
event["stderr"].write("UPC/EAN not found")
|
||||||
|
@ -47,7 +49,8 @@ class Module(object):
|
||||||
lowest_price, highest_price, currency)
|
lowest_price, highest_price, currency)
|
||||||
|
|
||||||
event["stdout"].write("%s%s%s(weight: %s"
|
event["stdout"].write("%s%s%s(weight: %s"
|
||||||
", size: %s, price: %s)" % (
|
", size: %s, price: %s)" % (
|
||||||
brand, title, description, weight, size, pricing))
|
brand, title, description, weight, size,
|
||||||
|
pricing))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
|
@ -4,12 +4,13 @@ import Utils
|
||||||
URL_URBANDICTIONARY = "http://api.urbandictionary.com/v0/define"
|
URL_URBANDICTIONARY = "http://api.urbandictionary.com/v0/define"
|
||||||
REGEX_DEFNUMBER = re.compile("-n(\d+) \S+")
|
REGEX_DEFNUMBER = re.compile("-n(\d+) \S+")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("urbandictionary", "ud"
|
bot.events.on("received").on("command").on("urbandictionary", "ud"
|
||||||
).hook(self.ud, min_args=1,
|
).hook(self.ud, min_args=1,
|
||||||
help="Get the definition of a provided term",
|
help="Get the definition of a provided term",
|
||||||
usage="<term>")
|
usage="<term>")
|
||||||
|
|
||||||
def ud(self, event):
|
def ud(self, event):
|
||||||
term = event["args"]
|
term = event["args"]
|
||||||
|
@ -19,14 +20,17 @@ class Module(object):
|
||||||
number = int(match.group(1))
|
number = int(match.group(1))
|
||||||
term = term.split(" ", 1)[1]
|
term = term.split(" ", 1)[1]
|
||||||
page = Utils.get_url(URL_URBANDICTIONARY, get_params={"term": term},
|
page = Utils.get_url(URL_URBANDICTIONARY, get_params={"term": term},
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if len(page["list"]):
|
if len(page["list"]):
|
||||||
if number > 0 and len(page["list"]) > number-1:
|
if number > 0 and len(page["list"]) > number - 1:
|
||||||
definition = page["list"][number-1]
|
definition = page["list"][number - 1]
|
||||||
event["stdout"].write("%s: %s" % (definition["word"],
|
event["stdout"].write("%s: %s" % (definition["word"],
|
||||||
definition["definition"].replace("\n", " ").replace(
|
definition[
|
||||||
"\r", "").replace(" ", " ")))
|
"definition"].replace(
|
||||||
|
"\n", " ").replace(
|
||||||
|
"\r", "").replace(
|
||||||
|
" ", " ")))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Definition number does not exist")
|
event["stderr"].write("Definition number does not exist")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#--require-config openweathermap-api-key
|
# --require-config openweathermap-api-key
|
||||||
|
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
URL_WEATHER = "http://api.openweathermap.org/data/2.5/weather"
|
URL_WEATHER = "http://api.openweathermap.org/data/2.5/weather"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -17,22 +18,23 @@ class Module(object):
|
||||||
page = Utils.get_url(URL_WEATHER, get_params={
|
page = Utils.get_url(URL_WEATHER, get_params={
|
||||||
"q": event["args"], "units": "metric",
|
"q": event["args"], "units": "metric",
|
||||||
"APPID": api_key},
|
"APPID": api_key},
|
||||||
json=True)
|
json=True)
|
||||||
if page:
|
if page:
|
||||||
if "weather" in page:
|
if "weather" in page:
|
||||||
location = "%s, %s" % (page["name"], page["sys"][
|
location = "%s, %s" % (page["name"], page["sys"][
|
||||||
"country"])
|
"country"])
|
||||||
celsius = "%dC" % page["main"]["temp"]
|
celsius = "%dC" % page["main"]["temp"]
|
||||||
fahrenheit = "%dF" % ((page["main"]["temp"]*(9/5))+32)
|
fahrenheit = "%dF" % ((page["main"]["temp"] * (9 / 5)) + 32)
|
||||||
description = page["weather"][0]["description"].title()
|
description = page["weather"][0]["description"].title()
|
||||||
humidity = "%s%%" % page["main"]["humidity"]
|
humidity = "%s%%" % page["main"]["humidity"]
|
||||||
wind_speed = "%sKM/h" % page["wind"]["speed"]
|
wind_speed = "%sKM/h" % page["wind"]["speed"]
|
||||||
|
|
||||||
event["stdout"].write(
|
event["stdout"].write(
|
||||||
"(%s) %s/%s | %s | Humidity: %s | Wind: %s" % (
|
"(%s) %s/%s | %s | Humidity: %s | Wind: %s" % (
|
||||||
location, celsius, fahrenheit, description, humidity,
|
location, celsius, fahrenheit, description, humidity,
|
||||||
wind_speed))
|
wind_speed))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No weather information for this location")
|
event["stderr"].write(
|
||||||
|
"No weather information for this location")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
|
@ -2,11 +2,13 @@ import Utils
|
||||||
|
|
||||||
URL_WIKIPEDIA = "https://en.wikipedia.org/w/api.php"
|
URL_WIKIPEDIA = "https://en.wikipedia.org/w/api.php"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("wiki", "wi"
|
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):
|
def wikipedia(self, event):
|
||||||
page = Utils.get_url(URL_WIKIPEDIA, get_params={
|
page = Utils.get_url(URL_WIKIPEDIA, get_params={
|
||||||
|
@ -25,4 +27,3 @@ class Module(object):
|
||||||
event["stderr"].write("No results found")
|
event["stderr"].write("No results found")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("Failed to load results")
|
event["stderr"].write("Failed to load results")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#--require-config wolframalpha-api-key
|
# --require-config wolframalpha-api-key
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import Utils
|
import Utils
|
||||||
|
@ -6,31 +6,39 @@ import Utils
|
||||||
URL_WA = "http://api.wolframalpha.com/v2/query"
|
URL_WA = "http://api.wolframalpha.com/v2/query"
|
||||||
REGEX_CHARHEX = re.compile("\\\\:(\S{4})")
|
REGEX_CHARHEX = re.compile("\\\\:(\S{4})")
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
_name = "Wolfram|Alpha"
|
_name = "Wolfram|Alpha"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
bot.events.on("received").on("command").on("wolframalpha", "wa"
|
bot.events.on("received").on("command").on("wolframalpha", "wa"
|
||||||
).hook(self.wa, min_args=1, help=
|
).hook(self.wa, min_args=1,
|
||||||
"Evauate a given string on Wolfram|Alpha",
|
help=
|
||||||
usage="<query>")
|
"Evauate a given string on Wolfram|Alpha",
|
||||||
|
usage="<query>")
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
def wa(self, event):
|
def wa(self, event):
|
||||||
soup = Utils.get_url(URL_WA, get_params={"input": event["args"],
|
soup = Utils.get_url(URL_WA, get_params={"input": event["args"],
|
||||||
"appid": self.bot.config["wolframalpha-api-key"],
|
"appid": self.bot.config[
|
||||||
"format": "plaintext", "reinterpret": "true"}, soup=True)
|
"wolframalpha-api-key"],
|
||||||
|
"format": "plaintext",
|
||||||
|
"reinterpret": "true"},
|
||||||
|
soup=True)
|
||||||
|
|
||||||
if soup:
|
if soup:
|
||||||
if int(soup.find("queryresult").get("numpods")) > 0:
|
if int(soup.find("queryresult").get("numpods")) > 0:
|
||||||
input = soup.find(id="Input").find("subpod").find("plaintext"
|
input = soup.find(id="Input").find("subpod").find("plaintext"
|
||||||
).text
|
).text
|
||||||
answered = False
|
answered = False
|
||||||
for pod in soup.find_all("pod"):
|
for pod in soup.find_all("pod"):
|
||||||
if pod.get("primary") == "true":
|
if pod.get("primary") == "true":
|
||||||
answer = pod.find("subpod").find("plaintext")
|
answer = pod.find("subpod").find("plaintext")
|
||||||
text = "(%s) %s" % (input.replace(" | ", ": "),
|
text = "(%s) %s" % (input.replace(" | ", ": "),
|
||||||
answer.text.strip().replace(" | ", ": "
|
answer.text.strip().replace(" | ",
|
||||||
).replace("\n", " | ").replace("\r", ""))
|
": "
|
||||||
|
).replace(
|
||||||
|
"\n", " | ").replace("\r", ""))
|
||||||
while True:
|
while True:
|
||||||
match = re.search(REGEX_CHARHEX, text)
|
match = re.search(REGEX_CHARHEX, text)
|
||||||
if match:
|
if match:
|
||||||
|
|
|
@ -1,39 +1,45 @@
|
||||||
import time
|
import time
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("message").on("channel"
|
bot.events.on("received").on("message").on("channel"
|
||||||
).hook(self.channel_message)
|
).hook(self.channel_message)
|
||||||
bot.events.on("self").on("message").on("channel"
|
bot.events.on("self").on("message").on("channel"
|
||||||
).hook(self.self_channel_message)
|
).hook(self.self_channel_message)
|
||||||
bot.events.on("received").on("command").on("words"
|
bot.events.on("received").on("command").on("words"
|
||||||
).hook(self.words, channel_only=True,
|
).hook(self.words,
|
||||||
usage="<nickname>", help=
|
channel_only=True,
|
||||||
"See how many words you or the given nickname have used")
|
usage="<nickname>",
|
||||||
|
help=
|
||||||
|
"See how many words you or the given nickname have used")
|
||||||
bot.events.on("received").on("command").on("trackword"
|
bot.events.on("received").on("command").on("trackword"
|
||||||
).hook(self.track_word, min_args=1,
|
).hook(self.track_word,
|
||||||
help="Start tracking a word", usage="<word>",
|
min_args=1,
|
||||||
permission="track-word")
|
help="Start tracking a word",
|
||||||
|
usage="<word>",
|
||||||
|
permission="track-word")
|
||||||
bot.events.on("received").on("command").on("wordusers"
|
bot.events.on("received").on("command").on("wordusers"
|
||||||
).hook(self.word_users, min_args=1,
|
).hook(self.word_users,
|
||||||
help="Show who has used a tracked word the most",
|
min_args=1,
|
||||||
usage="<word>")
|
help="Show who has used a tracked word the most",
|
||||||
|
usage="<word>")
|
||||||
|
|
||||||
def _channel_message(self, user, event):
|
def _channel_message(self, user, event):
|
||||||
words = list(filter(None, event["message_split"]))
|
words = list(filter(None, event["message_split"]))
|
||||||
word_count = len(words)
|
word_count = len(words)
|
||||||
|
|
||||||
user_words = event["channel"].get_user_setting(user.id,
|
user_words = event["channel"].get_user_setting(user.id,
|
||||||
"words", 0)
|
"words", 0)
|
||||||
user_words += word_count
|
user_words += word_count
|
||||||
|
|
||||||
if user.get_setting("first-words", None) == None:
|
if user.get_setting("first-words", None) == None:
|
||||||
user.set_setting("first-words", time.time())
|
user.set_setting("first-words", time.time())
|
||||||
|
|
||||||
event["channel"].set_user_setting(user.id,
|
event["channel"].set_user_setting(user.id,
|
||||||
"words", user_words)
|
"words", user_words)
|
||||||
|
|
||||||
tracked_words = set(event["server"].get_setting(
|
tracked_words = set(event["server"].get_setting(
|
||||||
"tracked-words", []))
|
"tracked-words", []))
|
||||||
|
@ -43,8 +49,10 @@ class Module(object):
|
||||||
word_count = user.get_setting(setting, 0)
|
word_count = user.get_setting(setting, 0)
|
||||||
word_count += 1
|
word_count += 1
|
||||||
user.set_setting(setting, word_count)
|
user.set_setting(setting, word_count)
|
||||||
|
|
||||||
def channel_message(self, event):
|
def channel_message(self, event):
|
||||||
self._channel_message(event["user"], event)
|
self._channel_message(event["user"], event)
|
||||||
|
|
||||||
def self_channel_message(self, event):
|
def self_channel_message(self, event):
|
||||||
self._channel_message(event["server"].get_user(
|
self._channel_message(event["server"].get_user(
|
||||||
event["server"].nickname), event)
|
event["server"].nickname), event)
|
||||||
|
@ -52,7 +60,7 @@ class Module(object):
|
||||||
def words(self, event):
|
def words(self, event):
|
||||||
if event["args_split"]:
|
if event["args_split"]:
|
||||||
target = event["server"].get_user(event["args_split"
|
target = event["server"].get_user(event["args_split"
|
||||||
][0])
|
][0])
|
||||||
else:
|
else:
|
||||||
target = event["user"]
|
target = event["user"]
|
||||||
words = dict(target.get_channel_settings_per_setting(
|
words = dict(target.get_channel_settings_per_setting(
|
||||||
|
@ -86,8 +94,9 @@ class Module(object):
|
||||||
top_10 = sorted(word_users.keys())
|
top_10 = sorted(word_users.keys())
|
||||||
top_10 = sorted(top_10, key=word_users.get, reverse=True)[:10]
|
top_10 = sorted(top_10, key=word_users.get, reverse=True)[:10]
|
||||||
top_10 = ", ".join("%s (%d)" % (Utils.prevent_highlight(event[
|
top_10 = ", ".join("%s (%d)" % (Utils.prevent_highlight(event[
|
||||||
"server"].get_user(nickname).nickname), word_users[nickname]
|
"server"].get_user(
|
||||||
) for nickname in top_10)
|
nickname).nickname), word_users[nickname]
|
||||||
|
) for nickname in top_10)
|
||||||
event["stdout"].write("Top '%s' users: %s" % (word, top_10))
|
event["stdout"].write("Top '%s' users: %s" % (word, top_10))
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("That word is not being tracked")
|
event["stderr"].write("That word is not being tracked")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#--require-config google-api-key
|
# --require-config google-api-key
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import Utils
|
import Utils
|
||||||
|
@ -16,25 +16,30 @@ URL_YOUTUBESHORT = "https://youtu.be/%s"
|
||||||
ARROW_UP = "▲"
|
ARROW_UP = "▲"
|
||||||
ARROW_DOWN = "▼"
|
ARROW_DOWN = "▼"
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Module(object):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
bot.events.on("received").on("command").on("yt", "youtube"
|
bot.events.on("received").on("command").on("yt", "youtube"
|
||||||
).hook(self.yt,
|
).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(
|
bot.events.on("received").on("message").on("channel").hook(
|
||||||
self.channel_message)
|
self.channel_message)
|
||||||
|
|
||||||
bot.events.on("postboot").on("configure").on(
|
bot.events.on("postboot").on("configure").on(
|
||||||
"channelset").assure_call(setting="auto-youtube",
|
"channelset").assure_call(setting="auto-youtube",
|
||||||
help="Disable/Enable automatically getting info from youtube URLs",
|
help="Disable/Enable automatically getting info from youtube URLs",
|
||||||
validate=Utils.bool_or_none)
|
validate=Utils.bool_or_none)
|
||||||
|
|
||||||
|
|
||||||
def get_video_page(self, video_id, part):
|
def get_video_page(self, video_id, part):
|
||||||
return Utils.get_url(URL_YOUTUBEVIDEO, get_params={"part": part,
|
return Utils.get_url(URL_YOUTUBEVIDEO, get_params={"part": part,
|
||||||
"id": video_id, "key": self.bot.config["google-api-key"]},
|
"id": video_id,
|
||||||
json=True)
|
"key":
|
||||||
|
self.bot.config[
|
||||||
|
"google-api-key"]},
|
||||||
|
json=True)
|
||||||
|
|
||||||
def video_details(self, video_id):
|
def video_details(self, video_id):
|
||||||
snippet = self.get_video_page(video_id, "snippet")
|
snippet = self.get_video_page(video_id, "snippet")
|
||||||
if snippet["items"]:
|
if snippet["items"]:
|
||||||
|
@ -52,19 +57,23 @@ class Module(object):
|
||||||
video_opinions = ""
|
video_opinions = ""
|
||||||
if video_likes and video_dislikes:
|
if video_likes and video_dislikes:
|
||||||
video_opinions = " (%s%s%s%s)" % (video_likes, ARROW_UP,
|
video_opinions = " (%s%s%s%s)" % (video_likes, ARROW_UP,
|
||||||
ARROW_DOWN, video_dislikes)
|
ARROW_DOWN, video_dislikes)
|
||||||
|
|
||||||
match = re.match(REGEX_ISO8601, video_duration)
|
match = re.match(REGEX_ISO8601, video_duration)
|
||||||
video_duration = ""
|
video_duration = ""
|
||||||
video_duration += "%s:" % match.group(1)[:-1].zfill(2
|
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
|
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
|
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" % (
|
return "%s (%s) uploaded by %s, %s views%s %s" % (
|
||||||
video_title, video_duration, video_uploader, "{:,}".format(
|
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):
|
def yt(self, event):
|
||||||
video_id = None
|
video_id = None
|
||||||
|
@ -74,14 +83,18 @@ class Module(object):
|
||||||
else:
|
else:
|
||||||
last_youtube = event["buffer"].find(REGEX_YOUTUBE)
|
last_youtube = event["buffer"].find(REGEX_YOUTUBE)
|
||||||
if last_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 search or video_id:
|
||||||
if not video_id:
|
if not video_id:
|
||||||
search_page = Utils.get_url(URL_YOUTUBESEARCH,
|
search_page = Utils.get_url(URL_YOUTUBESEARCH,
|
||||||
get_params={"q": search, "part": "snippet",
|
get_params={"q": search,
|
||||||
"maxResults": "1", "type": "video",
|
"part": "snippet",
|
||||||
"key": self.bot.config["google-api-key"]},
|
"maxResults": "1",
|
||||||
json=True)
|
"type": "video",
|
||||||
|
"key": self.bot.config[
|
||||||
|
"google-api-key"]},
|
||||||
|
json=True)
|
||||||
if search_page:
|
if search_page:
|
||||||
if search_page["pageInfo"]["totalResults"] > 0:
|
if search_page["pageInfo"]["totalResults"] > 0:
|
||||||
video_id = search_page["items"][0]["id"]["videoId"]
|
video_id = search_page["items"][0]["id"]["videoId"]
|
||||||
|
@ -94,7 +107,7 @@ class Module(object):
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No search phrase provided")
|
event["stderr"].write("No search phrase provided")
|
||||||
else:
|
else:
|
||||||
event["stderr"].write("No search phrase provided")
|
event["stderr"].write("No search phrase provided")
|
||||||
|
|
||||||
def channel_message(self, event):
|
def channel_message(self, event):
|
||||||
match = re.search(REGEX_YOUTUBE, event["message"])
|
match = re.search(REGEX_YOUTUBE, event["message"])
|
||||||
|
@ -104,4 +117,5 @@ class Module(object):
|
||||||
if video_details:
|
if video_details:
|
||||||
self.bot.events.on("send").on("stdout").call(target=event[
|
self.bot.events.on("send").on("stdout").call(target=event[
|
||||||
"channel"], message=video_details, module_name="Youtube",
|
"channel"], message=video_details, module_name="Youtube",
|
||||||
server=event["server"])
|
server=event[
|
||||||
|
"server"])
|
||||||
|
|
Loading…
Reference in a new issue