commit
f9dfffe91a
|
@ -0,0 +1,21 @@
|
||||||
|
# Generated by Django 3.2.15 on 2022-12-28 20:33
|
||||||
|
|
||||||
|
import django.core.files.storage
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import sync.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sync', '0013_fix_elative_media_file'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='media',
|
||||||
|
name='media_file',
|
||||||
|
field=models.FileField(blank=True, help_text='Media file', max_length=255, null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/media-data/', location=str(settings.DOWNLOAD_ROOT)), upload_to=sync.models.get_media_file_path, verbose_name='media file'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -477,7 +477,11 @@ class Source(models.Model):
|
||||||
response = indexer(self.index_url)
|
response = indexer(self.index_url)
|
||||||
if not isinstance(response, dict):
|
if not isinstance(response, dict):
|
||||||
return []
|
return []
|
||||||
return response.get('entries', [])
|
entries = response.get('entries', [])
|
||||||
|
|
||||||
|
if settings.MAX_ENTRIES_PROCESSING:
|
||||||
|
entries = entries[:settings.MAX_ENTRIES_PROCESSING]
|
||||||
|
return entries
|
||||||
|
|
||||||
|
|
||||||
def get_media_thumb_path(instance, filename):
|
def get_media_thumb_path(instance, filename):
|
||||||
|
@ -866,7 +870,7 @@ class Media(models.Model):
|
||||||
# Otherwise, calculate from matched format codes
|
# Otherwise, calculate from matched format codes
|
||||||
vformat = None
|
vformat = None
|
||||||
aformat = None
|
aformat = None
|
||||||
if '+' in format_str:
|
if format_str and '+' in format_str:
|
||||||
# Seperate audio and video streams
|
# Seperate audio and video streams
|
||||||
vformat_code, aformat_code = format_str.split('+')
|
vformat_code, aformat_code = format_str.split('+')
|
||||||
vformat = self.get_format_by_code(vformat_code)
|
vformat = self.get_format_by_code(vformat_code)
|
||||||
|
@ -875,7 +879,7 @@ class Media(models.Model):
|
||||||
# Combined stream or audio only
|
# Combined stream or audio only
|
||||||
cformat = self.get_format_by_code(format_str)
|
cformat = self.get_format_by_code(format_str)
|
||||||
aformat = cformat
|
aformat = cformat
|
||||||
if cformat['vcodec']:
|
if cformat and cformat['vcodec']:
|
||||||
# Combined
|
# Combined
|
||||||
vformat = cformat
|
vformat = cformat
|
||||||
if vformat:
|
if vformat:
|
||||||
|
@ -1266,7 +1270,7 @@ class Media(models.Model):
|
||||||
'''
|
'''
|
||||||
indexer = self.INDEXERS.get(self.source.source_type, None)
|
indexer = self.INDEXERS.get(self.source.source_type, None)
|
||||||
if not callable(indexer):
|
if not callable(indexer):
|
||||||
raise Exception(f'Meida with source type f"{self.source.source_type}" '
|
raise Exception(f'Media with source type f"{self.source.source_type}" '
|
||||||
f'has no indexer')
|
f'has no indexer')
|
||||||
return indexer(self.url)
|
return indexer(self.url)
|
||||||
|
|
||||||
|
|
|
@ -269,13 +269,7 @@ class ValidateSourceView(FormView):
|
||||||
return append_uri_params(url, fields)
|
return append_uri_params(url, fields)
|
||||||
|
|
||||||
|
|
||||||
class AddSourceView(CreateView):
|
class EditSourceMixin:
|
||||||
'''
|
|
||||||
Adds a new source, optionally takes some initial data querystring values to
|
|
||||||
prepopulate some of the more unclear values.
|
|
||||||
'''
|
|
||||||
|
|
||||||
template_name = 'sync/source-add.html'
|
|
||||||
model = Source
|
model = Source
|
||||||
fields = ('source_type', 'key', 'name', 'directory', 'media_format',
|
fields = ('source_type', 'key', 'name', 'directory', 'media_format',
|
||||||
'index_schedule', 'download_media', 'download_cap', 'delete_old_media',
|
'index_schedule', 'download_media', 'download_cap', 'delete_old_media',
|
||||||
|
@ -287,6 +281,29 @@ class AddSourceView(CreateView):
|
||||||
'this page for valid media name variables'),
|
'this page for valid media name variables'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
# Perform extra validation to make sure the media_format is valid
|
||||||
|
obj = form.save(commit=False)
|
||||||
|
source_type = form.cleaned_data['media_format']
|
||||||
|
example_media_file = obj.get_example_media_format()
|
||||||
|
if example_media_file == '':
|
||||||
|
form.add_error(
|
||||||
|
'media_format',
|
||||||
|
ValidationError(self.errors['invalid_media_format'])
|
||||||
|
)
|
||||||
|
if form.errors:
|
||||||
|
return super().form_invalid(form)
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class AddSourceView(EditSourceMixin, CreateView):
|
||||||
|
'''
|
||||||
|
Adds a new source, optionally takes some initial data querystring values to
|
||||||
|
prepopulate some of the more unclear values.
|
||||||
|
'''
|
||||||
|
|
||||||
|
template_name = 'sync/source-add.html'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.prepopulated_data = {}
|
self.prepopulated_data = {}
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -312,20 +329,6 @@ class AddSourceView(CreateView):
|
||||||
initial[k] = v
|
initial[k] = v
|
||||||
return initial
|
return initial
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
# Perform extra validation to make sure the media_format is valid
|
|
||||||
obj = form.save(commit=False)
|
|
||||||
source_type = form.cleaned_data['media_format']
|
|
||||||
example_media_file = obj.get_example_media_format()
|
|
||||||
if example_media_file == '':
|
|
||||||
form.add_error(
|
|
||||||
'media_format',
|
|
||||||
ValidationError(self.errors['invalid_media_format'])
|
|
||||||
)
|
|
||||||
if form.errors:
|
|
||||||
return super().form_invalid(form)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
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})
|
||||||
return append_uri_params(url, {'message': 'source-created'})
|
return append_uri_params(url, {'message': 'source-created'})
|
||||||
|
@ -364,33 +367,9 @@ class SourceView(DetailView):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
class UpdateSourceView(UpdateView):
|
class UpdateSourceView(EditSourceMixin, UpdateView):
|
||||||
|
|
||||||
template_name = 'sync/source-update.html'
|
template_name = 'sync/source-update.html'
|
||||||
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')
|
|
||||||
errors = {
|
|
||||||
'invalid_media_format': _('Invalid media format, the media format contains '
|
|
||||||
'errors or is empty. Check the table at the end of '
|
|
||||||
'this page for valid media name variables'),
|
|
||||||
}
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
# Perform extra validation to make sure the media_format is valid
|
|
||||||
obj = form.save(commit=False)
|
|
||||||
source_type = form.cleaned_data['media_format']
|
|
||||||
example_media_file = obj.get_example_media_format()
|
|
||||||
if example_media_file == '':
|
|
||||||
form.add_error(
|
|
||||||
'media_format',
|
|
||||||
ValidationError(self.errors['invalid_media_format'])
|
|
||||||
)
|
|
||||||
if form.errors:
|
|
||||||
return super().form_invalid(form)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
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})
|
||||||
|
@ -416,7 +395,7 @@ class DeleteSourceView(DeleteView, FormMixin):
|
||||||
for media in Media.objects.filter(source=source):
|
for media in Media.objects.filter(source=source):
|
||||||
if media.media_file:
|
if media.media_file:
|
||||||
# Delete the media file
|
# Delete the media file
|
||||||
delete_file(media.media_file.name)
|
delete_file(media.media_file.path)
|
||||||
# Delete thumbnail copy if it exists
|
# Delete thumbnail copy if it exists
|
||||||
delete_file(media.thumbpath)
|
delete_file(media.thumbpath)
|
||||||
# Delete NFO file if it exists
|
# Delete NFO file if it exists
|
||||||
|
|
|
@ -138,7 +138,7 @@ BACKGROUND_TASK_ASYNC_THREADS = 1 # Number of async tasks to run at on
|
||||||
MAX_BACKGROUND_TASK_ASYNC_THREADS = 8 # For sanity reasons
|
MAX_BACKGROUND_TASK_ASYNC_THREADS = 8 # For sanity reasons
|
||||||
BACKGROUND_TASK_PRIORITY_ORDERING = 'ASC' # Use 'niceness' task priority ordering
|
BACKGROUND_TASK_PRIORITY_ORDERING = 'ASC' # Use 'niceness' task priority ordering
|
||||||
COMPLETED_TASKS_DAYS_TO_KEEP = 7 # Number of days to keep completed tasks
|
COMPLETED_TASKS_DAYS_TO_KEEP = 7 # Number of days to keep completed tasks
|
||||||
|
MAX_ENTRIES_PROCESSING = 0 # Number of videos to process on source refresh (0 for no limit)
|
||||||
|
|
||||||
SOURCES_PER_PAGE = 100
|
SOURCES_PER_PAGE = 100
|
||||||
MEDIA_PER_PAGE = 144
|
MEDIA_PER_PAGE = 144
|
||||||
|
|
Loading…
Reference in New Issue