inc update diffs mwe
This commit is contained in:
@@ -193,8 +193,10 @@ class FileProperties():
|
||||
|
||||
|
||||
def getShowId(self) -> int:
|
||||
"""Result is -1 if the filename did not match anything in database"""
|
||||
return self.__pattern.getShowId() if self.__pattern is not None else -1
|
||||
|
||||
def getPattern(self) -> Pattern:
|
||||
"""Result is None if the filename did not match anything in database"""
|
||||
return self.__pattern
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
DIFF_ADDED_KEY = 'added'
|
||||
DIFF_REMOVED_KEY = 'removed'
|
||||
DIFF_CHANGED_KEY = 'changed'
|
||||
|
||||
def dictDiff(a : dict, b : dict):
|
||||
|
||||
a_keys = set(a.keys())
|
||||
|
||||
@@ -5,12 +5,14 @@ from typing import List, Self
|
||||
from ffx.track_type import TrackType
|
||||
from ffx.track_descriptor import TrackDescriptor
|
||||
|
||||
from ffx.helper import dictDiff
|
||||
from ffx.helper import dictDiff, DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY
|
||||
|
||||
class MediaDescriptor():
|
||||
"""This class represents the structural content of a media file including streams and metadata"""
|
||||
|
||||
TAGS_KEY = 'tags'
|
||||
TRACKS_KEY = 'tracks'
|
||||
|
||||
TRACK_DESCRIPTOR_LIST_KEY = 'track_descriptors'
|
||||
CLEAR_TAGS_KEY = 'clear_tags'
|
||||
|
||||
@@ -18,7 +20,6 @@ class MediaDescriptor():
|
||||
FFPROBE_TAGS_KEY = 'tags'
|
||||
FFPROBE_CODEC_TYPE_KEY = 'codec_type'
|
||||
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
if MediaDescriptor.TAGS_KEY in kwargs.keys():
|
||||
@@ -101,12 +102,12 @@ class MediaDescriptor():
|
||||
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())
|
||||
tagsDiff = dictDiff(vsMediaDescriptor.getTags(), self.getTags())
|
||||
|
||||
compareResult = {}
|
||||
|
||||
if mediaTagsResult:
|
||||
compareResult['tags'] = mediaTagsResult
|
||||
if tagsDiff:
|
||||
compareResult[MediaDescriptor.TAGS_KEY] = tagsDiff
|
||||
|
||||
|
||||
# Target track configuration (from DB)
|
||||
@@ -127,27 +128,27 @@ class MediaDescriptor():
|
||||
|
||||
# Will trigger if tracks are missing in file
|
||||
if tp > (numVsTracks - 1):
|
||||
if 'removed' not in trackCompareResult.keys():
|
||||
trackCompareResult['removed'] = set()
|
||||
trackCompareResult['removed'].add(tracks[tp].getIndex())
|
||||
if DIFF_REMOVED_KEY not in trackCompareResult.keys():
|
||||
trackCompareResult[DIFF_REMOVED_KEY] = set()
|
||||
trackCompareResult[DIFF_REMOVED_KEY].add(tracks[tp].getIndex())
|
||||
continue
|
||||
|
||||
# Will trigger if tracks are missing in DB definition
|
||||
if tp > (numTracks - 1):
|
||||
if 'added' not in trackCompareResult.keys():
|
||||
trackCompareResult['added'] = {}
|
||||
trackCompareResult['added'][vsTracks[tp].getIndex()] = vsTracks[tp]
|
||||
if DIFF_ADDED_KEY not in trackCompareResult.keys():
|
||||
trackCompareResult[DIFF_ADDED_KEY] = {}
|
||||
trackCompareResult[DIFF_ADDED_KEY][vsTracks[tp].getIndex()] = vsTracks[tp]
|
||||
continue
|
||||
|
||||
# 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'][vsTracks[tp].getIndex()] = tdiff
|
||||
if DIFF_CHANGED_KEY not in trackCompareResult.keys():
|
||||
trackCompareResult[DIFF_CHANGED_KEY] = {}
|
||||
trackCompareResult[DIFF_CHANGED_KEY][vsTracks[tp].getIndex()] = tdiff
|
||||
|
||||
if trackCompareResult:
|
||||
compareResult['tracks'] = trackCompareResult
|
||||
compareResult[MediaDescriptor.TRACKS_KEY] = trackCompareResult
|
||||
|
||||
return compareResult
|
||||
|
||||
@@ -12,6 +12,7 @@ from ffx.model.pattern import Pattern
|
||||
from .pattern_controller import PatternController
|
||||
from .show_controller import ShowController
|
||||
from .track_controller import TrackController
|
||||
from .tag_controller import TagController
|
||||
|
||||
from .track_details_screen import TrackDetailsScreen
|
||||
from .track_delete_screen import TrackDeleteScreen
|
||||
@@ -27,6 +28,8 @@ from textual.widgets._data_table import CellDoesNotExist
|
||||
from ffx.media_descriptor import MediaDescriptor
|
||||
from ffx.file_properties import FileProperties
|
||||
|
||||
from ffx.helper import DIFF_ADDED_KEY, DIFF_CHANGED_KEY, DIFF_REMOVED_KEY
|
||||
|
||||
|
||||
# Screen[dict[int, str, int]]
|
||||
class MediaDetailsScreen(Screen):
|
||||
@@ -108,6 +111,7 @@ class MediaDetailsScreen(Screen):
|
||||
self.__pc = PatternController(context = self.context)
|
||||
self.__sc = ShowController(context = self.context)
|
||||
self.__tc = TrackController(context = self.context)
|
||||
self.__tac = TagController(context = self.context)
|
||||
|
||||
if not 'command' in self.context.keys() or self.context['command'] != 'inspect':
|
||||
raise click.ClickException(f"MediaDetailsScreen.__init__(): Can only perform command 'inspect'")
|
||||
@@ -120,14 +124,8 @@ class MediaDetailsScreen(Screen):
|
||||
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() if self.__mediaFilenamePattern is not None else None
|
||||
|
||||
|
||||
self.loadProperties()
|
||||
# def loadTracks(self, show_id):
|
||||
#
|
||||
# try:
|
||||
@@ -206,74 +204,64 @@ class MediaDetailsScreen(Screen):
|
||||
return None
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
def loadProperties(self):
|
||||
|
||||
if self.__mediaFilenamePattern is None:
|
||||
row = (' ', '<New show>', ' ') # Convert each element to a string before adding
|
||||
self.showsTable.add_row(*map(str, row))
|
||||
self.__mediaFileProperties = FileProperties(self.context, self.__mediaFilename)
|
||||
self.__currentMediaDescriptor = self.__mediaFileProperties.getMediaDescriptor()
|
||||
|
||||
for show in self.__sc.getAllShows():
|
||||
row = (int(show.id), show.name, show.year) # Convert each element to a string before adding
|
||||
self.showsTable.add_row(*map(str, row))
|
||||
#HINT: This is None if the filename did not match anything in database
|
||||
self.__currentPattern = self.__mediaFileProperties.getPattern()
|
||||
|
||||
for mediaTagKey, mediaTagValue in self.__mediaDescriptor.getTags().items():
|
||||
row = (mediaTagKey, mediaTagValue) # Convert each element to a string before adding
|
||||
self.mediaTagsTable.add_row(*map(str, row))
|
||||
self.__targetMediaDescriptor = self.__currentPattern.getMediaDescriptor() if self.__currentPattern is not None else None
|
||||
|
||||
#self.updateAudioTracks(self.__mediaDescriptor.getAudioTracks())
|
||||
#self.updateSubtitleTracks(self.__mediaDescriptor.getSubtitleTracks())
|
||||
self.updateTracks()
|
||||
|
||||
if self.__mediaFilenamePattern is not None:
|
||||
|
||||
showIdentifier = self.__mediaFilenamePattern.getShowId()
|
||||
showRowIndex = self.getRowIndexFromShowId(showIdentifier)
|
||||
if showRowIndex is not None:
|
||||
self.showsTable.move_cursor(row=showRowIndex)
|
||||
# Enumerating differences between media descriptors
|
||||
# from file (=current) vs from stored in database (=target)
|
||||
self.__mediaDifferences = self.__targetMediaDescriptor.compare(self.__currentMediaDescriptor) if self.__currentPattern is not None else {}
|
||||
|
||||
|
||||
self.query_one("#pattern_input", Input).value = self.__mediaFilenamePattern.getPattern()
|
||||
def updateDifferences(self):
|
||||
|
||||
# Enumerating differences between media descriptor from file vs from stored in database
|
||||
targetMediaDescriptor = self.__mediaFilenamePattern.getMediaDescriptor()
|
||||
mediaDifferences = targetMediaDescriptor.compare(self.__mediaDescriptor)
|
||||
self.loadProperties()
|
||||
|
||||
if 'tags' in mediaDifferences.keys():
|
||||
self.differencesTable.clear()
|
||||
|
||||
mediaTags = self.__mediaDescriptor.getTags()
|
||||
if 'tags' in self.__mediaDifferences.keys():
|
||||
|
||||
if 'added' in mediaDifferences['tags'].keys():
|
||||
for addedTagKey in mediaDifferences['tags']['added']:
|
||||
row = (f"added media tag: key='{addedTagKey}' value='{mediaTags[addedTagKey]}'",)
|
||||
currentTags = self.__currentMediaDescriptor.getTags()
|
||||
targetTags = self.__targetMediaDescriptor.getTags()
|
||||
|
||||
if 'added' in self.__mediaDifferences['tags'].keys():
|
||||
for addedTagKey in self.__mediaDifferences['tags']['added']:
|
||||
row = (f"added media tag: key='{addedTagKey}' value='{targetTags[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]}'",)
|
||||
if 'removed' in self.__mediaDifferences['tags'].keys():
|
||||
for removedTagKey in self.__mediaDifferences['tags']['removed']:
|
||||
row = (f"removed media tag: key='{removedTagKey}' value='{currentTags[removedTagKey]}'",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
if 'tracks' in mediaDifferences.keys():
|
||||
if 'tracks' in self.__mediaDifferences.keys():
|
||||
|
||||
currentTracks = self.__mediaDescriptor.getAllTracks() # 0,1,2,3
|
||||
targetTracks = targetMediaDescriptor.getAllTracks() # 0 <- from DB
|
||||
currentTracks = self.__currentMediaDescriptor.getAllTracks() # 0,1,2,3
|
||||
targetTracks = self.__targetMediaDescriptor.getAllTracks() # 0 <- from DB
|
||||
|
||||
if 'added' in mediaDifferences['tracks'].keys():
|
||||
for addedTrackIndex in mediaDifferences['tracks']['added'].keys():
|
||||
if 'added' in self.__mediaDifferences['tracks'].keys():
|
||||
for addedTrackIndex in self.__mediaDifferences['tracks']['added'].keys():
|
||||
addedTrack : Track = currentTracks[addedTrackIndex]
|
||||
row = (f"added {addedTrack.getType().label()} track: index={addedTrackIndex} subIndex={addedTrack.getSubIndex()} lang={addedTrack.getLanguage().threeLetter()}",)
|
||||
row = (f"added {addedTrack.getType().label()} track: index={addedTrackIndex} lang={addedTrack.getLanguage().threeLetter()}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
if 'removed' in mediaDifferences['tracks'].keys():
|
||||
for removedTrackIndex in mediaDifferences['tracks']['removed']:
|
||||
if 'removed' in self.__mediaDifferences['tracks'].keys():
|
||||
for removedTrackIndex in self.__mediaDifferences['tracks']['removed']:
|
||||
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():
|
||||
if 'changed' in self.__mediaDifferences['tracks'].keys():
|
||||
for changedTrackIndex in self.__mediaDifferences['tracks']['changed'].keys():
|
||||
|
||||
changedTrack : Track = targetTracks[changedTrackIndex]
|
||||
changedTrackDiff : dict = mediaDifferences['tracks']['changed'][changedTrackIndex]
|
||||
changedTrackDiff : dict = self.__mediaDifferences['tracks']['changed'][changedTrackIndex]
|
||||
|
||||
if 'tags' in changedTrackDiff.keys():
|
||||
|
||||
@@ -289,6 +277,35 @@ class MediaDetailsScreen(Screen):
|
||||
row = (f"changed {changedTrack.getType().label()} track index={changedTrackIndex} removed key={removedTagKey}",)
|
||||
self.differencesTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
|
||||
if self.__currentPattern is None:
|
||||
row = (' ', '<New show>', ' ') # Convert each element to a string before adding
|
||||
self.showsTable.add_row(*map(str, row))
|
||||
|
||||
for show in self.__sc.getAllShows():
|
||||
row = (int(show.id), show.name, show.year) # Convert each element to a string before adding
|
||||
self.showsTable.add_row(*map(str, row))
|
||||
|
||||
for mediaTagKey, mediaTagValue in self.__currentMediaDescriptor.getTags().items():
|
||||
row = (mediaTagKey, mediaTagValue) # Convert each element to a string before adding
|
||||
self.mediaTagsTable.add_row(*map(str, row))
|
||||
|
||||
self.updateTracks()
|
||||
|
||||
|
||||
if self.__currentPattern is not None:
|
||||
|
||||
showIdentifier = self.__currentPattern.getShowId()
|
||||
showRowIndex = self.getRowIndexFromShowId(showIdentifier)
|
||||
if showRowIndex is not None:
|
||||
self.showsTable.move_cursor(row=showRowIndex)
|
||||
|
||||
self.query_one("#pattern_input", Input).value = self.__currentPattern.getPattern()
|
||||
|
||||
self.updateDifferences()
|
||||
|
||||
else:
|
||||
|
||||
self.query_one("#pattern_input", Input).value = self.__mediaFilename
|
||||
@@ -300,7 +317,7 @@ class MediaDetailsScreen(Screen):
|
||||
|
||||
self.tracksTable.clear()
|
||||
|
||||
trackDescriptorList = self.__mediaDescriptor.getAllTracks()
|
||||
trackDescriptorList = self.__currentMediaDescriptor.getAllTracks()
|
||||
|
||||
typeCounter = {}
|
||||
|
||||
@@ -369,7 +386,7 @@ class MediaDetailsScreen(Screen):
|
||||
self.differencesTable = DataTable(id='differences-table') # classes="triple"
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_differences = self.differencesTable.add_column("Differences", width=70)
|
||||
self.column_key_differences = self.differencesTable.add_column("Differences (file->db)", width=70)
|
||||
|
||||
self.differencesTable.cursor_type = 'row'
|
||||
|
||||
@@ -667,3 +684,39 @@ class MediaDetailsScreen(Screen):
|
||||
#
|
||||
# except CellDoesNotExist:
|
||||
# pass
|
||||
|
||||
|
||||
def action_new_pattern(self):
|
||||
pass
|
||||
|
||||
def action_update_pattern(self):
|
||||
"""When updating the database the actions must reverse the difference (eq to diff db->file)"""
|
||||
|
||||
if MediaDescriptor.TAGS_KEY in self.__mediaDifferences.keys():
|
||||
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys():
|
||||
for addedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_ADDED_KEY]:
|
||||
self.__tac.deleteMediaTagByKey(self.__currentPattern.getId(), addedTagKey)
|
||||
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys():
|
||||
for removedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_REMOVED_KEY]:
|
||||
mediaTags = self.__currentMediaDescriptor.getTags()
|
||||
self.__tac.updateMediaTag(self.__currentPattern.getId(), removedTagKey, mediaTags[removedTagKey])
|
||||
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TAGS_KEY].keys():
|
||||
for changedTagKey in self.__mediaDifferences[MediaDescriptor.TAGS_KEY][DIFF_CHANGED_KEY]:
|
||||
pass
|
||||
if MediaDescriptor.TRACKS_KEY in self.__mediaDifferences.keys():
|
||||
if DIFF_ADDED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys():
|
||||
for addedTrackKey in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_ADDED_KEY]:
|
||||
pass
|
||||
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys():
|
||||
for removedTrackKey in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_REMOVED_KEY]:
|
||||
pass
|
||||
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys():
|
||||
for changedTrackKey in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_CHANGED_KEY]:
|
||||
pass
|
||||
|
||||
self.updateDifferences()
|
||||
|
||||
|
||||
def action_edit_pattern(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -134,7 +134,6 @@ class PatternController():
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def getMediaDescriptor(self, patternId):
|
||||
|
||||
try:
|
||||
@@ -142,9 +141,9 @@ class PatternController():
|
||||
q = s.query(Pattern).filter(Pattern.id == int(patternId))
|
||||
|
||||
if q.count():
|
||||
pattern = q.first()
|
||||
#return self.getPatternDict(pattern)
|
||||
return pattern.getMediaDescriptor()
|
||||
return q.first().getMediaDescriptor()
|
||||
else:
|
||||
return None
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"PatternController.getPatternDescriptor(): {repr(ex)}")
|
||||
|
||||
@@ -13,10 +13,14 @@ from ffx.model.track import Track
|
||||
from .pattern_controller import PatternController
|
||||
from .show_controller import ShowController
|
||||
from .track_controller import TrackController
|
||||
from .tag_controller import TagController
|
||||
|
||||
from .track_details_screen import TrackDetailsScreen
|
||||
from .track_delete_screen import TrackDeleteScreen
|
||||
|
||||
from .tag_details_screen import TagDetailsScreen
|
||||
from .tag_delete_screen import TagDeleteScreen
|
||||
|
||||
from ffx.track_type import TrackType
|
||||
|
||||
from ffx.track_disposition import TrackDisposition
|
||||
@@ -31,8 +35,8 @@ class PatternDetailsScreen(Screen):
|
||||
CSS = """
|
||||
|
||||
Grid {
|
||||
grid-size: 5 9;
|
||||
grid-rows: 2 2 2 2 2 6 2 2 2;
|
||||
grid-size: 5 13;
|
||||
grid-rows: 2 2 2 2 2 8 2 2 8 2 2 2 2;
|
||||
grid-columns: 25 25 25 25 25;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -73,6 +77,10 @@ class PatternDetailsScreen(Screen):
|
||||
#tracks_table {
|
||||
row-span: 4;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
tint: yellow 40%;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, patternId = None, showId = None):
|
||||
@@ -84,6 +92,7 @@ class PatternDetailsScreen(Screen):
|
||||
self.__pc = PatternController(context = self.context)
|
||||
self.__sc = ShowController(context = self.context)
|
||||
self.__tc = TrackController(context = self.context)
|
||||
self.__tac = TagController(context = self.context)
|
||||
|
||||
self.__pattern : Pattern = self.__pc.getPattern(patternId) if patternId is not None else None
|
||||
|
||||
@@ -143,6 +152,22 @@ class PatternDetailsScreen(Screen):
|
||||
|
||||
typeCounter[trackType] += 1
|
||||
|
||||
def updateTags(self):
|
||||
|
||||
self.tagsTable.clear()
|
||||
|
||||
if self.__pattern is not None:
|
||||
|
||||
# raise click.ClickException(f"patternid={self.__pattern.getId()}") # 1
|
||||
|
||||
tags = self.__tac.findAllMediaTags(self.__pattern.getId())
|
||||
|
||||
#raise click.ClickException(f"tags={tags}") # encoder:blah
|
||||
|
||||
for tagKey, tagValue in tags.items():
|
||||
row = (tagKey, tagValue)
|
||||
self.tagsTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
|
||||
@@ -153,10 +178,21 @@ class PatternDetailsScreen(Screen):
|
||||
|
||||
self.query_one("#pattern_input", Input).value = str(self.__pattern.getPattern())
|
||||
|
||||
self.updateTags()
|
||||
self.updateTracks()
|
||||
|
||||
def compose(self):
|
||||
|
||||
|
||||
self.tagsTable = DataTable(classes="five")
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_tag_key = self.tagsTable.add_column("Key", width=10)
|
||||
self.column_key_tag_value = self.tagsTable.add_column("Value", width=100)
|
||||
|
||||
self.tagsTable.cursor_type = 'row'
|
||||
|
||||
|
||||
self.tracksTable = DataTable(id="tracks_table", classes="five")
|
||||
|
||||
self.column_key_track_index = self.tracksTable.add_column("Index", width=5)
|
||||
@@ -191,6 +227,24 @@ class PatternDetailsScreen(Screen):
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 5
|
||||
yield Static("Media Tags")
|
||||
yield Static(" ")
|
||||
|
||||
if self.__pattern is not None:
|
||||
yield Button("Add", id="button_add_tag")
|
||||
yield Button("Edit", id="button_edit_tag")
|
||||
yield Button("Delete", id="button_delete_tag")
|
||||
else:
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
# 6
|
||||
yield self.tagsTable
|
||||
|
||||
# 7
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 8
|
||||
yield Static("Streams")
|
||||
yield Static(" ")
|
||||
|
||||
@@ -202,19 +256,22 @@ class PatternDetailsScreen(Screen):
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
# 6
|
||||
# 9
|
||||
yield self.tracksTable
|
||||
|
||||
# 7
|
||||
# 10
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 8
|
||||
# 11
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 9
|
||||
# 12
|
||||
yield Button("Save", id="save_button")
|
||||
yield Button("Cancel", id="cancel_button")
|
||||
|
||||
# 13
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
yield Footer()
|
||||
|
||||
|
||||
@@ -249,6 +306,31 @@ class PatternDetailsScreen(Screen):
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def getSelectedTag(self):
|
||||
|
||||
try:
|
||||
|
||||
# Fetch the currently selected row when 'Enter' is pressed
|
||||
#selected_row_index = self.table.cursor_row
|
||||
row_key, col_key = self.tagsTable.coordinate_to_cell_key(self.tagsTable.cursor_coordinate)
|
||||
|
||||
if row_key is not None:
|
||||
selected_tag_data = self.tagsTable.get_row(row_key)
|
||||
|
||||
tagKey = str(selected_tag_data[0])
|
||||
tagValue = str(selected_tag_data[1])
|
||||
|
||||
return tagKey, tagValue
|
||||
|
||||
else:
|
||||
return None
|
||||
|
||||
except CellDoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
|
||||
# Event handler for button press
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
# Check if the button pressed is the one we are interested in
|
||||
@@ -276,7 +358,6 @@ class PatternDetailsScreen(Screen):
|
||||
self.app.pop_screen()
|
||||
|
||||
|
||||
|
||||
if event.button.id == "cancel_button":
|
||||
self.app.pop_screen()
|
||||
|
||||
@@ -296,6 +377,20 @@ class PatternDetailsScreen(Screen):
|
||||
if event.button.id == "button_delete_track":
|
||||
self.app.push_screen(TrackDeleteScreen(trackDescriptor = selectedTrack), self.handle_delete_track)
|
||||
|
||||
|
||||
if event.button.id == "button_add_tag":
|
||||
if self.__pattern is not None:
|
||||
self.app.push_screen(TagDetailsScreen(), self.handle_update_tag)
|
||||
|
||||
if event.button.id == "button_edit_tag":
|
||||
tagKey, tagValue = self.getSelectedTag()
|
||||
self.app.push_screen(TagDetailsScreen(key=tagKey, value=tagValue), self.handle_update_tag)
|
||||
|
||||
if event.button.id == "button_delete_tag":
|
||||
tagKey, tagValue = self.getSelectedTag()
|
||||
self.app.push_screen(TagDeleteScreen(key=tagKey, value=tagValue), self.handle_delete_tag)
|
||||
|
||||
|
||||
if event.button.id == "pattern_button":
|
||||
|
||||
INDICATOR_PATTERN = '([sS][0-9]+[eE][0-9]+)'
|
||||
@@ -346,3 +441,21 @@ class PatternDetailsScreen(Screen):
|
||||
|
||||
def handle_delete_track(self, trackDescriptor : TrackDescriptor):
|
||||
self.updateTracks()
|
||||
|
||||
|
||||
|
||||
def handle_update_tag(self, tag):
|
||||
|
||||
if self.__pattern is None:
|
||||
raise click.ClickException(f"PatternDetailsScreen.handle_update_tag: pattern not set")
|
||||
|
||||
if self.__tac.updateMediaTag(self.__pattern.getId(), tag[0], tag[1]) is not None:
|
||||
self.updateTags()
|
||||
|
||||
def handle_delete_tag(self, tag):
|
||||
|
||||
if self.__pattern is None:
|
||||
raise click.ClickException(f"PatternDetailsScreen.handle_delete_tag: pattern not set")
|
||||
|
||||
if self.__tac.deleteMediaTagByKey(self.__pattern.getId(), tag[0]):
|
||||
self.updateTags()
|
||||
|
||||
@@ -14,19 +14,19 @@ class TagController():
|
||||
self.Session = self.context['database']['session'] # convenience
|
||||
|
||||
|
||||
def updateMediaTag(self, trackId, tagKey, tagValue):
|
||||
def updateMediaTag(self, patternId, tagKey, tagValue):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
q = s.query(MediaTag).filter(MediaTag.track_id == int(trackId),
|
||||
q = s.query(MediaTag).filter(MediaTag.pattern_id == int(patternId),
|
||||
MediaTag.key == str(tagKey),
|
||||
MediaTag.value == str(tagValue))
|
||||
tag = q.first()
|
||||
if tag:
|
||||
tag.value = str(tagValue)
|
||||
else:
|
||||
tag = MediaTag(track_id = int(trackId),
|
||||
tag = MediaTag(pattern_id = int(patternId),
|
||||
key = str(tagKey),
|
||||
value = str(tagValue))
|
||||
s.add(tag)
|
||||
@@ -64,13 +64,52 @@ class TagController():
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def findAllMediaTags(self, trackId) -> dict:
|
||||
def deleteMediaTagByKey(self, patternId, tagKey):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
q = s.query(MediaTag).filter(MediaTag.track_id == int(trackId))
|
||||
q = s.query(MediaTag).filter(MediaTag.pattern_id == int(patternId),
|
||||
MediaTag.key == str(tagKey))
|
||||
if q.count():
|
||||
tag = q.first()
|
||||
s.delete(tag)
|
||||
s.commit()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TagController.deleteMediaTagByKey(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def deleteTrackTagByKey(self, trackId, tagKey):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
q = s.query(TrackTag).filter(TrackTag.track_id == int(trackId),
|
||||
TrackTag.key == str(tagKey))
|
||||
tag = q.first()
|
||||
if tag:
|
||||
s.delete(tag)
|
||||
s.commit()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TagController.deleteTrackTagByKey(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
def findAllMediaTags(self, patternId) -> dict:
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
q = s.query(MediaTag).filter(MediaTag.pattern_id == int(patternId))
|
||||
|
||||
if q.count():
|
||||
return {t.key:t.value for t in q.all()}
|
||||
|
||||
@@ -383,7 +383,7 @@ class TrackDetailsScreen(Screen):
|
||||
trackId = self.__trackDescriptor.getId()
|
||||
|
||||
if trackId == -1:
|
||||
raise click.ClickException(f"TrackDetailsScreen.handle_add_tag: trackId not set (-1) trackDescriptor={self.__trackDescriptor}")
|
||||
raise click.ClickException(f"TrackDetailsScreen.handle_update_tag: trackId not set (-1) trackDescriptor={self.__trackDescriptor}")
|
||||
|
||||
if self.__tac.updateTrackTag(trackId, tag[0], tag[1]) is not None:
|
||||
self.updateTags()
|
||||
|
||||
Reference in New Issue
Block a user