From aedaa6f7b748cb3ba83ac6238759de9f6530942d Mon Sep 17 00:00:00 2001 From: tcely Date: Fri, 16 May 2025 03:33:33 -0400 Subject: [PATCH 01/24] Copy generic functions from `sync.utils` --- tubesync/common/utils.py | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tubesync/common/utils.py b/tubesync/common/utils.py index c4798943..fdf04352 100644 --- a/tubesync/common/utils.py +++ b/tubesync/common/utils.py @@ -8,11 +8,22 @@ import string import time from datetime import datetime from django.core.paginator import Paginator +from functools import partial +from operator import attrgetter, itemgetter +from pathlib import Path from urllib.parse import urlunsplit, urlencode, urlparse from yt_dlp.utils import LazyList from .errors import DatabaseConnectionError +def directory_and_stem(arg_path, /): + filepath = Path(arg_path) + stem = Path(filepath.stem) + while stem.suffixes and '' != stem.suffix: + stem = Path(stem.stem) + return (filepath.parent, str(stem),) + + def getenv(key, default=None, /, *, integer=False, string=True): ''' Guarantees a returned type from calling `os.getenv` @@ -48,6 +59,51 @@ def getenv(key, default=None, /, *, integer=False, string=True): return r +def glob_quote(filestr, /): + _glob_specials = { + '?': '[?]', + '*': '[*]', + '[': '[[]', + ']': '[]]', # probably not needed, but it won't hurt + } + + if not isinstance(filestr, str): + raise TypeError(f'expected a str, got "{type(filestr)}"') + + return filestr.translate(str.maketrans(_glob_specials)) + + +def list_of_dictionaries(arg_list, /, *, arg_function=lambda x: x): + assert callable(arg_function) + if isinstance(arg_list, list): + _map_func = partial(lambda f, d: f(d) if isinstance(d, dict) else d, arg_function) + return (True, list(map(_map_func, arg_list)),) + return (False, arg_list,) + + +def mkdir_p(arg_path, /, *, mode=0o777): + ''' + Reminder: mode only affects the last directory + ''' + dirpath = Path(arg_path) + return dirpath.mkdir(mode=mode, parents=True, exist_ok=True) + + +def multi_key_sort(iterable, specs, /, use_reversed=False, *, item=False, attr=False, key_func=None): + result = list(iterable) + if key_func is None: + # itemgetter is the default + if item or not (item or attr): + key_func = itemgetter + elif attr: + key_func = attrgetter + for key, reverse in reversed(specs): + result.sort(key=key_func(key), reverse=reverse) + if use_reversed: + return list(reversed(result)) + return result + + def parse_database_connection_string(database_connection_string): ''' Parses a connection string in a URL style format, such as: @@ -180,6 +236,15 @@ def json_serial(obj): raise TypeError(f'Type {type(obj)} is not json_serial()-able') +def seconds_to_timestr(seconds): + seconds = seconds % (24 * 3600) + hour = seconds // 3600 + seconds %= 3600 + minutes = seconds // 60 + seconds %= 60 + return '{:02d}:{:02d}:{:02d}'.format(hour, minutes, seconds) + + def time_func(func): def wrapper(*args, **kwargs): start = time.perf_counter() From 3aa5ec9aae4a9f7caa80586a17428ba76df200ea Mon Sep 17 00:00:00 2001 From: tcely Date: Tue, 20 May 2025 04:25:47 -0400 Subject: [PATCH 02/24] Remove `json_serial` as it is in json.py instead --- tubesync/common/utils.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tubesync/common/utils.py b/tubesync/common/utils.py index 64c597cb..e773bb5b 100644 --- a/tubesync/common/utils.py +++ b/tubesync/common/utils.py @@ -223,14 +223,6 @@ def clean_emoji(s): return emoji.replace_emoji(s) -def json_serial(obj): - if isinstance(obj, datetime): - return obj.isoformat() - if isinstance(obj, LazyList): - return list(obj) - raise TypeError(f'Type {type(obj)} is not json_serial()-able') - - def seconds_to_timestr(seconds): seconds = seconds % (24 * 3600) hour = seconds // 3600 From 360b39ebcf166059d72f4cc7a94825cf17be76e3 Mon Sep 17 00:00:00 2001 From: tcely Date: Sat, 24 May 2025 23:03:45 -0400 Subject: [PATCH 03/24] Update `directory_and_stem` in utils.py --- tubesync/common/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tubesync/common/utils.py b/tubesync/common/utils.py index e773bb5b..7256b3d8 100644 --- a/tubesync/common/utils.py +++ b/tubesync/common/utils.py @@ -13,11 +13,10 @@ from pathlib import Path from urllib.parse import urlunsplit, urlencode, urlparse from .errors import DatabaseConnectionError - -def directory_and_stem(arg_path, /): +def directory_and_stem(arg_path, /, all_suffixes=False): filepath = Path(arg_path) stem = Path(filepath.stem) - while stem.suffixes and '' != stem.suffix: + while all_suffixes and stem.suffixes and '' != stem.suffix: stem = Path(stem.stem) return (filepath.parent, str(stem),) From 6d04d773c3bedfe5ed2cde907526ef1488f5f8a5 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 14:39:07 -0400 Subject: [PATCH 04/24] Remove `glob_quote` from sync/utils.py --- tubesync/sync/utils.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index fc7874fd..46668c25 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -95,20 +95,6 @@ def resize_image_to_height(image, width, height): return image -def glob_quote(filestr): - _glob_specials = { - '?': '[?]', - '*': '[*]', - '[': '[[]', - ']': '[]]', # probably not needed, but it won't hurt - } - - if not isinstance(filestr, str): - raise TypeError(f'filestr must be a str, got "{type(filestr)}"') - - return filestr.translate(str.maketrans(_glob_specials)) - - def file_is_editable(filepath): ''' Checks that a file exists and the file is in an allowed predefined tuple of From dbd30e65d6a4b96316b1561b6795785aeefd0573 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 14:42:12 -0400 Subject: [PATCH 05/24] Adjust the `glob_quote` import in sync/signals.py --- tubesync/sync/signals.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tubesync/sync/signals.py b/tubesync/sync/signals.py index d68a082f..e1a22ee5 100644 --- a/tubesync/sync/signals.py +++ b/tubesync/sync/signals.py @@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy as _ from background_task.signals import task_failed from background_task.models import Task from common.logger import log +from common.utils import glob_quote from .models import Source, Media, Metadata from .tasks import (delete_task_by_source, delete_task_by_media, index_source_task, download_media_thumbnail, download_media_metadata, @@ -17,7 +18,7 @@ from .tasks import (delete_task_by_source, delete_task_by_media, index_source_ta download_media, download_source_images, delete_all_media_for_source, save_all_media_for_source, rename_media, get_media_metadata_task, get_media_download_task) -from .utils import delete_file, glob_quote, mkdir_p +from .utils import delete_file, mkdir_p from .filtering import filter_media from .choices import Val, YouTube_SourceType From c7e8c974e67e6ed49f225c44411d5e7937d064b6 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 14:45:28 -0400 Subject: [PATCH 06/24] Adjust the `glob_quote` import in sync/media.py --- tubesync/sync/models/media.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/models/media.py b/tubesync/sync/models/media.py index 62f73d5d..32e026e8 100644 --- a/tubesync/sync/models/media.py +++ b/tubesync/sync/models/media.py @@ -17,7 +17,7 @@ from common.logger import log from common.errors import NoFormatException from common.json import JSONEncoder from common.utils import ( - clean_filename, clean_emoji, + clean_filename, clean_emoji, glob_quote, ) from ..youtube import ( get_media_info as get_youtube_media_info, @@ -25,7 +25,7 @@ from ..youtube import ( ) from ..utils import ( seconds_to_timestr, parse_media_format, filter_response, - write_text_file, mkdir_p, glob_quote, multi_key_sort, + write_text_file, mkdir_p, multi_key_sort, ) from ..matching import ( get_best_combined_format, From 7b23d3b0f01567df99408fac5052ceb5510421d8 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 14:51:45 -0400 Subject: [PATCH 07/24] Remove `seconds_to_timestr` from sync/utils.py --- tubesync/sync/utils.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index 46668c25..3f62492e 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -148,15 +148,6 @@ def delete_file(filepath): return False -def seconds_to_timestr(seconds): - seconds = seconds % (24 * 3600) - hour = seconds // 3600 - seconds %= 3600 - minutes = seconds // 60 - seconds %= 60 - return '{:02d}:{:02d}:{:02d}'.format(hour, minutes, seconds) - - def multi_key_sort(iterable, specs, /, use_reversed=False, *, item=False, attr=False, key_func=None): result = list(iterable) if key_func is None: From 2c67b2f31c4b1f0dd118c47b1e99c914a39a77e2 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 14:59:08 -0400 Subject: [PATCH 08/24] Adjust the `seconds_to_timestr` import in sync/tasks.py --- tubesync/sync/tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/tasks.py b/tubesync/sync/tasks.py index c5903bb0..f01f769e 100644 --- a/tubesync/sync/tasks.py +++ b/tubesync/sync/tasks.py @@ -31,11 +31,11 @@ from common.errors import ( NoFormatException, NoMediaException, NoThumbnailException, DownloadFailedException, ) from common.utils import ( django_queryset_generator as qs_gen, - remove_enclosed, ) + remove_enclosed, seconds_to_timestr, ) from .choices import Val, TaskQueue from .models import Source, Media, MediaServer from .utils import ( get_remote_image, resize_image_to_height, - write_text_file, filter_response, seconds_to_timestr, ) + write_text_file, filter_response, ) from .youtube import YouTubeError db_vendor = db.connection.vendor From db7af44cec1b8a9059969748157f1222ffdaa270 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:03:32 -0400 Subject: [PATCH 09/24] Adjust the `seconds_to_timestr` import in sync/media.py --- tubesync/sync/models/media.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tubesync/sync/models/media.py b/tubesync/sync/models/media.py index 32e026e8..f50de356 100644 --- a/tubesync/sync/models/media.py +++ b/tubesync/sync/models/media.py @@ -18,13 +18,14 @@ from common.errors import NoFormatException from common.json import JSONEncoder from common.utils import ( clean_filename, clean_emoji, glob_quote, + seconds_to_timestr, ) from ..youtube import ( get_media_info as get_youtube_media_info, download_media as download_youtube_media, ) from ..utils import ( - seconds_to_timestr, parse_media_format, filter_response, + parse_media_format, filter_response, write_text_file, mkdir_p, multi_key_sort, ) from ..matching import ( From 8852c8c2eff06ec916e653d033cf5af5ea4d1c98 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:16:47 -0400 Subject: [PATCH 10/24] Switch to the `common.utils` version --- tubesync/sync/models/media.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tubesync/sync/models/media.py b/tubesync/sync/models/media.py index f50de356..377d87c3 100644 --- a/tubesync/sync/models/media.py +++ b/tubesync/sync/models/media.py @@ -17,8 +17,8 @@ from common.logger import log from common.errors import NoFormatException from common.json import JSONEncoder from common.utils import ( - clean_filename, clean_emoji, glob_quote, - seconds_to_timestr, + clean_filename, clean_emoji, directory_and_stem, + glob_quote, seconds_to_timestr, ) from ..youtube import ( get_media_info as get_youtube_media_info, @@ -39,7 +39,7 @@ from ..choices import ( from ._migrations import ( media_file_storage, get_media_thumb_path, get_media_file_path, ) -from ._private import _srctype_dict, _nfo_element, directory_and_stem +from ._private import _srctype_dict, _nfo_element from .media__tasks import ( download_checklist, download_finished, wait_for_premiere, ) From 8b127afc234f1bddca5198aea53b022c78767b06 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:18:57 -0400 Subject: [PATCH 11/24] Remove the old copy from sync/models/_private.py --- tubesync/sync/models/_private.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tubesync/sync/models/_private.py b/tubesync/sync/models/_private.py index 8cf41ce1..094d3763 100644 --- a/tubesync/sync/models/_private.py +++ b/tubesync/sync/models/_private.py @@ -11,11 +11,3 @@ def _nfo_element(nfo, label, text, /, *, attrs={}, tail='\n', char=' ', indent=2 element.tail = tail + (char * indent) return element -def directory_and_stem(arg_path, /, all_suffixes=False): - filepath = Path(arg_path) - stem = Path(filepath.stem) - while all_suffixes and stem.suffixes and '' != stem.suffix: - stem = Path(stem.stem) - stem = str(stem) - return (filepath.parent, stem,) - From 432bc019d5197b3adcdfaaabc924e533a3e99268 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:23:18 -0400 Subject: [PATCH 12/24] fixup: remove an unused import --- tubesync/sync/models/_private.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tubesync/sync/models/_private.py b/tubesync/sync/models/_private.py index 094d3763..5ec14d7c 100644 --- a/tubesync/sync/models/_private.py +++ b/tubesync/sync/models/_private.py @@ -1,4 +1,3 @@ -from pathlib import Path from ..choices import Val, YouTube_SourceType # noqa From dc0edef5624d1dc0bc8c0231c9eb3790a42275d2 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:31:32 -0400 Subject: [PATCH 13/24] Remove `list_of_dictionaries` from sync/utils.py --- tubesync/sync/utils.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index 3f62492e..617bccca 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -7,6 +7,7 @@ from pathlib import Path from tempfile import NamedTemporaryFile import requests from PIL import Image +from common.utils import list_of_dictionaries from django.conf import settings from urllib.parse import urlsplit, parse_qs from django.forms import ValidationError @@ -178,17 +179,6 @@ def normalize_codec(codec_str): return result -def list_of_dictionaries(arg_list, arg_function=lambda x: x): - assert callable(arg_function) - if isinstance(arg_list, list): - def _call_func_with_dict(arg_dict): - if isinstance(arg_dict, dict): - return arg_function(arg_dict) - return arg_dict - return (True, list(map(_call_func_with_dict, arg_list)),) - return (False, arg_list,) - - def _url_keys(arg_dict, filter_func): result = {} if isinstance(arg_dict, dict): From f097b6b4e06e33db0b3b5f9840bc6d64d3791ba4 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:38:36 -0400 Subject: [PATCH 14/24] Remove `mkdir_p` from sync/utils.py --- tubesync/sync/utils.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index 617bccca..9b18248b 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -117,14 +117,6 @@ def file_is_editable(filepath): return False -def mkdir_p(arg_path, mode=0o777): - ''' - Reminder: mode only affects the last directory - ''' - dirpath = Path(arg_path) - return dirpath.mkdir(mode=mode, parents=True, exist_ok=True) - - def write_text_file(filepath, filedata): if not isinstance(filedata, str): raise TypeError(f'filedata must be a str, got "{type(filedata)}"') From 0be0aa9e812cf1acc74a68bbf40a4352ccc1af77 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:46:50 -0400 Subject: [PATCH 15/24] Adjust the `mkdir_p` import in sync/models/media.py --- tubesync/sync/models/media.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/models/media.py b/tubesync/sync/models/media.py index 377d87c3..ab21fb9f 100644 --- a/tubesync/sync/models/media.py +++ b/tubesync/sync/models/media.py @@ -18,7 +18,7 @@ from common.errors import NoFormatException from common.json import JSONEncoder from common.utils import ( clean_filename, clean_emoji, directory_and_stem, - glob_quote, seconds_to_timestr, + glob_quote, mkdir_p, seconds_to_timestr, ) from ..youtube import ( get_media_info as get_youtube_media_info, @@ -26,7 +26,7 @@ from ..youtube import ( ) from ..utils import ( parse_media_format, filter_response, - write_text_file, mkdir_p, multi_key_sort, + write_text_file, multi_key_sort, ) from ..matching import ( get_best_combined_format, From ff30543a2016a78bfac6da4b59a03395b21cce55 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:55:58 -0400 Subject: [PATCH 16/24] Adjust the `mkdir_p` import in sync/signals.py --- tubesync/sync/signals.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/signals.py b/tubesync/sync/signals.py index e1a22ee5..f25d6a92 100644 --- a/tubesync/sync/signals.py +++ b/tubesync/sync/signals.py @@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _ from background_task.signals import task_failed from background_task.models import Task from common.logger import log -from common.utils import glob_quote +from common.utils import glob_quote, mkdir_p from .models import Source, Media, Metadata from .tasks import (delete_task_by_source, delete_task_by_media, index_source_task, download_media_thumbnail, download_media_metadata, @@ -18,7 +18,7 @@ from .tasks import (delete_task_by_source, delete_task_by_media, index_source_ta download_media, download_source_images, delete_all_media_for_source, save_all_media_for_source, rename_media, get_media_metadata_task, get_media_download_task) -from .utils import delete_file, mkdir_p +from .utils import delete_file from .filtering import filter_media from .choices import Val, YouTube_SourceType From fbb27eaa5dce8e3d351c6a50b47e21c6827e5c30 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 15:58:11 -0400 Subject: [PATCH 17/24] Adjust the `mkdir_p` import in sync/views.py --- tubesync/sync/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/views.py b/tubesync/sync/views.py index 5f13877f..45236465 100644 --- a/tubesync/sync/views.py +++ b/tubesync/sync/views.py @@ -20,13 +20,13 @@ from django.utils._os import safe_join from django.utils import timezone from django.utils.translation import gettext_lazy as _ from common.timestamp import timestamp_to_datetime -from common.utils import append_uri_params +from common.utils import append_uri_params, mkdir_p from background_task.models import Task, CompletedTask from .models import Source, Media, MediaServer from .forms import (ValidateSourceForm, ConfirmDeleteSourceForm, RedownloadMediaForm, SkipMediaForm, EnableMediaForm, ResetTasksForm, ScheduleTaskForm, ConfirmDeleteMediaServerForm, SourceForm) -from .utils import validate_url, delete_file, multi_key_sort, mkdir_p +from .utils import validate_url, delete_file, multi_key_sort from .tasks import (map_task_to_instance, get_error_message, get_source_completed_tasks, get_media_download_task, delete_task_by_media, index_source_task, From 021988ff9ffcc0e8009af4a82dbe625f23773521 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 16:02:12 -0400 Subject: [PATCH 18/24] Adjust the `mkdir_p` import in sync/youtube.py --- tubesync/sync/youtube.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tubesync/sync/youtube.py b/tubesync/sync/youtube.py index 7afdf337..f8516b69 100644 --- a/tubesync/sync/youtube.py +++ b/tubesync/sync/youtube.py @@ -7,6 +7,7 @@ import os from common.logger import log +from common.utils import mkdir_p from copy import deepcopy from pathlib import Path from tempfile import TemporaryDirectory @@ -15,7 +16,6 @@ from urllib.parse import urlsplit, parse_qs from django.conf import settings from .choices import Val, FileExtension from .hooks import postprocessor_hook, progress_hook -from .utils import mkdir_p import yt_dlp import yt_dlp.patch.check_thumbnails import yt_dlp.patch.fatal_http_errors From 1afe0d41539731fb7d16fd5969d8b825b5096a03 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 18:31:48 -0400 Subject: [PATCH 19/24] Adjust the `multi_key_sort` import in sync/matching.py --- tubesync/sync/matching.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tubesync/sync/matching.py b/tubesync/sync/matching.py index 4196a9f8..f5fe3fd1 100644 --- a/tubesync/sync/matching.py +++ b/tubesync/sync/matching.py @@ -6,7 +6,7 @@ from .choices import Val, Fallback -from .utils import multi_key_sort +from common.utils import multi_key_sort from django.conf import settings From 64cd082406ad3e6baf7887af6069e59c71275cb2 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 18:40:05 -0400 Subject: [PATCH 20/24] Remove `multi_key_sort` from sync/utils.py --- tubesync/sync/utils.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index 9b18248b..7c8947bb 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -141,21 +141,6 @@ def delete_file(filepath): return False -def multi_key_sort(iterable, specs, /, use_reversed=False, *, item=False, attr=False, key_func=None): - result = list(iterable) - if key_func is None: - # itemgetter is the default - if item or not (item or attr): - key_func = itemgetter - elif attr: - key_func = attrgetter - for key, reverse in reversed(specs): - result.sort(key=key_func(key), reverse=reverse) - if use_reversed: - return list(reversed(result)) - return result - - def normalize_codec(codec_str): result = str(codec_str).upper() parts = result.split('.') From decbe14968a5ce43df89d5f67d10345d64034226 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 18:47:52 -0400 Subject: [PATCH 21/24] Adjust the `multi_key_sort` import in sync/models/media.py --- tubesync/sync/models/media.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tubesync/sync/models/media.py b/tubesync/sync/models/media.py index ab21fb9f..b2c79e15 100644 --- a/tubesync/sync/models/media.py +++ b/tubesync/sync/models/media.py @@ -18,15 +18,14 @@ from common.errors import NoFormatException from common.json import JSONEncoder from common.utils import ( clean_filename, clean_emoji, directory_and_stem, - glob_quote, mkdir_p, seconds_to_timestr, + glob_quote, mkdir_p, multi_key_sort, seconds_to_timestr, ) from ..youtube import ( get_media_info as get_youtube_media_info, download_media as download_youtube_media, ) from ..utils import ( - parse_media_format, filter_response, - write_text_file, multi_key_sort, + filter_response, parse_media_format, write_text_file, ) from ..matching import ( get_best_combined_format, From ae1974b503c734c1b220a4f577f00cc6c101bdec Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 18:52:09 -0400 Subject: [PATCH 22/24] Adjust the `multi_key_sort` import in sync/views.py --- tubesync/sync/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tubesync/sync/views.py b/tubesync/sync/views.py index 45236465..493098cd 100644 --- a/tubesync/sync/views.py +++ b/tubesync/sync/views.py @@ -20,13 +20,13 @@ from django.utils._os import safe_join from django.utils import timezone from django.utils.translation import gettext_lazy as _ from common.timestamp import timestamp_to_datetime -from common.utils import append_uri_params, mkdir_p +from common.utils import append_uri_params, mkdir_p, multi_key_sort from background_task.models import Task, CompletedTask from .models import Source, Media, MediaServer from .forms import (ValidateSourceForm, ConfirmDeleteSourceForm, RedownloadMediaForm, SkipMediaForm, EnableMediaForm, ResetTasksForm, ScheduleTaskForm, ConfirmDeleteMediaServerForm, SourceForm) -from .utils import validate_url, delete_file, multi_key_sort +from .utils import delete_file, validate_url from .tasks import (map_task_to_instance, get_error_message, get_source_completed_tasks, get_media_download_task, delete_task_by_media, index_source_task, From 659e46a31f85535f6d199491958ec806e63719e8 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 18:55:36 -0400 Subject: [PATCH 23/24] fixup: remove unused imports --- tubesync/sync/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tubesync/sync/utils.py b/tubesync/sync/utils.py index 7c8947bb..cbd14eab 100644 --- a/tubesync/sync/utils.py +++ b/tubesync/sync/utils.py @@ -2,7 +2,6 @@ import os import re import math from copy import deepcopy -from operator import attrgetter, itemgetter from pathlib import Path from tempfile import NamedTemporaryFile import requests From 60aafbdab4c7f4b770be3c0b9ce77f8280b02757 Mon Sep 17 00:00:00 2001 From: tcely Date: Mon, 2 Jun 2025 19:04:40 -0400 Subject: [PATCH 24/24] fixup: accept the existing calls --- tubesync/common/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tubesync/common/utils.py b/tubesync/common/utils.py index 7256b3d8..0c7507e9 100644 --- a/tubesync/common/utils.py +++ b/tubesync/common/utils.py @@ -70,7 +70,7 @@ def glob_quote(filestr, /): return filestr.translate(str.maketrans(_glob_specials)) -def list_of_dictionaries(arg_list, /, *, arg_function=lambda x: x): +def list_of_dictionaries(arg_list, /, arg_function=lambda x: x): assert callable(arg_function) if isinstance(arg_list, list): _map_func = partial(lambda f, d: f(d) if isinstance(d, dict) else d, arg_function)