nightly
This commit is contained in:
113
bin/ffx/iso_language.py
Normal file
113
bin/ffx/iso_language.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from enum import Enum
|
||||
import difflib
|
||||
|
||||
class IsoLanguage(Enum):
|
||||
|
||||
AFRIKAANS = {"name": "Afrikaans", "iso639_1": "af", "iso639_2": "afr"}
|
||||
ALBANIAN = {"name": "Albanian", "iso639_1": "sq", "iso639_2": "alb"}
|
||||
ARABIC = {"name": "Arabic", "iso639_1": "ar", "iso639_2": "ara"}
|
||||
ARMENIAN = {"name": "Armenian", "iso639_1": "hy", "iso639_2": "arm"}
|
||||
AZERBAIJANI = {"name": "Azerbaijani", "iso639_1": "az", "iso639_2": "aze"}
|
||||
BASQUE = {"name": "Basque", "iso639_1": "eu", "iso639_2": "baq"}
|
||||
BELARUSIAN = {"name": "Belarusian", "iso639_1": "be", "iso639_2": "bel"}
|
||||
BULGARIAN = {"name": "Bulgarian", "iso639_1": "bg", "iso639_2": "bul"}
|
||||
CATALAN = {"name": "Catalan", "iso639_1": "ca", "iso639_2": "cat"}
|
||||
CHINESE = {"name": "Chinese", "iso639_1": "zh", "iso639_2": "chi"}
|
||||
CROATIAN = {"name": "Croatian", "iso639_1": "hr", "iso639_2": "hrv"}
|
||||
CZECH = {"name": "Czech", "iso639_1": "cs", "iso639_2": "cze"}
|
||||
DANISH = {"name": "Danish", "iso639_1": "da", "iso639_2": "dan"}
|
||||
DUTCH = {"name": "Dutch", "iso639_1": "nl", "iso639_2": "dut"}
|
||||
ENGLISH = {"name": "English", "iso639_1": "en", "iso639_2": "eng"}
|
||||
ESTONIAN = {"name": "Estonian", "iso639_1": "et", "iso639_2": "est"}
|
||||
FINNISH = {"name": "Finnish", "iso639_1": "fi", "iso639_2": "fin"}
|
||||
FRENCH = {"name": "French", "iso639_1": "fr", "iso639_2": "fre"}
|
||||
GEORGIAN = {"name": "Georgian", "iso639_1": "ka", "iso639_2": "geo"}
|
||||
GERMAN = {"name": "German", "iso639_1": "de", "iso639_2": "ger"}
|
||||
GREEK = {"name": "Greek", "iso639_1": "el", "iso639_2": "gre"}
|
||||
HEBREW = {"name": "Hebrew", "iso639_1": "he", "iso639_2": "heb"}
|
||||
HINDI = {"name": "Hindi", "iso639_1": "hi", "iso639_2": "hin"}
|
||||
HUNGARIAN = {"name": "Hungarian", "iso639_1": "hu", "iso639_2": "hun"}
|
||||
ICELANDIC = {"name": "Icelandic", "iso639_1": "is", "iso639_2": "ice"}
|
||||
INDONESIAN = {"name": "Indonesian", "iso639_1": "id", "iso639_2": "ind"}
|
||||
IRISH = {"name": "Irish", "iso639_1": "ga", "iso639_2": "gle"}
|
||||
ITALIAN = {"name": "Italian", "iso639_1": "it", "iso639_2": "ita"}
|
||||
JAPANESE = {"name": "Japanese", "iso639_1": "ja", "iso639_2": "jpn"}
|
||||
KAZAKH = {"name": "Kazakh", "iso639_1": "kk", "iso639_2": "kaz"}
|
||||
KOREAN = {"name": "Korean", "iso639_1": "ko", "iso639_2": "kor"}
|
||||
LATIN = {"name": "Latin", "iso639_1": "la", "iso639_2": "lat"}
|
||||
LATVIAN = {"name": "Latvian", "iso639_1": "lv", "iso639_2": "lav"}
|
||||
LITHUANIAN = {"name": "Lithuanian", "iso639_1": "lt", "iso639_2": "lit"}
|
||||
MACEDONIAN = {"name": "Macedonian", "iso639_1": "mk", "iso639_2": "mac"}
|
||||
MALAY = {"name": "Malay", "iso639_1": "ms", "iso639_2": "may"}
|
||||
MALTESE = {"name": "Maltese", "iso639_1": "mt", "iso639_2": "mlt"}
|
||||
NORWEGIAN = {"name": "Norwegian", "iso639_1": "no", "iso639_2": "nor"}
|
||||
PERSIAN = {"name": "Persian", "iso639_1": "fa", "iso639_2": "per"}
|
||||
POLISH = {"name": "Polish", "iso639_1": "pl", "iso639_2": "pol"}
|
||||
PORTUGUESE = {"name": "Portuguese", "iso639_1": "pt", "iso639_2": "por"}
|
||||
ROMANIAN = {"name": "Romanian", "iso639_1": "ro", "iso639_2": "rum"}
|
||||
RUSSIAN = {"name": "Russian", "iso639_1": "ru", "iso639_2": "rus"}
|
||||
NORTHERN_SAMI = {"name": "Northern Sami", "iso639_1": "se", "iso639_2": "sme"}
|
||||
SAMOAN = {"name": "Samoan", "iso639_1": "sm", "iso639_2": "smo"}
|
||||
SANGO = {"name": "Sango", "iso639_1": "sg", "iso639_2": "sag"}
|
||||
SANSKRIT = {"name": "Sanskrit", "iso639_1": "sa", "iso639_2": "san"}
|
||||
SARDINIAN = {"name": "Sardinian", "iso639_1": "sc", "iso639_2": "srd"}
|
||||
SERBIAN = {"name": "Serbian", "iso639_1": "sr", "iso639_2": "srp"}
|
||||
SHONA = {"name": "Shona", "iso639_1": "sn", "iso639_2": "sna"}
|
||||
SINDHI = {"name": "Sindhi", "iso639_1": "sd", "iso639_2": "snd"}
|
||||
SINHALA = {"name": "Sinhala", "iso639_1": "si", "iso639_2": "sin"}
|
||||
SLOVAK = {"name": "Slovak", "iso639_1": "sk", "iso639_2": "slk"}
|
||||
SLOVENIAN = {"name": "Slovenian", "iso639_1": "sl", "iso639_2": "slv"}
|
||||
SOMALI = {"name": "Somali", "iso639_1": "so", "iso639_2": "som"}
|
||||
SOUTHERN_SOTHO = {"name": "Southern Sotho", "iso639_1": "st", "iso639_2": "sot"}
|
||||
SPANISH = {"name": "Spanish", "iso639_1": "es", "iso639_2": "spa"}
|
||||
SUNDANESE = {"name": "Sundanese", "iso639_1": "su", "iso639_2": "sun"}
|
||||
SWAHILI = {"name": "Swahili", "iso639_1": "sw", "iso639_2": "swa"}
|
||||
SWATI = {"name": "Swati", "iso639_1": "ss", "iso639_2": "ssw"}
|
||||
SWEDISH = {"name": "Swedish", "iso639_1": "sv", "iso639_2": "swe"}
|
||||
TAGALOG = {"name": "Tagalog", "iso639_1": "tl", "iso639_2": "tgl"}
|
||||
TAMIL = {"name": "Tamil", "iso639_1": "ta", "iso639_2": "tam"}
|
||||
THAI = {"name": "Thai", "iso639_1": "th", "iso639_2": "tha"}
|
||||
TURKISH = {"name": "Turkish", "iso639_1": "tr", "iso639_2": "tur"}
|
||||
UKRAINIAN = {"name": "Ukrainian", "iso639_1": "uk", "iso639_2": "ukr"}
|
||||
URDU = {"name": "Urdu", "iso639_1": "ur", "iso639_2": "urd"}
|
||||
VIETNAMESE = {"name": "Vietnamese", "iso639_1": "vi", "iso639_2": "vie"}
|
||||
WELSH = {"name": "Welsh", "iso639_1": "cy", "iso639_2": "wel"}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def find(label : str):
|
||||
|
||||
closestMatches = difflib.get_close_matches(label, [l.value["name"] for l in IsoLanguage], n=1)
|
||||
|
||||
if closestMatches:
|
||||
foundLangs = [l for l in IsoLanguage if l.value['name'] == closestMatches[0]]
|
||||
return foundLangs[0] if foundLangs else None
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def findThreeLetter(theeLetter : str):
|
||||
foundLangs = [l for l in IsoLanguage if l.value['iso639_2'] == str(theeLetter)]
|
||||
return foundLangs[0] if foundLangs else None
|
||||
|
||||
|
||||
# def get(lang : str):
|
||||
#
|
||||
# selectedLangs = [l for l in IsoLanguage if l.value['iso639_2'] == lang]
|
||||
#
|
||||
# if selectedLangs:
|
||||
# return selectedLangs[0]
|
||||
# else:
|
||||
# return None
|
||||
|
||||
def label(self):
|
||||
return str(self.value['name'])
|
||||
|
||||
def twoLetter(self):
|
||||
return str(self.value['iso639_1'])
|
||||
|
||||
def threeLetter(self):
|
||||
return str(self.value['iso639_2'])
|
||||
|
||||
|
||||
|
||||
30
bin/ffx/model/tag.py
Normal file
30
bin/ffx/model/tag.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# from typing import List
|
||||
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Enum
|
||||
from sqlalchemy.orm import relationship, declarative_base, sessionmaker
|
||||
|
||||
from .show import Base
|
||||
|
||||
from ffx.track_type import TrackType
|
||||
|
||||
|
||||
class Tag(Base):
|
||||
"""
|
||||
relationship(argument, opt1, opt2, ...)
|
||||
argument is string of class or Mapped class of the target entity
|
||||
backref creates a bi-directional corresponding relationship (back_populates preferred)
|
||||
back_populates points to the corresponding relationship (the actual class attribute identifier)
|
||||
|
||||
See: https://docs.sqlalchemy.org/en/(14|20)/orm/basic_relationships.html
|
||||
"""
|
||||
|
||||
__tablename__ = 'tags'
|
||||
|
||||
# v1.x
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
key = Column(String)
|
||||
value = Column(String)
|
||||
|
||||
# v1.x
|
||||
track_id = Column(Integer, ForeignKey('tracks.id', ondelete="CASCADE"))
|
||||
track = relationship('Track', back_populates='tags')
|
||||
@@ -1,11 +1,16 @@
|
||||
# from typing import List
|
||||
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Enum
|
||||
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
|
||||
from sqlalchemy.orm import relationship, declarative_base, sessionmaker
|
||||
|
||||
from .show import Base
|
||||
|
||||
from ffx.track_type import TrackType
|
||||
|
||||
from ffx.iso_language import IsoLanguage
|
||||
|
||||
from ffx.model.tag import Tag
|
||||
|
||||
|
||||
|
||||
class Track(Base):
|
||||
"""
|
||||
@@ -20,11 +25,21 @@ class Track(Base):
|
||||
__tablename__ = 'tracks'
|
||||
|
||||
# v1.x
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement = True)
|
||||
|
||||
track_type = Column(Enum[TrackType])
|
||||
# P=pattern_id+sub_index+track_type
|
||||
track_type = Column(Integer) # TrackType
|
||||
sub_index = Column(Integer)
|
||||
|
||||
# v1.x
|
||||
pattern_id = Column(Integer, ForeignKey('patterns.id', ondelete="CASCADE"))
|
||||
pattern = relationship('Pattern', back_populates='tracks')
|
||||
|
||||
|
||||
language = Column(String) # IsoLanguage threeLetter
|
||||
title = Column(String)
|
||||
|
||||
tags = relationship('Tag', back_populates='track', cascade="all, delete")
|
||||
|
||||
|
||||
disposition_flags = Column(Integer)
|
||||
|
||||
@@ -11,12 +11,16 @@ 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
|
||||
|
||||
|
||||
# Screen[dict[int, str, int]]
|
||||
class PatternDetailsScreen(Screen):
|
||||
|
||||
@@ -71,23 +75,29 @@ class PatternDetailsScreen(Screen):
|
||||
|
||||
self.__pc = PatternController(context = self.context)
|
||||
self.__sc = ShowController(context = self.context)
|
||||
self.__tc = TrackController(context = self.context)
|
||||
|
||||
self.pattern_obj = self.__pc.getPatternDescriptor(patternId) if patternId is not None else {}
|
||||
self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {}
|
||||
|
||||
|
||||
# def loadPatterns(self, show_id):
|
||||
#
|
||||
# try:
|
||||
# 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:
|
||||
# click.ClickException(f"loadPatterns(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
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:
|
||||
click.ClickException(f"loadPatterns(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
@@ -97,30 +107,52 @@ class PatternDetailsScreen(Screen):
|
||||
|
||||
if self.show_obj:
|
||||
self.query_one("#showlabel", Static).update(f"{self.show_obj['id']} - {self.show_obj['name']} ({self.show_obj['year']})")
|
||||
|
||||
# for pattern in self.loadPatterns(int(self.show_obj['id'])):
|
||||
# row = (pattern['pattern'],)
|
||||
# self.patternTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
if self.pattern_obj:
|
||||
|
||||
for subIndex in range(3):
|
||||
trackIds = self.__tc.findAllTracks(self.pattern_obj['id'])
|
||||
|
||||
row4 = (str(subIndex),str(subIndex),str(subIndex),str(subIndex),)
|
||||
self.audioStreamsTable.add_row(*map(str, row4))
|
||||
for audioTrackId in trackIds['audio']:
|
||||
|
||||
row5 = (str(subIndex),str(subIndex),str(subIndex),str(subIndex),str(subIndex),)
|
||||
self.subtitleStreamsTable.add_row(*map(str, row5))
|
||||
ad = self.__tc.getTrackDescriptor(audioTrackId)
|
||||
dispoList = ad['disposition_list']
|
||||
|
||||
row = (ad['sub_index'],
|
||||
" ",
|
||||
ad['language'].label(),
|
||||
ad['title'],
|
||||
'Yes' if TrackDisposition.DEFAULT in dispoList else 'No',
|
||||
'Yes' if TrackDisposition.FORCED in dispoList else 'No')
|
||||
|
||||
self.audioStreamsTable.add_row(*map(str, row))
|
||||
|
||||
for subtitleTrackId in trackIds['subtitle']:
|
||||
|
||||
sd = self.__tc.getTrackDescriptor(subtitleTrackId)
|
||||
dispoList = sd['disposition_list']
|
||||
|
||||
row = (sd['sub_index'],
|
||||
" ",
|
||||
sd['language'].label(),
|
||||
sd['title'],
|
||||
'Yes' if TrackDisposition.DEFAULT in dispoList else 'No',
|
||||
'Yes' if TrackDisposition.FORCED in dispoList else 'No')
|
||||
|
||||
self.subtitleStreamsTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
def compose(self):
|
||||
|
||||
self.audioStreamsTable = DataTable(classes="five")
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_audio_subid = self.audioStreamsTable.add_column("Subindex", width=10)
|
||||
self.column_key_audio_layout = self.audioStreamsTable.add_column("Layout", width=10)
|
||||
self.column_key_audio_language = self.audioStreamsTable.add_column("Language", width=10)
|
||||
self.column_key_audio_title = self.audioStreamsTable.add_column("Title", width=10)
|
||||
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_subtitle_default = self.audioStreamsTable.add_column("Default", width=10)
|
||||
self.column_key_subtitle_forced = self.audioStreamsTable.add_column("Forced", width=10)
|
||||
|
||||
self.audioStreamsTable.cursor_type = 'row'
|
||||
|
||||
@@ -128,9 +160,10 @@ class PatternDetailsScreen(Screen):
|
||||
self.subtitleStreamsTable = DataTable(classes="five")
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_subtitle_subid = self.subtitleStreamsTable.add_column("Subindex", width=10)
|
||||
self.column_key_subtitle_language = self.subtitleStreamsTable.add_column("Language", width=10)
|
||||
self.column_key_subtitle_title = self.subtitleStreamsTable.add_column("Title", width=10)
|
||||
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)
|
||||
|
||||
@@ -157,9 +190,15 @@ class PatternDetailsScreen(Screen):
|
||||
# 5
|
||||
yield Static("Audio streams")
|
||||
yield Static(" ")
|
||||
yield Button("Add", id="button_add_audio_stream")
|
||||
yield Button("Edit", id="button_edit_audio_stream")
|
||||
yield Button("Delete", id="button_delete_audio_stream")
|
||||
|
||||
if self.pattern_obj:
|
||||
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
|
||||
|
||||
@@ -169,9 +208,15 @@ class PatternDetailsScreen(Screen):
|
||||
# 8
|
||||
yield Static("Subtitle streams")
|
||||
yield Static(" ")
|
||||
yield Button("Add", id="button_add_subtitle_stream")
|
||||
yield Button("Edit", id="button_edit_subtitle_stream")
|
||||
yield Button("Delete", id="button_delete_subtitle_stream")
|
||||
|
||||
if self.pattern_obj:
|
||||
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
|
||||
|
||||
@@ -211,24 +256,51 @@ class PatternDetailsScreen(Screen):
|
||||
self.app.pop_screen()
|
||||
|
||||
|
||||
# Save pattern when just created before adding streams
|
||||
if self.pattern_obj:
|
||||
|
||||
if event.button.id == "button_add_audio_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(TrackType.AUDIO), self.handle_add_stream)
|
||||
if event.button.id == "button_edit_audio_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(TrackType.AUDIO), self.handle_edit_stream)
|
||||
if event.button.id == "button_delete_audio_stream":
|
||||
self.app.push_screen(TrackDeleteScreen(TrackType.AUDIO), self.handle_delete_stream)
|
||||
if event.button.id == "button_add_audio_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.AUDIO, patternId = self.pattern_obj['id'], subIndex = len(self.audioStreamsTable.rows)), self.handle_add_stream)
|
||||
if event.button.id == "button_edit_audio_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.AUDIO, patternId = self.pattern_obj['id']), self.handle_edit_stream)
|
||||
if event.button.id == "button_delete_audio_stream":
|
||||
self.app.push_screen(TrackDeleteScreen(trackType = TrackType.AUDIO, patternId = self.pattern_obj['id']), self.handle_delete_stream)
|
||||
|
||||
if event.button.id == "button_add_subtitle_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(TrackType.SUBTITLE), self.handle_add_stream)
|
||||
if event.button.id == "button_edit_subtitle_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(TrackType.SUBTITLE), self.handle_edit_stream)
|
||||
if event.button.id == "button_delete_subtitle_stream":
|
||||
self.app.push_screen(TrackDeleteScreen(TrackType.SUBTITLE), self.handle_delete_stream)
|
||||
if event.button.id == "button_add_subtitle_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.SUBTITLE, patternId = self.pattern_obj['id'], subIndex = len(self.subtitleStreamsTable.rows)), self.handle_add_stream)
|
||||
if event.button.id == "button_edit_subtitle_stream":
|
||||
self.app.push_screen(TrackDetailsScreen(trackType = TrackType.SUBTITLE, patternId = self.pattern_obj['id']), self.handle_edit_stream)
|
||||
if event.button.id == "button_delete_subtitle_stream":
|
||||
self.app.push_screen(TrackDeleteScreen(trackType = TrackType.SUBTITLE, patternId = self.pattern_obj['id']), self.handle_delete_stream)
|
||||
|
||||
|
||||
def handle_add_stream(self, trackDescriptor):
|
||||
|
||||
dispoList = trackDescriptor['disposition_list']
|
||||
|
||||
if trackDescriptor['type'] == TrackType.AUDIO:
|
||||
|
||||
row = (trackDescriptor['sub_index'],
|
||||
" ",
|
||||
trackDescriptor['language'].label(),
|
||||
trackDescriptor['title'],
|
||||
'Yes' if TrackDisposition.DEFAULT in dispoList else 'No',
|
||||
'Yes' if TrackDisposition.FORCED in dispoList else 'No')
|
||||
|
||||
self.audioStreamsTable.add_row(*map(str, row))
|
||||
|
||||
if trackDescriptor['type'] == TrackType.SUBTITLE:
|
||||
|
||||
row = (trackDescriptor['sub_index'],
|
||||
" ",
|
||||
trackDescriptor['language'].label(),
|
||||
trackDescriptor['title'],
|
||||
'Yes' if TrackDisposition.DEFAULT in dispoList else 'No',
|
||||
'Yes' if TrackDisposition.FORCED in dispoList else 'No')
|
||||
|
||||
self.subtitleStreamsTable.add_row(*map(str, row))
|
||||
|
||||
|
||||
def handle_add_stream(self):
|
||||
pass
|
||||
def handle_edit_stream(self):
|
||||
pass
|
||||
def handle_delete_stream(self):
|
||||
|
||||
@@ -5,6 +5,8 @@ from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input
|
||||
from textual.containers import Grid, Horizontal
|
||||
from textual.widgets._data_table import CellDoesNotExist
|
||||
|
||||
|
||||
from ffx.model.show import Show
|
||||
from ffx.model.pattern import Pattern
|
||||
@@ -21,9 +23,9 @@ class ShowDetailsScreen(Screen):
|
||||
CSS = """
|
||||
|
||||
Grid {
|
||||
grid-size: 2;
|
||||
grid-rows: 2 auto;
|
||||
grid-columns: 30 330;
|
||||
grid-size: 2 14;
|
||||
grid-rows: 2 2 2 2 2 2 2 2 2 2 2 6 2 2;
|
||||
grid-columns: 30 90;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 1;
|
||||
@@ -114,22 +116,30 @@ class ShowDetailsScreen(Screen):
|
||||
|
||||
def getSelectedPattern(self):
|
||||
|
||||
# Fetch the currently selected row when 'Enter' is pressed
|
||||
#selected_row_index = self.table.cursor_row
|
||||
row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate)
|
||||
|
||||
selectedPattern = {}
|
||||
|
||||
if row_key is not None:
|
||||
selected_row_data = self.patternTable.get_row(row_key)
|
||||
|
||||
selectedPattern['pattern'] = str(selected_row_data[0])
|
||||
#selectedPattern['pattern'] = selected_row_data[1]
|
||||
try:
|
||||
|
||||
# Fetch the currently selected row when 'Enter' is pressed
|
||||
#selected_row_index = self.table.cursor_row
|
||||
row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate)
|
||||
|
||||
|
||||
if row_key is not None:
|
||||
selected_row_data = self.patternTable.get_row(row_key)
|
||||
|
||||
selectedPattern['pattern'] = str(selected_row_data[0])
|
||||
#selectedPattern['pattern'] = selected_row_data[1]
|
||||
|
||||
except CellDoesNotExist:
|
||||
pass
|
||||
|
||||
return selectedPattern
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def action_add_pattern(self):
|
||||
if self.show_obj:
|
||||
self.app.push_screen(PatternDetailsScreen(showId = self.show_obj['id']), self.handle_add_pattern)
|
||||
@@ -186,7 +196,7 @@ class ShowDetailsScreen(Screen):
|
||||
self.patternTable = DataTable(classes="two")
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_id = self.patternTable.add_column("Pattern", width=60)
|
||||
self.column_key_id = self.patternTable.add_column("Pattern", width=90)
|
||||
#self.column_key_name = self.patternTable.add_column("Name", width=50)
|
||||
#self.column_key_year = self.patternTable.add_column("Year", width=10)
|
||||
|
||||
@@ -197,36 +207,55 @@ class ShowDetailsScreen(Screen):
|
||||
|
||||
with Grid():
|
||||
|
||||
# 1
|
||||
yield Static("Show" if self.show_obj else "New Show", id="toplabel", classes="two")
|
||||
|
||||
# 2
|
||||
yield Static("ID")
|
||||
if self.show_obj:
|
||||
yield Static("", id="id_wdg")
|
||||
else:
|
||||
yield Input(type="integer", id="id_wdg")
|
||||
|
||||
# 3
|
||||
yield Static("Name")
|
||||
yield Input(type="text", id="name_input")
|
||||
|
||||
# 4
|
||||
yield Static("Year")
|
||||
yield Input(type="integer", id="year_input")
|
||||
|
||||
#5
|
||||
yield Static(" ", classes="two")
|
||||
|
||||
#6
|
||||
yield Static("Index Season Digits")
|
||||
yield Input(type="integer", id="index_season_digits_input")
|
||||
|
||||
#7
|
||||
yield Static("Index Episode Digits")
|
||||
yield Input(type="integer", id="index_episode_digits_input")
|
||||
|
||||
#8
|
||||
yield Static("Indicator Season Digits")
|
||||
yield Input(type="integer", id="indicator_season_digits_input")
|
||||
|
||||
#9
|
||||
yield Static("Indicator Edisode Digits")
|
||||
yield Input(type="integer", id="indicator_episode_digits_input")
|
||||
|
||||
# 10
|
||||
yield Static(" ", classes="two")
|
||||
|
||||
# 11
|
||||
yield Static("File patterns", classes="two")
|
||||
# 12
|
||||
yield self.patternTable
|
||||
|
||||
# 13
|
||||
yield Static(" ", classes="two")
|
||||
|
||||
# 14
|
||||
yield Button("Save", id="save_button")
|
||||
yield Button("Cancel", id="cancel_button")
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@ import click
|
||||
|
||||
from ffx.model.track import Track
|
||||
|
||||
from .track_type import TrackType
|
||||
|
||||
from .track_disposition import TrackDisposition
|
||||
from .iso_language import IsoLanguage
|
||||
|
||||
|
||||
class TrackController():
|
||||
|
||||
@@ -11,82 +16,151 @@ class TrackController():
|
||||
self.Session = self.context['database_session'] # convenience
|
||||
|
||||
|
||||
# def updatePattern(self, show_id, pattern):
|
||||
#
|
||||
# try:
|
||||
# s = self.Session()
|
||||
# q = s.query(Pattern).filter(Pattern.show_id == int(show_id), Pattern.pattern == str(pattern))
|
||||
#
|
||||
# if not q.count():
|
||||
# pattern = Pattern(show_id = int(show_id), pattern = str(pattern))
|
||||
# s.add(pattern)
|
||||
# s.commit()
|
||||
# return True
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"PatternController.updatePattern(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
#
|
||||
#
|
||||
#
|
||||
# def findPattern(self, showId, pattern):
|
||||
#
|
||||
# try:
|
||||
# s = self.Session()
|
||||
# q = s.query(Pattern).filter(Pattern.show_id == int(showId), Pattern.pattern == str(pattern))
|
||||
#
|
||||
# if q.count():
|
||||
# pattern = q.first()
|
||||
# return int(pattern.id)
|
||||
# else:
|
||||
# return None
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"PatternController.findPattern(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
#
|
||||
#
|
||||
# def getPatternDescriptor(self, patternId):
|
||||
#
|
||||
# try:
|
||||
# s = self.Session()
|
||||
# q = s.query(Pattern).filter(Pattern.id == int(patternId))
|
||||
#
|
||||
# patternDescriptor = {}
|
||||
# if q.count():
|
||||
# pattern = q.first()
|
||||
#
|
||||
# patternDescriptor['id'] = pattern.id
|
||||
# patternDescriptor['pattern'] = pattern.pattern
|
||||
# patternDescriptor['show_id'] = pattern.show_id
|
||||
#
|
||||
# return patternDescriptor
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"PatternController.getPatternDescriptor(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
#
|
||||
#
|
||||
# def deletePattern(self, patternId):
|
||||
# try:
|
||||
# s = self.Session()
|
||||
# q = s.query(Pattern).filter(Pattern.id == int(patternId))
|
||||
#
|
||||
# if q.count():
|
||||
#
|
||||
# #DAFUQ: https://stackoverflow.com/a/19245058
|
||||
# # q.delete()
|
||||
# pattern = q.first()
|
||||
# s.delete(pattern)
|
||||
#
|
||||
# s.commit()
|
||||
# return True
|
||||
# return False
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"PatternController.deletePattern(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
def addTrack(self, trackDescriptor):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
track = Track(pattern_id = int(trackDescriptor['pattern_id']),
|
||||
|
||||
track_type = int(trackDescriptor['type'].value),
|
||||
|
||||
sub_index = int(trackDescriptor['sub_index']),
|
||||
|
||||
language = str(trackDescriptor['language'].threeLetter()),
|
||||
|
||||
title = str(trackDescriptor['title']),
|
||||
|
||||
disposition_flags = int(TrackDisposition.toFlags(trackDescriptor['disposition_list'])))
|
||||
|
||||
s.add(track)
|
||||
s.commit()
|
||||
return True
|
||||
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TrackController.addTrack(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
# def updateTrack(self, trackDescriptor):
|
||||
#
|
||||
# try:
|
||||
# s = self.Session()
|
||||
# q = s.query(Track).filter(Track.id == int(trackId))
|
||||
#
|
||||
# if not q.count():
|
||||
# track = Track(pattern_id = int(trackDescriptor['pattern_id']),
|
||||
# track_type = TrackType(trackDescriptor['type']),
|
||||
# sub_index = int(trackDescriptor['sub_index']),
|
||||
# language = IsoLanguage(trackDescriptor['language']),
|
||||
# title = str(trackDescriptor['title']),
|
||||
# disposition_flags = TrackDisposition.toFlags(trackDescriptor['disposition_list']))
|
||||
# s.add(track)
|
||||
# s.commit()
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
#
|
||||
# except Exception as ex:
|
||||
# raise click.ClickException(f"TrackController.updateTrack(): {repr(ex)}")
|
||||
# finally:
|
||||
# s.close()
|
||||
|
||||
|
||||
def findAllTracks(self, patternId):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
|
||||
trackDescriptors = {}
|
||||
trackDescriptors['audio'] = []
|
||||
trackDescriptors['subtitle'] = []
|
||||
|
||||
q_audio = s.query(Track).filter(Track.pattern_id == int(patternId), Track.track_type == TrackType.AUDIO.value)
|
||||
|
||||
for audioTrack in q_audio.all():
|
||||
trackDescriptors['audio'].append(audioTrack.id)
|
||||
|
||||
q_subtitle = s.query(Track).filter(Track.pattern_id == int(patternId), Track.track_type == TrackType.SUBTITLE.value)
|
||||
for subtitleTrack in q_subtitle.all():
|
||||
trackDescriptors['subtitle'].append(subtitleTrack.id)
|
||||
|
||||
|
||||
return trackDescriptors
|
||||
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TrackController.findAllTracks(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def findTrack(self, patternId, trackType, subIndex):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
q = s.query(Track).filter(Track.pattern_id == int(patternId), Track.track_type == trackType, Track.sub_index == int(subIndex))
|
||||
|
||||
if q.count():
|
||||
track = q.first()
|
||||
return int(track.id)
|
||||
else:
|
||||
return None
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TrackController.findTrack(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def getTrackDict(self, track):
|
||||
trackDescriptor = {}
|
||||
trackDescriptor['pattern_id'] = int(track.pattern_id)
|
||||
trackDescriptor['type'] = TrackType(track.track_type)
|
||||
trackDescriptor['sub_index'] = int(track.sub_index)
|
||||
trackDescriptor['language'] = IsoLanguage.findThreeLetter(track.language)
|
||||
trackDescriptor['title'] = str(track.title)
|
||||
trackDescriptor['disposition_list'] = TrackDisposition.toList(track.disposition_flags)
|
||||
return trackDescriptor
|
||||
|
||||
|
||||
def getTrackDescriptor(self, trackId):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
q = s.query(Track).filter(Track.id == int(trackId))
|
||||
|
||||
if q.count():
|
||||
track = q.first()
|
||||
return self.getTrackDict(track)
|
||||
else:
|
||||
return {}
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TrackController.getTrackDescriptor(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def deleteTrack(self, trackId):
|
||||
try:
|
||||
s = self.Session()
|
||||
q = s.query(Track).filter(Track.id == int(trackId))
|
||||
|
||||
if q.count():
|
||||
|
||||
#DAFUQ: https://stackoverflow.com/a/19245058
|
||||
# q.delete()
|
||||
pattern = q.first()
|
||||
s.delete(pattern)
|
||||
|
||||
s.commit()
|
||||
return True
|
||||
return False
|
||||
|
||||
except Exception as ex:
|
||||
raise click.ClickException(f"TrackController.deleteTrack(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import click
|
||||
import click, time
|
||||
|
||||
from textual import events
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input
|
||||
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input, Checkbox, SelectionList, Select
|
||||
from textual.containers import Grid, Horizontal
|
||||
|
||||
|
||||
from ffx.model.show import Show
|
||||
from ffx.model.pattern import Pattern
|
||||
|
||||
from .track_controller import TrackController
|
||||
# from .pattern_controller import PatternController
|
||||
from .pattern_controller import PatternController
|
||||
# from .show_controller import ShowController
|
||||
|
||||
from .track_type import TrackType
|
||||
|
||||
from .iso_language import IsoLanguage
|
||||
from .track_disposition import TrackDisposition
|
||||
|
||||
|
||||
# Screen[dict[int, str, int]]
|
||||
class TrackDetailsScreen(Screen):
|
||||
@@ -22,8 +26,8 @@ class TrackDetailsScreen(Screen):
|
||||
CSS = """
|
||||
|
||||
Grid {
|
||||
grid-size: 5 11;
|
||||
grid-rows: 2 2 2 2 6 2 2 6 2 2 2;
|
||||
grid-size: 5 18;
|
||||
grid-rows: 2 2 2 2 2 3 2 2 2 2 2 6 2 2 6 2 2 2;
|
||||
grid-columns: 25 25 25 25 25;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -36,7 +40,13 @@ class TrackDetailsScreen(Screen):
|
||||
Button {
|
||||
border: none;
|
||||
}
|
||||
|
||||
SelectionList {
|
||||
border: none;
|
||||
min-height: 6;
|
||||
}
|
||||
Select {
|
||||
border: none;
|
||||
}
|
||||
DataTable {
|
||||
min-height: 6;
|
||||
}
|
||||
@@ -44,7 +54,10 @@ class TrackDetailsScreen(Screen):
|
||||
#toplabel {
|
||||
height: 1;
|
||||
}
|
||||
|
||||
|
||||
.two {
|
||||
column-span: 2;
|
||||
}
|
||||
.three {
|
||||
column-span: 3;
|
||||
}
|
||||
@@ -62,21 +75,25 @@ class TrackDetailsScreen(Screen):
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, trackType : TrackType, streamId = None, patternId = None):
|
||||
def __init__(self, trackId = None, patternId = None, trackType : TrackType = None, subIndex = None):
|
||||
super().__init__()
|
||||
|
||||
self.context = self.app.getContext()
|
||||
self.Session = self.context['database_session'] # convenience
|
||||
|
||||
self.trackType = trackType
|
||||
|
||||
self.__tc = TrackController(context = self.context)
|
||||
#self.__pc = PatternController(context = self.context)
|
||||
#self.__sc = ShowController(context = self.context)
|
||||
self.__pc = PatternController(context = self.context)
|
||||
|
||||
self.track_obj = self.__tc.getTrackDescriptor(trackId) if trackId is not None else {} #TODO: Overwriting alternative values if set
|
||||
|
||||
if trackType is None:
|
||||
raise click.ClickException('Track type is required to be set')
|
||||
|
||||
self.trackType = trackType
|
||||
self.subIndex = subIndex
|
||||
|
||||
self.pattern_obj = self.__pc.getPatternDescriptor(patternId) if patternId is not None else {}
|
||||
|
||||
# self.pattern_obj = self.__pc.getPatternDescriptor(patternId) if patternId is not None else {}
|
||||
# self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {}
|
||||
self.track_obj = {}
|
||||
|
||||
# def loadPatterns(self, show_id):
|
||||
#
|
||||
@@ -93,9 +110,12 @@ class TrackDetailsScreen(Screen):
|
||||
|
||||
|
||||
def on_mount(self):
|
||||
pass
|
||||
# if self.pattern_obj:
|
||||
# self.query_one("#pattern_input", Input).value = str(self.pattern_obj['pattern'])
|
||||
|
||||
if self.pattern_obj:
|
||||
self.query_one("#patternlabel", Static).update(str(self.pattern_obj['pattern']))
|
||||
|
||||
if self.subIndex is not None:
|
||||
self.query_one("#subindexlabel", Static).update(str(self.subIndex))
|
||||
|
||||
# if self.show_obj:
|
||||
# self.query_one("#showlabel", Static).update(f"{self.show_obj['id']} - {self.show_obj['name']} ({self.show_obj['year']})")
|
||||
@@ -116,27 +136,19 @@ class TrackDetailsScreen(Screen):
|
||||
|
||||
def compose(self):
|
||||
|
||||
# self.audioStreamsTable = DataTable(classes="five")
|
||||
#
|
||||
# # Define the columns with headers
|
||||
# self.column_key_audio_subid = self.audioStreamsTable.add_column("Subindex", width=10)
|
||||
# self.column_key_audio_layout = self.audioStreamsTable.add_column("Layout", width=10)
|
||||
# self.column_key_audio_language = self.audioStreamsTable.add_column("Language", width=10)
|
||||
# self.column_key_audio_title = self.audioStreamsTable.add_column("Title", 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=10)
|
||||
# self.column_key_subtitle_language = self.subtitleStreamsTable.add_column("Language", width=10)
|
||||
# self.column_key_subtitle_title = self.subtitleStreamsTable.add_column("Title", width=10)
|
||||
# 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'
|
||||
self.trackTagsTable = DataTable(classes="five")
|
||||
|
||||
# Define the columns with headers
|
||||
self.column_key_track_tag_key = self.trackTagsTable.add_column("Key", width=10)
|
||||
self.column_key_track_tag_value = self.trackTagsTable.add_column("Value", width=30)
|
||||
|
||||
self.trackTagsTable.cursor_type = 'row'
|
||||
|
||||
|
||||
languages = [l.label() for l in IsoLanguage]
|
||||
|
||||
dispositions = [(d.label(), d.index(), False) for d in TrackDisposition]
|
||||
|
||||
|
||||
yield Header()
|
||||
|
||||
@@ -144,69 +156,102 @@ class TrackDetailsScreen(Screen):
|
||||
|
||||
# 1
|
||||
yield Static(f"Edit {self.trackType.label()} stream" if self.track_obj else f"New {self.trackType.label()} stream", id="toplabel", classes="five")
|
||||
# yield Input(type="text", id="pattern_input", classes="four")
|
||||
|
||||
# 2
|
||||
# yield Static("from show")
|
||||
# yield Static("", id="showlabel")
|
||||
#
|
||||
# # 3
|
||||
# yield Static(" ", classes="five")
|
||||
# # 4
|
||||
# yield Static(" ", classes="five")
|
||||
#
|
||||
# # 5
|
||||
# yield Static("Audio streams")
|
||||
# yield Static(" ")
|
||||
# yield Button("Add", id="button_add_audio_stream")
|
||||
# yield Button("Edit", id="button_edit_audio_stream")
|
||||
# yield Button("Delete", id="button_delete_audio_stream")
|
||||
# # 6
|
||||
# yield self.audioStreamsTable
|
||||
#
|
||||
# # 7
|
||||
# yield Static(" ", classes="five")
|
||||
#
|
||||
# # 8
|
||||
# yield Static("Subtitle streams")
|
||||
# yield Static(" ")
|
||||
# yield Button("Add", id="button_add_subtitle_stream")
|
||||
# yield Button("Edit", id="button_edit_subtitle_stream")
|
||||
# yield Button("Delete", id="button_delete_subtitle_stream")
|
||||
# # 9
|
||||
# yield self.subtitleStreamsTable
|
||||
#
|
||||
yield Static("for pattern")
|
||||
yield Static("", id="patternlabel", classes="four")
|
||||
|
||||
# 3
|
||||
yield Static("sub index")
|
||||
yield Static("", id="subindexlabel", classes="four")
|
||||
|
||||
# 4
|
||||
yield Static(" ", classes="five")
|
||||
# 5
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 6
|
||||
yield Static("Language")
|
||||
yield Select.from_values(languages, classes="four", id="language_select")
|
||||
# 7
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 8
|
||||
yield Static("Title")
|
||||
yield Input(id="title_input", classes="four")
|
||||
|
||||
# 9
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 10
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 11
|
||||
yield Static("Stream tags")
|
||||
yield Static(" ", classes="two")
|
||||
yield Button("Add", id="button_add_stream_tag")
|
||||
yield Button("Delete", id="button_delete_stream_tag")
|
||||
# 12
|
||||
yield self.trackTagsTable
|
||||
|
||||
# 13
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 14
|
||||
yield Static("Stream dispositions", classes="five")
|
||||
|
||||
# 15
|
||||
yield SelectionList[int](
|
||||
*dispositions,
|
||||
classes="five",
|
||||
id = "dispositions_selection_list"
|
||||
)
|
||||
|
||||
# 16
|
||||
yield Static(" ", classes="five")
|
||||
# 17
|
||||
yield Static(" ", classes="five")
|
||||
|
||||
# 18
|
||||
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 getTrackDescriptorFromInput(self):
|
||||
|
||||
trackDescriptor = {}
|
||||
|
||||
trackDescriptor['pattern_id'] = int(self.pattern_obj['id'])
|
||||
|
||||
trackDescriptor['type'] = TrackType(self.trackType)
|
||||
trackDescriptor['sub_index'] = self.subIndex
|
||||
|
||||
trackDescriptor['language'] = IsoLanguage.find(str(self.query_one("#language_select", Select).value))
|
||||
trackDescriptor['title'] = str(self.query_one("#title_input", Input).value)
|
||||
|
||||
|
||||
disposition_flags = sum([2**f for f in self.query_one("#dispositions_selection_list", SelectionList).selected])
|
||||
|
||||
trackDescriptor['disposition_list'] = TrackDisposition.toList(disposition_flags)
|
||||
|
||||
|
||||
return trackDescriptor
|
||||
|
||||
|
||||
# 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
|
||||
# if event.button.id == "save_button":
|
||||
#
|
||||
# pattern = self.getPatternFromInput()
|
||||
#
|
||||
# if self.__pc.updatePattern(self.show_obj['id'], pattern):
|
||||
#
|
||||
# screenResult = {}
|
||||
# screenResult['show_id'] = self.show_obj['id']
|
||||
# screenResult['pattern'] = pattern
|
||||
#
|
||||
# self.dismiss(screenResult)
|
||||
# else:
|
||||
# #TODO: Meldung
|
||||
# self.app.pop_screen()
|
||||
if event.button.id == "save_button":
|
||||
|
||||
trackDescriptor = self.getTrackDescriptorFromInput()
|
||||
|
||||
if self.__tc.addTrack(trackDescriptor): #!
|
||||
self.dismiss(trackDescriptor)
|
||||
else:
|
||||
#TODO: Meldung
|
||||
self.app.pop_screen()
|
||||
|
||||
if event.button.id == "cancel_button":
|
||||
self.app.pop_screen()
|
||||
|
||||
49
bin/ffx/track_disposition.py
Normal file
49
bin/ffx/track_disposition.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from enum import Enum
|
||||
import difflib
|
||||
|
||||
class TrackDisposition(Enum):
|
||||
|
||||
DEFAULT = {"name": "default", "index": 0}
|
||||
FORCED = {"name": "forced", "index": 1}
|
||||
|
||||
DUB = {"name": "dub", "index": 2}
|
||||
ORIGINAL = {"name": "original", "index": 3}
|
||||
COMMENT = {"name": "comment", "index": 4}
|
||||
LYRICS = {"name": "lyrics", "index": 5}
|
||||
KARAOKE = {"name": "karaoke", "index": 6}
|
||||
HEARING_IMPAIRED = {"name": "hearing_impaired", "index": 7}
|
||||
VISUAL_IMPAIRED = {"name": "visual_impaired", "index": 8}
|
||||
CLEAN_EFFECTS = {"name": "clean_effects", "index": 9}
|
||||
ATTACHED_PIC = {"name": "attached_pic", "index": 10}
|
||||
TIMED_THUMBNAILS = {"name": "timed_thumbnails", "index": 11}
|
||||
NON_DIEGETICS = {"name": "non_diegetic", "index": 12}
|
||||
CAPTIONS = {"name": "captions", "index": 13}
|
||||
DESCRIPTIONS = {"name": "descriptions", "index": 14}
|
||||
METADATA = {"name": "metadata", "index": 15}
|
||||
DEPENDENT = {"name": "dependent", "index": 16}
|
||||
STILL_IMAGE = {"name": "still_image", "index": 17}
|
||||
|
||||
def label(self):
|
||||
return str(self.value['name'])
|
||||
|
||||
def index(self):
|
||||
return int(self.value['index'])
|
||||
|
||||
|
||||
@staticmethod
|
||||
def toFlags(dispositionList):
|
||||
"""Flags stored in integer bits (2**index)"""
|
||||
|
||||
flags = 0
|
||||
for d in dispositionList:
|
||||
flags += 2 ** d.index()
|
||||
return flags
|
||||
|
||||
@staticmethod
|
||||
def toList(flags):
|
||||
|
||||
dispositionList = []
|
||||
for d in TrackDisposition:
|
||||
if flags & int(2 ** d.index()):
|
||||
dispositionList += [d]
|
||||
return dispositionList
|
||||
Reference in New Issue
Block a user