Commit Graph

4052 Commits

Author SHA1 Message Date
tcely
e4a017ca6f Merge pull request #1572 from meeb/tcely-handler-fork-lock
fix(logs): lock _after_fork changes
2026-08-31 03:56:22 -04:00
tcely
7140bbbd39 fix(close_db): simplify guard condition for huey immediate mode 2026-08-30 01:02:18 -04:00
tcely
c2b49b215b fix(logs): lock _after_fork changes 2026-08-29 15:55:33 -04:00
tcely
c058ece431 Merge branch 'main' into fix/filename-max-bytes 2026-08-28 10:31:05 -04:00
tcely
18ee1440e0 chore(ci): set GITHUB_API_KEY for asfald-latest 2026-08-27 22:53:18 -04:00
tcely
b703703c50 chore(lint): ignore SIM117 2026-08-27 15:29:39 -04:00
tcely
1d588b617f chore: use Path instead of PurePosixPath 2026-08-27 15:15:51 -04:00
tcely
1ad1a94fc5 fix: clean before trucate 2026-08-27 15:06:24 -04:00
tcely
e13df54127 fix: clamp max_bytes to realistic values 2026-08-27 14:52:22 -04:00
tcely
a7e2e192e9 chore: rename truncate_filename_bytes to truncate_filename 2026-08-27 13:45:35 -04:00
tcely
661f928e3c chore(lint): ignore B010,RUF059,SIM118 2026-08-27 13:25:33 -04:00
tcely
c77a82feb6 chore(lint): ignore BLE001 2026-08-27 13:25:31 -04:00
tcely
c931730a46 Merge branch 'main' into fix/filename-max-bytes 2026-08-27 12:53:22 -04:00
tcely
034ffad1f4 Merge pull request #1571 from meeb/issue/493/bulk-editing-in-the-django-admin-control-panel
chore: add additional actions
2026-08-27 12:52:13 -04:00
tcely
7c14c3a69e Merge branch 'main' into fix/filename-max-bytes 2026-08-27 12:51:27 -04:00
tcely
bb8d155369 fix: count the metadata loop too 2026-08-27 12:47:22 -04:00
tcely
ba41626f29 fix: match the other actions 2026-08-27 12:41:34 -04:00
tcely
2d0dc29840 chore: clean up the merge from main 2026-08-27 12:31:22 -04:00
tcely
318479ebed Merge branch 'main' into issue/493/bulk-editing-in-the-django-admin-control-panel 2026-08-27 12:22:04 -04:00
tcely
5deac47742 Merge pull request #1570 from Agi-Asi/feat/admin-bulk-actions
feat: bulk admin actions for `Media.skip`
2026-08-27 12:17:25 -04:00
tcely
2679cb1198 fix: use distinct/iterator for the queryset 2026-08-27 12:05:37 -04:00
tcely
2dd4b88aed fix: provide an example to enable the setting 2026-08-27 11:41:50 -04:00
Agi-Asi
be4313ba1f review: optionally queue save_media tasks after bulk actions
Adds SAVE_MEDIA_AFTER_BULK_ACTION (env:
TUBESYNC_SAVE_MEDIA_AFTER_BULK_ACTION, default False). When enabled,
each admin bulk action queues a save_media task per changed item so
flags are re-evaluated without waiting for the next source edit or
indexing run. When disabled (the default) behaviour is unchanged:
re-evaluation happens on the next source edit/index pass.

Requested by tcely in review.
2026-08-27 14:56:58 +00:00
tcely
e76b05ebd3 chore(lint): ignore TRY002 & TRY004 2026-08-27 10:53:21 -04:00
tcely
7e62a082f9 fix(lint): address DTZ007 2026-08-27 10:39:40 -04:00
tcely
964025fa85 fix(lint): address PIE790 2026-08-27 10:39:37 -04:00
tcely
e520f9c254 fix(lint): address B006 2026-08-27 10:39:35 -04:00
tcely
ee5416309b fix(test): specify max_bytes for truncate_filename_bytes 2026-08-27 09:30:47 -04:00
tcely
2be3b9f23e fix(lint): address TRY004 2026-08-27 09:25:45 -04:00
tcely
45237a2cd4 chore(lint): ignore RUF059 2026-08-27 09:25:41 -04:00
tcely
137e65ae01 fix(lint): address UP032 2026-08-27 09:25:38 -04:00
tcely
ab269c3702 fix(lint): address FURB188 2026-08-27 09:25:35 -04:00
tcely
f8d8da4df3 fix(lint): address RUF012 2026-08-27 09:25:32 -04:00
tcely
af0230f088 chore: move some imports 2026-08-27 09:24:49 -04:00
Agi-Asi
d9f28d4e31 review: parse names with pathlib, raise TypeError, add encoding-edge tests
Addresses review feedback:
- truncate_filename_bytes parses stem/suffix with PurePosixPath instead
  of str.rpartition; Media.filename splits directory/name with
  PurePosixPath.with_name instead of string slicing
