Rework Descriptor Diff

dev
Maveno 11 months ago
parent 86cc7dfc6f
commit 2d8622506e

@ -1,13 +1,12 @@
import os, click import os, click
from ffx.media_descriptor_change_set import MediaDescriptorChangeSet
from ffx.media_descriptor import MediaDescriptor from ffx.media_descriptor import MediaDescriptor
from ffx.track_descriptor import TrackDescriptor
from ffx.audio_layout import AudioLayout from ffx.audio_layout import AudioLayout
from ffx.track_type import TrackType from ffx.track_type import TrackType
from ffx.video_encoder import VideoEncoder from ffx.video_encoder import VideoEncoder
from ffx.process import executeProcess from ffx.process import executeProcess
from ffx.track_disposition import TrackDisposition
from ffx.track_codec import TrackCodec
from ffx.constants import DEFAULT_CROP_START, DEFAULT_CROP_LENGTH from ffx.constants import DEFAULT_CROP_START, DEFAULT_CROP_LENGTH
@ -31,8 +30,7 @@ class FfxController():
CHANNEL_MAP_5_1 = 'FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1' CHANNEL_MAP_5_1 = 'FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1'
#! # SIGNATURE_TAGS = {'RECODED_WITH': 'FFX'}
SIGNATURE_TAGS = {'RECODED_WITH': 'FFX'}
def __init__(self, def __init__(self,
context : dict, context : dict,
@ -40,10 +38,11 @@ class FfxController():
sourceMediaDescriptor : MediaDescriptor = None): sourceMediaDescriptor : MediaDescriptor = None):
self.__context = context self.__context = context
self.__sourceMediaDescriptor = sourceMediaDescriptor
self.__targetMediaDescriptor = targetMediaDescriptor
self.__configurationData = self.__context['config'].getData() self.__targetMediaDescriptor = targetMediaDescriptor
self.__mdcs = MediaDescriptorChangeSet(context,
targetMediaDescriptor,
sourceMediaDescriptor)
self.__logger = context['logger'] self.__logger = context['logger']
@ -147,92 +146,92 @@ class FfxController():
trackSubIndex += 1 trackSubIndex += 1
return audioTokens return audioTokens
#
# -disposition:s:0 default -disposition:s:1 0 # # -disposition:s:0 default -disposition:s:1 0
def generateDispositionTokens(self): # def generateDispositionTokens(self):
#
targetTrackDescriptors = self.__targetMediaDescriptor.getAllTrackDescriptors() # targetTrackDescriptors = self.__targetMediaDescriptor.getAllTrackDescriptors()
#
sourceTrackDescriptors = ([] if self.__sourceMediaDescriptor is None # sourceTrackDescriptors = ([] if self.__sourceMediaDescriptor is None
else self.__sourceMediaDescriptor.getAllTrackDescriptors()) # else self.__sourceMediaDescriptor.getAllTrackDescriptors())
#
dispositionTokens = [] # dispositionTokens = []
#
for trackIndex in range(len(targetTrackDescriptors)): # for trackIndex in range(len(targetTrackDescriptors)):
#
td = targetTrackDescriptors[trackIndex] # td = targetTrackDescriptors[trackIndex]
#
#HINT: No dispositions for pgs subtitle tracks that have no external file source # #HINT: No dispositions for pgs subtitle tracks that have no external file source
if (td.getExternalSourceFilePath() # if (td.getExternalSourceFilePath()
or td.getCodec() != TrackCodec.PGS): # or td.getCodec() != TrackCodec.PGS):
#
subIndex = td.getSubIndex() # subIndex = td.getSubIndex()
streamIndicator = td.getType().indicator() # streamIndicator = td.getType().indicator()
#
#
sourceDispositionSet = sourceTrackDescriptors[td.getSourceIndex()].getDispositionSet() if sourceTrackDescriptors else set() # sourceDispositionSet = sourceTrackDescriptors[td.getSourceIndex()].getDispositionSet() if sourceTrackDescriptors else set()
#
#TODO: Alles discarden was im targetDescriptor vorhanden ist (?) # #TODO: Alles discarden was im targetDescriptor vorhanden ist (?)
sourceDispositionSet.discard(TrackDisposition.DEFAULT) # sourceDispositionSet.discard(TrackDisposition.DEFAULT)
#
dispositionSet = td.getDispositionSet() | sourceDispositionSet # dispositionSet = td.getDispositionSet() | sourceDispositionSet
#
if dispositionSet: # if dispositionSet:
dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '+'.join([d.label() for d in dispositionSet])] # dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '+'.join([d.label() for d in dispositionSet])]
else: # else:
dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '0'] # dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '0']
#
return dispositionTokens # return dispositionTokens
#
#
def generateMetadataTokens(self): # def generateMetadataTokens(self):
#
metadataTokens = [] # metadataTokens = []
#
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {} # metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
#
signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {} # signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else [] # removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
removeTrackKeys = metadataConfiguration['streams']['remove'] if 'streams' in metadataConfiguration.keys() and 'remove' in metadataConfiguration['streams'].keys() else [] # removeTrackKeys = metadataConfiguration['streams']['remove'] if 'streams' in metadataConfiguration.keys() and 'remove' in metadataConfiguration['streams'].keys() else []
#
mediaTags = {k:v for k,v in self.__targetMediaDescriptor.getTags().items() if not k in removeGlobalKeys} # mediaTags = {k:v for k,v in self.__targetMediaDescriptor.getTags().items() if not k in removeGlobalKeys}
#
if (not 'no_signature' in self.__context.keys() # if (not 'no_signature' in self.__context.keys()
or not self.__context['no_signature']): # or not self.__context['no_signature']):
outputMediaTags = mediaTags | signatureTags # outputMediaTags = mediaTags | signatureTags
else: # else:
outputMediaTags = mediaTags # outputMediaTags = mediaTags
#
for tagKey, tagValue in outputMediaTags.items(): # for tagKey, tagValue in outputMediaTags.items():
metadataTokens += [f"-metadata:g", # metadataTokens += [f"-metadata:g",
f"{tagKey}={tagValue}"] # f"{tagKey}={tagValue}"]
#
for removeKey in removeGlobalKeys: # for removeKey in removeGlobalKeys:
metadataTokens += [f"-metadata:g", # metadataTokens += [f"-metadata:g",
f"{removeKey}="] # f"{removeKey}="]
#
#
removeMkvmergeMetadata = (not 'keep_mkvmerge_metadata' in self.__context.keys() # removeMkvmergeMetadata = (not 'keep_mkvmerge_metadata' in self.__context.keys()
or not self.__context['keep_mkvmerge_metadata']) # or not self.__context['keep_mkvmerge_metadata'])
#
#HINT: With current ffmpeg version track metadata tags are not passed to the outfile # #HINT: With current ffmpeg version track metadata tags are not passed to the outfile
for td in self.__targetMediaDescriptor.getAllTrackDescriptors(): # for td in self.__targetMediaDescriptor.getAllTrackDescriptors():
#
typeIndicator = td.getType().indicator() # typeIndicator = td.getType().indicator()
subIndex = td.getSubIndex() # subIndex = td.getSubIndex()
#
for tagKey, tagValue in td.getTags().items(): # for tagKey, tagValue in td.getTags().items():
#
if not tagKey in removeTrackKeys: # if not tagKey in removeTrackKeys:
metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}", # metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}",
f"{tagKey}={tagValue}"] # f"{tagKey}={tagValue}"]
#
for removeKey in removeTrackKeys: # for removeKey in removeTrackKeys:
metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}", # metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}",
f"{removeKey}="] # f"{removeKey}="]
#
#
return metadataTokens # return metadataTokens
def runJob(self, def runJob(self,
@ -262,10 +261,10 @@ class FfxController():
commandSequence = (commandTokens commandSequence = (commandTokens
+ self.__targetMediaDescriptor.getImportFileTokens() + self.__targetMediaDescriptor.getImportFileTokens()
+ self.__targetMediaDescriptor.getInputMappingTokens() + self.__targetMediaDescriptor.getInputMappingTokens()
+ self.generateDispositionTokens()) + self.__mdcs.generateDispositionTokens())
# Optional tokens # Optional tokens
commandSequence += self.generateMetadataTokens() commandSequence += self.__mdcs.generateMetadataTokens()
commandSequence += denoiseTokens commandSequence += denoiseTokens
commandSequence += (self.generateAudioEncodingTokens() commandSequence += (self.generateAudioEncodingTokens()
@ -314,10 +313,10 @@ class FfxController():
commandSequence2 = (commandTokens commandSequence2 = (commandTokens
+ self.__targetMediaDescriptor.getImportFileTokens() + self.__targetMediaDescriptor.getImportFileTokens()
+ self.__targetMediaDescriptor.getInputMappingTokens() + self.__targetMediaDescriptor.getInputMappingTokens()
+ self.generateDispositionTokens()) + self.__mdcs.generateDispositionTokens())
# Optional tokens # Optional tokens
commandSequence2 += self.generateMetadataTokens() commandSequence2 += self.__mdcs.generateMetadataTokens()
commandSequence2 += denoiseTokens commandSequence2 += denoiseTokens
commandSequence2 += self.generateVP9Pass2Tokens(int(quality)) + self.generateAudioEncodingTokens() commandSequence2 += self.generateVP9Pass2Tokens(int(quality)) + self.generateAudioEncodingTokens()

@ -15,8 +15,41 @@ DIFF_REMOVED_KEY = 'removed'
DIFF_CHANGED_KEY = 'changed' DIFF_CHANGED_KEY = 'changed'
DIFF_UNCHANGED_KEY = 'unchanged' DIFF_UNCHANGED_KEY = 'unchanged'
RICH_COLOR_PATTERN = '\[[a-z_]+\](.+)\[\/[a-z_]+\]'
def dictDiff(a : dict, b : dict):
def dictDiff(a : dict, b : dict, ignoreKeys: list = [], removeKeys: list = []):
"""
ignoreKeys: Ignored keys are filtered from calculating diff at all
removeKeys: Override diff calculation to remove keys certainly
"""
a_filtered = {k:v for k,v in a.items() if k not in ignoreKeys}
b_filtered = {k:v for k,v in b.items() if k not in ignoreKeys and k not in removeKeys}
a_only = {k:v for k,v in a_filtered.items() if k not in b_filtered.keys()}
b_only = {k:v for k,v in b_filtered.items() if k not in a_filtered.keys()}
a_b = set(a_filtered.keys()) & set(b_filtered.keys())
changed = {k:b_filtered[k] for k in a_b if a_filtered[k] != b_filtered[k]}
unchanged = {k:b_filtered[k] for k in a_b if a_filtered[k] == b_filtered[k]}
diffResult = {}
if a_only:
diffResult[DIFF_REMOVED_KEY] = a_only
diffResult[DIFF_UNCHANGED_KEY] = unchanged
if b_only:
diffResult[DIFF_ADDED_KEY] = b_only
if changed:
diffResult[DIFF_CHANGED_KEY] = changed
return diffResult
def dictKeysDiff(a : dict, b : dict):
a_keys = set(a.keys()) a_keys = set(a.keys())
b_keys = set(b.keys()) b_keys = set(b.keys())
@ -40,9 +73,10 @@ def dictDiff(a : dict, b : dict):
return diffResult return diffResult
def dictCache(element: dict, cache: list = []): def dictCache(element: dict, cache: list = []):
for index in range(len(cache)): for index in range(len(cache)):
diff = dictDiff(cache[index], element) diff = dictKeysDiff(cache[index], element)
if not diff: if not diff:
return index, cache return index, cache
cache.append(element) cache.append(element)
@ -53,11 +87,13 @@ def setDiff(a : set, b : set) -> set:
a_only = a - b a_only = a - b
b_only = b - a b_only = b - a
a_and_b = a & b
diffResult = {} diffResult = {}
if a_only: if a_only:
diffResult[DIFF_REMOVED_KEY] = a_only diffResult[DIFF_REMOVED_KEY] = a_only
diffResult[DIFF_UNCHANGED_KEY] = a_and_b
if b_only: if b_only:
diffResult[DIFF_ADDED_KEY] = b_only diffResult[DIFF_ADDED_KEY] = b_only
@ -187,3 +223,17 @@ def getEpisodeFileBasename(showName,
# return ''.join(filenameTokens) # return ''.join(filenameTokens)
def formatRichColor(text: str, color: str = None):
if color is None:
return text
else:
return f"[{color}]{text}[/{color}]"
def removeRichColor(text: str):
richColorMatch = re.search(RICH_COLOR_PATTERN, text)
if richColorMatch is None:
return text
else:
return str(richColorMatch.group(1))

@ -10,8 +10,6 @@ from ffx.track_codec import TrackCodec
from ffx.track_descriptor import TrackDescriptor from ffx.track_descriptor import TrackDescriptor
from ffx.helper import dictDiff, DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY
class MediaDescriptor: class MediaDescriptor:
"""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"""
@ -318,80 +316,6 @@ class MediaDescriptor:
] ]
def compare(self, vsMediaDescriptor: Self):
if not isinstance(vsMediaDescriptor, self.__class__):
self.__logger.error(f"MediaDescriptor.compare(): Argument is required to be of type {self.__class__}")
raise click.Abort()
vsTags = vsMediaDescriptor.getTags()
tags = self.getTags()
# HINT: Some tags differ per file, for example creation_time, so these are removed before diff
for emt in MediaDescriptor.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[MediaDescriptor.TAGS_KEY] = tagsDiff
# Target track configuration (from DB)
# tracks = self.getAllTrackDescriptors()
tracks = self.getAllTrackDescriptors() # filtern
numTracks = len(tracks)
# Current track configuration (of file)
vsTracks = vsMediaDescriptor.getAllTrackDescriptors()
numVsTracks = len(vsTracks)
maxNumOfTracks = max(numVsTracks, numTracks)
trackCompareResult = {}
for tp in range(maxNumOfTracks):
#!
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[MediaDescriptor.TRACKS_KEY] = trackCompareResult
return compareResult
def getImportFileTokens(self, use_sub_index: bool = True): def getImportFileTokens(self, use_sub_index: bool = True):
importFileTokens = [] importFileTokens = []

@ -0,0 +1,266 @@
import click
from ffx.media_descriptor import MediaDescriptor
from ffx.track_descriptor import TrackDescriptor
from ffx.helper import dictDiff, setDiff, DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY, DIFF_UNCHANGED_KEY
from ffx.track_codec import TrackCodec
from ffx.track_disposition import TrackDisposition
class MediaDescriptorChangeSet():
TAGS_KEY = "tags"
TRACKS_KEY = "tracks"
DISPOSITION_SET_KEY = "disposition_set"
TRACK_DESCRIPTOR_KEY = "track_descriptor"
def __init__(self, context,
targetMediaDescriptor: MediaDescriptor = None,
sourceMediaDescriptor: MediaDescriptor = None):
self.__context = context
self.__logger = context['logger']
self.__configurationData = self.__context['config'].getData()
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
self.__signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
self.__removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
self.__ignoreGlobalKeys = metadataConfiguration['ignore'] if 'ignore' in metadataConfiguration.keys() else []
self.__removeTrackKeys = (metadataConfiguration['streams']['remove']
if 'streams' in metadataConfiguration.keys()
and 'remove' in metadataConfiguration['streams'].keys() else [])
self.__ignoreTrackKeys = (metadataConfiguration['streams']['ignore']
if 'streams' in metadataConfiguration.keys()
and 'ignore' in metadataConfiguration['streams'].keys() else [])
self.__changeSetObj = {}
if targetMediaDescriptor is not None:
sourceMediaTags = sourceMediaDescriptor.getTags() if sourceMediaDescriptor is not None else {}
targetMediaTags = targetMediaDescriptor.getTags()
#!!#
tagsDiff = dictDiff(sourceMediaTags,
targetMediaTags,
ignoreKeys=self.__ignoreGlobalKeys,
removeKeys=self.__removeGlobalKeys)
if tagsDiff:
self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY] = tagsDiff
self.__targetTrackDescriptors = targetMediaDescriptor.getTrackDescriptors()
self.__numTargetTracks = len(self.__targetTrackDescriptors)
# Current track configuration (of file)
self.__sourceTrackDescriptors = sourceMediaDescriptor.getTrackDescriptors() if sourceMediaDescriptor is not None else []
self.__numSourceTracks = len(self.__sourceTrackDescriptors)
maxNumOfTracks = max(self.__numSourceTracks, self.__numTargetTracks)
trackCompareResult = {}
for trackIndex in range(maxNumOfTracks):
correspondingSourceTrackDescriptors = [st for st in self.__sourceTrackDescriptors if st.getIndex() == trackIndex]
correspondingTargetTrackDescriptors = [tt for tt in self.__targetTrackDescriptors if tt.getIndex() == trackIndex]
# Track present in target but not in source
if (not correspondingSourceTrackDescriptors
and correspondingTargetTrackDescriptors):
if DIFF_ADDED_KEY not in trackCompareResult.keys():
trackCompareResult[DIFF_ADDED_KEY] = {}
trackCompareResult[DIFF_ADDED_KEY][trackIndex] = correspondingTargetTrackDescriptors[0]
continue
# Track present in target but not in source
if (correspondingSourceTrackDescriptors
and not correspondingTargetTrackDescriptors):
if DIFF_REMOVED_KEY not in trackCompareResult.keys():
trackCompareResult[DIFF_REMOVED_KEY] = {}
trackCompareResult[DIFF_REMOVED_KEY][trackIndex] = correspondingSourceTrackDescriptors[0]
continue
if (correspondingSourceTrackDescriptors
and correspondingTargetTrackDescriptors):
trackDiff = self.compareTracks(correspondingSourceTrackDescriptors[0], correspondingTargetTrackDescriptors[0])
if trackDiff:
if DIFF_CHANGED_KEY not in trackCompareResult.keys():
trackCompareResult[DIFF_CHANGED_KEY] = {}
trackCompareResult[DIFF_CHANGED_KEY][trackIndex] = trackDiff
if trackCompareResult:
self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY] = trackCompareResult
def compareTracks(self,
targetTrackDescriptor: TrackDescriptor,
sourceTrackDescriptor: TrackDescriptor = None):
if not isinstance(targetTrackDescriptor, TrackDescriptor):
self.__logger.error(f"MediaDescriptorChangeSet.compareTracks(): Argument targetTrackDescriptor is required to be of type TrackDescriptor")
raise click.Abort()
sourceTrackTags = sourceTrackDescriptor.getTags() if sourceTrackDescriptor is not None else {}
targetTrackTags = targetTrackDescriptor.getTags()
trackCompareResult = {}
tagsDiffResult = dictDiff(sourceTrackTags,
targetTrackTags,
ignoreKeys=self.__ignoreTrackKeys,
removeKeys=self.__removeTrackKeys)
if tagsDiffResult:
trackCompareResult[MediaDescriptorChangeSet.TAGS_KEY] = tagsDiffResult
sourceDispositions = sourceTrackDescriptor.getDispositionSet()
targetDispositions = targetTrackDescriptor.getDispositionSet()
dispositionDiffResult = setDiff(sourceDispositions, targetDispositions)
if dispositionDiffResult:
trackCompareResult[MediaDescriptorChangeSet.DISPOSITION_SET_KEY] = dispositionDiffResult
if trackCompareResult:
trackCompareResult[MediaDescriptorChangeSet.TRACK_DESCRIPTOR_KEY] = targetTrackDescriptor
return trackCompareResult
def generateDispositionTokens(self):
"""
#Example: -disposition:s:0 default -disposition:s:1 0
"""
dispositionTokens = []
if MediaDescriptorChangeSet.TRACKS_KEY in self.__changeSetObj.keys():
if DIFF_ADDED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
trackDescriptor: TrackDescriptor
for trackDescriptor in addedTracks.values():
dispositionSet = trackDescriptor.getDispositionSet()
if dispositionSet:
dispositionTokens += [f"-disposition:{trackDescriptor.getType().indicator()}:{trackDescriptor.getSubIndex()}",
'+'.join([d.label() for d in dispositionSet])]
if DIFF_CHANGED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
changedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_CHANGED_KEY]
trackDiffObj: dict
for trackDiffObj in changedTracks.values():
addedDispositions = trackDiffObj[DIFF_ADDED_KEY] if DIFF_ADDED_KEY in trackDiffObj.keys() else set()
removedDispositions = trackDiffObj[DIFF_REMOVED_KEY] if DIFF_REMOVED_KEY in trackDiffObj.keys() else set()
unchangedDispositions = trackDiffObj[DIFF_UNCHANGED_KEY] if DIFF_UNCHANGED_KEY in trackDiffObj.keys() else set()
targetDispositions = addedDispositions | unchangedDispositions
streamIndicator = trackDescriptor.getType().indicator()
subIndex = trackDescriptor.getSubIndex()
if targetDispositions:
dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '+'.join([d.label() for d in targetDispositions])]
if not targetDispositions and removedDispositions:
dispositionTokens += [f"-disposition:{streamIndicator}:{subIndex}", '0']
return dispositionTokens
def generateMetadataTokens(self):
metadataTokens = []
if MediaDescriptorChangeSet.TAGS_KEY in self.__changeSetObj.keys():
addedMediaTags = (self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_ADDED_KEY]
if DIFF_ADDED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
removedMediaTags = (self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_REMOVED_KEY]
if DIFF_REMOVED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
changedMediaTags = (self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_CHANGED_KEY]
if DIFF_CHANGED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
outputMediaTags = addedMediaTags | changedMediaTags
if (not 'no_signature' in self.__context.keys()
or not self.__context['no_signature']):
outputMediaTags = outputMediaTags | self.__signatureTags
# outputMediaTags = {k:v for k,v in outputMediaTags.items() if k not in self.__removeGlobalKeys}
for tagKey, tagValue in outputMediaTags.items():
metadataTokens += [f"-metadata:g",
f"{tagKey}={tagValue}"]
for tagKey, tagValue in changedMediaTags.items():
metadataTokens += [f"-metadata:g",
f"{tagKey}={tagValue}"]
for removeKey in removedMediaTags.keys():
metadataTokens += [f"-metadata:g",
f"{removeKey}="]
if MediaDescriptorChangeSet.TRACKS_KEY in self.__changeSetObj.keys():
if DIFF_ADDED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
trackDescriptor: TrackDescriptor
for trackDescriptor in addedTracks.values():
for tagKey, tagValue in trackDescriptor.getTags().items():
if not tagKey in self.__removeTrackKeys:
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
+ f":{trackDescriptor.getSubIndex()}",
f"{tagKey}={tagValue}"]
if DIFF_CHANGED_KEY in self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
changedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_CHANGED_KEY]
trackDiffObj: dict
for trackDiffObj in changedTracks.values():
addedTrackTags = trackDiffObj[DIFF_ADDED_KEY] if DIFF_ADDED_KEY in trackDiffObj.keys() else {}
changedTrackTags = trackDiffObj[DIFF_CHANGED_KEY] if DIFF_CHANGED_KEY in trackDiffObj.keys() else {}
removedTrackTags = trackDiffObj[DIFF_REMOVED_KEY] if DIFF_REMOVED_KEY in trackDiffObj.keys() else {}
# outputTrackTags = {k:v for k,v in (addedTrackTags | changedTrackTags).items() if k not in self.__removeTrackKeys}
outputTrackTags = addedTrackTags | changedTrackTags
for tagKey, tagValue in outputTrackTags.items():
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
+ f":{trackDescriptor.getSubIndex()}",
f"{tagKey}={tagValue}"]
for tagKey, tagValue in changedTrackTags.items():
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
+ f":{trackDescriptor.getSubIndex()}",
f"{tagKey}={tagValue}"]
for removeKey in removedTrackTags.keys():
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
+ f":{trackDescriptor.getSubIndex()}",
f"{removeKey}="]
return metadataTokens
def getChangeSetObj(self):
return self.__changeSetObj

