diff --git a/tubesync/sync/migrations/0019_add_delete_removed_media.py b/tubesync/sync/migrations/0019_add_delete_removed_media.py new file mode 100644 index 0000000..0762be8 --- /dev/null +++ b/tubesync/sync/migrations/0019_add_delete_removed_media.py @@ -0,0 +1,17 @@ +# Generated by pac + +from django.db import migrations, models + +class Migration(migrations.Migration): + + dependencies = [ + ('sync', '0018_source_subtitles'), + ] + + operations = [ + migrations.AddField( + model_name='source', + name='delete_removed_media', + field=models.BooleanField(default=False, help_text='Delete media that is no longer on this playlist', verbose_name='delete removed media'), + ), + ] diff --git a/tubesync/sync/models.py b/tubesync/sync/models.py index 18bddc1..bb8c723 100644 --- a/tubesync/sync/models.py +++ b/tubesync/sync/models.py @@ -287,6 +287,11 @@ class Source(models.Model): help_text=_('If "delete old media" is ticked, the number of days after which ' 'to automatically delete media') ) + delete_removed_media = models.BooleanField( + _('delete removed media'), + default=False, + help_text=_('Delete media that is no longer on this playlist') + ) source_resolution = models.CharField( _('source resolution'), max_length=8, diff --git a/tubesync/sync/tasks.py b/tubesync/sync/tasks.py index 720f8ae..2f94621 100644 --- a/tubesync/sync/tasks.py +++ b/tubesync/sync/tasks.py @@ -142,6 +142,15 @@ def cleanup_old_media(): media.delete() +def cleanup_removed_media(source, videos): + media_objects = Media.objects.filter(source=source, downloaded=True) + for item in media_objects: + matching_source_item = [video['id'] for video in videos if video['id'] == item.key] + if not matching_source_item: + log.info(f'{item.title} is no longer in source, removing') + item.delete() + + @background(schedule=0) def index_source_task(source_id): ''' @@ -186,6 +195,9 @@ def index_source_task(source_id): cleanup_completed_tasks() # Tack on a cleanup of old media cleanup_old_media() + if source.delete_removed_media: + log.info(f'Cleaning up media no longer in source {source}') + cleanup_removed_media(source, videos) @background(schedule=0) diff --git a/tubesync/sync/templates/sync/source.html b/tubesync/sync/templates/sync/source.html index 65cf242..22122e2 100644 --- a/tubesync/sync/templates/sync/source.html +++ b/tubesync/sync/templates/sync/source.html @@ -115,6 +115,10 @@ Write JSON? Write JSON?
{% if source.write_json %}{% else %}{% endif %} + + Delete removed media + Delete removed media
{% if source.delete_removed_media %}{% else %}{% endif %} + {% if source.delete_old_media and source.days_to_keep > 0 %} Delete old media diff --git a/tubesync/sync/views.py b/tubesync/sync/views.py index 6fb36d1..e187cd8 100644 --- a/tubesync/sync/views.py +++ b/tubesync/sync/views.py @@ -296,10 +296,11 @@ class EditSourceMixin: model = Source fields = ('source_type', 'key', 'name', 'directory', 'media_format', 'index_schedule', 'download_media', 'download_cap', 'delete_old_media', - 'days_to_keep', 'source_resolution', 'source_vcodec', 'source_acodec', - 'prefer_60fps', 'prefer_hdr', 'fallback', 'copy_thumbnails', 'write_nfo', - 'write_json', 'embed_metadata', 'embed_thumbnail', 'enable_sponsorblock', - 'sponsorblock_categories', 'write_subtitles', 'auto_subtitles', 'sub_langs') + 'delete_removed_media', 'days_to_keep', 'source_resolution', 'source_vcodec', + 'source_acodec', 'prefer_60fps', 'prefer_hdr', 'fallback', 'copy_thumbnails', + 'write_nfo', 'write_json', 'embed_metadata', 'embed_thumbnail', + 'enable_sponsorblock', 'sponsorblock_categories', 'write_subtitles', + 'auto_subtitles', 'sub_langs') errors = { 'invalid_media_format': _('Invalid media format, the media format contains ' 'errors or is empty. Check the table at the end of '