- non-str input now raises TypeError (was ValueError) to match the
  type-error semantics
- new tests cover bytes known to cause encoding/decoding trouble: cuts
  landing inside 4-byte emoji, combining sequences, ZWJ families,
  mixed-width boundaries, RTL text, dotfiles, no-extension and
  oversized-extension names — asserting byte budget, UTF-8 round-trip
  validity, and non-empty results in every case
2026-08-27 09:24:37 -04:00
tcely
b88d2456d4 chore: move the import 2026-08-27 06:20:09 -04:00
Agi-Asi
81eec0da04 Add bulk admin actions for skip and can_download on Media
Managing large libraries through the Django admin required editing
every media item individually to toggle 'skip' or 'can download'
(#493). Add the standard admin bulk actions for exactly the two
fields requested there:

- Set / unset 'skip' — also sets manual_skip to match, so a bulk
  un-skip is not immediately re-skipped by the filtering logic, and a
  bulk skip is treated as the operator's explicit decision
- Set / unset 'can download'

Also adds list_filter for can_download/skip/downloaded so the items
to bulk-edit can actually be narrowed down first.

Uses queryset.update() so a bulk action on thousands of rows is a
single UPDATE, not thousands of model saves.

Tests cover both action pairs and the action registration.

Fixes #493
2026-08-27 09:37:41 +00:00
Agi-Asi
050bce8094 Truncate generated filenames to the filesystem byte limit
Filesystems limit each path component to 255 bytes, not characters.
Multi-byte titles (CJK, emoji) hit that with far fewer characters — a
98-character Japanese title is already 225+ bytes before TubeSync adds
prefixes and yt-dlp adds '.fNNN.mp4.part(-FragNN)' suffixes — and the
download then fails permanently with:

    ERROR: unable to open for writing: [Errno 36] File name too long

(#522). The task retries and fails forever with no way out short of
renaming the source format.

Media.filename now clamps the final name component to a 200-byte
budget (leaving headroom for the suffixes appended during download):

- only the name component is shortened; directories from the format
  string are preserved untouched
- bytes are removed from the middle of the stem, keeping its start
  (the beginning of the title) and its end (the unique {key}/{format}
  suffixes of the default media format), joined by '_..._' — so
  uniqueness of generated names survives truncation
- truncation never splits a multi-byte character (partial sequences
  are dropped when decoding)
- a warning is logged when a name is shortened

Names within the limit are returned byte-identical, so existing
installs see no change unless they were already broken.

Fixes #522
2026-08-27 09:33:01 +00:00
tcely
2249c38f81 chore: include the latest wiki changes 2026-08-27 01:26:38 -04:00
tcely
c48284f125 Merge pull request #1568 from meeb/tcely-retry-save
feat: retry saves when the database is locked
2026-08-27 01:14:20 -04:00
tcely
820b3e2a59 fix(lint): address UP025 & UP032; ignore SIM117 2026-08-26 16:26:23 -04:00
tcely
ea3293f11c fix: retry save and update for tasks 2026-08-26 16:08:21 -04:00
tcely
83906dde1b chore: tweak comments 2026-08-26 11:25:54 -04:00
tcely
f50f9b906b fix: retry TaskHistory.objects.get_or_create 2026-08-26 11:25:51 -04:00
tcely
6608c975b5 feat: retry TaskHistory.save 2026-08-26 11:25:48 -04:00
tcely
b70e184a8a feat: implement retry_django_db decorator 2026-08-26 11:25:46 -04:00
tcely
b02246e242 fix: remove a buggy version of hat-juggler 2026-08-26 03:46:39 -04:00
tcely
cd4e4588ab Merge pull request #1565 from ryanduguid/source-images-from-index
feat: use indexing response to save channel images
2026-08-26 03:03:59 -04:00
tcely
2e02ef43e0 chore: adjust CancelExecution import 2026-08-26 02:41:41 -04:00
tcely
1c9efc5132 fix: use default_site as the default for site 2026-08-26 00:22:09 -04:00