@ -27,7 +27,9 @@ from textual.widgets._data_table import CellDoesNotExist
from ffx.media_descriptor import MediaDescriptor from ffx.media_descriptor import MediaDescriptor
from ffx.file_properties import FileProperties from ffx.file_properties import FileProperties
from ffx.helper import DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY from ffx.media_descriptor_change_set import MediaDescriptorChangeSet
from ffx.helper import formatRichColor, DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY, DIFF_UNCHANGED_KEY
# Screen[dict[int, str, int]] # Screen[dict[int, str, int]]
@ -38,7 +40,7 @@ class MediaDetailsScreen(Screen):
Grid { Grid {
grid-size: 5 8; grid-size: 5 8;
grid-rows: 8 2 2 2 2 8 2 2 8; grid-rows: 8 2 2 2 2 8 2 2 8;
grid-columns: 25 25 120 10 75; grid-columns: 15 25 90 10 105;
height: 100%; height: 100%;
width: 100%; width: 100%;
padding: 1; padding: 1;
@ -110,6 +112,19 @@ class MediaDetailsScreen(Screen):
""" """
TRACKS_TABLE_INDEX_COLUMN_LABEL = "Index"
TRACKS_TABLE_TYPE_COLUMN_LABEL = "Type"
TRACKS_TABLE_SUB_INDEX_COLUMN_LABEL = "SubIndex"
TRACKS_TABLE_CODEC_COLUMN_LABEL = "Codec"
TRACKS_TABLE_LAYOUT_COLUMN_LABEL = "Layout"
TRACKS_TABLE_LANGUAGE_COLUMN_LABEL = "Language"
TRACKS_TABLE_TITLE_COLUMN_LABEL = "Title"
TRACKS_TABLE_DEFAULT_COLUMN_LABEL = "Default"
TRACKS_TABLE_FORCED_COLUMN_LABEL = "Forced"
DIFFERENCES_TABLE_DIFFERENCES_COLUMN_LABEL = 'Differences (file->db/output)'
BINDINGS = [ BINDINGS = [
("n", "new_pattern", "New Pattern"), ("n", "new_pattern", "New Pattern"),
("u", "update_pattern", "Update Pattern"), ("u", "update_pattern", "Update Pattern"),
@ -123,6 +138,22 @@ class MediaDetailsScreen(Screen):
self.context = self.app.getContext() self.context = self.app.getContext()
self.Session = self.context['database']['session'] # convenience self.Session = self.context['database']['session'] # convenience
self.__configurationData = self.context['config'].getData()
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
self.__signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
self.__removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
self.__ignoreGlobalKeys = metadataConfiguration['ignore'] if 'ignore' in metadataConfiguration.keys() else []
self.__removeTrackKeys = (metadataConfiguration['streams']['remove']
if 'streams' in metadataConfiguration.keys()
and 'remove' in metadataConfiguration['streams'].keys() else [])
self.__ignoreTrackKeys = (metadataConfiguration['streams']['ignore']
if 'streams' in metadataConfiguration.keys()
and 'ignore' in metadataConfiguration['streams'].keys() else [])
self.__pc = PatternController(context = self.context) self.__pc = PatternController(context = self.context)
self.__sc = ShowController(context = self.context) self.__sc = ShowController(context = self.context)
self.__tc = TrackController(context = self.context) self.__tc = TrackController(context = self.context)
@ -191,9 +222,10 @@ class MediaDetailsScreen(Screen):
# Enumerating differences between media descriptors # Enumerating differences between media descriptors
# from file (=current) vs from stored in database (=target) # from file (=current) vs from stored in database (=target)
try: try:
self.__mediaDifferences = self.__targetMediaDescriptor.compare(self.__currentMediaDescriptor) if self.__currentPattern is not None else {} mdcs = MediaDescriptorChangeSet(self.context, self.__targetMediaDescriptor, self.__currentMediaDescriptor)
self.__mediaChangeSetObj = mdcs.getChangeSetObj()
except ValueError: except ValueError:
self.__mediaDifferences = {} self.__mediaChangeSetObj = {}
def updateDifferences(self): def updateDifferences(self):
@ -202,73 +234,87 @@ class MediaDetailsScreen(Screen):
self.differencesTable.clear() self.differencesTable.clear()
if MediaDescriptor.TAGS_KEY in self.__mediaDifferences.keys():
currentTags = self.__currentMediaDescriptor.getTags() if MediaDescriptorChangeSet.TAGS_KEY in self.__mediaChangeSetObj.keys():
targetTags = self.__targetMediaDescriptor.getTags()
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_ADDED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for addedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_ADDED_KEY]: for tagKey, tagValue in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_ADDED_KEY].items():
row = (f"added media tag: key='{addedTagKey}' value='{targetTags[addedTagKey]}'",) if tagKey not in self.__ignoreGlobalKeys:
row = (f"add media tag: key='{tagKey}' value='{tagValue}'",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_REMOVED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for removedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_REMOVED_KEY]: for tagKey, tagValue in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_REMOVED_KEY].items():
row = (f"removed media tag: key='{removedTagKey}' value='{currentTags[removedTagKey]}'",) if tagKey not in self.__ignoreGlobalKeys and tagKey not in self.__removeGlobalKeys:
row = (f"remove media tag: key='{tagKey}' value='{tagValue}'",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_CHANGED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for changedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_CHANGED_KEY]: for tagKey, tagValue in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_CHANGED_KEY].items():
row = (f"changed media tag: key='{changedTagKey}' value='{currentTags[changedTagKey]}'->'{targetTags[changedTagKey]}'",) if tagKey not in self.__ignoreGlobalKeys:
row = (f"change media tag: key='{tagKey}' value='{tagValue}'",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if MediaDescriptor.TRACKS_KEY in self.__mediaDifferences.keys():
currentTracks = self.__currentMediaDescriptor.getAllTrackDescriptors() # 0,1,2,3 if MediaDescriptorChangeSet.TRACKS_KEY in self.__mediaChangeSetObj.keys():
targetTracks = self.__targetMediaDescriptor.getAllTrackDescriptors() # 0 <- from DB
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_ADDED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
#raise click.ClickException(f"add track {self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_ADDED_KEY]}") trackDescriptor: TrackDescriptor
for addedTrackIndex in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_ADDED_KEY]: for trackIndex, trackDescriptor in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY].items():
addedTrack : Track = targetTracks[addedTrackIndex] row = (f"add {trackDescriptor.getType().label()} track: index={trackDescriptor.getIndex()} lang={trackDescriptor.getLanguage().threeLetter()}",)
row = (f"added {addedTrack.getType().label()} track: index={addedTrackIndex} lang={addedTrack.getLanguage().threeLetter()}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_REMOVED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
for removedTrackIndex in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_REMOVED_KEY]: for trackIndex, trackDescriptor in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_REMOVED_KEY].items():
row = (f"removed track: index={removedTrackIndex}",) row = (f"remove stream #{trackIndex}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_CHANGED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
for changedTrackIndex in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_CHANGED_KEY].keys():
changedTracks: dict = self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_CHANGED_KEY]
targetTrackDescriptors = self.__targetMediaDescriptor.getTrackDescriptors()
trackDiffObj: dict
for trackIndex, trackDiffObj in changedTracks.items():
changedTrack : Track = targetTracks[changedTrackIndex] ttd: TrackDescriptor = targetTrackDescriptors[trackIndex]
changedTrackDiff : dict = self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_CHANGED_KEY][changedTrackIndex]
if MediaDescriptor.TAGS_KEY in changedTrackDiff.keys():
if DIFF_ADDED_KEY in changedTrackDiff[MediaDescriptor.TAGS_KEY]: if MediaDescriptorChangeSet.TAGS_KEY in trackDiffObj.keys():
for addedTagKey in changedTrackDiff[MediaDescriptor.TAGS_KEY][DIFF_ADDED_KEY]:
addedTagValue = changedTrack.getTags()[addedTagKey] removedTags = (trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_REMOVED_KEY]
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} added key={addedTagKey} value={addedTagValue}",) if DIFF_REMOVED_KEY in trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
for tagKey, tagValue in removedTags.items():
row = (f"change stream #{ttd.getIndex()} ({ttd.getType().label()}:{ttd.getSubIndex()}) remove key={tagKey} value={tagValue}",)
self.differencesTable.add_row(*map(str, row))
addedTags = (trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_ADDED_KEY]
if DIFF_ADDED_KEY in trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
for tagKey, tagValue in addedTags.items():
row = (f"change stream #{ttd.getIndex()} ({ttd.getType().label()}:{ttd.getSubIndex()}) add key={tagKey} value={tagValue}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_REMOVED_KEY in changedTrackDiff[MediaDescriptor.TAGS_KEY]: changedTags = (trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_CHANGED_KEY]
for removedTagKey in changedTrackDiff[MediaDescriptor.TAGS_KEY][DIFF_REMOVED_KEY]: if DIFF_CHANGED_KEY in trackDiffObj[MediaDescriptorChangeSet.TAGS_KEY].keys() else {})
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} removed key={removedTagKey}",) for tagKey, tagValue in changedTags.items():
row = (f"change stream #{ttd.getIndex()} ({ttd.getType().label()}:{ttd.getSubIndex()}) change key={tagKey} value={tagValue}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if TrackDescriptor.DISPOSITION_SET_KEY in changedTrackDiff.keys():
if DIFF_ADDED_KEY in changedTrackDiff[TrackDescriptor.DISPOSITION_SET_KEY]: if MediaDescriptorChangeSet.DISPOSITION_SET_KEY in trackDiffObj.keys():
for addedDisposition in changedTrackDiff[TrackDescriptor.DISPOSITION_SET_KEY][DIFF_ADDED_KEY]:
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} added disposition={addedDisposition.label()}",) addedDispositions = (trackDiffObj[MediaDescriptorChangeSet.DISPOSITION_SET_KEY][DIFF_ADDED_KEY]
if DIFF_ADDED_KEY in trackDiffObj[MediaDescriptorChangeSet.DISPOSITION_SET_KEY].keys() else set())
for ad in addedDispositions:
row = (f"change stream #{ttd.getIndex()} ({ttd.getType().label()}:{ttd.getSubIndex()}) add disposition={ad.label()}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
if DIFF_REMOVED_KEY in changedTrackDiff[TrackDescriptor.DISPOSITION_SET_KEY]: removedDispositions = (trackDiffObj[MediaDescriptorChangeSet.DISPOSITION_SET_KEY][DIFF_REMOVED_KEY]
for removedDisposition in changedTrackDiff[TrackDescriptor.DISPOSITION_SET_KEY][DIFF_REMOVED_KEY]: if DIFF_REMOVED_KEY in trackDiffObj[MediaDescriptorChangeSet.DISPOSITION_SET_KEY].keys() else set())
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} removed disposition={removedDisposition.label()}",) for rd in removedDispositions:
row = (f"change stream #{ttd.getIndex()} ({ttd.getType().label()}:{ttd.getSubIndex()}) remove disposition={rd.label()}",)
self.differencesTable.add_row(*map(str, row)) self.differencesTable.add_row(*map(str, row))
@ -283,7 +329,14 @@ class MediaDetailsScreen(Screen):
self.showsTable.add_row(*map(str, row)) self.showsTable.add_row(*map(str, row))
for mediaTagKey, mediaTagValue in self.__currentMediaDescriptor.getTags().items(): for mediaTagKey, mediaTagValue in self.__currentMediaDescriptor.getTags().items():
row = (mediaTagKey, mediaTagValue) # Convert each element to a string before adding
textColor = None
if mediaTagKey in self.__ignoreGlobalKeys:
textColor = 'blue'
if mediaTagKey in self.__removeGlobalKeys:
textColor = 'red'
row = (formatRichColor(mediaTagKey, textColor), formatRichColor(mediaTagValue, textColor)) # Convert each element to a string before adding
self.mediaTagsTable.add_row(*map(str, row)) self.mediaTagsTable.add_row(*map(str, row))
self.updateTracks() self.updateTracks()
@ -352,7 +405,7 @@ class MediaDetailsScreen(Screen):
# Define the columns with headers # Define the columns with headers
self.column_key_show_id = self.showsTable.add_column("ID", width=10) self.column_key_show_id = self.showsTable.add_column("ID", width=10)
self.column_key_show_name = self.showsTable.add_column("Name", width=50) self.column_key_show_name = self.showsTable.add_column("Name", width=80)
self.column_key_show_year = self.showsTable.add_column("Year", width=10) self.column_key_show_year = self.showsTable.add_column("Year", width=10)
self.showsTable.cursor_type = 'row' self.showsTable.cursor_type = 'row'
@ -361,8 +414,8 @@ class MediaDetailsScreen(Screen):
self.mediaTagsTable = DataTable(classes="two") self.mediaTagsTable = DataTable(classes="two")
# Define the columns with headers # Define the columns with headers
self.column_key_track_tag_key = self.mediaTagsTable.add_column("Key", width=50) self.column_key_track_tag_key = self.mediaTagsTable.add_column("Key", width=30)
self.column_key_track_tag_value = self.mediaTagsTable.add_column("Value", width=100) self.column_key_track_tag_value = self.mediaTagsTable.add_column("Value", width=70)
self.mediaTagsTable.cursor_type = 'row' self.mediaTagsTable.cursor_type = 'row'
@ -370,15 +423,15 @@ class MediaDetailsScreen(Screen):
self.tracksTable = DataTable(classes="two") self.tracksTable = DataTable(classes="two")
# Define the columns with headers # Define the columns with headers
self.column_key_track_index = self.tracksTable.add_column("Index", width=5) self.column_key_track_index = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_INDEX_COLUMN_LABEL, width=5)
self.column_key_track_type = self.tracksTable.add_column("Type", width=10) self.column_key_track_type = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_TYPE_COLUMN_LABEL, width=10)
self.column_key_track_sub_index = self.tracksTable.add_column("SubIndex", width=8) self.column_key_track_sub_index = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_SUB_INDEX_COLUMN_LABEL, width=8)
self.column_key_track_codec = self.tracksTable.add_column("Codec", width=10) self.column_key_track_codec = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_CODEC_COLUMN_LABEL, width=10)
self.column_key_track_layout = self.tracksTable.add_column("Layout", width=10) self.column_key_track_layout = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_LAYOUT_COLUMN_LABEL, width=10)
self.column_key_track_language = self.tracksTable.add_column("Language", width=15) self.column_key_track_language = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_LANGUAGE_COLUMN_LABEL, width=15)
self.column_key_track_title = self.tracksTable.add_column("Title", width=48) self.column_key_track_title = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_TITLE_COLUMN_LABEL, width=48)
self.column_key_track_default = self.tracksTable.add_column("Default", width=8) self.column_key_track_default = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_DEFAULT_COLUMN_LABEL, width=8)
self.column_key_track_forced = self.tracksTable.add_column("Forced", width=8) self.column_key_track_forced = self.tracksTable.add_column(MediaDetailsScreen.TRACKS_TABLE_FORCED_COLUMN_LABEL, width=8)
self.tracksTable.cursor_type = 'row' self.tracksTable.cursor_type = 'row'
@ -387,7 +440,7 @@ class MediaDetailsScreen(Screen):
self.differencesTable = DataTable(id='differences-table') # classes="triple" self.differencesTable = DataTable(id='differences-table') # classes="triple"
# Define the columns with headers # Define the columns with headers
self.column_key_differences = self.differencesTable.add_column("Differences (file->db)", width=70) self.column_key_differences = self.differencesTable.add_column(MediaDetailsScreen.DIFFERENCES_TABLE_DIFFERENCES_COLUMN_LABEL, width=100)
self.differencesTable.cursor_type = 'row' self.differencesTable.cursor_type = 'row'
@ -439,15 +492,15 @@ class MediaDetailsScreen(Screen):
yield Footer() yield Footer()
def getPatternDescriptorFromInput(self): def getPatternObjFromInput(self):
"""Returns show id and pattern from corresponding inputs""" """Returns show id and pattern as obj from corresponding inputs"""
patternDescriptor = {} patternObj = {}
try: try:
patternDescriptor['show_id'] = self.getSelectedShowDescriptor().getId() patternObj['show_id'] = self.getSelectedShowDescriptor().getId()
patternDescriptor['pattern'] = str(self.query_one("#pattern_input", Input).value) patternObj['pattern'] = str(self.query_one("#pattern_input", Input).value)
except: except:
pass return {}
return patternDescriptor return patternObj
def on_button_pressed(self, event: Button.Pressed) -> None: def on_button_pressed(self, event: Button.Pressed) -> None:
@ -526,6 +579,7 @@ class MediaDetailsScreen(Screen):
def handle_new_pattern(self, showDescriptor: ShowDescriptor): def handle_new_pattern(self, showDescriptor: ShowDescriptor):
""""""
if type(showDescriptor) is not ShowDescriptor: if type(showDescriptor) is not ShowDescriptor:
raise TypeError("MediaDetailsScreen.handle_new_pattern(): Argument 'showDescriptor' has to be of type ShowDescriptor") raise TypeError("MediaDetailsScreen.handle_new_pattern(): Argument 'showDescriptor' has to be of type ShowDescriptor")
@ -541,14 +595,17 @@ class MediaDetailsScreen(Screen):
if showRowIndex is not None: if showRowIndex is not None:
self.showsTable.move_cursor(row=showRowIndex) self.showsTable.move_cursor(row=showRowIndex)
patternDescriptor = self.getPatternDescriptorFromInput() patternObj = self.getPatternObjFromInput()
if patternDescriptor: if patternObj:
patternId = self.__pc.addPattern(patternDescriptor) patternId = self.__pc.addPattern(patternObj)
if patternId: if patternId:
self.highlightPattern(False) self.highlightPattern(False)
for tagKey, tagValue in self.__currentMediaDescriptor.getTags().items(): for tagKey, tagValue in self.__currentMediaDescriptor.getTags().items():
# Filter tags that make no sense to preserve
if tagKey not in self.__ignoreGlobalKeys and not tagKey in self.__removeGlobalKeys:
self.__tac.updateMediaTag(patternId, tagKey, tagValue) self.__tac.updateMediaTag(patternId, tagKey, tagValue)
for trackDescriptor in self.__currentMediaDescriptor.getAllTrackDescriptors(): for trackDescriptor in self.__currentMediaDescriptor.getAllTrackDescriptors():
@ -556,6 +613,9 @@ class MediaDetailsScreen(Screen):
def action_new_pattern(self): def action_new_pattern(self):
"""Adding new patterns
If the corresponding show does not exists in DB it is added beforehand"""
selectedShowDescriptor = self.getSelectedShowDescriptor() selectedShowDescriptor = self.getSelectedShowDescriptor()
@ -568,90 +628,104 @@ class MediaDetailsScreen(Screen):
def action_update_pattern(self): def action_update_pattern(self):
"""When updating the database the actions must reverse the difference (eq to diff db->file)""" """Updating patterns
When updating the database the actions must reverse the difference (eq to diff db->file)"""
if self.__currentPattern is not None: if self.__currentPattern is not None:
patternDescriptor = self.getPatternDescriptorFromInput() patternObj = self.getPatternObjFromInput()
if (patternDescriptor if (patternObj
and self.__currentPattern.getPattern() != patternDescriptor['pattern']): and self.__currentPattern.getPattern() != patternObj['pattern']):
return self.__pc.updatePattern(self.__currentPattern.getId(), patternDescriptor) return self.__pc.updatePattern(self.__currentPattern.getId(), patternObj)
self.loadProperties() self.loadProperties()
if MediaDescriptor.TAGS_KEY in self.__mediaDifferences.keys(): # __mediaChangeSetObj is file vs database
if MediaDescriptorChangeSet.TAGS_KEY in self.__mediaChangeSetObj.keys():
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_ADDED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for addedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_ADDED_KEY]: for addedTagKey in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_ADDED_KEY].keys():
# click.ClickException(f"delete media tag patternId={self.__currentPattern.getId()} addedTagKey={addedTagKey}")
self.__tac.deleteMediaTagByKey(self.__currentPattern.getId(), addedTagKey) self.__tac.deleteMediaTagByKey(self.__currentPattern.getId(), addedTagKey)
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_REMOVED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for removedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_REMOVED_KEY]: for removedTagKey in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_REMOVED_KEY].keys():
currentTags = self.__currentMediaDescriptor.getTags() currentTags = self.__currentMediaDescriptor.getTags()
# click.ClickException(f"delete media tag patternId={self.__currentPattern.getId()} removedTagKey={removedTagKey} currentTags={currentTags[removedTagKey]}")
self.__tac.updateMediaTag(self.__currentPattern.getId(), removedTagKey, currentTags[removedTagKey]) self.__tac.updateMediaTag(self.__currentPattern.getId(), removedTagKey, currentTags[removedTagKey])
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys(): if DIFF_CHANGED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY].keys():
for changedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_CHANGED_KEY]: for changedTagKey in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TAGS_KEY][DIFF_CHANGED_KEY].keys():
currentTags = self.__currentMediaDescriptor.getTags() currentTags = self.__currentMediaDescriptor.getTags()
# click.ClickException(f"delete media tag patternId={self.__currentPattern.getId()} changedTagKey={changedTagKey} currentTags={currentTags[changedTagKey]}")
self.__tac.updateMediaTag(self.__currentPattern.getId(), changedTagKey, currentTags[changedTagKey]) self.__tac.updateMediaTag(self.__currentPattern.getId(), changedTagKey, currentTags[changedTagKey])
if MediaDescriptor.TRACKS_KEY in self.__mediaDifferences.keys(): if MediaDescriptorChangeSet.TRACKS_KEY in self.__mediaChangeSetObj.keys():
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_ADDED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
for addedTrackIndex in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_ADDED_KEY]: for trackIndex, trackDescriptor in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY].items():
targetTracks = [t for t in self.__targetMediaDescriptor.getAllTrackDescriptors() if t.getIndex() == addedTrackIndex] #targetTracks = [t for t in self.__targetMediaDescriptor.getAllTrackDescriptors() if t.getIndex() == addedTrackIndex]
if targetTracks: # if targetTracks:
self.__tc.deleteTrack(targetTracks[0].getId()) # id # self.__tc.deleteTrack(targetTracks[0].getId()) # id
# self.__tc.deleteTrack(targetTracks[0].getId())
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): self.__tc.addTrack(trackDescriptor, patternId = self.__currentPattern.getId())
for removedTrackIndex, removedTrack in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_REMOVED_KEY].items():
if DIFF_REMOVED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
trackDescriptor: TrackDescriptor
for trackIndex, trackDescriptor in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_REMOVED_KEY].items():
# Track per inspect/update hinzufügen # Track per inspect/update hinzufügen
self.__tc.addTrack(removedTrack, patternId = self.__currentPattern.getId()) #self.__tc.addTrack(removedTrack, patternId = self.__currentPattern.getId())
self.__tc.deleteTrack(trackDescriptor.getId())
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_CHANGED_KEY in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY].keys():
# [vsTracks[tp].getIndex()] = trackDiff # [vsTracks[tp].getIndex()] = trackDiff
for changedTrackIndex, changedTrackDiff in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_CHANGED_KEY].items(): for trackIndex, trackDiff in self.__mediaChangeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_CHANGED_KEY].items():
changedTargetTracks = [t for t in self.__targetMediaDescriptor.getAllTrackDescriptors() if t.getIndex() == changedTrackIndex] targetTracks = [t for t in self.__targetMediaDescriptor.getTrackDescriptors() if t.getIndex() == trackIndex]
changedTargeTrackId = changedTargetTracks[0].getId() if changedTargetTracks else None targetTrackId = targetTracks[0].getId() if targetTracks else None
changedTargetTrackIndex = changedTargetTracks[0].getIndex() if changedTargetTracks else None targetTrackIndex = targetTracks[0].getIndex() if targetTracks else None
changedCurrentTracks = [t for t in self.__currentMediaDescriptor.getAllTrackDescriptors() if t.getIndex() == changedTrackIndex] changedCurrentTracks = [t for t in self.__currentMediaDescriptor.getTrackDescriptors() if t.getIndex() == trackIndex]
# changedCurrentTrackId #HINT: Undefined as track descriptors do not come from file with track_id # changedCurrentTrackId #HINT: Undefined as track descriptors do not come from file with track_id
if TrackDescriptor.TAGS_KEY in changedTrackDiff.keys(): if TrackDescriptor.TAGS_KEY in trackDiff.keys():
changedTrackTagsDiff = changedTrackDiff[TrackDescriptor.TAGS_KEY] tagsDiff = trackDiff[TrackDescriptor.TAGS_KEY]
if DIFF_ADDED_KEY in tagsDiff.keys():
for tagKey, tagValue in tagsDiff[DIFF_ADDED_KEY].items():
# if targetTracks:
# self.__tac.deleteTrackTagByKey(targetTrackId, addedTrackTagKey)
self.__tac.updateTrackTag(targetTrackId, tagKey, tagValue)
if DIFF_ADDED_KEY in changedTrackTagsDiff.keys():
for addedTrackTagKey in changedTrackTagsDiff[DIFF_ADDED_KEY]:
if changedTargetTracks: if DIFF_REMOVED_KEY in tagsDiff.keys():
self.__tac.deleteTrackTagByKey(changedTargeTrackId, addedTrackTagKey) for tagKey, tagValue in tagsDiff[DIFF_REMOVED_KEY].items():
# if changedCurrentTracks:
# self.__tac.updateTrackTag(targetTrackId, removedTrackTagKey, changedCurrentTracks[0].getTags()[removedTrackTagKey])
self.__tac.deleteTrackTagByKey(targetTrackId, tagKey)
if DIFF_REMOVED_KEY in changedTrackTagsDiff.keys(): if DIFF_CHANGED_KEY in tagsDiff.keys():
for removedTrackTagKey in changedTrackTagsDiff[DIFF_REMOVED_KEY]: for tagKey, tagValue in tagsDiff[DIFF_CHANGED_KEY].items():
if changedCurrentTracks: # if changedCurrentTracks:
self.__tac.updateTrackTag(changedTargeTrackId, removedTrackTagKey, changedCurrentTracks[0].getTags()[removedTrackTagKey]) # self.__tac.updateTrackTag(targetTrackId, changedTrackTagKey, changedCurrentTracks[0].getTags()[changedTrackTagKey])
self.__tac.updateTrackTag(targetTrackId, tagKey, tagValue)
if DIFF_CHANGED_KEY in changedTrackTagsDiff.keys():
for changedTrackTagKey in changedTrackTagsDiff[DIFF_CHANGED_KEY]:
if changedCurrentTracks:
self.__tac.updateTrackTag(changedTargeTrackId, changedTrackTagKey, changedCurrentTracks[0].getTags()[changedTrackTagKey])
if TrackDescriptor.DISPOSITION_SET_KEY in changedTrackDiff.keys(): if TrackDescriptor.DISPOSITION_SET_KEY in trackDiff.keys():
changedTrackDispositionDiff = changedTrackDiff[TrackDescriptor.DISPOSITION_SET_KEY] changedTrackDispositionDiff = trackDiff[TrackDescriptor.DISPOSITION_SET_KEY]
if DIFF_ADDED_KEY in changedTrackDispositionDiff.keys(): if DIFF_ADDED_KEY in changedTrackDispositionDiff.keys():
for changedTrackAddedDisposition in changedTrackDispositionDiff[DIFF_ADDED_KEY]: for changedDisposition in changedTrackDispositionDiff[DIFF_ADDED_KEY]:
if changedTargetTrackIndex is not None: if targetTrackIndex is not None:
self.__tc.setDispositionState(self.__currentPattern.getId(), changedTargetTrackIndex, changedTrackAddedDisposition, False) self.__tc.setDispositionState(self.__currentPattern.getId(), targetTrackIndex, changedDisposition, True)
if DIFF_REMOVED_KEY in changedTrackDispositionDiff.keys(): if DIFF_REMOVED_KEY in changedTrackDispositionDiff.keys():
for changedTrackRemovedDisposition in changedTrackDispositionDiff[DIFF_REMOVED_KEY]: for changedDisposition in changedTrackDispositionDiff[DIFF_REMOVED_KEY]:
if changedTargetTrackIndex is not None: if targetTrackIndex is not None:
self.__tc.setDispositionState(self.__currentPattern.getId(), changedTargetTrackIndex, changedTrackRemovedDisposition, True) self.__tc.setDispositionState(self.__currentPattern.getId(), targetTrackIndex, changedDisposition, False)
self.updateDifferences() self.updateDifferences()
@ -660,11 +734,11 @@ class MediaDetailsScreen(Screen):
def action_edit_pattern(self): def action_edit_pattern(self):
patternDescriptor = self.getPatternDescriptorFromInput() patternObj = self.getPatternObjFromInput()
if patternDescriptor['pattern']: if patternObj['pattern']:
selectedPatternId = self.__pc.findPattern(patternDescriptor) selectedPatternId = self.__pc.findPattern(patternObj)
if selectedPatternId is None: if selectedPatternId is None:
raise click.ClickException(f"MediaDetailsScreen.action_edit_pattern(): Pattern to edit has no id") raise click.ClickException(f"MediaDetailsScreen.action_edit_pattern(): Pattern to edit has no id")

