8 Commits
Author SHA1 Message Date
dsql 7adb8dc386 chore: bump to 1.1.0 (logging-discipline audit)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-08-10 23:00:50 -04:00
dsql d2bfb949ee fix: drop log-and-raise in create/delete emoji error paths
both HTTPException handlers logged at ERROR then re-raised - raise XOR log. the exception
propagates unwrapped to the caller (the documented fail-loud contract), so it already
carries the failure; the error log double-reported it. drop the log, keep the raise. the
module logger stays defined (emit-only) for future use.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-08-09 02:12:08 -04:00
dsql 818579215b release: 1.0.0
first stable release. pre-1.0.0 verification complete: all surviving MED regressions and
gaps resolved and independently re-fired, tree audited clean across the suite.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-09 18:53:15 -04:00
dsql de9fa8ad79 refactor: derive __version__ from package metadata (single source)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 17:00:17 -04:00
dsql 6fc4e14f3c fix: offload refresh() blocking I/O to a thread; document MissingApplicationID (v0.1.2)
refresh() did folder scan, magic-byte sniff, and per-file image reads directly
on the event loop. Offload via asyncio.to_thread so the loop stays responsive
during a large sync; behavior (validation, size cap, stem-collision and
missing-dir raises) is unchanged.

Also documents discord.MissingApplicationID in refresh()'s Raises contract -
it is a ClientException, not an HTTPException, so it was previously uncaught
by the existing except clauses and unlisted in the docstring.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 16:17:59 -04:00
dsql d59bdcc9b9 fix: fail loud on missing emoji dir, stem collisions, and corrupt images
refresh() previously treated a missing assets/emojis folder (wrong cwd,
missing WorkingDirectory=/WORKDIR) as an empty one, silently deleting
every application emoji on the app every restart with no signal and no
way back (recreated emojis get new IDs). _scan_folder now raises
DPYAppEmojisError naming the absent path instead; a present-but-empty
folder still mirrors as before.

Two files sharing a name stem across extensions (check.png + check.gif)
used to silently collapse to one synced emoji via last-write-wins,
breaking the documented delete+re-add replace workflow with no error.
_scan_folder now raises DPYAppEmojisError naming both colliding files.

A valid extension with unrecognized magic bytes (truncated download,
mismatched format) made discord.py raise an anonymous
ValueError('Unsupported image type given') from create_application_emoji,
which the lib's (Forbidden, HTTPException) catch didn't cover, leaving
no way to tell which file in a large folder was broken. _scan_folder now
pre-flights the same magic-byte check discord.py itself uses and raises
ValueError naming the offending file before any create is attempted.

Also collapses the redundant Forbidden member in the create/delete except
clauses (Forbidden already subclasses HTTPException); log-then-raise
behavior is unchanged.

Bump 0.1.0 -> 0.1.1.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 15:32:16 -04:00
dsql 7d878845df add package: pyproject + src (DPYAppEmojis, folder-mirror refresh, dot-access, fail-loud)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-02 19:59:13 -04:00
dsql 77cfc6a10a init: mirror a project folder onto the bot's application emojis for discord.py
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-02 19:59:13 -04:00