add option at source level to copy over thumbnails with media, resolves #8
This commit is contained in:
parent
ffe0049bab
commit
83b9c167a9
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.1.4 on 2020-12-18 01:34
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sync', '0002_auto_20201213_0817'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='source',
|
||||||
|
name='copy_thumbnails',
|
||||||
|
field=models.BooleanField(default=False, help_text='Copy thumbnails with the media, these may be detected and used by some media servers', verbose_name='copy thumbnails'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -234,6 +234,11 @@ class Source(models.Model):
|
||||||
default=FALLBACK_NEXT_BEST_HD,
|
default=FALLBACK_NEXT_BEST_HD,
|
||||||
help_text=_('What do do when media in your source resolution and codecs is not available')
|
help_text=_('What do do when media in your source resolution and codecs is not available')
|
||||||
)
|
)
|
||||||
|
copy_thumbnails = models.BooleanField(
|
||||||
|
_('copy thumbnails'),
|
||||||
|
default=False,
|
||||||
|
help_text=_('Copy thumbnails with the media, these may be detected and used by some media servers')
|
||||||
|
)
|
||||||
has_failed = models.BooleanField(
|
has_failed = models.BooleanField(
|
||||||
_('has failed'),
|
_('has failed'),
|
||||||
default=False,
|
default=False,
|
||||||
|
|
|
@ -150,8 +150,15 @@ def media_pre_delete(sender, instance, **kwargs):
|
||||||
delete_file(instance.thumb.path)
|
delete_file(instance.thumb.path)
|
||||||
# Delete the media file if it exists
|
# Delete the media file if it exists
|
||||||
if instance.media_file:
|
if instance.media_file:
|
||||||
log.info(f'Deleting media for: {instance} path: {instance.media_file.path}')
|
filepath = instance.media_file.path
|
||||||
|
log.info(f'Deleting media for: {instance} path: {filepath}')
|
||||||
delete_file(instance.media_file.path)
|
delete_file(instance.media_file.path)
|
||||||
|
# Delete thumbnail copy if it exists
|
||||||
|
barefilepath, fileext = os.path.splitext(filepath)
|
||||||
|
thumbpath = f'{barefilepath}.jpg'
|
||||||
|
log.info(f'Copying thumbnail: {instance} path: {thumbpath}')
|
||||||
|
delete_file(thumbpath)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Media)
|
@receiver(post_delete, sender=Media)
|
||||||
def media_post_delete(sender, instance, **kwargs):
|
def media_post_delete(sender, instance, **kwargs):
|
||||||
|
|
|
@ -11,6 +11,7 @@ import uuid
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from shutil import copyfile
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
@ -242,7 +243,7 @@ def download_media_thumbnail(media_id, url):
|
||||||
f'{width}x{height}: {url}')
|
f'{width}x{height}: {url}')
|
||||||
i = resize_image_to_height(i, width, height)
|
i = resize_image_to_height(i, width, height)
|
||||||
image_file = BytesIO()
|
image_file = BytesIO()
|
||||||
i.save(image_file, 'JPEG', quality=80, optimize=True, progressive=True)
|
i.save(image_file, 'JPEG', quality=85, optimize=True, progressive=True)
|
||||||
image_file.seek(0)
|
image_file.seek(0)
|
||||||
media.thumb.save(
|
media.thumb.save(
|
||||||
'thumb',
|
'thumb',
|
||||||
|
@ -272,17 +273,18 @@ def download_media(media_id):
|
||||||
log.warn(f'Download task triggeredd media: {media} (UUID: {media.pk}) but it '
|
log.warn(f'Download task triggeredd media: {media} (UUID: {media.pk}) but it '
|
||||||
f'is now marked to be skipped, not downloading')
|
f'is now marked to be skipped, not downloading')
|
||||||
return
|
return
|
||||||
log.info(f'Downloading media: {media} (UUID: {media.pk}) to: "{media.filepath}"')
|
filepath = media.filepath
|
||||||
|
log.info(f'Downloading media: {media} (UUID: {media.pk}) to: "{filepath}"')
|
||||||
format_str, container = media.download_media()
|
format_str, container = media.download_media()
|
||||||
if os.path.exists(media.filepath):
|
if os.path.exists(filepath):
|
||||||
# Media has been downloaded successfully
|
# Media has been downloaded successfully
|
||||||
log.info(f'Successfully downloaded media: {media} (UUID: {media.pk}) to: '
|
log.info(f'Successfully downloaded media: {media} (UUID: {media.pk}) to: '
|
||||||
f'"{media.filepath}"')
|
f'"{filepath}"')
|
||||||
# Link the media file to the object and update info about the download
|
# Link the media file to the object and update info about the download
|
||||||
media.media_file.name = str(media.filepath)
|
media.media_file.name = str(filepath)
|
||||||
media.downloaded = True
|
media.downloaded = True
|
||||||
media.download_date = timezone.now()
|
media.download_date = timezone.now()
|
||||||
media.downloaded_filesize = os.path.getsize(media.filepath)
|
media.downloaded_filesize = os.path.getsize(filepath)
|
||||||
media.downloaded_container = container
|
media.downloaded_container = container
|
||||||
if '+' in format_str:
|
if '+' in format_str:
|
||||||
# Seperate audio and video streams
|
# Seperate audio and video streams
|
||||||
|
@ -313,6 +315,13 @@ def download_media(media_id):
|
||||||
else:
|
else:
|
||||||
media.downloaded_format = 'audio'
|
media.downloaded_format = 'audio'
|
||||||
media.save()
|
media.save()
|
||||||
|
# If selected, copy the thumbnail over as well
|
||||||
|
if media.source.copy_thumbnails and media.thumb:
|
||||||
|
barefilepath, fileext = os.path.splitext(filepath)
|
||||||
|
thumbpath = f'{barefilepath}.jpg'
|
||||||
|
log.info(f'Copying media thumbnail from: {media.thumb.path} '
|
||||||
|
f'to: {thumbpath}')
|
||||||
|
copyfile(media.thumb.path, thumbpath)
|
||||||
# Schedule a task to update media servers
|
# Schedule a task to update media servers
|
||||||
for mediaserver in MediaServer.objects.all():
|
for mediaserver in MediaServer.objects.all():
|
||||||
log.info(f'Scheduling media server updates')
|
log.info(f'Scheduling media server updates')
|
||||||
|
|
|
@ -254,7 +254,8 @@ class AddSourceView(CreateView):
|
||||||
model = Source
|
model = Source
|
||||||
fields = ('source_type', 'key', 'name', 'directory', 'index_schedule',
|
fields = ('source_type', 'key', 'name', 'directory', 'index_schedule',
|
||||||
'delete_old_media', 'days_to_keep', 'source_resolution', 'source_vcodec',
|
'delete_old_media', 'days_to_keep', 'source_resolution', 'source_vcodec',
|
||||||
'source_acodec', 'prefer_60fps', 'prefer_hdr', 'fallback')
|
'source_acodec', 'prefer_60fps', 'prefer_hdr', 'fallback',
|
||||||
|
'copy_thumbnails')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.prepopulated_data = {}
|
self.prepopulated_data = {}
|
||||||
|
@ -325,7 +326,8 @@ class UpdateSourceView(UpdateView):
|
||||||
model = Source
|
model = Source
|
||||||
fields = ('source_type', 'key', 'name', 'directory', 'index_schedule',
|
fields = ('source_type', 'key', 'name', 'directory', 'index_schedule',
|
||||||
'delete_old_media', 'days_to_keep', 'source_resolution', 'source_vcodec',
|
'delete_old_media', 'days_to_keep', 'source_resolution', 'source_vcodec',
|
||||||
'source_acodec', 'prefer_60fps', 'prefer_hdr', 'fallback')
|
'source_acodec', 'prefer_60fps', 'prefer_hdr', 'fallback',
|
||||||
|
'copy_thumbnails')
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
url = reverse_lazy('sync:source', kwargs={'pk': self.object.pk})
|
url = reverse_lazy('sync:source', kwargs={'pk': self.object.pk})
|
||||||
|
|
Loading…
Reference in New Issue