style: run Black over the whole project

This commit is contained in:
dece 2022-08-09 23:47:28 +02:00
parent 4beead146f
commit 895b0dec47
26 changed files with 222 additions and 156 deletions

View file

@ -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] = {}

View file

@ -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)

View file

@ -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

View file

@ -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='')
) )

View file

@ -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

View file

@ -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)

View file

@ -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, [])

View file

@ -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)

View file

@ -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):

View file

@ -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:

View file

@ -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()

View file

@ -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

View file

@ -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):

View file

@ -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

View file

@ -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"])

View file

@ -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):

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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()

View file

@ -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):

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()
) )

View file

@ -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)