media/track comparison inc
This commit is contained in:
6
bin/dd.py
Normal file
6
bin/dd.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from ffx.helper import dictDiff
|
||||
|
||||
a = {'name': 'yolo', 'mass': 56}
|
||||
b = {'name': 'zolo', 'mass': 58}
|
||||
|
||||
print(dictDiff(a, b))
|
||||
35
bin/ffx.py
35
bin/ffx.py
@@ -6,9 +6,6 @@ from ffx.ffx_app import FfxApp
|
||||
|
||||
from ffx.database import databaseContext
|
||||
|
||||
from ffx.media_descriptor import MediaDescriptor
|
||||
from ffx.file_properties import FileProperties
|
||||
|
||||
|
||||
VERSION='0.1.0'
|
||||
|
||||
@@ -251,32 +248,12 @@ def help():
|
||||
@click.argument('filename', nargs=1)
|
||||
def inspect(ctx, filename):
|
||||
|
||||
fp = FileProperties(ctx.obj, filename)
|
||||
md = fp.getMediaDescriptor()
|
||||
ctx.obj['command'] = 'inspect'
|
||||
ctx.obj['arguments'] = {}
|
||||
ctx.obj['arguments']['filename'] = filename
|
||||
|
||||
click.echo('\nFile properties:\n')
|
||||
|
||||
click.echo(md.getTags())
|
||||
|
||||
for at in md.getAudioTracks():
|
||||
click.echo(f"Audio: {at.getLanguage()} {'|'.join([f"{k}={v}" for (k,v) in at.getTags().items()])}")
|
||||
|
||||
for st in md.getSubtitleTracks():
|
||||
click.echo(f"Subtitle: {st.getLanguage()} {'|'.join([f"{k}={v}" for (k,v) in st.getTags().items()])}")
|
||||
|
||||
|
||||
click.echo('\nRecognized pattern:\n')
|
||||
|
||||
click.echo(f"Show Id: {fp.getShowId()}")
|
||||
|
||||
pattern = fp.getPattern()
|
||||
click.echo(f"Pattern: {pattern} id={pattern.id} show={pattern.show.name} year={pattern.show.year}")
|
||||
|
||||
db_md = pattern.getMediaDescriptor()
|
||||
click.echo(f"md from db: {db_md} tags={'|'.join([f"{k}={v}" for (k,v) in db_md.getTags().items()])} a_tracks={db_md.getAudioTracks()} s_tracks={db_md.getSubtitleTracks()}")
|
||||
|
||||
atrack0 = db_md.getAudioTracks()[0]
|
||||
click.echo(f"a track0: lang={atrack0.getLanguage()} title={atrack0.getTitle()}")
|
||||
app = FfxApp(ctx.obj)
|
||||
app.run()
|
||||
|
||||
|
||||
|
||||
@@ -333,6 +310,8 @@ def shows(ctx):
|
||||
|
||||
# if 'database' not in ctx.obj.keys():
|
||||
# ctx.obj['database'] = databaseContext()
|
||||
|
||||
ctx.obj['command'] = 'shows'
|
||||
|
||||
app = FfxApp(ctx.obj)
|
||||
app.run()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from textual.app import App
|
||||
|
||||
from .shows_screen import ShowsScreen
|
||||
from .media_details_screen import MediaDetailsScreen
|
||||
|
||||
|
||||
class FfxApp(App):
|
||||
@@ -21,9 +22,17 @@ class FfxApp(App):
|
||||
|
||||
|
||||
def on_mount(self) -> None:
|
||||
self.push_screen(ShowsScreen())
|
||||
|
||||
if 'command' in self.context.keys():
|
||||
|
||||
if self.context['command'] == 'shows':
|
||||
self.push_screen(ShowsScreen())
|
||||
|
||||
if self.context['command'] == 'inspect':
|
||||
self.push_screen(MediaDetailsScreen())
|
||||
|
||||
|
||||
def getContext(self):
|
||||
"""Data 'output' method"""
|
||||
return self.context
|
||||
|
||||
|
||||
36
bin/ffx/helper.py
Normal file
36
bin/ffx/helper.py
Normal file
@@ -0,0 +1,36 @@
|
||||
def dictDiff(a : dict, b : dict):
|
||||
|
||||
a_keys = set(a.keys())
|
||||
b_keys = set(b.keys())
|
||||
|
||||
a_only = a_keys - b_keys
|
||||
b_only = b_keys - a_keys
|
||||
a_b = a_keys & b_keys
|
||||
|
||||
changed = {k for k in a_b if a[k] != b[k]}
|
||||
|
||||
diffResult = {}
|
||||
|
||||
if a_only:
|
||||
diffResult['removed'] = a_only
|
||||
if b_only:
|
||||
diffResult['added'] = b_only
|
||||
if changed:
|
||||
diffResult['changed'] = changed
|
||||
|
||||
return diffResult
|
||||
|
||||
|
||||
def setDiff(a : set, b : set) -> set:
|
||||
|
||||
a_only = a - b
|
||||
b_only = b - a
|
||||
|
||||
diffResult = {}
|
||||
|
||||
if a_only:
|
||||
diffResult['removed'] = a_only
|
||||
if b_only:
|
||||
diffResult['added'] = b_only
|
||||
|
||||
return diffResult
|
||||
@@ -3,6 +3,8 @@ from typing import List
|
||||
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"""
|
||||
@@ -49,8 +51,6 @@ class MediaDescriptor():
|
||||
@classmethod
|
||||
def fromFfprobe(cls, formatData, streamData):
|
||||
|
||||
#trackDescriptors = {}
|
||||
|
||||
kwargs = {}
|
||||
|
||||
if MediaDescriptor.FFPROBE_TAGS_KEY in formatData.keys():
|
||||
@@ -59,22 +59,9 @@ class MediaDescriptor():
|
||||
kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY] = []
|
||||
|
||||
for streamObj in streamData:
|
||||
|
||||
#trackType = TrackType.fromLabel(streamObj[MediaDescriptor.FFPROBE_CODEC_TYPE_KEY])
|
||||
|
||||
# if trackType != TrackType.UNKNOWN:
|
||||
#
|
||||
# if trackType.label() not in trackDescriptors.keys():
|
||||
# trackDescriptors[trackType.label()] = []
|
||||
#
|
||||
# trackDescriptors[trackType.label()].append(TrackDescriptor.fromFfprobe(streamObj))
|
||||
|
||||
if TrackType.fromLabel(streamObj[MediaDescriptor.FFPROBE_CODEC_TYPE_KEY]) != TrackType.UNKNOWN:
|
||||
kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY].append(TrackDescriptor.fromFfprobe(streamObj))
|
||||
|
||||
|
||||
# kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY] = trackDescriptors
|
||||
|
||||
return cls(**kwargs)
|
||||
|
||||
|
||||
@@ -82,10 +69,58 @@ class MediaDescriptor():
|
||||
return self.__mediaTags
|
||||
|
||||
|
||||
def getAllTracks(self) -> List[TrackDescriptor]:
|
||||
return self.__trackDescriptors
|
||||
|
||||
def getAudioTracks(self) -> List[TrackDescriptor]:
|
||||
#return self.__trackDescriptors[TrackType.AUDIO.label()] if TrackType.AUDIO.label() in self.__trackDescriptors.keys() else []
|
||||
return [d for d in self.__trackDescriptors if d.getType() == TrackType.AUDIO]
|
||||
|
||||
def getSubtitleTracks(self) -> List[TrackDescriptor]:
|
||||
#return self.__trackDescriptors[TrackType.SUBTITLE.label()] if TrackType.SUBTITLE.label() in self.__trackDescriptors.keys() else []
|
||||
return [d for d in self.__trackDescriptors if d.getType() == TrackType.SUBTITLE]
|
||||
|
||||
|
||||
|
||||
def compare(self, vsMediaDescriptor):
|
||||
|
||||
mediaTagsResult = dictDiff(vsMediaDescriptor.getTags(), self.getTags())
|
||||
|
||||
compareResult = {}
|
||||
|
||||
if mediaTagsResult:
|
||||
compareResult['tags'] = mediaTagsResult
|
||||
|
||||
|
||||
vsTracks = vsMediaDescriptor.getAllTracks()
|
||||
tracks = self.getAllTracks()
|
||||
|
||||
numVsTracks = len(vsTracks)
|
||||
numTracks = len(tracks)
|
||||
maxNumOfTracks = max(numVsTracks, numTracks)
|
||||
|
||||
|
||||
trackCompareResult = {}
|
||||
|
||||
for trackIndex in range(maxNumOfTracks):
|
||||
|
||||
if trackIndex > numVsTracks - 1:
|
||||
if 'removed' not in trackCompareResult.keys():
|
||||
trackCompareResult['removed'] = set()
|
||||
trackCompareResult['removed'].add(trackIndex)
|
||||
continue
|
||||
|
||||
if trackIndex > numTracks - 1:
|
||||
if 'added' not in trackCompareResult.keys():
|
||||
trackCompareResult['added'] = {}
|
||||
trackCompareResult['added'][trackIndex] = vsTracks[trackIndex]
|
||||
continue
|
||||
|
||||
trackResult = tracks[trackIndex].compare(vsTracks[trackIndex])
|
||||
if trackResult:
|
||||
if 'changed' not in trackCompareResult.keys():
|
||||
trackCompareResult['changed'] = {}
|
||||
trackCompareResult['changed'][trackIndex] = trackResult
|
||||
|
||||
if trackCompareResult:
|
||||
compareResult['tracks'] = trackCompareResult
|
||||
|
||||
return compareResult
|
||||
|
||||
456
bin/ffx/media_details_screen.py
Normal file
456
bin/ffx/media_details_screen.py
Normal file
@@ -0,0 +1,456 @@
|
||||
import os, click, re
|
||||
|
||||
from textual import events
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Static, Button, Input, DataTable
|
||||
from textual.containers import Grid
|
||||
|
||||
from ffx.model.show import Show
|
||||
from ffx.model.pattern import Pattern
|
||||
|
||||
from .pattern_controller import PatternController
|
||||
from .show_controller import ShowController
|
||||
from .track_controller import TrackController
|
||||
|
||||
from .track_details_screen import TrackDetailsScreen
|
||||
from .track_delete_screen import TrackDeleteScreen
|
||||
|
||||
from ffx.track_type import TrackType
|
||||
|
||||
from ffx.track_disposition import TrackDisposition
|
||||
from ffx.track_descriptor import TrackDescriptor
|
||||
|
||||
from textual.widgets._data_table import CellDoesNotExist
|
||||
|
||||
from ffx.media_descriptor import MediaDescriptor
|
||||
from ffx.file_properties import FileProperties
|
||||
|
||||
|
||||
# Screen[dict[int, str, int]]
|
||||
class MediaDetailsScreen(Screen):
|
||||
|
||||
CSS = """
|
||||
|
||||
Grid {
|
||||
grid-size: 5 12;
|
||||
grid-rows: 2 2 2 2 2 6 2 2 6 2 2 2;
|
||||
grid-columns: 25 25 25 25 25;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 1;
|
||||
}
|
||||
|
||||
Input {
|
||||
border: none;
|
||||
}
|
||||
Button {
|
||||
border: none;
|
||||
}
|
||||
|
||||
DataTable {
|
||||
min-height: 6;
|
||||
}
|
||||
|
||||
#toplabel {
|
||||
height: 1;
|
||||
}
|
||||
|
||||
.three {
|
||||
column-span: 3;
|
||||
}
|
||||
|
||||
.four {
|
||||
column-span: 4;
|
||||
}
|
||||
.five {
|
||||
column-span: 5;
|
||||
}
|
||||
|
||||
.box {
|
||||
height: 100%;
|
||||
border: solid green;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, patternId = None, showId = None):
|
||||
super().__init__()
|
||||
|
||||
self.context = self.app.getContext()
|
||||
self.Session = self.context['database']['session'] # convenience
|
||||
|
||||
if not 'command' in self.context.keys() or self.context['command'] != 'inspect':
|
||||
raise click.ClickException(f"MediaDetailsScreen.__init__(): Can only perform command 'inspect'")
|
||||
|
||||
if not 'arguments' in self.context.keys() or not 'filename' in self.context['arguments'].keys() or not self.context['arguments']['filename']:
|
||||
raise click.ClickException(f"MediaDetailsScreen.__init__(): Argument 'filename' is required to be provided for command 'inspect'")
|
||||
|
||||
self.__mediaFilename = self.context['arguments']['filename']
|
||||
|
||||
if not os.path.isfile(self.__mediaFilename):
|
||||
raise click.ClickException(f"MediaDetailsScreen.__init__(): Media file {self.__mediaFilename} does not exist")
|
||||
|
||||
self.__mediaFileProperties = FileProperties(self.context, self.__mediaFilename)
|
||||
self.__mediaDescriptor = self.__mediaFileProperties.getMediaDescriptor()
|
||||
|
||||
self.__mediaFilenamePattern = self.__mediaFileProperties.getPattern()
|
||||
self.__storedMediaFilenamePattern = self.__mediaFilenamePattern.getMediaDescriptor()
|
||||
|
||||
raise click.ClickException(f"diff {self.__mediaDescriptor.compare(self.__storedMediaFilenamePattern)}")
|
||||
|
||||
# def loadTracks(self, show_id):
|
||||
#
|
||||
# try:
|
||||
#
|
||||
# tracks = {}
|
||||
# tracks['audio'] = {}
|
||||
# tracks['subtitle'] = {}
|
||||
#
|
||||
# s = self.Session()
|
||||
# q = s.query(Pattern).filter(Pattern.show_id == int(show_id))
|
||||
#
|
||||
# return [{'id': int(p.id), 'pattern': p.pattern} for p in q.all()]
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"loadTracks(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
#
|
||||
#
|
||||
# def updateAudioTracks(self):
|
||||
#
|
||||
# self.audioStreamsTable.clear()
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
#
|
||||
# audioTracks = self.__tc.findAudioTracks(self.__pattern.getId())
|
||||
#
|
||||
# for at in audioTracks:
|
||||
#
|
||||
# dispoSet = at.getDispositionSet()
|
||||
#
|
||||
# row = (at.getSubIndex(),
|
||||
# " ",
|
||||
# at.getLanguage().label(),
|
||||
# at.getTitle(),
|
||||
# 'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No',
|
||||
# 'Yes' if TrackDisposition.FORCED in dispoSet else 'No')
|
||||
#
|
||||
# self.audioStreamsTable.add_row(*map(str, row))
|
||||
#
|
||||
# def updateSubtitleTracks(self):
|
||||
#
|
||||
# self.subtitleStreamsTable.clear()
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
#
|
||||
# subtitleTracks = self.__tc.findSubtitleTracks(self.__pattern.getId())
|
||||
#
|
||||
# for st in subtitleTracks:
|
||||
#
|
||||
# dispoSet = st.getDispositionSet()
|
||||
#
|
||||
# row = (st.getSubIndex(),
|
||||
# " ",
|
||||
# st.getLanguage().label(),
|
||||
# st.getTitle(),
|
||||
# 'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No',
|
||||
# 'Yes' if TrackDisposition.FORCED in dispoSet else 'No')
|
||||
#
|
||||
# self.subtitleStreamsTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
pass
|
||||
|
||||
# if self.show_obj:
|
||||
# self.query_one("#showlabel", Static).update(f"{self.show_obj['id']} - {self.show_obj['name']} ({self.show_obj['year']})")
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
#
|
||||
# self.query_one("#pattern_input", Input).value = str(self.__pattern.getPattern())
|
||||
#
|
||||
# self.updateAudioTracks()
|
||||
# self.updateSubtitleTracks()
|
||||
|
||||
|
||||
def compose(self):
|
||||
|
||||
# self.audioStreamsTable = DataTable(classes="five")
|
||||
#
|
||||
# # Define the columns with headers
|
||||
# self.column_key_audio_subid = self.audioStreamsTable.add_column("Subindex", width=20)
|
||||
# self.column_key_audio_layout = self.audioStreamsTable.add_column("Layout", width=20)
|
||||
# self.column_key_audio_language = self.audioStreamsTable.add_column("Language", width=20)
|
||||
# self.column_key_audio_title = self.audioStreamsTable.add_column("Title", width=30)
|
||||
# self.column_key_audio_default = self.audioStreamsTable.add_column("Default", width=10)
|
||||
# self.column_key_audio_forced = self.audioStreamsTable.add_column("Forced", width=10)
|
||||
#
|
||||
# self.audioStreamsTable.cursor_type = 'row'
|
||||
#
|
||||
#
|
||||
# self.subtitleStreamsTable = DataTable(classes="five")
|
||||
#
|
||||
# # Define the columns with headers
|
||||
# self.column_key_subtitle_subid = self.subtitleStreamsTable.add_column("Subindex", width=20)
|
||||
# self.column_key_subtitle_spacer = self.subtitleStreamsTable.add_column(" ", width=20)
|
||||
# self.column_key_subtitle_language = self.subtitleStreamsTable.add_column("Language", width=20)
|
||||
# self.column_key_subtitle_title = self.subtitleStreamsTable.add_column("Title", width=30)
|
||||
# self.column_key_subtitle_default = self.subtitleStreamsTable.add_column("Default", width=10)
|
||||
# self.column_key_subtitle_forced = self.subtitleStreamsTable.add_column("Forced", width=10)
|
||||
#
|
||||
# self.subtitleStreamsTable.cursor_type = 'row'
|
||||
|
||||
|
||||
yield Header()
|
||||
|
||||
# with Grid():
|
||||
|
||||
# 1
|
||||
# yield Static("Edit filename pattern" if self.__pattern is not None else "New filename pattern", id="toplabel")
|
||||
# yield Input(type="text", id="pattern_input", classes="four")
|
||||
#
|
||||
# # 2
|
||||
# yield Static("from show")
|
||||
# yield Static("", id="showlabel", classes="three")
|
||||
# yield Button("Substitute pattern", id="patternbutton")
|
||||
#
|
||||
# # 3
|
||||
# yield Static(" ", classes="five")
|
||||
# # 4
|
||||
# yield Static(" ", classes="five")
|
||||
#
|
||||
# # 5
|
||||
# yield Static("Audio streams")
|
||||
# yield Static(" ")
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
# yield Button("Add", id="button_add_audio_stream")
|
||||
# yield Button("Edit", id="button_edit_audio_stream")
|
||||
# yield Button("Delete", id="button_delete_audio_stream")
|
||||
# else:
|
||||
# yield Static("")
|
||||
# yield Static("")
|
||||
# yield Static("")
|
||||
# # 6
|
||||
# yield self.audioStreamsTable
|
||||
#
|
||||
# # 7
|
||||
# yield Static(" ", classes="five")
|
||||
#
|
||||
# # 8
|
||||
# yield Static("Subtitle streams")
|
||||
# yield Static(" ")
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
# yield Button("Add", id="button_add_subtitle_stream")
|
||||
# yield Button("Edit", id="button_edit_subtitle_stream")
|
||||
# yield Button("Delete", id="button_delete_subtitle_stream")
|
||||
# else:
|
||||
# yield Static("")
|
||||
# yield Static("")
|
||||
# yield Static("")
|
||||
# # 9
|
||||
# yield self.subtitleStreamsTable
|
||||
#
|
||||
# # 10
|
||||
# yield Static(" ", classes="five")
|
||||
#
|
||||
# # 11
|
||||
# yield Button("Save", id="save_button")
|
||||
# yield Button("Cancel", id="cancel_button")
|
||||
|
||||
yield Footer()
|
||||
|
||||
|
||||
# def getPatternFromInput(self):
|
||||
# return str(self.query_one("#pattern_input", Input).value)
|
||||
|
||||
|
||||
|
||||
# def getSelectedAudioTrackDescriptor(self):
|
||||
#
|
||||
# if not self.__pattern:
|
||||
# return None
|
||||
#
|
||||
# try:
|
||||
#
|
||||
# # Fetch the currently selected row when 'Enter' is pressed
|
||||
# #selected_row_index = self.table.cursor_row
|
||||
# row_key, col_key = self.audioStreamsTable.coordinate_to_cell_key(self.audioStreamsTable.cursor_coordinate)
|
||||
#
|
||||
# if row_key is not None:
|
||||
# selected_track_data = self.audioStreamsTable.get_row(row_key)
|
||||
#
|
||||
# subIndex = int(selected_track_data[0])
|
||||
#
|
||||
# return self.__tc.findTrack(self.__pattern.getId(), TrackType.AUDIO, subIndex).getDescriptor()
|
||||
#
|
||||
# else:
|
||||
# return None
|
||||
#
|
||||
# except CellDoesNotExist:
|
||||
# return None
|
||||
#
|
||||
|
||||
# def getSelectedSubtitleTrackDescriptor(self) -> TrackDescriptor:
|
||||
#
|
||||
# if not self.__pattern is None:
|
||||
# return None
|
||||
#
|
||||
# try:
|
||||
#
|
||||
# # Fetch the currently selected row when 'Enter' is pressed
|
||||
# #selected_row_index = self.table.cursor_row
|
||||
# row_key, col_key = self.subtitleStreamsTable.coordinate_to_cell_key(self.subtitleStreamsTable.cursor_coordinate)
|
||||
#
|
||||
# if row_key is not None:
|
||||
#
|
||||
# selected_track_data = self.subtitleStreamsTable.get_row(row_key)
|
||||
# subIndex = int(selected_track_data[0])
|
||||
#
|
||||
# return self.__tc.findTrack(self.__pattern.getId(), TrackType.SUBTITLE, subIndex).getDescriptor()
|
||||
#
|
||||
# else:
|
||||
# return None
|
||||
#
|
||||
# except CellDoesNotExist:
|
||||
# return None
|
||||
|
||||
|
||||
|
||||
# Event handler for button press
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
pass
|
||||
|
||||
# # Check if the button pressed is the one we are interested in
|
||||
# if event.button.id == "save_button":
|
||||
#
|
||||
# patternDescriptor = {}
|
||||
# patternDescriptor['show_id'] = self.show_obj['id']
|
||||
# patternDescriptor['pattern'] = self.getPatternFromInput()
|
||||
#
|
||||
# if self.__pattern is not None:
|
||||
#
|
||||
# if self.__pc.updatePattern(self.__pattern.getId(), patternDescriptor):
|
||||
# self.dismiss(patternDescriptor)
|
||||
# else:
|
||||
# #TODO: Meldung
|
||||
# self.app.pop_screen()
|
||||
#
|
||||
# else:
|
||||
# if self.__pc.addPattern(patternDescriptor):
|
||||
# self.dismiss(patternDescriptor)
|
||||
# else:
|
||||
# #TODO: Meldung
|
||||
# self.app.pop_screen()
|
||||
#
|
||||
#
|
||||
#
|
||||
# if event.button.id == "cancel_button":
|
||||
# self.app.pop_screen()
|
||||
#
|
||||
#
|
||||
# # Save pattern when just created before adding streams
|
||||
# if self.__pattern is not None:
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
# selectedAudioTrack = self.getSelectedAudioTrackDescriptor()
|
||||
# if selectedAudioTrack is not None:
|
||||
# if event.button.id == "button_edit_audio_stream":
|
||||
#
|
||||
# self.app.push_screen(TrackDetailsScreen(trackDescriptor = selectedAudioTrack), self.handle_edit_track)
|
||||
# if event.button.id == "button_delete_audio_stream":
|
||||
# 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)
|
||||
#
|
||||
# selectedSubtitleTrack = self.getSelectedSubtitleTrackDescriptor()
|
||||
# if selectedSubtitleTrack is not None:
|
||||
# if event.button.id == "button_edit_subtitle_stream":
|
||||
# self.app.push_screen(TrackDetailsScreen(trackDescriptor = selectedSubtitleTrack), self.handle_edit_track)
|
||||
# if event.button.id == "button_delete_subtitle_stream":
|
||||
# self.app.push_screen(TrackDeleteScreen(trackDescriptor = selectedSubtitleTrack), self.handle_delete_track)
|
||||
#
|
||||
# if event.button.id == "patternbutton":
|
||||
#
|
||||
# INDICATOR_PATTERN = '([sS][0-9]+[eE][0-9]+)'
|
||||
#
|
||||
# pattern = self.query_one("#pattern_input", Input).value
|
||||
#
|
||||
# patternMatch = re.search(INDICATOR_PATTERN, pattern)
|
||||
#
|
||||
# if patternMatch:
|
||||
# self.query_one("#pattern_input", Input).value = pattern.replace(patternMatch.group(1), INDICATOR_PATTERN)
|
||||
|
||||
|
||||
# def handle_add_track(self, trackDescriptor):
|
||||
#
|
||||
# dispoSet = trackDescriptor.getDispositionSet()
|
||||
# trackType = trackDescriptor.getType()
|
||||
# subIndex = trackDescriptor.getSubIndex()
|
||||
# language = trackDescriptor.getLanguage()
|
||||
# title = trackDescriptor.getTitle()
|
||||
#
|
||||
# if trackType == TrackType.AUDIO:
|
||||
#
|
||||
# row = (subIndex,
|
||||
# " ",
|
||||
# language.label(),
|
||||
# title,
|
||||
# 'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No',
|
||||
# 'Yes' if TrackDisposition.FORCED in dispoSet else 'No')
|
||||
#
|
||||
# self.audioStreamsTable.add_row(*map(str, row))
|
||||
#
|
||||
# if trackType == TrackType.SUBTITLE:
|
||||
#
|
||||
# row = (subIndex,
|
||||
# " ",
|
||||
# language.label(),
|
||||
# title,
|
||||
# 'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No',
|
||||
# 'Yes' if TrackDisposition.FORCED in dispoSet else 'No')
|
||||
#
|
||||
# self.subtitleStreamsTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
# def handle_edit_track(self, trackDescriptor : TrackDescriptor):
|
||||
#
|
||||
# try:
|
||||
# if trackDescriptor.getType() == TrackType.AUDIO:
|
||||
#
|
||||
# row_key, col_key = self.audioStreamsTable.coordinate_to_cell_key(self.audioStreamsTable.cursor_coordinate)
|
||||
#
|
||||
# self.audioStreamsTable.update_cell(row_key, self.column_key_audio_language, trackDescriptor.getLanguage().label())
|
||||
# self.audioStreamsTable.update_cell(row_key, self.column_key_audio_title, trackDescriptor.getTitle())
|
||||
# self.audioStreamsTable.update_cell(row_key, self.column_key_audio_default, 'Yes' if TrackDisposition.DEFAULT in trackDescriptor.getDispositionSet() else 'No')
|
||||
# self.audioStreamsTable.update_cell(row_key, self.column_key_audio_forced, 'Yes' if TrackDisposition.FORCED in trackDescriptor.getDispositionSet() else 'No')
|
||||
#
|
||||
# if trackDescriptor.getType() == TrackType.SUBTITLE:
|
||||
#
|
||||
# row_key, col_key = self.subtitleStreamsTable.coordinate_to_cell_key(self.subtitleStreamsTable.cursor_coordinate)
|
||||
#
|
||||
# self.subtitleStreamsTable.update_cell(row_key, self.column_key_subtitle_language, trackDescriptor.getLanguage().label())
|
||||
# self.subtitleStreamsTable.update_cell(row_key, self.column_key_subtitle_title, trackDescriptor.getTitle())
|
||||
# self.subtitleStreamsTable.update_cell(row_key, self.column_key_subtitle_default, 'Yes' if TrackDisposition.DEFAULT in trackDescriptor.getDispositionSet() else 'No')
|
||||
# self.subtitleStreamsTable.update_cell(row_key, self.column_key_subtitle_forced, 'Yes' if TrackDisposition.FORCED in trackDescriptor.getDispositionSet() else 'No')
|
||||
#
|
||||
# except CellDoesNotExist:
|
||||
# pass
|
||||
|
||||
|
||||
# def handle_delete_track(self, trackDescriptor : TrackDescriptor):
|
||||
#
|
||||
# try:
|
||||
# if trackDescriptor.getType() == TrackType.AUDIO:
|
||||
# self.updateAudioTracks()
|
||||
#
|
||||
# if trackDescriptor.getType() == TrackType.SUBTITLE:
|
||||
# self.updateSubtitleTracks()
|
||||
#
|
||||
# except CellDoesNotExist:
|
||||
# pass
|
||||
@@ -3,6 +3,8 @@ from .track_type import TrackType
|
||||
from .audio_layout import AudioLayout
|
||||
from .track_disposition import TrackDisposition
|
||||
|
||||
from .helper import dictDiff, setDiff
|
||||
|
||||
|
||||
class TrackDescriptor():
|
||||
|
||||
@@ -179,3 +181,22 @@ class TrackDescriptor():
|
||||
|
||||
def getDispositionSet(self):
|
||||
return self.__dispositionSet
|
||||
|
||||
|
||||
|
||||
def compare(self, vsTrackDescriptor):
|
||||
|
||||
compareResult = {}
|
||||
|
||||
tagsDiffResult = dictDiff(vsTrackDescriptor.getTags(), self.getTags())
|
||||
|
||||
if tagsDiffResult:
|
||||
compareResult['tags'] = tagsDiffResult
|
||||
|
||||
vsDispositions = vsTrackDescriptor.getDispositionSet()
|
||||
dispositions = self.getDispositionSet()
|
||||
|
||||
dispositionDiffResult = setDiff(vsDispositions, dispositions)
|
||||
|
||||
if dispositionDiffResult:
|
||||
compareResult['dispositions'] = dispositionDiffResult
|
||||
|
||||
Reference in New Issue
Block a user