Compare commits
1 Commits
fix/issue-
...
feat/issue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7503ecd14 |
@@ -8,6 +8,7 @@ from telegram.ext import Application, CommandHandler, MessageHandler, filters
|
|||||||
|
|
||||||
from commands import (
|
from commands import (
|
||||||
cmd_add,
|
cmd_add,
|
||||||
|
cmd_admin,
|
||||||
cmd_bounty,
|
cmd_bounty,
|
||||||
cmd_delete,
|
cmd_delete,
|
||||||
cmd_edit,
|
cmd_edit,
|
||||||
@@ -41,6 +42,7 @@ def build_app() -> Application:
|
|||||||
app.add_handler(CommandHandler("delete", cmd_delete))
|
app.add_handler(CommandHandler("delete", cmd_delete))
|
||||||
app.add_handler(CommandHandler("track", cmd_track))
|
app.add_handler(CommandHandler("track", cmd_track))
|
||||||
app.add_handler(CommandHandler("untrack", cmd_untrack))
|
app.add_handler(CommandHandler("untrack", cmd_untrack))
|
||||||
|
app.add_handler(CommandHandler("admin", cmd_admin))
|
||||||
|
|
||||||
app.add_handler(MessageHandler(filters.COMMAND, cmd_help))
|
app.add_handler(MessageHandler(filters.COMMAND, cmd_help))
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ async def post_init(app: Application) -> None:
|
|||||||
("edit", "Edit a bounty"),
|
("edit", "Edit a bounty"),
|
||||||
("track", "Track a bounty"),
|
("track", "Track a bounty"),
|
||||||
("untrack", "Stop tracking"),
|
("untrack", "Stop tracking"),
|
||||||
|
("admin", "List room admins"),
|
||||||
("help", "Show help"),
|
("help", "Show help"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -48,24 +48,21 @@ def parse_args(args: list[str]) -> tuple[Optional[str], Optional[str], Optional[
|
|||||||
return text, link, due_date_ts
|
return text, link, due_date_ts
|
||||||
|
|
||||||
|
|
||||||
def format_bounty(b, show_id: bool = True, slice_length: int = 0) -> str:
|
def format_bounty(b, show_id: bool = True) -> str:
|
||||||
parts = []
|
parts = []
|
||||||
if show_id:
|
if show_id:
|
||||||
parts.append(f"[#{b.id}]")
|
parts.append(f"[#{b.id}]")
|
||||||
if b.text:
|
if b.text:
|
||||||
text = b.text
|
parts.append(b.text)
|
||||||
if slice_length > 0 and len(text) > slice_length:
|
|
||||||
text = text[:slice_length] + "..."
|
|
||||||
parts.append(text)
|
|
||||||
if b.link:
|
if b.link:
|
||||||
parts.append(f"🔗 {b.link}")
|
parts.append(f"🔗 {b.link}")
|
||||||
if b.due_date_ts:
|
if b.due_date_ts:
|
||||||
due_str = time.strftime("%d %b %Y", time.localtime(b.due_date_ts))
|
due_str = time.strftime("%Y-%m-%d", time.localtime(b.due_date_ts))
|
||||||
days_left = (b.due_date_ts - int(time.time())) // 86400
|
days_left = (b.due_date_ts - int(time.time())) // 86400
|
||||||
if days_left < 0:
|
if days_left < 0:
|
||||||
parts.append(f"⏰ {due_str} (OVERDUE)")
|
parts.append(f"⏰ {due_str} (OVERDUE)")
|
||||||
elif days_left == 0:
|
elif days_left == 0:
|
||||||
parts.append(f"⏰ Today (OVERDUE)")
|
parts.append(f"⏰ {due_str} (TODAY)")
|
||||||
else:
|
else:
|
||||||
parts.append(f"⏰ {due_str} ({days_left}d)")
|
parts.append(f"⏰ {due_str} ({days_left}d)")
|
||||||
if b.created_by_user_id:
|
if b.created_by_user_id:
|
||||||
@@ -98,58 +95,13 @@ def get_room_id(update: Update) -> int:
|
|||||||
|
|
||||||
async def cmd_bounty(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
async def cmd_bounty(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
room_id = get_room_id(update)
|
room_id = get_room_id(update)
|
||||||
args = extract_args(update.message.text)
|
bounties = BOUNTY_SERVICE.list_bounties(room_id)
|
||||||
|
|
||||||
show_all = "all" in args
|
if not bounties:
|
||||||
args = [a for a in args if a != "all"]
|
await update.message.reply_text("No bounties yet.")
|
||||||
|
|
||||||
try:
|
|
||||||
limit = int(args[0]) if args else 5
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
limit = 5
|
|
||||||
|
|
||||||
now = int(time.time())
|
|
||||||
cutoff_24h = now - 86400
|
|
||||||
|
|
||||||
all_bounties = BOUNTY_SERVICE.list_bounties(room_id)
|
|
||||||
|
|
||||||
def is_expired(b) -> bool:
|
|
||||||
return b.due_date_ts is not None and b.due_date_ts < cutoff_24h
|
|
||||||
|
|
||||||
def sort_key(b):
|
|
||||||
if b.due_date_ts is not None:
|
|
||||||
return (0, b.due_date_ts)
|
|
||||||
return (1, b.created_at)
|
|
||||||
|
|
||||||
filtered_bounties = [b for b in all_bounties if not is_expired(b) or show_all]
|
|
||||||
filtered_bounties.sort(key=sort_key)
|
|
||||||
|
|
||||||
total_count = len(filtered_bounties)
|
|
||||||
displayed_bounties = filtered_bounties[:limit]
|
|
||||||
|
|
||||||
if not displayed_bounties:
|
|
||||||
if show_all:
|
|
||||||
await update.message.reply_text("No bounties yet.")
|
|
||||||
else:
|
|
||||||
await update.message.reply_text(
|
|
||||||
"No active bounties. Use /bounty all to show expired."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
lines = []
|
lines = [format_bounty(b, show_id=True) for b in bounties]
|
||||||
if limit < total_count:
|
|
||||||
lines.append(f"Showing {limit} of {total_count} bounties:")
|
|
||||||
slice_length = 40
|
|
||||||
elif show_all and total_count > limit:
|
|
||||||
lines.append(f"Showing {limit} of {total_count} bounties (including expired):")
|
|
||||||
slice_length = 40
|
|
||||||
else:
|
|
||||||
lines.append(f"Showing {total_count} bounties:")
|
|
||||||
slice_length = 0
|
|
||||||
|
|
||||||
for b in displayed_bounties:
|
|
||||||
lines.append(format_bounty(b, show_id=True, slice_length=slice_length))
|
|
||||||
|
|
||||||
await update.message.reply_text("\n".join(lines), disable_web_page_preview=True)
|
await update.message.reply_text("\n".join(lines), disable_web_page_preview=True)
|
||||||
|
|
||||||
|
|
||||||
@@ -369,7 +321,23 @@ async def cmd_help(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
|||||||
"/delete <id> — delete bounty\n"
|
"/delete <id> — delete bounty\n"
|
||||||
"/track <id> — track a bounty (groups only)\n"
|
"/track <id> — track a bounty (groups only)\n"
|
||||||
"/untrack <id> — stop tracking (groups only)\n"
|
"/untrack <id> — stop tracking (groups only)\n"
|
||||||
|
"/admin — list room admins\n"
|
||||||
"/start — re-initialize\n"
|
"/start — re-initialize\n"
|
||||||
"/help — this message",
|
"/help — this message",
|
||||||
disable_web_page_preview=True,
|
disable_web_page_preview=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def cmd_admin(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
|
room_id = get_room_id(update)
|
||||||
|
admin_ids = BOUNTY_SERVICE.list_admins(room_id)
|
||||||
|
|
||||||
|
if not admin_ids:
|
||||||
|
await update.message.reply_text("No admins configured for this room.")
|
||||||
|
return
|
||||||
|
|
||||||
|
lines = [f"Room Admins:"]
|
||||||
|
for admin_id in admin_ids:
|
||||||
|
lines.append(f"- @{admin_id}")
|
||||||
|
|
||||||
|
await update.message.reply_text("\n".join(lines))
|
||||||
|
|||||||
Reference in New Issue
Block a user