#389 Templating für Ausgabe-Dateinamen
This commit is contained in:
@@ -8,6 +8,8 @@ class ConfigurationController():
|
||||
|
||||
DATABASE_PATH_CONFIG_KEY = 'databasePath'
|
||||
LOG_DIRECTORY_CONFIG_KEY = 'logDirectory'
|
||||
OUTPUT_FILENAME_TEMPLATE_KEY = 'outputFilenameTemplate'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
|
||||
|
||||
@@ -11,3 +11,5 @@ DEFAULT_7_1_BANDWIDTH = "384"
|
||||
|
||||
DEFAULT_CROP_START = 60
|
||||
DEFAULT_CROP_LENGTH = 180
|
||||
|
||||
DEFAULT_OUTPUT_FILENAME_TEMPLATE = '{{ ffx_show_name }} - {{ ffx_index }}{{ ffx_index_separator }}{{ ffx_episode_name }}{{ ffx_indicator_separator }}{{ ffx_indicator }}'
|
||||
|
||||
@@ -23,6 +23,7 @@ from ffx.track_codec import TrackCodec
|
||||
|
||||
from ffx.process import executeProcess
|
||||
from ffx.helper import filterFilename
|
||||
from ffx.helper import getEpisodeFileBasename
|
||||
|
||||
from ffx.constants import DEFAULT_STEREO_BANDWIDTH, DEFAULT_AC3_BANDWIDTH, DEFAULT_DTS_BANDWIDTH, DEFAULT_7_1_BANDWIDTH
|
||||
|
||||
@@ -649,14 +650,15 @@ def convert(ctx,
|
||||
|
||||
if tmdbEpisodeResult:
|
||||
filteredEpisodeName = filterFilename(tmdbEpisodeResult['name'])
|
||||
sourceFileBasename = TmdbController.getEpisodeFileBasename(showFilenamePrefix,
|
||||
sourceFileBasename = getEpisodeFileBasename(showFilenamePrefix,
|
||||
filteredEpisodeName,
|
||||
shiftedShowSeason,
|
||||
shiftedShowEpisode,
|
||||
indexSeasonDigits,
|
||||
indexEpisodeDigits,
|
||||
indicatorSeasonDigits,
|
||||
indicatorEpisodeDigits)
|
||||
indicatorEpisodeDigits,
|
||||
context=ctx.obj)
|
||||
|
||||
if label:
|
||||
if shiftedShowSeason > -1 and shiftedShowEpisode > -1:
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import logging
|
||||
|
||||
from jinja2 import Environment, Undefined
|
||||
from .constants import DEFAULT_OUTPUT_FILENAME_TEMPLATE
|
||||
from .configuration_controller import ConfigurationController
|
||||
|
||||
|
||||
class EmptyStringUndefined(Undefined):
|
||||
def __str__(self):
|
||||
return ''
|
||||
|
||||
|
||||
DIFF_ADDED_KEY = 'added'
|
||||
DIFF_REMOVED_KEY = 'removed'
|
||||
DIFF_CHANGED_KEY = 'changed'
|
||||
DIFF_UNCHANGED_KEY = 'unchanged'
|
||||
|
||||
|
||||
def dictDiff(a : dict, b : dict):
|
||||
|
||||
a_keys = set(a.keys())
|
||||
@@ -75,3 +88,79 @@ def filterFilename(fileName: str) -> str:
|
||||
fileName = str(fileName).replace("?", '#')
|
||||
|
||||
return fileName.strip()
|
||||
|
||||
|
||||
def getEpisodeFileBasename(showName,
|
||||
episodeName,
|
||||
season,
|
||||
episode,
|
||||
indexSeasonDigits = 2,
|
||||
indexEpisodeDigits = 2,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 2,
|
||||
context = None):
|
||||
"""
|
||||
One Piece:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 4,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 4
|
||||
|
||||
Three-Body:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 2,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 2
|
||||
|
||||
Dragonball:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 3,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 3
|
||||
|
||||
Boruto:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 4,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 4
|
||||
"""
|
||||
|
||||
cc: ConfigurationController = context['config'] if context is not None and 'config' in context.keys() else None
|
||||
configData = cc.getData() if cc is not None else {}
|
||||
outputFilenameTemplate = configData.get(ConfigurationController.OUTPUT_FILENAME_TEMPLATE_KEY,
|
||||
DEFAULT_OUTPUT_FILENAME_TEMPLATE)
|
||||
|
||||
if context is not None and 'logger' in context.keys():
|
||||
logger = context['logger']
|
||||
else:
|
||||
logger = logging.getLogger('FFX')
|
||||
logger.addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
indexSeparator = ' ' if indexSeasonDigits or indexEpisodeDigits else ''
|
||||
seasonIndex = '{num:{fill}{width}}'.format(num=season, fill='0', width=indexSeasonDigits) if indexSeasonDigits else ''
|
||||
episodeIndex = '{num:{fill}{width}}'.format(num=episode, fill='0', width=indexEpisodeDigits) if indexEpisodeDigits else ''
|
||||
|
||||
indicatorSeparator = ' - ' if indicatorSeasonDigits or indicatorEpisodeDigits else ''
|
||||
seasonIndicator = 'S{num:{fill}{width}}'.format(num=season, fill='0', width=indicatorSeasonDigits) if indicatorSeasonDigits else ''
|
||||
episodeIndicator = 'E{num:{fill}{width}}'.format(num=episode, fill='0', width=indicatorEpisodeDigits) if indicatorEpisodeDigits else ''
|
||||
|
||||
jinjaKwargs = {
|
||||
'ffx_show_name': showName,
|
||||
'ffx_index_separator': indexSeparator,
|
||||
'ffx_season_index': str(seasonIndex),
|
||||
'ffx_episode_index': str(episodeIndex),
|
||||
'ffx_index': str(seasonIndex) + str(episodeIndex),
|
||||
'ffx_episode_name': episodeName,
|
||||
'ffx_indicator_separator': indicatorSeparator,
|
||||
'ffx_season_indicator': str(seasonIndicator),
|
||||
'ffx_episode_indicator': str(episodeIndicator),
|
||||
'ffx_indicator': str(seasonIndicator) + str(episodeIndicator)
|
||||
}
|
||||
|
||||
jinjaEnv = Environment(undefined=EmptyStringUndefined)
|
||||
jinjaTemplate = jinjaEnv.from_string(outputFilenameTemplate)
|
||||
return jinjaTemplate.render(**jinjaKwargs)
|
||||
|
||||
# return ''.join(filenameTokens)
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ class MediaDescriptor:
|
||||
self.__logger = self.__context['logger']
|
||||
else:
|
||||
self.__context = {}
|
||||
self.__logger = logging.getLogger('FFX').addHandler(logging.NullHandler())
|
||||
self.__logger = logging.getLogger('FFX')
|
||||
self.__logger.addHandler(logging.NullHandler())
|
||||
|
||||
if MediaDescriptor.TAGS_KEY in kwargs.keys():
|
||||
if type(kwargs[MediaDescriptor.TAGS_KEY]) is not dict:
|
||||
@@ -402,7 +403,8 @@ class MediaDescriptor:
|
||||
|
||||
if importedFilePath:
|
||||
|
||||
self.__logger.info(f"Substituting subtitle stream {td.getSubIndex()} "
|
||||
self.__logger.info(f"Substituting subtitle stream #{td.getIndex()} "
|
||||
+ f"({td.getType().label()}:{td.getSubIndex()})"
|
||||
+ f"with import from file {td.getExternalSourceFilePath()}")
|
||||
|
||||
importFileTokens += [
|
||||
|
||||
@@ -32,7 +32,8 @@ class ShowDescriptor():
|
||||
self.__logger = self.__context['logger']
|
||||
else:
|
||||
self.__context = {}
|
||||
self.__logger = logging.getLogger('FFX').addHandler(logging.NullHandler())
|
||||
self.__logger = logging.getLogger('FFX')
|
||||
self.__logger.addHandler(logging.NullHandler())
|
||||
|
||||
if ShowDescriptor.ID_KEY in kwargs.keys():
|
||||
if type(kwargs[ShowDescriptor.ID_KEY]) is not int:
|
||||
|
||||
@@ -5,7 +5,9 @@ from .scenario import Scenario
|
||||
from ffx.test.helper import createMediaTestFile
|
||||
from ffx.process import executeProcess
|
||||
from ffx.database import databaseContext
|
||||
|
||||
from ffx.test.helper import createEmptyDirectory
|
||||
from ffx.helper import getEpisodeFileBasename
|
||||
|
||||
from ffx.file_properties import FileProperties
|
||||
|
||||
@@ -205,9 +207,10 @@ class Scenario4(Scenario):
|
||||
tmdbEpisodeResult = self.__tc.queryEpisode(Scenario4.TEST_SHOW_IDENTIFIER,
|
||||
tfo['season'], tfo['episode'])
|
||||
|
||||
expectedFileBasename = TmdbController.getEpisodeFileBasename(self.__testShowDescriptor.getFilenamePrefix(),
|
||||
expectedFileBasename = getEpisodeFileBasename(self.__testShowDescriptor.getFilenamePrefix(),
|
||||
tmdbEpisodeResult['name'],
|
||||
tfo['season'], tfo['episode'])
|
||||
tfo['season'], tfo['episode'],
|
||||
context=testContext)
|
||||
|
||||
expectedFilename = f"{expectedFileBasename}.{Scenario4.EXPECTED_FILE_EXTENSION}"
|
||||
expectedFilePath = os.path.join(self._testDirectory, expectedFilename)
|
||||
|
||||
@@ -25,8 +25,12 @@ class TmdbController():
|
||||
|
||||
def __init__(self, context = None):
|
||||
self.__context = context
|
||||
self.__logger = (context['logger'] if context is not None and 'logger' in context.keys()
|
||||
else logging.getLogger('FFX').addHandler(logging.NullHandler()))
|
||||
|
||||
if context is None:
|
||||
self.__logger = logging.getLogger('FFX')
|
||||
self.__logger.addHandler(logging.NullHandler())
|
||||
else:
|
||||
self.__logger = context['logger']
|
||||
|
||||
self.__tmdbApiKey = os.environ.get('TMDB_API_KEY', None)
|
||||
if self.__tmdbApiKey is None:
|
||||
@@ -128,61 +132,3 @@ class TmdbController():
|
||||
tmdbUrl = f"https://api.themoviedb.org/3/tv/{showId}/season/{season}/episode/{episode}{urlParams}"
|
||||
|
||||
return self.getTmdbRequest(tmdbUrl)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def getEpisodeFileBasename(showName,
|
||||
episodeName,
|
||||
season,
|
||||
episode,
|
||||
indexSeasonDigits = 2,
|
||||
indexEpisodeDigits = 2,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 2):
|
||||
"""
|
||||
One Piece:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 4,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 4
|
||||
|
||||
Three-Body:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 2,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 2
|
||||
|
||||
Dragonball:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 3,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 3
|
||||
|
||||
Boruto:
|
||||
indexSeasonDigits = 0,
|
||||
indexEpisodeDigits = 4,
|
||||
indicatorSeasonDigits = 2,
|
||||
indicatorEpisodeDigits = 4
|
||||
"""
|
||||
filenameTokens = [str(showName), ' - ']
|
||||
|
||||
if indexSeasonDigits:
|
||||
filenameTokens += ['{num:{fill}{width}}'.format(num=season, fill='0', width=indexSeasonDigits)]
|
||||
if indexEpisodeDigits:
|
||||
filenameTokens += ['{num:{fill}{width}}'.format(num=episode, fill='0', width=indexEpisodeDigits)]
|
||||
if indexSeasonDigits or indexEpisodeDigits:
|
||||
filenameTokens += [' ']
|
||||
|
||||
filenameTokens += [episodeName]
|
||||
|
||||
if indicatorSeasonDigits or indicatorEpisodeDigits:
|
||||
filenameTokens += [' - ']
|
||||
if indicatorSeasonDigits:
|
||||
filenameTokens += ['S{num:{fill}{width}}'.format(num=season, fill='0', width=indicatorSeasonDigits)]
|
||||
if indicatorEpisodeDigits:
|
||||
filenameTokens += ['E{num:{fill}{width}}'.format(num=episode, fill='0', width=indicatorEpisodeDigits)]
|
||||
|
||||
return ''.join(filenameTokens)
|
||||
|
||||
def importShow(self, showId: int):
|
||||
pass
|
||||
@@ -47,7 +47,8 @@ class TrackDescriptor:
|
||||
self.__logger = self.__context['logger']
|
||||
else:
|
||||
self.__context = {}
|
||||
self.__logger = logging.getLogger('FFX').addHandler(logging.NullHandler())
|
||||
self.__logger = logging.getLogger('FFX')
|
||||
self.__logger.addHandler(logging.NullHandler())
|
||||
|
||||
if TrackDescriptor.ID_KEY in kwargs.keys():
|
||||
if type(kwargs[TrackDescriptor.ID_KEY]) is not int:
|
||||
|
||||
Reference in New Issue
Block a user