|
|
@ -13,7 +13,7 @@ from ffx.helper import dictDiff, DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_
|
|
|
|
class ShowDescriptor():
|
|
|
|
class ShowDescriptor():
|
|
|
|
"""This class represents the structural content of a media file including streams and metadata"""
|
|
|
|
"""This class represents the structural content of a media file including streams and metadata"""
|
|
|
|
|
|
|
|
|
|
|
|
CONTEXT_KEY = 'context'
|
|
|
|
# CONTEXT_KEY = 'context'
|
|
|
|
|
|
|
|
|
|
|
|
ID_KEY = 'id'
|
|
|
|
ID_KEY = 'id'
|
|
|
|
NAME_KEY = 'name'
|
|
|
|
NAME_KEY = 'name'
|
|
|
@ -29,306 +29,74 @@ class ShowDescriptor():
|
|
|
|
DEFAULT_INDICATOR_SEASON_DIGITS = 2
|
|
|
|
DEFAULT_INDICATOR_SEASON_DIGITS = 2
|
|
|
|
DEFAULT_INDICATOR_EPISODE_DIGITS = 2
|
|
|
|
DEFAULT_INDICATOR_EPISODE_DIGITS = 2
|
|
|
|
|
|
|
|
|
|
|
|
def getDesciptor(self):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
descriptor = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
descriptor['id'] = int(self.id)
|
|
|
|
|
|
|
|
descriptor['name'] = str(self.name)
|
|
|
|
|
|
|
|
descriptor['year'] = int(self.year)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
descriptor['index_season_digits'] = int(self.index_season_digits)
|
|
|
|
|
|
|
|
descriptor['index_episode_digits'] = int(self.index_episode_digits)
|
|
|
|
|
|
|
|
descriptor['indicator_season_digits'] = int(self.indicator_season_digits)
|
|
|
|
|
|
|
|
descriptor['indicator_episode_digits'] = int(self.indicator_episode_digits)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return descriptor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.ID_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.ID_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.ID_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.ID_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.ID_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.ID_KEY} is required to be of type int")
|
|
|
|
self.__showId = kwargs[ShowDescriptor.ID_KEY]
|
|
|
|
self.__showId = kwargs[ShowDescriptor.ID_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__showId = {}
|
|
|
|
self.__showId = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.NAME_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.NAME_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.NAME_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.NAME_KEY]) is not str:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.NAME_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.NAME_KEY} is required to be of type str")
|
|
|
|
self.__showName = kwargs[ShowDescriptor.NAME_KEY]
|
|
|
|
self.__showName = kwargs[ShowDescriptor.NAME_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__showName = {}
|
|
|
|
self.__showName = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.YEAR_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.YEAR_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.YEAR_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.YEAR_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.YEAR_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.YEAR_KEY} is required to be of type int")
|
|
|
|
self.__showYear = kwargs[ShowDescriptor.YEAR_KEY]
|
|
|
|
self.__showYear = kwargs[ShowDescriptor.YEAR_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__showYear = {}
|
|
|
|
self.__showYear = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.INDEX_SEASON_DIGITS_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.INDEX_SEASON_DIGITS_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.INDEX_SEASON_DIGITS_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.INDEX_SEASON_DIGITS_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDEX_SEASON_DIGITS_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDEX_SEASON_DIGITS_KEY} is required to be of type int")
|
|
|
|
self.__indexSeasonDigits = kwargs[ShowDescriptor.INDEX_SEASON_DIGITS_KEY]
|
|
|
|
self.__indexSeasonDigits = kwargs[ShowDescriptor.INDEX_SEASON_DIGITS_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__indexSeasonDigits = {}
|
|
|
|
self.__indexSeasonDigits = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.INDEX_EPISODE_DIGITS_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.INDEX_EPISODE_DIGITS_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.INDEX_EPISODE_DIGITS_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.INDEX_EPISODE_DIGITS_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDEX_EPISODE_DIGITS_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDEX_EPISODE_DIGITS_KEY} is required to be of type int")
|
|
|
|
self.__indexEpisodeDigits = kwargs[ShowDescriptor.INDEX_EPISODE_DIGITS_KEY]
|
|
|
|
self.__indexEpisodeDigits = kwargs[ShowDescriptor.INDEX_EPISODE_DIGITS_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__indexEpisodeDigits = {}
|
|
|
|
self.__indexEpisodeDigits = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY} is required to be of type int")
|
|
|
|
self.__indicatorSeasonDigits = kwargs[ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY]
|
|
|
|
self.__indicatorSeasonDigits = kwargs[ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__indicatorSeasonDigits = {}
|
|
|
|
self.__indicatorSeasonDigits = {}
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY in kwargs.keys():
|
|
|
|
if ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY in kwargs.keys():
|
|
|
|
if type(kwargs[ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY]) is not dict:
|
|
|
|
if type(kwargs[ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY]) is not int:
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY} is required to be of type dict")
|
|
|
|
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY} is required to be of type int")
|
|
|
|
self.__indicatorEpisodeDigits = kwargs[ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY]
|
|
|
|
self.__indicatorEpisodeDigits = kwargs[ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.__indicatorEpisodeDigits = {}
|
|
|
|
self.__indicatorEpisodeDigits = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getId(self):
|
|
|
|
def getDefaultVideoTrack(self):
|
|
|
|
return self.__showId
|
|
|
|
videoDefaultTracks = [v for v in self.getVideoTracks() if TrackDisposition.DEFAULT in v.getDispositionSet()]
|
|
|
|
def getName(self):
|
|
|
|
if len(videoDefaultTracks) > 1:
|
|
|
|
return self.__showName
|
|
|
|
raise ValueError('ShowDescriptor.getDefaultVideoTrack(): More than one default video track is not supported')
|
|
|
|
def getYear(self):
|
|
|
|
return videoDefaultTracks[0] if videoDefaultTracks else None
|
|
|
|
return self.__showYear
|
|
|
|
|
|
|
|
|
|
|
|
def getForcedVideoTrack(self):
|
|
|
|
def getIndexSeasonDigits(self):
|
|
|
|
videoForcedTracks = [v for v in self.getVideoTracks() if TrackDisposition.FORCED in v.getDispositionSet()]
|
|
|
|
return self.__indexSeasonDigits
|
|
|
|
if len(videoForcedTracks) > 1:
|
|
|
|
def getIndexEpisodeDigits(self):
|
|
|
|
raise ValueError('ShowDescriptor.getForcedVideoTrack(): More than one forced video track is not supported')
|
|
|
|
return self.__indexEpisodeDigits
|
|
|
|
return videoForcedTracks[0] if videoForcedTracks else None
|
|
|
|
def getIndicatorSeasonDigits(self):
|
|
|
|
|
|
|
|
return self.__indicatorSeasonDigits
|
|
|
|
def getDefaultAudioTrack(self):
|
|
|
|
def getIndicatorEpisodeDigits(self):
|
|
|
|
audioDefaultTracks = [a for a in self.getAudioTracks() if TrackDisposition.DEFAULT in a.getDispositionSet()]
|
|
|
|
return self.__indicatorEpisodeDigits
|
|
|
|
if len(audioDefaultTracks) > 1:
|
|
|
|
|
|
|
|
raise ValueError('ShowDescriptor.getDefaultAudioTrack(): More than one default audio track is not supported')
|
|
|
|
def getFilenamePrefix(self):
|
|
|
|
return audioDefaultTracks[0] if audioDefaultTracks else None
|
|
|
|
return f"{self.__showName} ({str(self.__showYear)})"
|
|
|
|
|
|
|
|
|
|
|
|
def getForcedAudioTrack(self):
|
|
|
|
|
|
|
|
audioForcedTracks = [a for a in self.getAudioTracks() if TrackDisposition.FORCED in a.getDispositionSet()]
|
|
|
|
|
|
|
|
if len(audioForcedTracks) > 1:
|
|
|
|
|
|
|
|
raise ValueError('ShowDescriptor.getForcedAudioTrack(): More than one forced audio track is not supported')
|
|
|
|
|
|
|
|
return audioForcedTracks[0] if audioForcedTracks else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getDefaultSubtitleTrack(self):
|
|
|
|
|
|
|
|
subtitleDefaultTracks = [s for s in self.getSubtitleTracks() if TrackDisposition.DEFAULT in s.getDispositionSet()]
|
|
|
|
|
|
|
|
if len(subtitleDefaultTracks) > 1:
|
|
|
|
|
|
|
|
raise ValueError('ShowDescriptor.getDefaultSubtitleTrack(): More than one default subtitle track is not supported')
|
|
|
|
|
|
|
|
return subtitleDefaultTracks[0] if subtitleDefaultTracks else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getForcedSubtitleTrack(self):
|
|
|
|
|
|
|
|
subtitleForcedTracks = [s for s in self.getSubtitleTracks() if TrackDisposition.FORCED in s.getDispositionSet()]
|
|
|
|
|
|
|
|
if len(subtitleForcedTracks) > 1:
|
|
|
|
|
|
|
|
raise ValueError('ShowDescriptor.getForcedSubtitleTrack(): More than one forced subtitle track is not supported')
|
|
|
|
|
|
|
|
return subtitleForcedTracks[0] if subtitleForcedTracks else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setDefaultSubTrack(self, trackType : TrackType, subIndex : int):
|
|
|
|
|
|
|
|
for t in self.getAllTrackDescriptors():
|
|
|
|
|
|
|
|
if t.getType() == trackType:
|
|
|
|
|
|
|
|
t.setDispositionFlag(TrackDisposition.DEFAULT, t.getSubIndex() == int(subIndex))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setForcedSubTrack(self, trackType : TrackType, subIndex : int):
|
|
|
|
|
|
|
|
for t in self.getAllTrackDescriptors():
|
|
|
|
|
|
|
|
if t.getType() == trackType:
|
|
|
|
|
|
|
|
t.setDispositionFlag(TrackDisposition.FORCED, t.getSubIndex() == int(subIndex))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getReorderedTrackDescriptors(self):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
videoTracks = self.sortSubIndices(self.getVideoTracks())
|
|
|
|
|
|
|
|
audioTracks = self.sortSubIndices(self.getAudioTracks())
|
|
|
|
|
|
|
|
subtitleTracks = self.sortSubIndices(self.getSubtitleTracks())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
videoDefaultTrack = self.getDefaultVideoTrack()
|
|
|
|
|
|
|
|
self.getForcedVideoTrack()
|
|
|
|
|
|
|
|
audioDefaultTrack = self.getDefaultAudioTrack()
|
|
|
|
|
|
|
|
self.getForcedAudioTrack()
|
|
|
|
|
|
|
|
subtitleDefaultTrack = self.getDefaultSubtitleTrack()
|
|
|
|
|
|
|
|
self.getForcedSubtitleTrack()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.__jellyfinOrder:
|
|
|
|
|
|
|
|
if not videoDefaultTrack is None:
|
|
|
|
|
|
|
|
videoTracks.append(videoTracks.pop(videoTracks.index(videoDefaultTrack)))
|
|
|
|
|
|
|
|
if not audioDefaultTrack is None:
|
|
|
|
|
|
|
|
audioTracks.append(audioTracks.pop(audioTracks.index(audioDefaultTrack)))
|
|
|
|
|
|
|
|
if not subtitleDefaultTrack is None:
|
|
|
|
|
|
|
|
subtitleTracks.append(subtitleTracks.pop(subtitleTracks.index(subtitleDefaultTrack)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reorderedTrackDescriptors = videoTracks + audioTracks + subtitleTracks
|
|
|
|
|
|
|
|
orderedSourceTrackSequence = [t.getSourceIndex() for t in reorderedTrackDescriptors]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(set(orderedSourceTrackSequence)) < len(orderedSourceTrackSequence):
|
|
|
|
|
|
|
|
raise ValueError(f"Multiple streams originating from the same source stream not supported")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return reorderedTrackDescriptors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
|
|
def fromFfprobe(cls, formatData, streamData):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kwargs = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ShowDescriptor.FFPROBE_TAGS_KEY in formatData.keys():
|
|
|
|
|
|
|
|
kwargs[ShowDescriptor.TAGS_KEY] = formatData[ShowDescriptor.FFPROBE_TAGS_KEY]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kwargs[ShowDescriptor.TRACK_DESCRIPTOR_LIST_KEY] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#TODO: Evtl obsolet
|
|
|
|
|
|
|
|
subIndexCounters = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for streamObj in streamData:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ffprobeCodecType = streamObj[ShowDescriptor.FFPROBE_CODEC_TYPE_KEY]
|
|
|
|
|
|
|
|
trackType = TrackType.fromLabel(ffprobeCodecType)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if trackType != TrackType.UNKNOWN:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if trackType not in subIndexCounters.keys():
|
|
|
|
|
|
|
|
subIndexCounters[trackType] = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kwargs[ShowDescriptor.TRACK_DESCRIPTOR_LIST_KEY].append(TrackDescriptor.fromFfprobe(streamObj,
|
|
|
|
|
|
|
|
subIndex=subIndexCounters[trackType]))
|
|
|
|
|
|
|
|
subIndexCounters[trackType] += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return cls(**kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getTags(self):
|
|
|
|
|
|
|
|
return self.__mediaTags
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sortSubIndices(self, descriptors : List[TrackDescriptor]) -> List[TrackDescriptor]:
|
|
|
|
|
|
|
|
subIndex = 0
|
|
|
|
|
|
|
|
for t in descriptors:
|
|
|
|
|
|
|
|
t.setSubIndex(subIndex)
|
|
|
|
|
|
|
|
subIndex += 1
|
|
|
|
|
|
|
|
return descriptors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getAllTrackDescriptors(self) -> List[TrackDescriptor]:
|
|
|
|
|
|
|
|
return self.getVideoTracks() + self.getAudioTracks() + self.getSubtitleTracks()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getVideoTracks(self) -> List[TrackDescriptor]:
|
|
|
|
|
|
|
|
return [v for v in self.__trackDescriptors.copy() if v.getType() == TrackType.VIDEO]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getAudioTracks(self) -> List[TrackDescriptor]:
|
|
|
|
|
|
|
|
return [a for a in self.__trackDescriptors.copy() if a.getType() == TrackType.AUDIO]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getSubtitleTracks(self) -> List[TrackDescriptor]:
|
|
|
|
|
|
|
|
return [s for s in self.__trackDescriptors.copy() if s.getType() == TrackType.SUBTITLE]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getJellyfin(self):
|
|
|
|
|
|
|
|
return self.__jellyfinOrder
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setJellyfinOrder(self, state):
|
|
|
|
|
|
|
|
self.__jellyfinOrder = state
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getClearTags(self):
|
|
|
|
|
|
|
|
return self.__clearTags
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compare(self, vsShowDescriptor : Self):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not isinstance(vsShowDescriptor, self.__class__):
|
|
|
|
|
|
|
|
raise click.ClickException(f"ShowDescriptor.compare(): Argument is required to be of type {self.__class__}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vsTags = vsShowDescriptor.getTags()
|
|
|
|
|
|
|
|
tags = self.getTags()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#HINT: Some tags differ per file, for example creation_time, so these are removed before diff
|
|
|
|
|
|
|
|
for emt in ShowDescriptor.EXCLUDED_MEDIA_TAGS:
|
|
|
|
|
|
|
|
if emt in tags.keys():
|
|
|
|
|
|
|
|
del tags[emt]
|
|
|
|
|
|
|
|
if emt in vsTags.keys():
|
|
|
|
|
|
|
|
del vsTags[emt]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tagsDiff = dictDiff(vsTags, tags)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compareResult = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if tagsDiff:
|
|
|
|
|
|
|
|
compareResult[ShowDescriptor.TAGS_KEY] = tagsDiff
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Target track configuration (from DB)
|
|
|
|
|
|
|
|
#tracks = self.getAllTrackDescriptors()
|
|
|
|
|
|
|
|
tracks = self.getReorderedTrackDescriptors()
|
|
|
|
|
|
|
|
numTracks = len(tracks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Current track configuration (of file)
|
|
|
|
|
|
|
|
vsTracks = vsShowDescriptor.getAllTrackDescriptors()
|
|
|
|
|
|
|
|
numVsTracks = len(vsTracks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maxNumOfTracks = max(numVsTracks, numTracks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trackCompareResult = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for tp in range(maxNumOfTracks):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# inspect/update funktionier nur so
|
|
|
|
|
|
|
|
if self.__jellyfinOrder:
|
|
|
|
|
|
|
|
vsTrackIndex = tracks[tp].getSourceIndex()
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
vsTrackIndex = tp
|
|
|
|
|
|
|
|
# vsTrackIndex = tracks[tp].getSourceIndex()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Will trigger if tracks are missing in file
|
|
|
|
|
|
|
|
if tp > (numVsTracks - 1):
|
|
|
|
|
|
|
|
if DIFF_ADDED_KEY not in trackCompareResult.keys():
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_ADDED_KEY] = set()
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_ADDED_KEY].add(tracks[tp].getIndex())
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Will trigger if tracks are missing in DB definition
|
|
|
|
|
|
|
|
# New tracks will be added per update via this way
|
|
|
|
|
|
|
|
if tp > (numTracks - 1):
|
|
|
|
|
|
|
|
if DIFF_REMOVED_KEY not in trackCompareResult.keys():
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_REMOVED_KEY] = {}
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_REMOVED_KEY][vsTracks[vsTrackIndex].getIndex()] = vsTracks[vsTrackIndex]
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# assumption is made here that the track order will not change for all files of a sequence
|
|
|
|
|
|
|
|
trackDiff = tracks[tp].compare(vsTracks[vsTrackIndex])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if trackDiff:
|
|
|
|
|
|
|
|
if DIFF_CHANGED_KEY not in trackCompareResult.keys():
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_CHANGED_KEY] = {}
|
|
|
|
|
|
|
|
trackCompareResult[DIFF_CHANGED_KEY][vsTracks[vsTrackIndex].getIndex()] = trackDiff
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if trackCompareResult:
|
|
|
|
|
|
|
|
compareResult[ShowDescriptor.TRACKS_KEY] = trackCompareResult
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return compareResult
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getInputMappingTokens(self, use_sub_index : bool = True):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reorderedTrackDescriptors = self.getReorderedTrackDescriptors()
|
|
|
|
|
|
|
|
inputMappingTokens = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for rtd in reorderedTrackDescriptors:
|
|
|
|
|
|
|
|
trackType = rtd.getType()
|
|
|
|
|
|
|
|
if use_sub_index:
|
|
|
|
|
|
|
|
inputMappingTokens += ['-map', f"0:{trackType.indicator()}:{rtd.getSubIndex()}"]
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
inputMappingTokens += ['-map', f"0:{rtd.getIndex()}"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inputMappingTokens
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|