style: run Black over the whole project
This commit is contained in:
parent
4beead146f
commit
895b0dec47
|
@ -5,7 +5,7 @@ import time
|
||||||
import signal
|
import signal
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import irc.client
|
import irc.client # type: ignore
|
||||||
from irc.client import NickMask
|
from irc.client import NickMask
|
||||||
|
|
||||||
from edmond.log import Logger
|
from edmond.log import Logger
|
||||||
|
@ -52,8 +52,10 @@ class Bot(irc.client.SimpleIRCClient, Logger):
|
||||||
return storage
|
return storage
|
||||||
except (OSError, json.decoder.JSONDecodeError) as exc:
|
except (OSError, json.decoder.JSONDecodeError) as exc:
|
||||||
self.log_e(f"Could not load storage file: {exc}")
|
self.log_e(f"Could not load storage file: {exc}")
|
||||||
self.log_w("If it's not the first time Edm0nd is run, you may lose"
|
self.log_w(
|
||||||
" data when closing the program.")
|
"If it's not the first time Edm0nd is run, you may lose"
|
||||||
|
" data when closing the program."
|
||||||
|
)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def __save_storage(self):
|
def __save_storage(self):
|
||||||
|
@ -129,7 +131,7 @@ class Bot(irc.client.SimpleIRCClient, Logger):
|
||||||
plugin_files = os.listdir(Path(__file__).parent / "plugins")
|
plugin_files = os.listdir(Path(__file__).parent / "plugins")
|
||||||
plugin_names = map(
|
plugin_names = map(
|
||||||
lambda f: os.path.splitext(f)[0],
|
lambda f: os.path.splitext(f)[0],
|
||||||
filter(lambda f: f.endswith(".py"), plugin_files)
|
filter(lambda f: f.endswith(".py"), plugin_files),
|
||||||
)
|
)
|
||||||
for plugin_name in plugin_names:
|
for plugin_name in plugin_names:
|
||||||
module = importlib.import_module(f"edmond.plugins.{plugin_name}")
|
module = importlib.import_module(f"edmond.plugins.{plugin_name}")
|
||||||
|
@ -138,10 +140,10 @@ class Bot(irc.client.SimpleIRCClient, Logger):
|
||||||
self.log_e(f"Dependencies not found for plugin {plugin_name}.")
|
self.log_e(f"Dependencies not found for plugin {plugin_name}.")
|
||||||
continue
|
continue
|
||||||
# Get plugin class name from its module name.
|
# Get plugin class name from its module name.
|
||||||
class_name = "".join(map(
|
class_name = (
|
||||||
lambda w: w.capitalize(),
|
"".join(map(lambda w: w.capitalize(), plugin_name.split("_")))
|
||||||
plugin_name.split("_")
|
+ "Plugin"
|
||||||
)) + "Plugin"
|
)
|
||||||
plugin_class = getattr(module, class_name)
|
plugin_class = getattr(module, class_name)
|
||||||
self.plugins.append(plugin_class(self))
|
self.plugins.append(plugin_class(self))
|
||||||
self.values[plugin_name] = {}
|
self.values[plugin_name] = {}
|
||||||
|
|
|
@ -9,17 +9,17 @@ import ctypes.util
|
||||||
|
|
||||||
class _AnsiColorStreamHandler(logging.StreamHandler):
|
class _AnsiColorStreamHandler(logging.StreamHandler):
|
||||||
|
|
||||||
DEFAULT = '\x1b[0m'
|
DEFAULT = "\x1b[0m"
|
||||||
RED = '\x1b[31m'
|
RED = "\x1b[31m"
|
||||||
GREEN = '\x1b[32m'
|
GREEN = "\x1b[32m"
|
||||||
YELLOW = '\x1b[33m'
|
YELLOW = "\x1b[33m"
|
||||||
CYAN = '\x1b[36m'
|
CYAN = "\x1b[36m"
|
||||||
|
|
||||||
CRITICAL = RED
|
CRITICAL = RED
|
||||||
ERROR = RED
|
ERROR = RED
|
||||||
WARNING = YELLOW
|
WARNING = YELLOW
|
||||||
INFO = GREEN
|
INFO = GREEN
|
||||||
DEBUG = CYAN
|
DEBUG = CYAN
|
||||||
|
|
||||||
def __init__(self, stream=None):
|
def __init__(self, stream=None):
|
||||||
super().__init__(stream)
|
super().__init__(stream)
|
||||||
|
@ -49,37 +49,37 @@ class _AnsiColorStreamHandler(logging.StreamHandler):
|
||||||
# pylint: disable=W0212
|
# pylint: disable=W0212
|
||||||
class _WinColorStreamHandler(logging.StreamHandler):
|
class _WinColorStreamHandler(logging.StreamHandler):
|
||||||
|
|
||||||
STD_INPUT_HANDLE = -10
|
STD_INPUT_HANDLE = -10
|
||||||
STD_OUTPUT_HANDLE = -11
|
STD_OUTPUT_HANDLE = -11
|
||||||
STD_ERROR_HANDLE = -12
|
STD_ERROR_HANDLE = -12
|
||||||
|
|
||||||
FOREGROUND_BLACK = 0x0000
|
FOREGROUND_BLACK = 0x0000
|
||||||
FOREGROUND_BLUE = 0x0001
|
FOREGROUND_BLUE = 0x0001
|
||||||
FOREGROUND_GREEN = 0x0002
|
FOREGROUND_GREEN = 0x0002
|
||||||
FOREGROUND_CYAN = 0x0003
|
FOREGROUND_CYAN = 0x0003
|
||||||
FOREGROUND_RED = 0x0004
|
FOREGROUND_RED = 0x0004
|
||||||
FOREGROUND_MAGENTA = 0x0005
|
FOREGROUND_MAGENTA = 0x0005
|
||||||
FOREGROUND_YELLOW = 0x0006
|
FOREGROUND_YELLOW = 0x0006
|
||||||
FOREGROUND_GREY = 0x0007
|
FOREGROUND_GREY = 0x0007
|
||||||
FOREGROUND_INTENSITY = 0x0008
|
FOREGROUND_INTENSITY = 0x0008
|
||||||
FOREGROUND_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
|
FOREGROUND_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
|
||||||
|
|
||||||
BACKGROUND_BLACK = 0x0000
|
BACKGROUND_BLACK = 0x0000
|
||||||
BACKGROUND_BLUE = 0x0010
|
BACKGROUND_BLUE = 0x0010
|
||||||
BACKGROUND_GREEN = 0x0020
|
BACKGROUND_GREEN = 0x0020
|
||||||
BACKGROUND_CYAN = 0x0030
|
BACKGROUND_CYAN = 0x0030
|
||||||
BACKGROUND_RED = 0x0040
|
BACKGROUND_RED = 0x0040
|
||||||
BACKGROUND_MAGENTA = 0x0050
|
BACKGROUND_MAGENTA = 0x0050
|
||||||
BACKGROUND_YELLOW = 0x0060
|
BACKGROUND_YELLOW = 0x0060
|
||||||
BACKGROUND_GREY = 0x0070
|
BACKGROUND_GREY = 0x0070
|
||||||
BACKGROUND_INTENSITY = 0x0080
|
BACKGROUND_INTENSITY = 0x0080
|
||||||
|
|
||||||
DEFAULT = FOREGROUND_WHITE
|
DEFAULT = FOREGROUND_WHITE
|
||||||
CRITICAL = FOREGROUND_RED | FOREGROUND_INTENSITY
|
CRITICAL = FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||||
ERROR = FOREGROUND_RED | FOREGROUND_INTENSITY
|
ERROR = FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||||
WARNING = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
|
WARNING = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
|
||||||
INFO = FOREGROUND_GREEN
|
INFO = FOREGROUND_GREEN
|
||||||
DEBUG = FOREGROUND_CYAN
|
DEBUG = FOREGROUND_CYAN
|
||||||
|
|
||||||
def __init__(self, stream=None):
|
def __init__(self, stream=None):
|
||||||
super().__init__(stream)
|
super().__init__(stream)
|
||||||
|
@ -116,23 +116,31 @@ class _WinColorStreamHandler(logging.StreamHandler):
|
||||||
return cls.DEFAULT
|
return cls.DEFAULT
|
||||||
|
|
||||||
def _set_color_code(self, code):
|
def _set_color_code(self, code):
|
||||||
ctypes.windll.kernel32.SetConsoleTextAttribute(self.output_handle, code)
|
ctypes.windll.kernel32.SetConsoleTextAttribute(
|
||||||
|
self.output_handle, code
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
ColorStreamHandler = (
|
||||||
ColorStreamHandler = _WinColorStreamHandler
|
_WinColorStreamHandler
|
||||||
else:
|
if platform.system() == "Windows"
|
||||||
ColorStreamHandler = _AnsiColorStreamHandler
|
else _AnsiColorStreamHandler
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
_LOG_LEVEL = logging.DEBUG
|
_LOG_LEVEL = logging.DEBUG
|
||||||
_FORMAT = "%(asctime)s %(levelname)-8s %(message)s"
|
_FORMAT = "%(asctime)s %(levelname)-8s %(message)s"
|
||||||
_DATE_FORMAT = "%H:%M:%S"
|
_DATE_FORMAT = "%H:%M:%S"
|
||||||
|
|
||||||
|
|
||||||
def get_logger( name="pyshgck", level=_LOG_LEVEL
|
def get_logger(
|
||||||
, log_format=_FORMAT, date_format=_DATE_FORMAT
|
name="pyshgck",
|
||||||
, into_stderr=True, into_log_file=None ):
|
level=_LOG_LEVEL,
|
||||||
|
log_format=_FORMAT,
|
||||||
|
date_format=_DATE_FORMAT,
|
||||||
|
into_stderr=True,
|
||||||
|
into_log_file=None,
|
||||||
|
):
|
||||||
logger = logging.getLogger(name)
|
logger = logging.getLogger(name)
|
||||||
logger.setLevel(level)
|
logger.setLevel(level)
|
||||||
formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
||||||
|
@ -153,7 +161,6 @@ def get_logger( name="pyshgck", level=_LOG_LEVEL
|
||||||
|
|
||||||
|
|
||||||
class Logger:
|
class Logger:
|
||||||
|
|
||||||
def log_d(self, message):
|
def log_d(self, message):
|
||||||
self.logger.debug(message)
|
self.logger.debug(message)
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ class Plugin:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Is it a question I can answer?
|
# Is it a question I can answer?
|
||||||
question = message[len(words[0]):].strip()
|
question = message[len(words[0]) :].strip()
|
||||||
for preamble in self.config.get("questions", []):
|
for preamble in self.config.get("questions", []):
|
||||||
aliases = self.config.get("aliases", {}).get(preamble, [])
|
aliases = self.config.get("aliases", {}).get(preamble, [])
|
||||||
for q in (preamble, *aliases):
|
for q in (preamble, *aliases):
|
||||||
|
@ -189,7 +189,7 @@ class Plugin:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __save_question(self, question, matched, preamble):
|
def __save_question(self, question, matched, preamble):
|
||||||
content = question[len(matched):].strip()
|
content = question[len(matched) :].strip()
|
||||||
content = content.rstrip("?").rstrip()
|
content = content.rstrip("?").rstrip()
|
||||||
question = Question(preamble, content)
|
question = Question(preamble, content)
|
||||||
self.question = question
|
self.question = question
|
||||||
|
@ -310,7 +310,7 @@ class Plugin:
|
||||||
If it causes an issue with a plugin requiring the original target even
|
If it causes an issue with a plugin requiring the original target even
|
||||||
on private message, override this method.
|
on private message, override this method.
|
||||||
"""
|
"""
|
||||||
if (on_pubmsg := getattr(self, "on_pubmsg", None)):
|
if on_pubmsg := getattr(self, "on_pubmsg", None):
|
||||||
event.target = NickMask(event.source).nick
|
event.target = NickMask(event.source).nick
|
||||||
return on_pubmsg(event)
|
return on_pubmsg(event)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -78,10 +78,9 @@ class AmbiencePlugin(Plugin):
|
||||||
return "".join(item * reps for item in random_items)
|
return "".join(item * reps for item in random_items)
|
||||||
|
|
||||||
def apply_effect(self, chunk, word):
|
def apply_effect(self, chunk, word):
|
||||||
return {
|
return {1: self.insert_word, 2: self.interleave_word,}[
|
||||||
1: self.insert_word,
|
random.randint(1, 2)
|
||||||
2: self.interleave_word,
|
](chunk, word)
|
||||||
}[random.randint(1, 2)](chunk, word)
|
|
||||||
|
|
||||||
def insert_word(self, chunk, word):
|
def insert_word(self, chunk, word):
|
||||||
index = random.randint(0, len(chunk))
|
index = random.randint(0, len(chunk))
|
||||||
|
@ -89,6 +88,5 @@ class AmbiencePlugin(Plugin):
|
||||||
|
|
||||||
def interleave_word(self, chunk, word):
|
def interleave_word(self, chunk, word):
|
||||||
return "".join(
|
return "".join(
|
||||||
a + b
|
a + b for a, b in zip_longest(chunk, word, fillvalue="")
|
||||||
for a, b in zip_longest(chunk, word, fillvalue='')
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,8 +22,7 @@ class BeersPlugin(Plugin):
|
||||||
|
|
||||||
beer = random.choice(self.config["beers"])
|
beer = random.choice(self.config["beers"])
|
||||||
opening_text = self.config["opening_text"].format(
|
opening_text = self.config["opening_text"].format(
|
||||||
beer=beer,
|
beer=beer, target=target
|
||||||
target=target
|
|
||||||
)
|
)
|
||||||
self.bot.say(event.target, opening_text)
|
self.bot.say(event.target, opening_text)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -9,7 +9,10 @@ from edmond.utils import proc
|
||||||
class CapturePlugin(Plugin):
|
class CapturePlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"rate", "things", "capture_sentence", "captured_sentence"
|
"rate",
|
||||||
|
"things",
|
||||||
|
"capture_sentence",
|
||||||
|
"captured_sentence",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -43,8 +46,7 @@ class CapturePlugin(Plugin):
|
||||||
|
|
||||||
def capture(self, winner, target):
|
def capture(self, winner, target):
|
||||||
congratz = self.config["captured_sentence"].format(
|
congratz = self.config["captured_sentence"].format(
|
||||||
winner=winner,
|
winner=winner, thing=self.current_thing
|
||||||
thing=self.current_thing
|
|
||||||
)
|
)
|
||||||
self.bot.say(target, congratz)
|
self.bot.say(target, congratz)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class CaptureGivePlugin(Plugin):
|
||||||
|
|
||||||
# "give" command.
|
# "give" command.
|
||||||
if self.command.ident == self.config["commands"][0]:
|
if self.command.ident == self.config["commands"][0]:
|
||||||
content = self.command.raw[len(self.command.matched):].strip()
|
content = self.command.raw[len(self.command.matched) :].strip()
|
||||||
matched = self.content_re.match(content)
|
matched = self.content_re.match(content)
|
||||||
if not matched:
|
if not matched:
|
||||||
return False
|
return False
|
||||||
|
@ -41,9 +41,7 @@ class CaptureGivePlugin(Plugin):
|
||||||
|
|
||||||
# Check the sender has the thing they attempt to give.
|
# Check the sender has the thing they attempt to give.
|
||||||
collections = self.get_storage_value(
|
collections = self.get_storage_value(
|
||||||
"collections",
|
"collections", default={}, ns="capture"
|
||||||
default={},
|
|
||||||
ns="capture"
|
|
||||||
)
|
)
|
||||||
source = event.source.nick
|
source = event.source.nick
|
||||||
source_collection = collections.get(source, [])
|
source_collection = collections.get(source, [])
|
||||||
|
@ -51,7 +49,7 @@ class CaptureGivePlugin(Plugin):
|
||||||
reply = self.config["no_such_thing_reply"].format(thing=thing)
|
reply = self.config["no_such_thing_reply"].format(thing=thing)
|
||||||
self.bot.say(event.target, reply)
|
self.bot.say(event.target, reply)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
source_collection.remove(thing)
|
source_collection.remove(thing)
|
||||||
collections[source] = source_collection
|
collections[source] = source_collection
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,14 @@ class CaptureListPlugin(Plugin):
|
||||||
|
|
||||||
collec_target = self.command.content or event.source.nick
|
collec_target = self.command.content or event.source.nick
|
||||||
collections = self.get_storage_value(
|
collections = self.get_storage_value(
|
||||||
"collections",
|
"collections", default={}, ns="capture"
|
||||||
default={},
|
|
||||||
ns="capture"
|
|
||||||
)
|
)
|
||||||
collection = collections.get(collec_target, [])
|
collection = collections.get(collec_target, [])
|
||||||
if collection:
|
if collection:
|
||||||
reply = self.config["reply"].format(
|
reply = self.config["reply"].format(
|
||||||
target=collec_target,
|
target=collec_target,
|
||||||
num=len(collection),
|
num=len(collection),
|
||||||
things="".join(collection)
|
things="".join(collection),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
reply = self.config["empty_reply"].format(target=collec_target)
|
reply = self.config["empty_reply"].format(target=collec_target)
|
||||||
|
|
|
@ -9,8 +9,12 @@ class CaretakerPlugin(Plugin):
|
||||||
"""Say hello and farewall on people joining/parting."""
|
"""Say hello and farewall on people joining/parting."""
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"warm_welcome", "cold_welcome", "nice_farewell", "bad_farewell",
|
"warm_welcome",
|
||||||
"welcome_rate", "farewell_rate"
|
"cold_welcome",
|
||||||
|
"nice_farewell",
|
||||||
|
"bad_farewell",
|
||||||
|
"welcome_rate",
|
||||||
|
"farewell_rate",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
|
@ -34,9 +34,8 @@ class JourneeMondialePlugin(Plugin):
|
||||||
today_obs = map(
|
today_obs = map(
|
||||||
lambda line: line.split(maxsplit=1)[1],
|
lambda line: line.split(maxsplit=1)[1],
|
||||||
filter(
|
filter(
|
||||||
lambda line: line.startswith(date_tag),
|
lambda line: line.startswith(date_tag), self.config["dates"]
|
||||||
self.config["dates"]
|
),
|
||||||
)
|
|
||||||
)
|
)
|
||||||
reply = ", ".join(today_obs)
|
reply = ", ".join(today_obs)
|
||||||
if not reply:
|
if not reply:
|
||||||
|
|
|
@ -2,6 +2,7 @@ import time
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import meteofrance_api as mf
|
import meteofrance_api as mf
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -12,9 +13,14 @@ from edmond.plugin import Plugin
|
||||||
class MeteoFrancePlugin(Plugin):
|
class MeteoFrancePlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "result_message", "nearest_message", "temp_format",
|
"commands",
|
||||||
"rain_chance_format", "all_rain_format", "today_message",
|
"result_message",
|
||||||
"minmax_temp_format"
|
"nearest_message",
|
||||||
|
"temp_format",
|
||||||
|
"rain_chance_format",
|
||||||
|
"all_rain_format",
|
||||||
|
"today_message",
|
||||||
|
"minmax_temp_format",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -54,7 +60,8 @@ class MeteoFrancePlugin(Plugin):
|
||||||
return
|
return
|
||||||
|
|
||||||
result = self.config["result_message"].format(
|
result = self.config["result_message"].format(
|
||||||
nearest_s=nearest_s, today_s=today_s)
|
nearest_s=nearest_s, today_s=today_s
|
||||||
|
)
|
||||||
self.bot.say(event.target, result)
|
self.bot.say(event.target, result)
|
||||||
|
|
||||||
def format_nearest_forecast(self, nearest, place):
|
def format_nearest_forecast(self, nearest, place):
|
||||||
|
@ -65,43 +72,52 @@ class MeteoFrancePlugin(Plugin):
|
||||||
wind = self.format_wind(nearest["wind"])
|
wind = self.format_wind(nearest["wind"])
|
||||||
rain = self.format_rain_perc(nearest["rain"])
|
rain = self.format_rain_perc(nearest["rain"])
|
||||||
return self.config["nearest_message"].format(
|
return self.config["nearest_message"].format(
|
||||||
city=city, hour=hour, weather=weather, temp=temp, wind=wind,
|
city=city,
|
||||||
rain=rain
|
hour=hour,
|
||||||
|
weather=weather,
|
||||||
|
temp=temp,
|
||||||
|
wind=wind,
|
||||||
|
rain=rain,
|
||||||
)
|
)
|
||||||
|
|
||||||
def format_temperature(self, temperature):
|
def format_temperature(self, temperature):
|
||||||
temp_c = temperature.get("value", "?")
|
temp_c = temperature.get("value", "?")
|
||||||
temp_wc = temperature.get("windchill", "?")
|
temp_wc = temperature.get("windchill", "?")
|
||||||
return self.config["temp_format"].format(
|
return self.config["temp_format"].format(
|
||||||
temp_c=temp_c, temp_wc=temp_wc)
|
temp_c=temp_c, temp_wc=temp_wc
|
||||||
|
)
|
||||||
|
|
||||||
def format_rain_perc(self, rain_percs):
|
def format_rain_perc(self, rain_percs):
|
||||||
perc_fmt = self.config["rain_chance_format"]
|
perc_fmt = self.config["rain_chance_format"]
|
||||||
all_percs = ', '.join(
|
all_percs = ", ".join(
|
||||||
perc_fmt.format(p=p, h=h)
|
perc_fmt.format(p=p, h=h) for h, p in rain_percs.items()
|
||||||
for h, p in rain_percs.items()
|
|
||||||
)
|
)
|
||||||
return self.config["all_rain_format"].format(all_percs=all_percs)
|
return self.config["all_rain_format"].format(all_percs=all_percs)
|
||||||
|
|
||||||
def format_wind(self, wind):
|
def format_wind(self, wind):
|
||||||
speed = wind.get('speed')
|
speed = wind.get("speed")
|
||||||
direction = wind.get('icon')
|
direction = wind.get("icon")
|
||||||
if direction == "Variable":
|
if direction == "Variable":
|
||||||
direction = self.config["unknown_direction"]
|
direction = self.config["unknown_direction"]
|
||||||
return self.config["wind_format"].format(
|
return self.config["wind_format"].format(
|
||||||
speed=speed, direction=direction)
|
speed=speed, direction=direction
|
||||||
|
)
|
||||||
|
|
||||||
def format_today_forecast(self, today_f):
|
def format_today_forecast(self, today_f):
|
||||||
temp = today_f['T']
|
temp = today_f["T"]
|
||||||
temp_minmax = self.config["minmax_temp_format"].format(
|
temp_minmax = self.config["minmax_temp_format"].format(
|
||||||
t_max=temp["max"], t_min=temp["min"])
|
t_max=temp["max"], t_min=temp["min"]
|
||||||
rain = self.format_rain_perc(today_f['precipitation'])
|
)
|
||||||
sunset = format_ts_hour(today_f['sun']['set'])
|
rain = self.format_rain_perc(today_f["precipitation"])
|
||||||
|
sunset = format_ts_hour(today_f["sun"]["set"])
|
||||||
return self.config["today_message"].format(
|
return self.config["today_message"].format(
|
||||||
temp_minmax=temp_minmax, rain=rain, sunset=sunset)
|
temp_minmax=temp_minmax, rain=rain, sunset=sunset
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def format_ts_hour(timestamp):
|
def format_ts_hour(timestamp):
|
||||||
return time.strftime("%H:%M", time.localtime(timestamp))
|
return time.strftime("%H:%M", time.localtime(timestamp))
|
||||||
|
|
||||||
|
|
||||||
def format_weather(weather):
|
def format_weather(weather):
|
||||||
return weather.get("desc", "?").lower()
|
return weather.get("desc", "?").lower()
|
||||||
|
|
|
@ -21,16 +21,18 @@ class MiscReactionsPlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = ["reactions", "rate"]
|
REQUIRED_CONFIGS = ["reactions", "rate"]
|
||||||
|
|
||||||
REACTIONS = set([
|
REACTIONS = set(
|
||||||
"sentence",
|
[
|
||||||
"stop",
|
"sentence",
|
||||||
"king",
|
"stop",
|
||||||
"mmm",
|
"king",
|
||||||
"ooo",
|
"mmm",
|
||||||
"detector",
|
"ooo",
|
||||||
"repeat_letters",
|
"detector",
|
||||||
"nudge",
|
"repeat_letters",
|
||||||
])
|
"nudge",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
super().__init__(bot)
|
super().__init__(bot)
|
||||||
|
@ -136,8 +138,12 @@ class MiscReactionsPlugin(Plugin):
|
||||||
detector_neg = self.config.get("detector_neg")
|
detector_neg = self.config.get("detector_neg")
|
||||||
if any(
|
if any(
|
||||||
s is None
|
s is None
|
||||||
for s in (detector_message, detector_process, detector_pos,
|
for s in (
|
||||||
detector_neg)
|
detector_message,
|
||||||
|
detector_process,
|
||||||
|
detector_pos,
|
||||||
|
detector_neg,
|
||||||
|
)
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
self.bot.say(event.target, detector_message.format(subject=words[-1]))
|
self.bot.say(event.target, detector_message.format(subject=words[-1]))
|
||||||
|
@ -155,10 +161,9 @@ class MiscReactionsPlugin(Plugin):
|
||||||
biggest_word = sorted(words, key=lambda w: len(w))[-1]
|
biggest_word = sorted(words, key=lambda w: len(w))[-1]
|
||||||
num_repeats = 2
|
num_repeats = 2
|
||||||
repeated = biggest_word[:num_repeats]
|
repeated = biggest_word[:num_repeats]
|
||||||
while (
|
while (not any(letter in repeated for letter in "aeiouy")) and len(
|
||||||
(not any(letter in repeated for letter in "aeiouy"))
|
repeated
|
||||||
and len(repeated) < len(biggest_word)
|
) < len(biggest_word):
|
||||||
):
|
|
||||||
num_repeats += 1
|
num_repeats += 1
|
||||||
repeated = biggest_word[:num_repeats]
|
repeated = biggest_word[:num_repeats]
|
||||||
word = biggest_word[:2] + biggest_word
|
word = biggest_word[:2] + biggest_word
|
||||||
|
|
|
@ -21,7 +21,11 @@ class MoodPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "questions", "greetings", "answer", "calmed_message",
|
"commands",
|
||||||
|
"questions",
|
||||||
|
"greetings",
|
||||||
|
"answer",
|
||||||
|
"calmed_message",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
|
@ -2,6 +2,7 @@ import random
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from scaruffi.api import ScaruffiApi
|
from scaruffi.api import ScaruffiApi
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -11,7 +12,7 @@ from edmond.plugin import Plugin
|
||||||
|
|
||||||
class MusicPlugin(Plugin):
|
class MusicPlugin(Plugin):
|
||||||
"""Get some good music for your friends using the scaruffi library.
|
"""Get some good music for your friends using the scaruffi library.
|
||||||
|
|
||||||
The first command returns a random good album. The second command allows you
|
The first command returns a random good album. The second command allows you
|
||||||
to choose the decade: you can say 1960, 60, 60s or 60's, all of these will
|
to choose the decade: you can say 1960, 60, 60s or 60's, all of these will
|
||||||
return an album from the sixties.
|
return an album from the sixties.
|
||||||
|
|
|
@ -6,8 +6,12 @@ from edmond.plugin import Plugin
|
||||||
class NotesPlugin(Plugin):
|
class NotesPlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "content_regex", "confirmation", "deliver_format", "limit",
|
"commands",
|
||||||
"too_many_notes"
|
"content_regex",
|
||||||
|
"confirmation",
|
||||||
|
"deliver_format",
|
||||||
|
"limit",
|
||||||
|
"too_many_notes",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -32,7 +36,7 @@ class NotesPlugin(Plugin):
|
||||||
|
|
||||||
# "note down" command.
|
# "note down" command.
|
||||||
if self.command.ident == self.config["commands"][0]:
|
if self.command.ident == self.config["commands"][0]:
|
||||||
content = self.command.raw[len(self.command.matched):].strip()
|
content = self.command.raw[len(self.command.matched) :].strip()
|
||||||
matched = self.content_re.match(content)
|
matched = self.content_re.match(content)
|
||||||
if not matched:
|
if not matched:
|
||||||
return False
|
return False
|
||||||
|
@ -51,7 +55,7 @@ class NotesPlugin(Plugin):
|
||||||
note = {
|
note = {
|
||||||
"sender": event.source.nick,
|
"sender": event.source.nick,
|
||||||
"dest": target,
|
"dest": target,
|
||||||
"message": message
|
"message": message,
|
||||||
}
|
}
|
||||||
self.append_storage_list_value("notes", note)
|
self.append_storage_list_value("notes", note)
|
||||||
self.bot.say(event.target, self.config["confirmation"])
|
self.bot.say(event.target, self.config["confirmation"])
|
||||||
|
|
|
@ -8,7 +8,11 @@ from edmond.plugin import Plugin
|
||||||
class OpinionPlugin(Plugin):
|
class OpinionPlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"questions", "thinking", "thinking_time", "positive", "negative"
|
"questions",
|
||||||
|
"thinking",
|
||||||
|
"thinking_time",
|
||||||
|
"positive",
|
||||||
|
"negative",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
|
@ -9,8 +9,13 @@ class SleepPlugin(Plugin):
|
||||||
"""Handle sleep state of the bot, snore a little bit."""
|
"""Handle sleep state of the bot, snore a little bit."""
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "sleep_time", "wakeup_time", "snore", "sleep_messages",
|
"commands",
|
||||||
"wakeup_messages", "snore_rate"
|
"sleep_time",
|
||||||
|
"wakeup_time",
|
||||||
|
"snore",
|
||||||
|
"sleep_messages",
|
||||||
|
"wakeup_messages",
|
||||||
|
"snore_rate",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -65,7 +70,9 @@ class SleepPlugin(Plugin):
|
||||||
return
|
return
|
||||||
self.set_runtime_value("awake", True)
|
self.set_runtime_value("awake", True)
|
||||||
for channel in self.bot.channels:
|
for channel in self.bot.channels:
|
||||||
self.bot.say(channel, random.choice(self.config["wakeup_messages"]))
|
self.bot.say(
|
||||||
|
channel, random.choice(self.config["wakeup_messages"])
|
||||||
|
)
|
||||||
|
|
||||||
def is_sleep_time(self, now):
|
def is_sleep_time(self, now):
|
||||||
"""Return True if the bot should be sleeping by now.
|
"""Return True if the bot should be sleeping by now.
|
||||||
|
@ -83,9 +90,7 @@ class SleepPlugin(Plugin):
|
||||||
else:
|
else:
|
||||||
ref_dt = now
|
ref_dt = now
|
||||||
sleep_dt, wakeup_dt = self._get_sleep_range(
|
sleep_dt, wakeup_dt = self._get_sleep_range(
|
||||||
ref_dt,
|
ref_dt, sleep_time, wakeup_time
|
||||||
sleep_time,
|
|
||||||
wakeup_time
|
|
||||||
)
|
)
|
||||||
return sleep_dt <= now < wakeup_dt
|
return sleep_dt <= now < wakeup_dt
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,11 @@ IMG_FETCH_HTML = """\
|
||||||
class TaxrefPlugin(Plugin):
|
class TaxrefPlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "not_found_reply", "reply", "ambiguous_reply",
|
"commands",
|
||||||
"unnamed_species"
|
"not_found_reply",
|
||||||
|
"reply",
|
||||||
|
"ambiguous_reply",
|
||||||
|
"unnamed_species",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -90,7 +93,8 @@ class TaxrefPlugin(Plugin):
|
||||||
# If there are several species, check if one of them has the
|
# If there are several species, check if one of them has the
|
||||||
# exact same name; else show an ambiguous reply.
|
# exact same name; else show an ambiguous reply.
|
||||||
species_with_same_name = [
|
species_with_same_name = [
|
||||||
item for item in species_items
|
item
|
||||||
|
for item in species_items
|
||||||
if item["scientificName"].lower() == name
|
if item["scientificName"].lower() == name
|
||||||
]
|
]
|
||||||
if len(species_with_same_name) != 1:
|
if len(species_with_same_name) != 1:
|
||||||
|
@ -109,7 +113,7 @@ class TaxrefPlugin(Plugin):
|
||||||
)
|
)
|
||||||
self.bot.say(target, reply)
|
self.bot.say(target, reply)
|
||||||
|
|
||||||
if (images_reply := self.get_images_reply(item_to_use)):
|
if images_reply := self.get_images_reply(item_to_use):
|
||||||
self.bot.say(target, images_reply)
|
self.bot.say(target, images_reply)
|
||||||
|
|
||||||
def get_ambiguous_reply(self, items):
|
def get_ambiguous_reply(self, items):
|
||||||
|
@ -153,7 +157,7 @@ class TaxrefPlugin(Plugin):
|
||||||
def get_img_url(item):
|
def get_img_url(item):
|
||||||
return item.get("_links", {}).get("file", {}).get("href")
|
return item.get("_links", {}).get("file", {}).get("href")
|
||||||
|
|
||||||
if (shrlok := self.bot.get_plugin("shrlok")):
|
if shrlok := self.bot.get_plugin("shrlok"):
|
||||||
if len(items) > 10:
|
if len(items) > 10:
|
||||||
items = random.sample(items, 10)
|
items = random.sample(items, 10)
|
||||||
urls = map(get_img_url, items)
|
urls = map(get_img_url, items)
|
||||||
|
@ -191,15 +195,18 @@ class TaxrefPlugin(Plugin):
|
||||||
else:
|
else:
|
||||||
# More than one result? For simplicity sake, use the shrlok plugin
|
# More than one result? For simplicity sake, use the shrlok plugin
|
||||||
# if available or just show an ambiguous response.
|
# if available or just show an ambiguous response.
|
||||||
if (shrlok := self.bot.get_plugin("shrlok")):
|
if shrlok := self.bot.get_plugin("shrlok"):
|
||||||
text = "\n".join(
|
text = (
|
||||||
(
|
"\n".join(
|
||||||
item['frenchVernacularName'] +
|
(
|
||||||
" → " +
|
item["frenchVernacularName"]
|
||||||
TaxrefPlugin.item_to_full_name(item)
|
+ " → "
|
||||||
|
+ TaxrefPlugin.item_to_full_name(item)
|
||||||
|
)
|
||||||
|
for item in items
|
||||||
)
|
)
|
||||||
for item in items
|
+ "\n"
|
||||||
) + "\n"
|
)
|
||||||
reply = shrlok.post_text(text)
|
reply = shrlok.post_text(text)
|
||||||
else:
|
else:
|
||||||
reply = self.get_ambiguous_reply(items)
|
reply = self.get_ambiguous_reply(items)
|
||||||
|
|
|
@ -7,7 +7,6 @@ from ..sleep import SleepPlugin
|
||||||
|
|
||||||
|
|
||||||
class TestSleepPlugin(unittest.TestCase):
|
class TestSleepPlugin(unittest.TestCase):
|
||||||
|
|
||||||
def test_is_sleep_time(self):
|
def test_is_sleep_time(self):
|
||||||
with get_plugin_patcher(SleepPlugin):
|
with get_plugin_patcher(SleepPlugin):
|
||||||
plugin = SleepPlugin()
|
plugin = SleepPlugin()
|
||||||
|
|
|
@ -5,7 +5,6 @@ from ..translate import TranslatePlugin
|
||||||
|
|
||||||
|
|
||||||
class TestTranslatePlugin(unittest.TestCase):
|
class TestTranslatePlugin(unittest.TestCase):
|
||||||
|
|
||||||
def test_parse_words(self):
|
def test_parse_words(self):
|
||||||
with get_plugin_patcher(TranslatePlugin):
|
with get_plugin_patcher(TranslatePlugin):
|
||||||
plugin = TranslatePlugin()
|
plugin = TranslatePlugin()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
try:
|
try:
|
||||||
from translate import Translator
|
from translate import Translator
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -10,7 +11,10 @@ from edmond.plugin import Plugin
|
||||||
class TranslatePlugin(Plugin):
|
class TranslatePlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "default_dest", "param_source", "param_dest",
|
"commands",
|
||||||
|
"default_dest",
|
||||||
|
"param_source",
|
||||||
|
"param_dest",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
try:
|
try:
|
||||||
import wolframalpha
|
import wolframalpha
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -79,7 +80,9 @@ class UnknownCommandPlugin(Plugin):
|
||||||
else:
|
else:
|
||||||
reply = answer_text
|
reply = answer_text
|
||||||
if len(reply) > self.MAX_LENGTH - len(self.CUT_MARK):
|
if len(reply) > self.MAX_LENGTH - len(self.CUT_MARK):
|
||||||
reply = reply[:self.MAX_LENGTH - len(self.CUT_MARK)] + self.CUT_MARK
|
reply = (
|
||||||
|
reply[: self.MAX_LENGTH - len(self.CUT_MARK)] + self.CUT_MARK
|
||||||
|
)
|
||||||
self.bot.say(target, reply)
|
self.bot.say(target, reply)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -2,6 +2,7 @@ import time
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import wikipedia
|
import wikipedia
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -12,7 +13,10 @@ from edmond.plugin import Plugin
|
||||||
class WikipediaPlugin(Plugin):
|
class WikipediaPlugin(Plugin):
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "ambiguous_response", "empty_response", "lang",
|
"commands",
|
||||||
|
"ambiguous_response",
|
||||||
|
"empty_response",
|
||||||
|
"lang",
|
||||||
]
|
]
|
||||||
NUM_RETRIES = 3
|
NUM_RETRIES = 3
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
try:
|
try:
|
||||||
from googleapiclient.discovery import build as gapi_discovery_build
|
from googleapiclient.discovery import build as gapi_discovery_build
|
||||||
from googleapiclient.errors import Error as GoogleApiError
|
from googleapiclient.errors import Error as GoogleApiError
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -23,9 +24,7 @@ class YoutubePlugin(Plugin):
|
||||||
def youtube(self):
|
def youtube(self):
|
||||||
if self._youtube is None:
|
if self._youtube is None:
|
||||||
self._youtube = gapi_discovery_build(
|
self._youtube = gapi_discovery_build(
|
||||||
"youtube",
|
"youtube", "v3", developerKey=self.config["api_key"]
|
||||||
"v3",
|
|
||||||
developerKey=self.config["api_key"]
|
|
||||||
)
|
)
|
||||||
return self._youtube
|
return self._youtube
|
||||||
|
|
||||||
|
@ -43,11 +42,15 @@ class YoutubePlugin(Plugin):
|
||||||
def handle_commands(self, target):
|
def handle_commands(self, target):
|
||||||
if self.command.ident == self.config["commands"][0]:
|
if self.command.ident == self.config["commands"][0]:
|
||||||
try:
|
try:
|
||||||
search_response = self.youtube.search().list(
|
search_response = (
|
||||||
q=self.command.content,
|
self.youtube.search()
|
||||||
part="id,snippet",
|
.list(
|
||||||
maxResults=1,
|
q=self.command.content,
|
||||||
).execute()
|
part="id,snippet",
|
||||||
|
maxResults=1,
|
||||||
|
)
|
||||||
|
.execute()
|
||||||
|
)
|
||||||
except GoogleApiError:
|
except GoogleApiError:
|
||||||
self.signal_failure(target)
|
self.signal_failure(target)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,7 @@ import re
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from googleapiclient.errors import Error as GoogleApiError
|
from googleapiclient.errors import Error as GoogleApiError
|
||||||
|
|
||||||
DEPENDENCIES_FOUND = True
|
DEPENDENCIES_FOUND = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
DEPENDENCIES_FOUND = False
|
DEPENDENCIES_FOUND = False
|
||||||
|
@ -49,8 +50,7 @@ class YoutubeParserPlugin(Plugin):
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
search_response = (
|
search_response = (
|
||||||
self.youtube_plugin.youtube
|
self.youtube_plugin.youtube.videos()
|
||||||
.videos()
|
|
||||||
.list(id=code, part="snippet")
|
.list(id=code, part="snippet")
|
||||||
.execute()
|
.execute()
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,5 +8,6 @@ def http_get(url):
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return response.text
|
return response.text
|
||||||
|
|
||||||
|
|
||||||
def proc(proba_percentage):
|
def proc(proba_percentage):
|
||||||
return random.random() < (proba_percentage / 100.0)
|
return random.random() < (proba_percentage / 100.0)
|
||||||
|
|
Loading…
Reference in a new issue