added /help with a category dropdown that covers all non-mod commands, also
user's avatar fading in from the left side at an angle.
went through every file and fixed pylance errors - Optional type hints on
params that default to None, made cog_unload async everywhere, added isinstance
guards before accessing Member-only attributes, and narrowed get_channel()
return types before calling send().
birthday list now removes db entries for users who have left the server when
someone queries a month.
daily fractal:
- add events/daily_fractal.py: posts today's fractal from lilacrose.dev
to channel 876772600704020533 daily at noon UTC
- palette name derived from seed as fallback for cached fractals
- add !fractal owner-only command to manually trigger a fractal post
stats:
- add per_command_usage table to track usage per command name
- increment_usage now accepts command name from both prefix and slash commands
- expose per-command breakdown in stats payload
avatar bad apple:
- add invert parameter to flip dark/light regions
- add real-time render and encode progress bars via interaction edits
- process frames in chunks to cap peak RAM usage
- track and cancel active render tasks and ffmpeg processes on cog unload
- switch output to mp4 only (drop webm/alpha path), use ultrafast preset
- check file size against guild limit before uploading
- remove 30-second frame cap
moderation:
- infraction auto-removal: skip users who left and rejoined after infraction date
- add Reason field to infraction removal approval and denial embeds
send_embed: support zlib-compressed embed strings with legacy fallback
chore:
- remove events/status_alerts.py
- remove arg from COG_FOLDERS
- update .gitignore: add *.zip, bad_apple.mp3, */bad-apple/
avatar:
- add /avatar bad_apple command: tiles user pfp as fill for Bad Apple frames
- support two-user mode (user1=silhouette, user2=background), outputs MP4
- single-user mode outputs WebM with alpha transparency
- audio sync: detect and trim leading silence via atrim filter, skip
equivalent video frames so Discord cannot strip silence at playback
- avatar_type global/server fix: use user.avatar explicitly for global
- delta_only option: only render pixels that changed from previous frame
- parallel frame processing with ThreadPoolExecutor (load + composite)
- np.tile replaces PIL paste loop for tiled canvas (major speedup)
- frame list cached at cog_load to avoid re-globbing 6572 files each call
- uses imageio-ffmpeg bundled binary (no system ffmpeg required)
moderation:
- fix InfractionRemovalView buttons erroring with closed database after
cog reload by opening a fresh connection per button click
- add approval_message_id column to infractions table
- store message ID when sending approval embed
- re-register persistent views on cog_load so buttons survive bot restarts
- add inf resend command to re-send a broken approval embed