@ -11,17 +11,20 @@ class PatternController():
self.Session = self.context['database']['session'] # convenience self.Session = self.context['database']['session'] # convenience
def addPattern(self, patternDescriptor): def addPattern(self, patternObj):
"""Adds pattern to database from obj
Returns database id or 0 if pattern already exists"""
try: try:
s = self.Session() s = self.Session()
q = s.query(Pattern).filter(Pattern.show_id == int(patternDescriptor['show_id']), q = s.query(Pattern).filter(Pattern.show_id == int(patternObj['show_id']),
Pattern.pattern == str(patternDescriptor['pattern'])) Pattern.pattern == str(patternObj['pattern']))
if not q.count(): if not q.count():
pattern = Pattern(show_id = int(patternDescriptor['show_id']), pattern = Pattern(show_id = int(patternObj['show_id']),
pattern = str(patternDescriptor['pattern'])) pattern = str(patternObj['pattern']))
s.add(pattern) s.add(pattern)
s.commit() s.commit()
return pattern.getId() return pattern.getId()
@ -34,7 +37,7 @@ class PatternController():
s.close() s.close()
def updatePattern(self, patternId, patternDescriptor): def updatePattern(self, patternId, patternObj):
try: try:
s = self.Session() s = self.Session()
@ -44,8 +47,8 @@ class PatternController():
pattern = q.first() pattern = q.first()
pattern.show_id = int(patternDescriptor['show_id']) pattern.show_id = int(patternObj['show_id'])
pattern.pattern = str(patternDescriptor['pattern']) pattern.pattern = str(patternObj['pattern'])
s.commit() s.commit()
return True return True
@ -60,11 +63,11 @@ class PatternController():
def findPattern(self, patternDescriptor): def findPattern(self, patternObj):
try: try:
s = self.Session() s = self.Session()
q = s.query(Pattern).filter(Pattern.show_id == int(patternDescriptor['show_id']), Pattern.pattern == str(patternDescriptor['pattern'])) q = s.query(Pattern).filter(Pattern.show_id == int(patternObj['show_id']), Pattern.pattern == str(patternObj['pattern']))
if q.count(): if q.count():
pattern = q.first() pattern = q.first()

