diff --git a/apps/telegram-bot/commands.py b/apps/telegram-bot/commands.py index 941934c..c8931d9 100644 --- a/apps/telegram-bot/commands.py +++ b/apps/telegram-bot/commands.py @@ -56,26 +56,62 @@ def extract_args(text: str) -> list[str]: return tokens[1:] if len(tokens) > 1 else [] -def parse_args(args: list[str]) -> tuple[Optional[str], Optional[str], Optional[int]]: +def parse_args( + args: list[str], +) -> tuple[Optional[str], Optional[str], Optional[int], bool, bool]: text = None link = None due_date_ts = None + clear_link = False + clear_date = False - remaining = [] - for arg in args: - if not link and (arg.startswith("http://") or arg.startswith("https://")): + i = 0 + while i < len(args): + arg = args[i] + + if arg == "-link": + if i + 1 < len(args) and ( + args[i + 1].startswith("http://") or args[i + 1].startswith("https://") + ): + link = args[i + 1] + i += 2 + else: + clear_link = True + i += 1 + elif arg == "-date": + if i + 1 < len(args): + parsed = dateparser.parse(args[i + 1]) + if parsed: + due_date_ts = int(parsed.timestamp()) + i += 2 + else: + clear_date = True + i += 1 + else: + clear_date = True + i += 1 + elif not link and (arg.startswith("http://") or arg.startswith("https://")): link = arg + i += 1 elif due_date_ts is None: parsed = dateparser.parse(arg) if parsed: due_date_ts = int(parsed.timestamp()) + i += 1 else: - remaining.append(arg) + i += 1 + if text is None: + text = arg + else: + text = text + " " + arg else: - remaining.append(arg) + i += 1 + if text is None: + text = arg + else: + text = text + " " + arg - text = " ".join(remaining) if remaining else None - return text, link, due_date_ts + return text, link, due_date_ts, clear_link, clear_date def format_bounty(b, show_id: bool = True, room_id: int | None = None) -> str: @@ -172,7 +208,7 @@ async def cmd_add(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: ) return - text, link, due_date_ts = parse_args(args) + text, link, due_date_ts, _, _ = parse_args(args) if not text and not link: await update.message.reply_text("A bounty needs at least text or a link.") return @@ -203,7 +239,14 @@ async def cmd_update(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: args = extract_args(update.message.text) if len(args) < 1: await update.message.reply_text( - "Usage: /update [text] [link] [due_date]" + "Usage: /update [text] [link] [due_date]\n" + " /update -link [] - clear or set link\n" + " /update -date [] - clear or set date\n" + "Examples:\n" + " /update 1 new text - update text only\n" + " /update 1 -link - clear link\n" + " /update 1 -link https://... - set link\n" + " /update 1 -link -date - clear both link and date" ) return @@ -213,8 +256,14 @@ async def cmd_update(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: await update.message.reply_text("Invalid bounty ID.") return - text, link, due_date_ts = parse_args(args[1:]) - if not text and not link and due_date_ts is None: + text, link, due_date_ts, clear_link, clear_date = parse_args(args[1:]) + if ( + not text + and not link + and due_date_ts is None + and not clear_link + and not clear_date + ): await update.message.reply_text("Nothing to update.") return @@ -229,10 +278,15 @@ async def cmd_update(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: text=text, link=link, due_date_ts=due_date_ts, + clear_link=clear_link, + clear_due=clear_date, ) except PermissionError as e: await update.message.reply_text(f"⛔ {e}") return + except ValueError as e: + await update.message.reply_text(f"⛔ {e}") + return if success: await update.message.reply_text(f"✅ Bounty #{bounty_id} updated.") @@ -353,8 +407,11 @@ async def cmd_help(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: "/bounty — list all bounties\n" "/my — bounties you're tracking\n" "/add [link] [due] — add bounty\n" - "/update [text> [link] [due] — update bounty\n" - "/delete — delete bounty\n" + "/update [text] [link] [due] — update bounty\n" + "/edit [text] [link] [due] — edit bounty (same as update)\n" + " /edit -link [] — clear or set link\n" + " /edit -date [] — clear or set date\n" + "/delete — delete bounty (admin only)\n" "/track — track a bounty (groups only)\n" "/untrack — stop tracking (groups only)\n" "/timezone [tz] — get/set room timezone (admin only)\n"