nightl: bugfixes und media diff inc
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
from typing import List
|
||||
import click
|
||||
|
||||
from typing import List, Self
|
||||
|
||||
from ffx.track_type import TrackType
|
||||
from ffx.track_descriptor import TrackDescriptor
|
||||
|
||||
from ffx.helper import dictDiff
|
||||
|
||||
|
||||
class MediaDescriptor():
|
||||
"""This class represents the structural content of a media file including streams and metadata"""
|
||||
|
||||
@@ -84,6 +85,9 @@ class MediaDescriptor():
|
||||
def getAllTracks(self) -> List[TrackDescriptor]:
|
||||
return self.__trackDescriptors
|
||||
|
||||
def getVideoTracks(self) -> List[TrackDescriptor]:
|
||||
return [d for d in self.__trackDescriptors if d.getType() == TrackType.VIDEO]
|
||||
|
||||
def getAudioTracks(self) -> List[TrackDescriptor]:
|
||||
return [d for d in self.__trackDescriptors if d.getType() == TrackType.AUDIO]
|
||||
|
||||
@@ -92,7 +96,10 @@ class MediaDescriptor():
|
||||
|
||||
|
||||
|
||||
def compare(self, vsMediaDescriptor):
|
||||
def compare(self, vsMediaDescriptor : Self):
|
||||
|
||||
if not isinstance(vsMediaDescriptor, self.__class__):
|
||||
raise click.ClickException(f"MediaDescriptor.compare(): Argument is required to be of type {self.__class__}")
|
||||
|
||||
mediaTagsResult = dictDiff(vsMediaDescriptor.getTags(), self.getTags())
|
||||
|
||||
@@ -102,35 +109,43 @@ class MediaDescriptor():
|
||||
compareResult['tags'] = mediaTagsResult
|
||||
|
||||
|
||||
vsTracks = vsMediaDescriptor.getAllTracks()
|
||||
tracks = self.getAllTracks()
|
||||
|
||||
numVsTracks = len(vsTracks)
|
||||
# Target track configuration (from DB)
|
||||
tracks = [t for t in self.getAllTracks() if t.getType() != TrackType.VIDEO]
|
||||
numTracks = len(tracks)
|
||||
|
||||
# Current track configuration (of file)
|
||||
vsTracks = [t for t in vsMediaDescriptor.getAllTracks() if t.getType() != TrackType.VIDEO]
|
||||
numVsTracks = len(vsTracks)
|
||||
|
||||
maxNumOfTracks = max(numVsTracks, numTracks)
|
||||
|
||||
# raise click.ClickException(f"numTracks={numTracks} numVsTracks={numVsTracks}") # 1 4
|
||||
|
||||
trackCompareResult = {}
|
||||
|
||||
for trackIndex in range(maxNumOfTracks):
|
||||
for tp in range(maxNumOfTracks):
|
||||
|
||||
if trackIndex > numVsTracks - 1:
|
||||
# Will trigger if tracks are missing in file
|
||||
if tp > (numVsTracks - 1):
|
||||
if 'removed' not in trackCompareResult.keys():
|
||||
trackCompareResult['removed'] = set()
|
||||
trackCompareResult['removed'].add(trackIndex)
|
||||
trackCompareResult['removed'].add(tracks[tp].getIndex())
|
||||
continue
|
||||
|
||||
if trackIndex > numTracks - 1:
|
||||
# Will trigger if tracks are missing in DB definition
|
||||
if tp > (numTracks - 1):
|
||||
if 'added' not in trackCompareResult.keys():
|
||||
trackCompareResult['added'] = {}
|
||||
trackCompareResult['added'][trackIndex] = vsTracks[trackIndex]
|
||||
trackCompareResult['added'][vsTracks[tp].getIndex()] = vsTracks[tp]
|
||||
continue
|
||||
|
||||
trackResult = tracks[trackIndex].compare(vsTracks[trackIndex])
|
||||
if trackResult:
|
||||
# assumption is made here that the track order will not change for all files of a sequence
|
||||
tdiff = tracks[tp].compare(vsTracks[tp])
|
||||
|
||||
if tdiff:
|
||||
if 'changed' not in trackCompareResult.keys():
|
||||
trackCompareResult['changed'] = {}
|
||||
trackCompareResult['changed'][trackIndex] = trackResult
|
||||
trackCompareResult['changed'][vsTracks[tp].getIndex()] = tdiff
|
||||
|
||||
if trackCompareResult:
|
||||
compareResult['tracks'] = trackCompareResult
|
||||
|
||||
@@ -91,6 +91,14 @@ class MediaDetailsScreen(Screen):
|
||||
}*/
|
||||
"""
|
||||
|
||||
|
||||
BINDINGS = [
|
||||
("n", "new_pattern", "New Pattern"),
|
||||
("u", "update_pattern", "Update Pattern"),
|
||||
("e", "edit_pattern", "Update Pattern"),
|
||||
]
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@@ -119,8 +127,6 @@ class MediaDetailsScreen(Screen):
|
||||
|
||||
self.__storedMediaFilenamePattern = self.__mediaFilenamePattern.getMediaDescriptor() if self.__mediaFilenamePattern is not None else None
|
||||
|
||||
# raise click.ClickException(f"diff {self.__mediaDescriptor.compare(self.__storedMediaFilenamePattern)}")
|
||||
|
||||
|
||||
# def loadTracks(self, show_id):
|
||||
#
|
||||
@@ -202,6 +208,7 @@ class MediaDetailsScreen(Screen):
|
||||
|
||||
def on_mount(self):
|
||||
|
||||
if self.__mediaFilenamePattern is None:
|
||||
row = (' ', '<New show>', ' ') # Convert each element to a string before adding
|
||||
self.showsTable.add_row(*map(str, row))
|
||||
|
||||
@@ -226,31 +233,61 @@ class MediaDetailsScreen(Screen):
|
||||
|
||||
self.query_one("#pattern_input", Input).value = self.__mediaFilenamePattern.getPattern()
|
||||
|
||||
mediaDifferences = self.__mediaDescriptor.compare(self.__mediaFilenamePattern.getMediaDescriptor())
|
||||
# Enumerating differences between media descriptor from file vs from stored in database
|
||||
targetMediaDescriptor = self.__mediaFilenamePattern.getMediaDescriptor()
|
||||
mediaDifferences = targetMediaDescriptor.compare(self.__mediaDescriptor)
|
||||
|
||||
if 'tags' in mediaDifferences.keys():
|
||||
|
||||
mediaTags = self.__mediaDescriptor.getTags()
|
||||
|
||||
if 'added' in mediaDifferences['tags'].keys():
|
||||
|
||||
for addedTagKey in mediaDifferences['tags']['added']:
|
||||
|
||||
row = (f"added media tag: key='{addedTagKey}' value='{mediaTags[addedTagKey]}'",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
if 'removed' in mediaDifferences['tags'].keys():
|
||||
for removedTagKey in mediaDifferences['tags']['removed']:
|
||||
row = (f"removed media tag: key='{removedTagKey}' value='{mediaTags[removedTagKey]}'",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
if 'tracks' in mediaDifferences.keys():
|
||||
|
||||
tracks = self.__mediaDescriptor.getAllTracks()
|
||||
currentTracks = self.__mediaDescriptor.getAllTracks() # 0,1,2,3
|
||||
targetTracks = targetMediaDescriptor.getAllTracks() # 0 <- from DB
|
||||
|
||||
if 'added' in mediaDifferences['tracks'].keys():
|
||||
for addedTrackIndex in mediaDifferences['tracks']['added'].keys():
|
||||
addedTrack : Track = currentTracks[addedTrackIndex]
|
||||
row = (f"added {addedTrack.getType().label()} track: index={addedTrackIndex} subIndex={addedTrack.getSubIndex()} lang={addedTrack.getLanguage().threeLetter()}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
if 'removed' in mediaDifferences['tracks'].keys():
|
||||
|
||||
for removedTrackIndex in mediaDifferences['tracks']['removed']:
|
||||
|
||||
removedTrack : Track = tracks[removedTrackIndex]
|
||||
|
||||
row = (f"removed {removedTrack.getType().label()} track: index={removedTrackIndex} subIndex={removedTrack.getSubIndex()} lang={removedTrack.getLanguage().threeLetter()}",)
|
||||
row = (f"removed track: index={removedTrackIndex}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
if 'changed' in mediaDifferences['tracks'].keys():
|
||||
for changedTrackIndex in mediaDifferences['tracks']['changed'].keys():
|
||||
|
||||
changedTrack : Track = targetTracks[changedTrackIndex]
|
||||
changedTrackDiff : dict = mediaDifferences['tracks']['changed'][changedTrackIndex]
|
||||
|
||||
if 'tags' in changedTrackDiff.keys():
|
||||
|
||||
if 'added' in changedTrackDiff['tags']:
|
||||
for addedTagKey in changedTrackDiff['tags']['added']:
|
||||
|
||||
addedTagValue = changedTrack.getTags()[addedTagKey]
|
||||
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} added key={addedTagKey} value={addedTagValue}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
if 'removed' in changedTrackDiff['tags']:
|
||||
for removedTagKey in changedTrackDiff['tags']['removed']:
|
||||
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} removed key={removedTagKey}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
else:
|
||||
|
||||
self.query_one("#pattern_input", Input).value = self.__mediaFilename
|
||||
|
||||
@@ -55,13 +55,6 @@ class Pattern(Base):
|
||||
|
||||
kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY] = []
|
||||
|
||||
# for track in self.tracks:
|
||||
#
|
||||
# if track.getType() not in kwargs[MediaDescriptor.TRACK_DESCRIPTORS_KEY].keys():
|
||||
# kwargs[MediaDescriptor.TRACK_DESCRIPTORS_KEY][track.getType().label()] = []
|
||||
#
|
||||
# kwargs[MediaDescriptor.TRACK_DESCRIPTORS_KEY][track.getType().label()].append(track.getDescriptor())
|
||||
|
||||
for track in self.tracks:
|
||||
kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY].append(track.getDescriptor())
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ class Track(Base):
|
||||
kwargs[TrackDescriptor.ID_KEY] = self.getId()
|
||||
kwargs[TrackDescriptor.PATTERN_ID_KEY] = self.getPatternId()
|
||||
|
||||
kwargs[TrackDescriptor.SUB_INDEX_KEY] = self.getIndex()
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = self.getIndex()
|
||||
kwargs[TrackDescriptor.SUB_INDEX_KEY] = self.getSubIndex()
|
||||
|
||||
kwargs[TrackDescriptor.TRACK_TYPE_KEY] = self.getType()
|
||||
|
||||
@@ -23,9 +23,9 @@ class PatternController():
|
||||
pattern = str(patternDescriptor['pattern']))
|
||||
s.add(pattern)
|
||||
s.commit()
|
||||
return patternDescriptor
|
||||
return pattern.getId()
|
||||
else:
|
||||
return {}
|
||||
return None
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"PatternController.addPattern(): {repr(ex)}")
|
||||
|
||||
@@ -85,6 +85,7 @@ class PatternDetailsScreen(Screen):
|
||||
self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {}
|
||||
|
||||
|
||||
#TODO: per controller
|
||||
def loadTracks(self, show_id):
|
||||
|
||||
try:
|
||||
@@ -323,7 +324,17 @@ class PatternDetailsScreen(Screen):
|
||||
self.app.pop_screen()
|
||||
|
||||
else:
|
||||
if self.__pc.addPattern(patternDescriptor):
|
||||
patternId = self.__pc.addPattern(patternDescriptor)
|
||||
if patternId is not None:
|
||||
|
||||
# Add dummy video track
|
||||
kwargs = {}
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = 0
|
||||
kwargs[TrackDescriptor.SUB_INDEX_KEY] = 0
|
||||
kwargs[TrackDescriptor.PATTERN_ID_KEY] = patternId
|
||||
kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.VIDEO
|
||||
self.__tc.addTrack(TrackDescriptor(**kwargs))
|
||||
|
||||
self.dismiss(patternDescriptor)
|
||||
else:
|
||||
#TODO: Meldung
|
||||
@@ -338,8 +349,16 @@ class PatternDetailsScreen(Screen):
|
||||
# Save pattern when just created before adding streams
|
||||
if self.__pattern is not None:
|
||||
|
||||
numVideoStreams = len(self.__pattern.getMediaDescriptor().getVideoTracks())
|
||||
numAudioStreams = len(self.audioStreamsTable.rows)
|
||||
numSubtitleStreams = len(self.subtitleStreamsTable.rows)
|
||||
|
||||
addedTrackIndex = numVideoStreams + numAudioStreams + numSubtitleStreams
|
||||
|
||||
#NOTE: Track index
|
||||
|
||||
if event.button.id == "button_add_audio_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.AUDIO, patternId = self.__pattern.getId(), subIndex = len(self.audioStreamsTable.rows)), self.handle_add_track)
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.AUDIO, patternId = self.__pattern.getId(), index = addedTrackIndex, subIndex = numAudioStreams), self.handle_add_track)
|
||||
|
||||
selectedAudioTrack = self.getSelectedAudioTrackDescriptor()
|
||||
if selectedAudioTrack is not None:
|
||||
@@ -350,7 +369,7 @@ class PatternDetailsScreen(Screen):
|
||||
self.app.push_screen(TrackDeleteScreen(trackDescriptor = selectedAudioTrack), self.handle_delete_track)
|
||||
|
||||
if event.button.id == "button_add_subtitle_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.SUBTITLE, patternId = self.__pattern.getId(), subIndex = len(self.subtitleStreamsTable.rows)), self.handle_add_track)
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.SUBTITLE, patternId = self.__pattern.getId(), index = addedTrackIndex, subIndex = numSubtitleStreams), self.handle_add_track)
|
||||
|
||||
selectedSubtitleTrack = self.getSelectedSubtitleTrackDescriptor()
|
||||
if selectedSubtitleTrack is not None:
|
||||
|
||||
@@ -132,6 +132,8 @@ class ShowsScreen(Screen):
|
||||
|
||||
|
||||
def on_mount(self) -> None:
|
||||
allShows = self.__sc.getAllShows()
|
||||
if allShows is not None:
|
||||
for show in self.__sc.getAllShows():
|
||||
row = (int(show.id), show.name, show.year) # Convert each element to a string before adding
|
||||
self.table.add_row(*map(str, row))
|
||||
|
||||
@@ -27,6 +27,7 @@ class TrackController():
|
||||
s = self.Session()
|
||||
track = Track(pattern_id = int(trackDescriptor.getPatternId()),
|
||||
track_type = int(trackDescriptor.getType().index()),
|
||||
index = int(trackDescriptor.getIndex()),
|
||||
sub_index = int(trackDescriptor.getSubIndex()),
|
||||
disposition_flags = int(TrackDisposition.toFlags(trackDescriptor.getDispositionSet())))
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class TrackDescriptor():
|
||||
|
||||
kwargs = {}
|
||||
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = streamObj[TrackDescriptor.FFPROBE_INDEX_KEY] if TrackDescriptor.FFPROBE_INDEX_KEY in streamObj.keys() else -1
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = int(streamObj[TrackDescriptor.FFPROBE_INDEX_KEY]) if TrackDescriptor.FFPROBE_INDEX_KEY in streamObj.keys() else -1
|
||||
kwargs[TrackDescriptor.SUB_INDEX_KEY] = subIndex
|
||||
|
||||
kwargs[TrackDescriptor.TRACK_TYPE_KEY] = trackType
|
||||
@@ -205,3 +205,5 @@ class TrackDescriptor():
|
||||
|
||||
if dispositionDiffResult:
|
||||
compareResult['dispositions'] = dispositionDiffResult
|
||||
|
||||
return compareResult
|
||||
@@ -81,7 +81,7 @@ class TrackDetailsScreen(Screen):
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, trackDescriptor = None, patternId = None, trackType : TrackType = None, subIndex = None):
|
||||
def __init__(self, trackDescriptor : TrackDescriptor = None, patternId = None, trackType : TrackType = None, index = None, subIndex = None):
|
||||
super().__init__()
|
||||
|
||||
self.context = self.app.getContext()
|
||||
@@ -94,11 +94,13 @@ class TrackDetailsScreen(Screen):
|
||||
self.__isNew = trackDescriptor is None
|
||||
if self.__isNew:
|
||||
self.__trackType = trackType
|
||||
self.__index = index
|
||||
self.__subIndex = subIndex
|
||||
self.__trackDescriptor : TrackDescriptor = None
|
||||
self.__pattern : Pattern = self.__pc.getPattern(patternId) if patternId is not None else {}
|
||||
else:
|
||||
self.__trackType = trackDescriptor.getType()
|
||||
self.__index = trackDescriptor.getIndex()
|
||||
self.__subIndex = trackDescriptor.getSubIndex()
|
||||
self.__trackDescriptor : TrackDescriptor = trackDescriptor
|
||||
self.__pattern : Pattern = self.__pc.getPattern(self.__trackDescriptor.getPatternId())
|
||||
@@ -240,7 +242,7 @@ class TrackDetailsScreen(Screen):
|
||||
|
||||
kwargs[TrackDescriptor.PATTERN_ID_KEY] = int(self.__pattern.getId())
|
||||
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = -1
|
||||
kwargs[TrackDescriptor.INDEX_KEY] = self.__index
|
||||
kwargs[TrackDescriptor.SUB_INDEX_KEY] = self.__subIndex
|
||||
|
||||
kwargs[TrackDescriptor.TRACK_TYPE_KEY] = self.__trackType
|
||||
|
||||
Reference in New Issue
Block a user