@ -30,6 +30,8 @@ from ffx.file_properties import FileProperties
from ffx.iso_language import IsoLanguage from ffx.iso_language import IsoLanguage
from ffx.audio_layout import AudioLayout from ffx.audio_layout import AudioLayout
from ffx.helper import formatRichColor, removeRichColor
# Screen[dict[int, str, int]] # Screen[dict[int, str, int]]
class PatternDetailsScreen(Screen): class PatternDetailsScreen(Screen):
@ -103,6 +105,20 @@ class PatternDetailsScreen(Screen):
self.context = self.app.getContext() self.context = self.app.getContext()
self.Session = self.context['database']['session'] # convenience self.Session = self.context['database']['session'] # convenience
self.__configurationData = self.context['config'].getData()
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
self.__signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
self.__removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
self.__ignoreGlobalKeys = metadataConfiguration['ignore'] if 'ignore' in metadataConfiguration.keys() else []
self.__removeTrackKeys = (metadataConfiguration['streams']['remove']
if 'streams' in metadataConfiguration.keys()
and 'remove' in metadataConfiguration['streams'].keys() else [])
self.__ignoreTrackKeys = (metadataConfiguration['streams']['ignore']
if 'streams' in metadataConfiguration.keys()
and 'ignore' in metadataConfiguration['streams'].keys() else [])
self.__pc = PatternController(context = self.context) self.__pc = PatternController(context = self.context)
self.__sc = ShowController(context = self.context) self.__sc = ShowController(context = self.context)
self.__tc = TrackController(context = self.context) self.__tc = TrackController(context = self.context)
@ -218,7 +234,15 @@ class PatternDetailsScreen(Screen):
tags = self.__tac.findAllMediaTags(self.__pattern.getId()) tags = self.__tac.findAllMediaTags(self.__pattern.getId())
for tagKey, tagValue in tags.items(): for tagKey, tagValue in tags.items():
row = (tagKey, tagValue)
textColor = None
if tagKey in self.__ignoreGlobalKeys:
textColor = 'blue'
if tagKey in self.__removeGlobalKeys:
textColor = 'red'
# if tagKey not in self.__ignoreTrackKeys:
row = (formatRichColor(tagKey, textColor), formatRichColor(tagValue, textColor))
self.tagsTable.add_row(*map(str, row)) self.tagsTable.add_row(*map(str, row))
@ -383,8 +407,8 @@ class PatternDetailsScreen(Screen):
if row_key is not None: if row_key is not None:
selected_tag_data = self.tagsTable.get_row(row_key) selected_tag_data = self.tagsTable.get_row(row_key)
tagKey = str(selected_tag_data[0]) tagKey = removeRichColor(selected_tag_data[0])
tagValue = str(selected_tag_data[1]) tagValue = removeRichColor(selected_tag_data[1])
return tagKey, tagValue return tagKey, tagValue
@ -520,8 +544,10 @@ class PatternDetailsScreen(Screen):
self.tracksTable.update_cell(row_key, self.column_key_track_language, trackDescriptor.getLanguage().label()) self.tracksTable.update_cell(row_key, self.column_key_track_language, trackDescriptor.getLanguage().label())
self.tracksTable.update_cell(row_key, self.column_key_track_title, trackDescriptor.getTitle()) self.tracksTable.update_cell(row_key, self.column_key_track_title, trackDescriptor.getTitle())
self.tracksTable.update_cell(row_key, self.column_key_track_default, 'Yes' if TrackDisposition.DEFAULT in trackDescriptor.getDispositionSet() else 'No') self.tracksTable.update_cell(row_key, self.column_key_track_default,
self.tracksTable.update_cell(row_key, self.column_key_track_forced, 'Yes' if TrackDisposition.FORCED in trackDescriptor.getDispositionSet() else 'No') 'Yes' if TrackDisposition.DEFAULT in trackDescriptor.getDispositionSet() else 'No')
self.tracksTable.update_cell(row_key, self.column_key_track_forced,
'Yes' if TrackDisposition.FORCED in trackDescriptor.getDispositionSet() else 'No')
except CellDoesNotExist: except CellDoesNotExist:
pass pass
@ -547,3 +573,5 @@ class PatternDetailsScreen(Screen):
if self.__tac.deleteMediaTagByKey(self.__pattern.getId(), tag[0]): if self.__tac.deleteMediaTagByKey(self.__pattern.getId(), tag[0]):
self.updateTags() self.updateTags()
else:
raise click.ClickException('tag delete failed')

