Merge pull request #450 from InterN0te/main-delete-files-on-disk
Following Delete files on disk #426
This commit is contained in:
commit
e7788eb8fb
|
@ -0,0 +1,17 @@
|
|||
# Generated by pac
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sync', '0020_auto_20231024_1825'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='source',
|
||||
name='delete_files_on_disk',
|
||||
field=models.BooleanField(default=False, help_text='Delete files on disk when they are removed from TubeSync', verbose_name='delete files on disk'),
|
||||
),
|
||||
]
|
|
@ -296,6 +296,11 @@ class Source(models.Model):
|
|||
default=False,
|
||||
help_text=_('Delete media that is no longer on this playlist')
|
||||
)
|
||||
delete_files_on_disk = models.BooleanField(
|
||||
_('delete files on disk'),
|
||||
default=False,
|
||||
help_text=_('Delete files on disk when they are removed from TubeSync')
|
||||
)
|
||||
source_resolution = models.CharField(
|
||||
_('source resolution'),
|
||||
max_length=8,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import glob
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete
|
||||
from django.dispatch import receiver
|
||||
|
@ -74,6 +75,7 @@ def source_pre_delete(sender, instance, **kwargs):
|
|||
media.delete()
|
||||
|
||||
|
||||
|
||||
@receiver(post_delete, sender=Source)
|
||||
def source_post_delete(sender, instance, **kwargs):
|
||||
# Triggered after a source is deleted
|
||||
|
@ -222,6 +224,16 @@ def media_pre_delete(sender, instance, **kwargs):
|
|||
if thumbnail_url:
|
||||
delete_task_by_media('sync.tasks.download_media_thumbnail',
|
||||
(str(instance.pk), thumbnail_url))
|
||||
if instance.source.delete_files_on_disk and (instance.media_file or instance.thumb):
|
||||
# Delete all media files if it contains filename
|
||||
filepath = instance.media_file.path if instance.media_file else instance.thumb.path
|
||||
barefilepath, fileext = os.path.splitext(filepath)
|
||||
# Get all files that start with the bare file path
|
||||
all_related_files = glob.glob(f'{barefilepath}.*')
|
||||
for file in all_related_files:
|
||||
log.info(f'Deleting file for: {instance} path: {file}')
|
||||
delete_file(file)
|
||||
|
||||
|
||||
|
||||
@receiver(post_delete, sender=Media)
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<p>
|
||||
Are you sure you want to delete this source? Deleting a source is permanent.
|
||||
By default, deleting a source does not delete any saved media files. You can
|
||||
tick the "also delete downloaded media" checkbox to also remove save
|
||||
media when you delete the source. Deleting a source cannot be undone.
|
||||
<strong>tick the "also delete downloaded media" checkbox to also remove directory {{ source.directory_path }}
|
||||
</strong>when you delete the source. Deleting a source cannot be undone.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -122,6 +122,10 @@
|
|||
<tr title="Delete media that is no longer on this playlist?">
|
||||
<td class="hide-on-small-only">Delete removed media</td>
|
||||
<td><span class="hide-on-med-and-up">Delete removed media<br></span><strong>{% if source.delete_removed_media %}<i class="fas fa-check"></i>{% else %}<i class="fas fa-times"></i>{% endif %}</strong></td>
|
||||
</tr>
|
||||
<tr title="Delete files on disk when they are removed from TubeSync?">
|
||||
<td class="hide-on-small-only">Delete files on disk</td>
|
||||
<td><span class="hide-on-med-and-up">Delete files on disk<br></span><strong>{% if source.delete_files_on_disk %}<i class="fas fa-check"></i>{% else %}<i class="fas fa-times"></i>{% endif %}</strong></td>
|
||||
</tr>
|
||||
{% if source.delete_old_media and source.days_to_keep > 0 %}
|
||||
<tr title="Days after which your media from this source will be locally deleted">
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import glob
|
||||
import os
|
||||
import json
|
||||
from base64 import b64decode
|
||||
import pathlib
|
||||
import shutil
|
||||
import sys
|
||||
from django.conf import settings
|
||||
from django.http import FileResponse, Http404, HttpResponseNotFound, HttpResponseRedirect
|
||||
|
@ -296,9 +298,9 @@ class EditSourceMixin:
|
|||
model = Source
|
||||
fields = ('source_type', 'key', 'name', 'directory', 'filter_text', 'media_format',
|
||||
'index_schedule', 'download_media', 'download_cap', 'delete_old_media',
|
||||
'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',
|
||||
'delete_removed_media', 'delete_files_on_disk', '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 = {
|
||||
|
@ -435,14 +437,13 @@ class DeleteSourceView(DeleteView, FormMixin):
|
|||
source = self.get_object()
|
||||
for media in Media.objects.filter(source=source):
|
||||
if media.media_file:
|
||||
# Delete the media file
|
||||
delete_file(media.media_file.path)
|
||||
# Delete thumbnail copy if it exists
|
||||
delete_file(media.thumbpath)
|
||||
# Delete NFO file if it exists
|
||||
delete_file(media.nfopath)
|
||||
# Delete JSON file if it exists
|
||||
delete_file(media.jsonpath)
|
||||
file_path = media.media_file.path
|
||||
matching_files = glob.glob(os.path.splitext(file_path)[0] + '.*')
|
||||
for file in matching_files:
|
||||
delete_file(file)
|
||||
directory_path = source.directory_path
|
||||
if os.path.exists(directory_path):
|
||||
shutil.rmtree(directory_path, True)
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
||||
def get_success_url(self):
|
||||
|
@ -653,12 +654,13 @@ class MediaSkipView(FormView, SingleObjectMixin):
|
|||
delete_task_by_media('sync.tasks.download_media', (str(self.object.pk),))
|
||||
# If the media file exists on disk, delete it
|
||||
if self.object.media_file_exists:
|
||||
delete_file(self.object.media_file.path)
|
||||
self.object.media_file = None
|
||||
# If the media has an associated thumbnail copied, also delete it
|
||||
delete_file(self.object.thumbpath)
|
||||
# If the media has an associated NFO file with it, also delete it
|
||||
delete_file(self.object.nfopath)
|
||||
# Delete all files which contains filename
|
||||
filepath = self.object.media_file.path
|
||||
barefilepath, fileext = os.path.splitext(filepath)
|
||||
# Get all files that start with the bare file path
|
||||
all_related_files = glob.glob(f'{barefilepath}.*')
|
||||
for file in all_related_files:
|
||||
delete_file(file)
|
||||
# Reset all download data
|
||||
self.object.metadata = None
|
||||
self.object.downloaded = False
|
||||
|
|
Loading…
Reference in New Issue