diff --git a/fitnessCog/fitness.py b/fitnessCog/fitness.py index de02f9d..a95b134 100644 --- a/fitnessCog/fitness.py +++ b/fitnessCog/fitness.py @@ -1,67 +1,128 @@ import os -import discord -from redbot.core import Config, commands -from .activity_logger import log_activity, activity_log_path, activity_units_path +from pathlib import Path +import discord +from redbot.core import commands +from redbot.core.data_manager import bundled_data_path + +from .activity_logger import log_activity class FitnessCog(commands.Cog): def __init__(self, bot): self.bot = bot - # Some hardcoded values, this probably should be changed with redbot config. IDK how to use it or what's in it. + default_threads = "1457402451530350727,1328363409648910356" - self.threads_id = list(map(int, os.getenv("THREADS_ID", default_threads).split(","))) + threads_raw = os.getenv("THREADS_ID", default_threads) + + self.threads_id = [] + for x in threads_raw.split(","): + x = x.strip() + if x.isdigit(): + self.threads_id.append(int(x)) + self.confirm_reactions = os.getenv("CONFIRMATION_REACTIONS", "🐈💨") + self.bundled_activities_dir: Path = bundled_data_path(self) / "activities" + + # ---- path helpers ---- + def activity_units_path(self, activity: str) -> Path: + return self.bundled_activities_dir / f"{activity}.json" + + def activity_log_path(self, activity: str) -> Path: + return self.bundled_activities_dir / f"{activity}_log.json" @commands.Cog.listener() - async def on_message(self, message): + async def on_message(self, message: discord.Message): if message.author.bot: return if message.channel.id not in self.threads_id: return - if not message.content.startswith("!"): + + content = (message.content or "").strip() + if not content.startswith("!"): return - # region Fitness commands - if message.content.startswith("!getunits"): - await self.get_units_file(message) + cmdline = content[1:].strip() + if not cmdline: return - if message.content.startswith("!getlog"): - await self.get_log_file(message) + + cmd, *rest = cmdline.split(" ", 1) + cmd = cmd.lower() + arg = rest[0].strip() if rest else "" + + if cmd == "getunits": + await self.get_units_file(message, arg) return - # Make sure this one is past every other ! commands + + if cmd == "getlog": + await self.get_log_file(message, arg) + return + await self.log_fitness(message) - return - # endregion Fitness commands - # region Fitness commands functions - @staticmethod - async def get_units_file(message: discord.Message): + async def get_units_file(self, message: discord.Message, activity: str): try: - raw = message.content[1:].lower().strip().split(" ", 1) - filename = activity_units_path(raw[1]) - await message.channel.send(file=discord.File(fp=filename)) + if not activity: + await message.channel.send( + "Usage: `!getunits ` (example: `!getunits pushups`)" + ) + return + + activity = activity.lower() + path = self.activity_units_path(activity) + + if not path.exists(): + await message.channel.send(f"No units JSON found for `{activity}`.") + return + + await message.channel.send(file=discord.File(fp=str(path))) + except Exception as e: await message.channel.send(str(e)) - @staticmethod - async def get_log_file(message: discord.Message): + async def get_log_file(self, message: discord.Message, activity: str): try: - raw = message.content[1:].lower().strip().split(" ", 1) - filename = activity_log_path(raw[1]) - await message.channel.send(file=discord.File(fp=filename)) + if not activity: + await message.channel.send( + "Usage: `!getlog ` (example: `!getlog pushups`)" + ) + return + + activity = activity.lower() + path = self.activity_log_path(activity) + + if not path.exists(): + await message.channel.send(f"No log JSON found for `{activity}`.") + return + + await message.channel.send(file=discord.File(fp=str(path))) + except Exception as e: await message.channel.send(str(e)) - async def log_fitness(self, message): + async def log_fitness(self, message: discord.Message): try: - raw = message.content[1:].lower().strip().split(" ", 2) + parts = message.content[1:].strip().split() + if len(parts) < 2: + await message.reply( + "Usage: `! [unit]` (example: `!pushups 20 reps`)" + ) + return + + activity = parts[0].lower() + + try: + value = float(parts[1]) + except ValueError: + await message.reply( + "Invalid number. Usage: `! [unit]` (example: `!run 5 km`)" + ) + return + + unit = parts[2].lower() if len(parts) > 2 else "m" timestamp = int(message.created_at.timestamp()) username = message.author.name - activity = raw[0] - value = float(raw[1]) - unit = raw[2] if len(raw) > 2 else "m" log_activity(timestamp, username, activity, value, unit) @@ -70,9 +131,7 @@ class FitnessCog(commands.Cog): except Exception as e: await message.reply(str(e)) - # endregion Fitness commands functions def setup(bot): bot.add_cog(FitnessCog(bot)) -