@ -444,7 +444,7 @@ class ShowDetailsScreen(Screen):
# Event handler for button press # Event handler for button press
def on_button_pressed(self, event: Button.Pressed) -> None: def on_button_pressed(self, event: Button.Pressed) -> None:
# Check if the button pressed is the one we are interested in
if event.button.id == "save_button": if event.button.id == "save_button":
showDescriptor = self.getShowDescriptorFromInput() showDescriptor = self.getShowDescriptorFromInput()

@ -19,6 +19,20 @@ class TrackController():
self.context = context self.context = context
self.Session = self.context['database']['session'] # convenience self.Session = self.context['database']['session'] # convenience
self.__configurationData = self.context['config'].getData()
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
self.__signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
self.__removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
self.__ignoreGlobalKeys = metadataConfiguration['ignore'] if 'ignore' in metadataConfiguration.keys() else []
self.__removeTrackKeys = (metadataConfiguration['streams']['remove']
if 'streams' in metadataConfiguration.keys()
and 'remove' in metadataConfiguration['streams'].keys() else [])
self.__ignoreTrackKeys = (metadataConfiguration['streams']['ignore']
if 'streams' in metadataConfiguration.keys()
and 'ignore' in metadataConfiguration['streams'].keys() else [])
def addTrack(self, trackDescriptor : TrackDescriptor, patternId = None): def addTrack(self, trackDescriptor : TrackDescriptor, patternId = None):
@ -40,6 +54,8 @@ class TrackController():
for k,v in trackDescriptor.getTags().items(): for k,v in trackDescriptor.getTags().items():
# Filter tags that make no sense to preserve
if k not in self.__ignoreTrackKeys and k not in self.__removeTrackKeys:
tag = TrackTag(track_id = track.id, tag = TrackTag(track_id = track.id,
key = k, key = k,
value = v) value = v)

