Merge pull request #731 from tcely/patch-2

Review of signals.py
This commit is contained in:
meeb 2025-02-17 18:19:24 +11:00 committed by GitHub
commit 3de98335db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,3 @@
import os
import glob
from pathlib import Path from pathlib import Path
from django.conf import settings from django.conf import settings
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete from django.db.models.signals import pre_save, post_save, pre_delete, post_delete
@ -15,7 +13,7 @@ from .tasks import (delete_task_by_source, delete_task_by_media, index_source_ta
download_media, rescan_media_server, download_source_images, download_media, rescan_media_server, download_source_images,
save_all_media_for_source, rename_media, save_all_media_for_source, rename_media,
get_media_metadata_task, get_media_download_task) get_media_metadata_task, get_media_download_task)
from .utils import delete_file, glob_quote from .utils import delete_file, glob_quote, mkdir_p
from .filtering import filter_media from .filtering import filter_media
from .choices import Val, YouTube_SourceType from .choices import Val, YouTube_SourceType
@ -29,15 +27,29 @@ def source_pre_save(sender, instance, **kwargs):
except Source.DoesNotExist: except Source.DoesNotExist:
# Probably not possible? # Probably not possible?
return return
if existing_source.index_schedule != instance.index_schedule: existing_dirpath = existing_source.directory_path.resolve(strict=True)
new_dirpath = instance.directory_path.resolve(strict=False)
rename_source_directory = (
existing_dirpath != new_dirpath and
not new_dirpath.exists()
)
if rename_source_directory:
mkdir_p(new_dirpath.parent)
existing_dirpath.rename(new_dirpath)
recreate_index_source_task = (
existing_source.name != instance.name or
existing_source.index_schedule != instance.index_schedule
)
if recreate_index_source_task:
# Indexing schedule has changed, recreate the indexing task # Indexing schedule has changed, recreate the indexing task
delete_task_by_source('sync.tasks.index_source_task', instance.pk) delete_task_by_source('sync.tasks.index_source_task', instance.pk)
verbose_name = _('Index media from source "{}"') verbose_name = _('Index media from source "{}"')
index_source_task( index_source_task(
str(instance.pk), str(instance.pk),
schedule=instance.index_schedule,
repeat=instance.index_schedule, repeat=instance.index_schedule,
queue=str(instance.pk), queue=str(instance.pk),
priority=5, priority=10,
verbose_name=verbose_name.format(instance.name), verbose_name=verbose_name.format(instance.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -56,18 +68,19 @@ def source_post_save(sender, instance, created, **kwargs):
if instance.source_type != Val(YouTube_SourceType.PLAYLIST) and instance.copy_channel_images: if instance.source_type != Val(YouTube_SourceType.PLAYLIST) and instance.copy_channel_images:
download_source_images( download_source_images(
str(instance.pk), str(instance.pk),
priority=2, priority=5,
verbose_name=verbose_name.format(instance.name) verbose_name=verbose_name.format(instance.name)
) )
if instance.index_schedule > 0: if instance.index_schedule > 0:
delete_task_by_source('sync.tasks.index_source_task', instance.pk) delete_task_by_source('sync.tasks.index_source_task', instance.pk)
log.info(f'Scheduling media indexing for source: {instance.name}') log.info(f'Scheduling first media indexing for source: {instance.name}')
verbose_name = _('Index media from source "{}"') verbose_name = _('Index media from source "{}"')
index_source_task( index_source_task(
str(instance.pk), str(instance.pk),
schedule=600,
repeat=instance.index_schedule, repeat=instance.index_schedule,
queue=str(instance.pk), queue=str(instance.pk),
priority=5, priority=10,
verbose_name=verbose_name.format(instance.name), verbose_name=verbose_name.format(instance.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -86,14 +99,14 @@ def source_post_save(sender, instance, created, **kwargs):
rename_media( rename_media(
str(media.pk), str(media.pk),
queue=str(media.pk), queue=str(media.pk),
priority=1, priority=5,
verbose_name=verbose_name.format(media.key, media.name), verbose_name=verbose_name.format(media.key, media.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
verbose_name = _('Checking all media for source "{}"') verbose_name = _('Checking all media for source "{}"')
save_all_media_for_source( save_all_media_for_source(
str(instance.pk), str(instance.pk),
priority=2, priority=9,
verbose_name=verbose_name.format(instance.name), verbose_name=verbose_name.format(instance.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -160,7 +173,7 @@ def media_post_save(sender, instance, created, **kwargs):
verbose_name = _('Downloading metadata for "{}"') verbose_name = _('Downloading metadata for "{}"')
download_media_metadata( download_media_metadata(
str(instance.pk), str(instance.pk),
priority=5, priority=10,
verbose_name=verbose_name.format(instance.pk), verbose_name=verbose_name.format(instance.pk),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -177,7 +190,7 @@ def media_post_save(sender, instance, created, **kwargs):
str(instance.pk), str(instance.pk),
thumbnail_url, thumbnail_url,
queue=str(instance.source.pk), queue=str(instance.source.pk),
priority=10, priority=15,
verbose_name=verbose_name.format(instance.name), verbose_name=verbose_name.format(instance.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -196,7 +209,7 @@ def media_post_save(sender, instance, created, **kwargs):
download_media( download_media(
str(instance.pk), str(instance.pk),
queue=str(instance.source.pk), queue=str(instance.source.pk),
priority=10, priority=15,
verbose_name=verbose_name.format(instance.name), verbose_name=verbose_name.format(instance.name),
remove_existing_tasks=True remove_existing_tasks=True
) )
@ -209,27 +222,31 @@ def media_post_save(sender, instance, created, **kwargs):
@receiver(pre_delete, sender=Media) @receiver(pre_delete, sender=Media)
def media_pre_delete(sender, instance, **kwargs): def media_pre_delete(sender, instance, **kwargs):
# Triggered before media is deleted, delete any scheduled tasks # Triggered before media is deleted, delete any unlocked scheduled tasks
log.info(f'Deleting tasks for media: {instance.name}') log.info(f'Deleting tasks for media: {instance.name}')
delete_task_by_media('sync.tasks.download_media', (str(instance.pk),)) delete_task_by_media('sync.tasks.download_media', (str(instance.pk),))
delete_task_by_media('sync.tasks.download_media_metadata', (str(instance.pk),))
delete_task_by_media('sync.tasks.rename_media', (str(instance.pk),))
delete_task_by_media('sync.tasks.wait_for_media_premiere', (str(instance.pk),))
thumbnail_url = instance.thumbnail thumbnail_url = instance.thumbnail
if thumbnail_url: if thumbnail_url:
delete_task_by_media('sync.tasks.download_media_thumbnail', delete_task_by_media('sync.tasks.download_media_thumbnail',
(str(instance.pk), thumbnail_url)) (str(instance.pk), thumbnail_url))
# Remove thumbnail file for deleted media
if instance.thumb:
instance.thumb.delete(save=False)
@receiver(post_delete, sender=Media) @receiver(post_delete, sender=Media)
def media_post_delete(sender, instance, **kwargs): def media_post_delete(sender, instance, **kwargs):
# Remove thumbnail file for deleted media
if instance.thumb:
instance.thumb.delete(save=False)
# Remove the video file, when configured to do so # Remove the video file, when configured to do so
if instance.source.delete_files_on_disk and instance.media_file: if instance.source.delete_files_on_disk and instance.media_file:
video_path = Path(str(instance.media_file.path)).resolve() video_path = Path(str(instance.media_file.path)).resolve(strict=False)
instance.media_file.delete(save=False) instance.media_file.delete(save=False)
# the other files we created have these known suffixes # the other files we created have these known suffixes
for suffix in frozenset(('nfo', 'jpg', 'webp', 'info.json',)): for suffix in frozenset(('nfo', 'jpg', 'webp', 'info.json',)):
other_path = video_path.with_suffix(f'.{suffix}').resolve() other_path = video_path.with_suffix(f'.{suffix}').resolve(strict=False)
if other_path.is_file():
log.info(f'Deleting file for: {instance} path: {other_path!s}') log.info(f'Deleting file for: {instance} path: {other_path!s}')
delete_file(other_path) delete_file(other_path)
# subtitles include language code # subtitles include language code
@ -240,7 +257,7 @@ def media_post_delete(sender, instance, **kwargs):
# Jellyfin creates .trickplay directories and posters # Jellyfin creates .trickplay directories and posters
for suffix in frozenset(('.trickplay', '-poster.jpg', '-poster.webp',)): for suffix in frozenset(('.trickplay', '-poster.jpg', '-poster.webp',)):
# with_suffix insists on suffix beginning with '.' for no good reason # with_suffix insists on suffix beginning with '.' for no good reason
other_path = Path(str(video_path.with_suffix('')) + suffix).resolve() other_path = Path(str(video_path.with_suffix('')) + suffix).resolve(strict=False)
if other_path.is_file(): if other_path.is_file():
log.info(f'Deleting file for: {instance} path: {other_path!s}') log.info(f'Deleting file for: {instance} path: {other_path!s}')
delete_file(other_path) delete_file(other_path)
@ -284,6 +301,7 @@ def media_post_delete(sender, instance, **kwargs):
verbose_name = _('Request media server rescan for "{}"') verbose_name = _('Request media server rescan for "{}"')
rescan_media_server( rescan_media_server(
str(mediaserver.pk), str(mediaserver.pk),
schedule=5,
priority=0, priority=0,
verbose_name=verbose_name.format(mediaserver), verbose_name=verbose_name.format(mediaserver),
remove_existing_tasks=True remove_existing_tasks=True