@ -7,7 +7,7 @@ from .audio_layout import AudioLayout
from .track_disposition import TrackDisposition from .track_disposition import TrackDisposition
from .track_codec import TrackCodec from .track_codec import TrackCodec
from .helper import dictDiff, setDiff # from .helper import dictDiff, setDiff
class TrackDescriptor: class TrackDescriptor:
@ -321,24 +321,24 @@ class TrackDescriptor:
else: else:
self.__dispositionSet.discard(disposition) self.__dispositionSet.discard(disposition)
def compare(self, vsTrackDescriptor: Self): # def compare(self, vsTrackDescriptor: Self):
#
compareResult = {} # compareResult = {}
#
tagsDiffResult = dictDiff(vsTrackDescriptor.getTags(), self.getTags()) # tagsDiffResult = dictKeysDiff(vsTrackDescriptor.getTags(), self.getTags())
#
if tagsDiffResult: # if tagsDiffResult:
compareResult[TrackDescriptor.TAGS_KEY] = tagsDiffResult # compareResult[TrackDescriptor.TAGS_KEY] = tagsDiffResult
#
vsDispositions = vsTrackDescriptor.getDispositionSet() # vsDispositions = vsTrackDescriptor.getDispositionSet()
dispositions = self.getDispositionSet() # dispositions = self.getDispositionSet()
#
dispositionDiffResult = setDiff(vsDispositions, dispositions) # dispositionDiffResult = setDiff(vsDispositions, dispositions)
#
if dispositionDiffResult: # if dispositionDiffResult:
compareResult[TrackDescriptor.DISPOSITION_SET_KEY] = dispositionDiffResult # compareResult[TrackDescriptor.DISPOSITION_SET_KEY] = dispositionDiffResult
#
return compareResult # return compareResult
def setExternalSourceFilePath(self, filePath: str): def setExternalSourceFilePath(self, filePath: str):
self.__externalSourceFilePath = str(filePath) self.__externalSourceFilePath = str(filePath)

@ -24,6 +24,8 @@ from .tag_delete_screen import TagDeleteScreen
from textual.widgets._data_table import CellDoesNotExist from textual.widgets._data_table import CellDoesNotExist
from ffx.helper import formatRichColor, removeRichColor
# Screen[dict[int, str, int]] # Screen[dict[int, str, int]]
class TrackDetailsScreen(Screen): class TrackDetailsScreen(Screen):
@ -101,6 +103,21 @@ class TrackDetailsScreen(Screen):
self.context = self.app.getContext() self.context = self.app.getContext()
self.Session = self.context['database']['session'] # convenience self.Session = self.context['database']['session'] # convenience
self.__configurationData = self.context['config'].getData()
metadataConfiguration = self.__configurationData['metadata'] if 'metadata' in self.__configurationData.keys() else {}
self.__signatureTags = metadataConfiguration['signature'] if 'signature' in metadataConfiguration.keys() else {}
self.__removeGlobalKeys = metadataConfiguration['remove'] if 'remove' in metadataConfiguration.keys() else []
self.__ignoreGlobalKeys = metadataConfiguration['ignore'] if 'ignore' in metadataConfiguration.keys() else []
self.__removeTrackKeys = (metadataConfiguration['streams']['remove']
if 'streams' in metadataConfiguration.keys()
and 'remove' in metadataConfiguration['streams'].keys() else [])
self.__ignoreTrackKeys = (metadataConfiguration['streams']['ignore']
if 'streams' in metadataConfiguration.keys()
and 'ignore' in metadataConfiguration['streams'].keys() else [])
self.__tc = TrackController(context = self.context) self.__tc = TrackController(context = self.context)
self.__pc = PatternController(context = self.context) self.__pc = PatternController(context = self.context)
self.__tac = TagController(context = self.context) self.__tac = TagController(context = self.context)
@ -138,7 +155,14 @@ class TrackDetailsScreen(Screen):
for k,v in trackTags.items(): for k,v in trackTags.items():
if k != 'language' and k != 'title': if k != 'language' and k != 'title':
row = (k,v)
textColor = None
if k in self.__ignoreTrackKeys:
textColor = 'blue'
if k in self.__removeTrackKeys:
textColor = 'red'
row = (formatRichColor(k, textColor), formatRichColor(v, textColor))
self.trackTagsTable.add_row(*map(str, row)) self.trackTagsTable.add_row(*map(str, row))
@ -328,8 +352,8 @@ class TrackDetailsScreen(Screen):
if row_key is not None: if row_key is not None:
selected_tag_data = self.trackTagsTable.get_row(row_key) selected_tag_data = self.trackTagsTable.get_row(row_key)
tagKey = str(selected_tag_data[0]) tagKey = removeRichColor(selected_tag_data[0])
tagValue = str(selected_tag_data[1]) tagValue = removeRichColor(selected_tag_data[1])
return tagKey, tagValue return tagKey, tagValue

Loading…
Cancel
Save