diff --git a/CONTROL/control b/CONTROL/control index adf35ee..65e959f 100644 --- a/CONTROL/control +++ b/CONTROL/control @@ -1,6 +1,6 @@ Description: MediathekCockpit Maintainer: dream-alpha Package: enigma2-plugin-extensions-mediathekcockpit -Version: 2.5.1 +Version: 3.0.5 Architecture: all Depends: enigma2-plugin-systemplugins-jobcockpit diff --git a/README.md b/README.md index 2e49ab5..50d0e42 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ DreamOS plugin to browse Mediathek libraries and download movies. ![Screenshot](mtc1.png) +![Screenshot](mtc2.png) + ## Features - Plays back Mediathek video files. - Searches for media files manually or from EPG using blue button. diff --git a/mtc2.png b/mtc2.png new file mode 100755 index 0000000..4365fec Binary files /dev/null and b/mtc2.png differ diff --git a/po/de.po b/po/de.po index 8ec9298..4675417 100644 --- a/po/de.po +++ b/po/de.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: MediathekCockpit\n" -"POT-Creation-Date: 2024-10-06 19:40+0200\n" -"PO-Revision-Date: 2024-10-06 19:41+0200\n" +"POT-Creation-Date: 2024-10-08 18:01+0200\n" +"PO-Revision-Date: 2024-10-08 18:03+0200\n" "Last-Translator: dream-alpha\n" "Language-Team: \n" "Language: de_DE\n" @@ -83,33 +83,6 @@ msgstr "Download fehlgeschlagen" msgid "Abort" msgstr "Abbrechen" -msgid "Download Manager" -msgstr "Download Manager" - -msgid "Settings" -msgstr "Einstellungen" - -msgid "About" -msgstr "Über" - -msgid "Functions" -msgstr "Funktionen" - -msgid "Menu" -msgstr "Menü" - -msgid "Quit" -msgstr "Beenden" - -msgid "Restart from the beginning" -msgstr "Neustart von Anfang an" - -msgid "None" -msgstr "Nichts" - -msgid "Action" -msgstr "Aktion" - msgid "Movies" msgstr "Filme" @@ -128,18 +101,12 @@ msgstr "Download" msgid "Search" msgstr "Suche" +msgid "Downloading movies..." +msgstr "Laden der Filme..." + msgid "No movies available" msgstr "Keine Filme verfügbar" -msgid "Minutes" -msgstr "Minuten" - -msgid "Next page" -msgstr "Nächste Seite" - -msgid "Select" -msgstr "Auswählen" - msgid "Entries" msgstr "Einträge" @@ -170,6 +137,42 @@ msgstr "Filmverzeichnis existiert nicht" msgid "No movie to download" msgstr "Kein Film verfügbar" +msgid "Download Manager" +msgstr "Download Manager" + +msgid "Settings" +msgstr "Einstellungen" + +msgid "About" +msgstr "Über" + +msgid "Functions" +msgstr "Funktionen" + +msgid "Menu" +msgstr "Menü" + +msgid "Quit" +msgstr "Beenden" + +msgid "Restart from the beginning" +msgstr "Neustart von Anfang an" + +msgid "None" +msgstr "Nichts" + +msgid "Action" +msgstr "Aktion" + +msgid "Minutes" +msgstr "Minuten" + +msgid "Next page" +msgstr "Nächste Seite" + +msgid "Select" +msgstr "Auswählen" + msgid "Enter search text" msgstr "Eingabe des Suchtexts" diff --git a/src/ChannelSelection.py b/src/ChannelSelection.py index 72e3b67..2fe628e 100644 --- a/src/ChannelSelection.py +++ b/src/ChannelSelection.py @@ -54,7 +54,6 @@ def openChannelSelectionCallback(self, selection): if "queries" in self.postdata: del self.postdata["queries"] else: - self.postdata["queries"] = [] - self.postdata["queries"].append({"fields": ["channel"], "query": channel}) - self.postdata["offset"] = 0 - self.close("movies") + self.postdata["queries"] = [{"fields": ["channel"], "query": channel}] + self.postdata["offset"] = 0 + self.downloadMovies() diff --git a/src/Debug.py b/src/Debug.py index fbcfb9e..5045d56 100644 --- a/src/Debug.py +++ b/src/Debug.py @@ -27,7 +27,7 @@ logger = None streamer = None -format_string = (ID + ": " + "%(levelname)s: %(filename)s: %(funcName)s: %(message)s") +format_string = ID + ": " + "%(levelname)s: %(filename)s: %(funcName)s: %(message)s" log_levels = {"ERROR": logging.ERROR, "INFO": logging.INFO, "DEBUG": logging.DEBUG} plugin = PLUGIN.lower() exec("config.plugins." + plugin + " = ConfigSubsection()") # noqa: F401, pylint: disable=W0122 diff --git a/src/MediathekCockpit.py b/src/MediathekCockpit.py index 1357d05..b4ed685 100644 --- a/src/MediathekCockpit.py +++ b/src/MediathekCockpit.py @@ -19,43 +19,231 @@ # . +import os +import json +from time import localtime, strftime +from enigma import eServiceReference +from Plugins.SystemPlugins.JobCockpit.JobSupervisor import JobSupervisor +from Screens.Screen import Screen +from Screens.MessageBox import MessageBox +from Components.ActionMap import ActionMap from Components.config import config +from Components.Label import Label +from Components.Sources.StaticText import StaticText +from Components.Sources.List import List from .Debug import logger -from .Movies import Movies +from .__init__ import _ +from .Version import PLUGIN, ID +from .MoviePlayer import MoviePlayer +from .EventView import EventView +from .DownloadJob import DownloadJob +from .Menu import Menu +from .ChannelSelection import ChannelSelection +from .Constants import ( + LIST_DATE, LIST_EVENT_NAME, LIST_SHORT_DESCRIPTION, LIST_TIME, LIST_DURATION, LIST_CHANNEL, LIST_TOPIC, LIST_DESCRIPTION, LIST_TIMESTAMP +) +from .ChannelUtils import getServiceReference +from .UnicodeUtils import convertUni2Str +from .WebRequests import WebRequests +from .RecordingUtils import calcRecordingFilename +from .CallLater import callLater +from .MovieUtils import getVideoUrl, getVideoResolutions, getPlaylistSegments, getMovieRow, getNextRow from .Search import Search -class MediathekCockpit(Search): - def __init__(self, session, query=""): - logger.info("query: %s", query) - self.session = session - Search.__init__(self, session, self.keyboardCallback) +class MediathekCockpit(Screen, Menu, ChannelSelection, Search): + def __init__(self, session, query): + self.query = query + Screen.__init__(self, session) + self.skinName = "MediathekCockpit" + Menu.__init__(self) + ChannelSelection.__init__(self) + Search.__init__(self) self.last_service = self.session.nav.getCurrentlyPlayingServiceReference() + self.title_base = PLUGIN + " - " + _("Movies") + " - " + _("Search results") + self.title = self.title_base + " - " + _("Downloading movies...") - self.postdata = {} - self.postdata = {"sortOrder": "desc", "sortBy": "timestamp"} - self.postdata["size"] = config.plugins.mediathekcockpit.size.value - self.postdata["offset"] = 0 - self.postdata["future"] = config.plugins.mediathekcockpit.future.value + self["key_red"] = StaticText(_("Exit")) + self["key_green"] = StaticText(_("Channels")) + self["key_yellow"] = StaticText(_("Download")) + self["key_blue"] = StaticText(_("Search")) - if query: - self.openKeyboard(query) + self["description"] = Label("") + self["date"] = Label("") + self["sresult"] = Label("") + + self["list"] = List() + self.list = [] + self.curr_index = 0 + self.query_info = {} + + self["actions"] = ActionMap( + ["MTC_Actions"], + { + "ok": self.pressOk, + "cancel": self.pressClose, + "red": self.pressRed, + "green": self.pressGreen, + "yellow": self.pressYellow, + "blue": self.pressBlue, + "menu": self.openMenu, + "info": self.pressInfo + } + ) + self["list"].onSelectionChanged.append(self.__onSelectionChanged) + self.onLayoutFinish.append(self.__onLayoutFinish) + self.job_manager = JobSupervisor.getInstance().getJobManager(ID) + + def __onLayoutFinish(self): + logger.info("...") + if self.query: + query = self.query + self.query = "" + callLater(0, self.openKeyboard, query) else: - self.showScreen(Movies, self.postdata, self.last_service) - - def showScreen(self, screen, *args): - logger.info("screen: %s", screen) - self.session.openWithCallback(self.showScreenCallback, screen, *args) - - def showScreenCallback(self, return_screen, arg=""): - logger.info("return_screen: %s", return_screen) - if return_screen == "movies": - self.showScreen(Movies, self.postdata, self.last_service) - elif return_screen == "search": - self.openKeyboard(arg) + self.postdata["offset"] = 0 + callLater(0, self.downloadMovies) + + def downloadMovies(self): + logger.info("postdata: %s", self.postdata) + result_count = 0 + if self.postdata["offset"] == 0: + self.list = [] + url = "https://mediathekviewweb.de/api/query" + result = WebRequests().postContent(url, self.postdata) + if result.text: + data = convertUni2Str(json.loads(result.text)) + # logger.debug("data: %s", data) + results = data["result"]["results"] + # logger.debug("results: %s", results) + for x in results: + self.list.append(getMovieRow(x)) + + self.query_info = data["result"]["queryInfo"] + result_count = min(self.postdata["offset"] + self.query_info["resultCount"], self.query_info["totalResults"]) + self.query_info["filmlisteTimestamp"] = strftime("%d.%m.%Y %H:%M:%S", localtime(int(self.query_info["filmlisteTimestamp"]))) + # logger.debug("query_info: %s", self.query_info) + if self.query_info["totalResults"] != result_count: + self.list.append(getNextRow()) + + self["sresult"].setText("%s: %s/%s\n%s: %s ms\n%s: %s" % ( + _("Entries"), result_count, self.query_info.get("totalResults", 0), + _("Load time"), self.query_info.get("searchEngineTime", 0), + _("From"), self.query_info.get("filmlisteTimestamp", "-")) + ) + + logger.info("list: %s", self.list) + self["list"].setList(self.list) + self["list"].setIndex(self.curr_index) + if len(self.list) == 0: + self.title = self.title_base + " - " + _("No movies available") else: - # exit - self.session.nav.playService(self.last_service) + self.title = self.title_base + + def __onSelectionChanged(self): + logger.info("...") + self["description"].setText("") + self["date"].setText("") + self.curr = self["list"].getCurrent() + logger.debug("curr: %s", self.curr) + if self.curr and self.curr[LIST_CHANNEL] != ">>>": + self["description"].setText(self.curr[LIST_DESCRIPTION]) + self["date"].setText( + "%s: %s %s\n%s: %s\n%s: %s" % ( + _("Broadcast time"), self.curr[LIST_DATE], self.curr[LIST_TIME], + _("Duration"), self.curr[LIST_DURATION], + _("Quality"), ", ".join(getVideoResolutions(self.curr)) + ) + ) + + def pressOk(self): + self.curr = self["list"].getCurrent() + if self.curr: + if self.curr[LIST_CHANNEL] == ">>>": + self.curr_index = self["list"].getIndex() + logger.debug("curr_index: %s", self.curr_index) + self.postdata["offset"] += int(config.plugins.mediathekcockpit.size.value) + del self.list[len(self.list) - 1] + self.downloadMovies() + else: + val = int(config.plugins.mediathekcockpit.movie_resolution.value) + url, _resolution = getVideoUrl(self.curr, val) + if url: + if url.endswith(("mp4", "flv", "m3u8")): + self.playMovie(url) + else: + logger.error("unsupported url: %s", url) + + def playMovie(self, url, suburi=None): + logger.info("url: %s, suburi: %s", url, suburi) + sref = eServiceReference(eServiceReference.idGST, 0, url.encode("utf-8")) + sref.setName(self.curr[LIST_EVENT_NAME]) + if suburi: + sref.setSuburi(suburi.encode("utf-8")) + self.session.openWithCallback(self.playMovieCallback, MoviePlayer, sref, menuval=None, infoval=(EventView, self.curr)) + + def playMovieCallback(self): + self.session.nav.playService(self.last_service) + + def pressRed(self): + self.pressClose() + + def pressGreen(self): + self.openChannelSelection() + + def pressYellow(self): + logger.info("...") + self.curr = self["list"].getCurrent() + movie_dir = config.plugins.mediathekcockpit.movie_dir.value + if self.curr and self.curr[LIST_CHANNEL] != ">>>": + if os.path.exists(movie_dir): + url, resolution = getVideoUrl(self.curr, int(config.plugins.mediathekcockpit.movie_resolution.value)) + ext = url[url.rfind("."):] if url.rfind(".") != -1 else ".mp4" + + recording_file = calcRecordingFilename(self.curr[LIST_TIMESTAMP], self.curr[LIST_CHANNEL], self.curr[LIST_EVENT_NAME], movie_dir) + ext + service_ref = getServiceReference(self.curr[LIST_CHANNEL]) + segments = [] + if ".m3u8" in url: + segments = getPlaylistSegments(url) + self.job_manager.AddJob( + DownloadJob( + url, + segments, + recording_file, + self.curr[LIST_EVENT_NAME], + self.curr[LIST_SHORT_DESCRIPTION], + self.curr[LIST_DESCRIPTION], + self.curr[LIST_TIMESTAMP], + service_ref + ) + ) + self.session.open( + MessageBox, "%s:\n\n%s\n\n%s: %s" % ( + _("Download added"), + self.curr[LIST_EVENT_NAME], + _("Video resolution"), resolution, + ), + type=MessageBox.TYPE_INFO, + timeout=4 + ) + else: + self.session.open(MessageBox, _("Movie directory does not exist") + ":\n\n" + movie_dir, type=MessageBox.TYPE_ERROR) + + else: + self.session.open(MessageBox, _("No movie to download"), type=MessageBox.TYPE_INFO, timeout=4) + + def pressBlue(self): + query = "" + self.curr = self["list"].getCurrent() + if self.curr: + query = self.curr[LIST_TOPIC] + self.openKeyboard(query) + + def pressInfo(self): + self.curr = self["list"].getCurrent() + if self.curr and self.curr[LIST_CHANNEL] != ">>>": + self.session.open(EventView, self.curr) - def keyboardCallback(self): - self.showScreen(Movies, self.postdata, self.last_service) + def pressClose(self): + logger.info("...") + self.close() diff --git a/src/MovieUtils.py b/src/MovieUtils.py new file mode 100644 index 0000000..f956df7 --- /dev/null +++ b/src/MovieUtils.py @@ -0,0 +1,115 @@ +# !/usr/bin/python +# coding=utf-8 +# +# Copyright (C) 2018-2024 by dream-alpha +# +# In case of reuse of this source code please do not remove this copyright. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# For more information on the GNU General Public License see: +# . + + +import os +from datetime import datetime +from urlparse import urljoin +from . import m3u8 +from .Debug import logger +from .ConfigInit import VIDEO_RESOLUTIONS, VIDEO_RESOLUTIONS_DICT +from .Constants import ( + plugindir, LIST_URL_VIDEO_LOW, LIST_URL_VIDEO, LIST_URL_VIDEO_HD, LIST_DATE, LIST_EVENT_NAME, LIST_SHORT_DESCRIPTION, LIST_TIME, LIST_DURATION, LIST_CHANNEL, LIST_CHANNEL_PIXMAP, LIST_TOPIC, LIST_TITLE, LIST_DESCRIPTION, LIST_SIZE, LIST_ID, LIST_URL_WEBSITE, LIST_TIMESTAMP, LIST_END +) +from .__init__ import _ +from Tools.LoadPixmap import LoadPixmap + + +def getMovieRow(x): + logger.debug("x: %s", x) + row = [""] * LIST_END + row[LIST_TIMESTAMP] = timestamp = int(x.get("timestamp", "0")) + row_datetime = datetime.fromtimestamp(timestamp).strftime("%d.%m.%Y %H:%M:%S") + row[LIST_DATE] = row_datetime[0:10] + row[LIST_TIME] = row_datetime[11:16] + row[LIST_DURATION] = "%s" % str(int(x.get("duration", 0)) / 60) + " " + _("Minutes") + row[LIST_CHANNEL] = channel = x.get("channel", "") + row[LIST_CHANNEL_PIXMAP] = LoadPixmap("%slogos/%s.png" % (plugindir, channel.replace(" ", "").upper())) if channel else None + topic = x.get("topic", "") + title = x.get("title", "") + if title.startswith(topic): + title = title.replace(topic, "").strip() + if title.startswith("-"): + title = title[1:].strip() + row[LIST_TOPIC] = topic + row[LIST_TITLE] = title + row[LIST_EVENT_NAME] = topic + " - " + title if title else topic + row[LIST_SHORT_DESCRIPTION] = title + row[LIST_DESCRIPTION] = x.get("description", "") + size = x.get("size", 0) + row[LIST_SIZE] = int(size) / (1024 * 1024) if size is not None else 0 + row[LIST_ID] = x.get("id", "") + row[LIST_URL_VIDEO_LOW] = x.get("url_video_low", "") + row[LIST_URL_VIDEO] = x.get("url_video", "") + row[LIST_URL_VIDEO_HD] = x.get("url_video_hd", "") + row[LIST_URL_WEBSITE] = x.get("url_website", "") + logger.debug("row: %s", row) + return row + + +def getNextRow(): + row = [""] * LIST_END + row[LIST_CHANNEL] = ">>>" + row[LIST_EVENT_NAME] = _("Next page") + row[LIST_SHORT_DESCRIPTION] = _("Select") + row[LIST_DATE] = ">>>" + row[LIST_CHANNEL_PIXMAP] = None + logger.debug("row: %s", row) + return row + + +def getVideoResolutions(curr): + def checkVideoUrl(was, curr): + return curr[was] and curr[was].startswith("http") + + resolutions = [] + if checkVideoUrl(LIST_URL_VIDEO_LOW, curr): + resolutions.append(_("Low")) + if checkVideoUrl(LIST_URL_VIDEO, curr): + resolutions.append(_("Medium")) + if checkVideoUrl(LIST_URL_VIDEO_HD, curr): + resolutions.append(_("High")) + return resolutions + + +def getVideoUrl(curr, val): + url = "" + resolution_text = "" + resolutions = [val] + VIDEO_RESOLUTIONS + for resolution in resolutions: + if curr[resolution] and curr[resolution].startswith("http"): + url = curr[resolution] + resolution_text = VIDEO_RESOLUTIONS_DICT[resolution] + break + return url, resolution_text + + +def getPlaylistSegments(url): + file_url = os.path.dirname(url) + ext = os.path.splitext(file_url)[1] + logger.debug("ext: %s", ext) + playlist = m3u8.load(url) + logger.debug("base_path: %s, base_uri: %s, data: %s", playlist.base_path, playlist.base_uri, playlist.data) + url = playlist.base_uri + playlist = m3u8.load(urljoin(url, playlist.data["playlists"][0]["uri"])) + logger.debug("base_path: %s, base_uri: %s, data: %s", playlist.base_path, playlist.base_uri, playlist.data) + segments = playlist.data["segments"] + logger.debug("segments: %s", segments) + return segments diff --git a/src/Movies.py b/src/Movies.py deleted file mode 100644 index efc2f76..0000000 --- a/src/Movies.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/usr/bin/python -# coding=utf-8 -# -# Copyright (C) 2018-2024 by dream-alpha -# -# In case of reuse of this source code please do not remove this copyright. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For more information on the GNU General Public License see: -# . - - -import os -import json -from time import localtime, strftime -from urlparse import urljoin -from datetime import datetime -from enigma import eServiceReference -from Plugins.SystemPlugins.JobCockpit.JobSupervisor import JobSupervisor -from Screens.Screen import Screen -from Screens.MessageBox import MessageBox -from Components.ActionMap import ActionMap -from Components.config import config -from Components.Label import Label -from Components.Sources.StaticText import StaticText -from Components.Sources.List import List -from Tools.LoadPixmap import LoadPixmap -from .Debug import logger -from . import m3u8 -from .__init__ import _ -from .Version import PLUGIN, ID -from .MoviePlayer import MoviePlayer -from .EventView import EventView -from .DownloadJob import DownloadJob -from .Menu import Menu -from .ChannelSelection import ChannelSelection -from .ConfigInit import VIDEO_RESOLUTIONS, VIDEO_RESOLUTIONS_DICT -from .Constants import ( - plugindir, LIST_DATE, LIST_EVENT_NAME, LIST_SHORT_DESCRIPTION, LIST_TIME, LIST_DURATION, LIST_CHANNEL, LIST_CHANNEL_PIXMAP, LIST_TOPIC, LIST_TITLE, LIST_DESCRIPTION, LIST_SIZE, LIST_ID, LIST_URL_VIDEO_LOW, LIST_URL_VIDEO, LIST_URL_VIDEO_HD, LIST_URL_WEBSITE, LIST_TIMESTAMP, LIST_END -) -from .ChannelUtils import getServiceReference -from .UnicodeUtils import convertUni2Str -from .WebRequests import WebRequests -from .RecordingUtils import calcRecordingFilename -from .CallLater import callLater - - -class Movies(Screen, Menu, ChannelSelection): - def __init__(self, session, postdata, last_service): - self.postdata = postdata - self.last_service = last_service - Menu.__init__(self) - ChannelSelection.__init__(self) - Screen.__init__(self, session) - self.skinName = "MediathekCockpit" - self.title = PLUGIN + " - " + _("Movies") - self.title += " - " + _("Search results") - - self["key_red"] = StaticText(_("Exit")) - self["key_green"] = StaticText(_("Channels")) - self["key_yellow"] = StaticText(_("Download")) - self["key_blue"] = StaticText(_("Search")) - - self["description"] = Label("") - self["date"] = Label("") - self["sresult"] = Label("") - - self["list"] = List() - self.list = [] - self.curr_index = 0 - self.query_info = {} - - self["actions"] = ActionMap( - ["MTC_Actions"], - { - "ok": self.pressOk, - "cancel": self.pressClose, - "red": self.pressRed, - "green": self.pressGreen, - "yellow": self.pressYellow, - "blue": self.pressBlue, - "menu": self.openMenu, - "info": self.pressInfo - } - ) - self["list"].onSelectionChanged.append(self.__onSelectionChanged) - self.onLayoutFinish.append(self.__onLayoutFinish) - self.job_manager = JobSupervisor.getInstance().getJobManager(ID) - - def __onLayoutFinish(self): - logger.info("...") - if self.postdata: - self.postdata["offset"] = 0 - callLater(0.010, self.downloadMovies) - else: - self["list"].setList([]) - self.title += " - " + _("No movies available") - - def downloadMovies(self): - logger.info("postdata: %s", self.postdata) - result_count = 0 - url = "https://mediathekviewweb.de/api/query" - result = WebRequests().postContent(url, self.postdata) - if result.text: - logger.debug("result.status_code: %s", result.status_code) - data = convertUni2Str(json.loads(result.text)) - # logger.debug("data: %s", data) - self.query_info = data["result"]["queryInfo"] - result_count = min(self.postdata["offset"] + self.query_info["resultCount"], self.query_info["totalResults"]) - self.query_info["filmlisteTimestamp"] = strftime("%d.%m.%Y %H:%M:%S", localtime(int(self.query_info["filmlisteTimestamp"]))) - logger.debug("query_info: %s", self.query_info) - results = data["result"]["results"] - logger.debug("results: %s", results) - for x in results: - logger.debug("x: %s", x) - tmp = [""] * LIST_END - tmp[LIST_TIMESTAMP] = timestamp = int(x.get("timestamp", "0")) - dtmp = datetime.fromtimestamp(timestamp).strftime("%d.%m.%Y %H:%M:%S") - tmp[LIST_DATE] = dtmp[0:10] - tmp[LIST_TIME] = dtmp[11:16] - tmp[LIST_DURATION] = "%s" % str(int(x.get("duration", 0)) / 60) + " " + _("Minutes") - tmp[LIST_CHANNEL] = channel = x.get("channel", "") - tmp[LIST_CHANNEL_PIXMAP] = LoadPixmap("%slogos/%s.png" % (plugindir, channel.replace(" ", "").upper())) if channel else None - topic = x.get("topic", "") - title = x.get("title", "") - if title.startswith(topic): - title = title.replace(topic, "").strip() - if title.startswith("-"): - title = title[1:].strip() - tmp[LIST_TOPIC] = topic - tmp[LIST_TITLE] = title - tmp[LIST_EVENT_NAME] = topic + " - " + title if title else topic - tmp[LIST_SHORT_DESCRIPTION] = title - tmp[LIST_DESCRIPTION] = x.get("description", "") - size = x.get("size", 0) - tmp[LIST_SIZE] = int(size) / (1024 * 1024) if size is not None else 0 - tmp[LIST_ID] = x.get("id", "") - tmp[LIST_URL_VIDEO_LOW] = x.get("url_video_low", "") - tmp[LIST_URL_VIDEO] = x.get("url_video", "") - tmp[LIST_URL_VIDEO_HD] = x.get("url_video_hd", "") - tmp[LIST_URL_WEBSITE] = x.get("url_website", "") - logger.debug("tmp: %s", tmp) - self.list.append(tmp) - - if self.query_info["totalResults"] != result_count: - addtmp = [""] * LIST_END - addtmp[LIST_CHANNEL] = ">>>" - addtmp[LIST_TOPIC] = _("Next page") - addtmp[LIST_TITLE] = _("Select") - addtmp[LIST_DATE] = ">>>" - logger.debug("addtmp: %s", addtmp) - self.list.append(addtmp) - # logger.info("list: %s", self.list) - self["list"].setList(self.list) - self["list"].setIndex(self.curr_index) - if len(self.list) == 0: - self.title += " - " + _("No movies available") - - self["sresult"].setText("%s: %s/%s\n%s: %s ms\n%s: %s" % ( - _("Entries"), result_count, str(self.query_info["totalResults"]), - _("Load time"), str(self.query_info["searchEngineTime"]), - _("From"), str(self.query_info["filmlisteTimestamp"])) - ) - - def __onSelectionChanged(self): - logger.info("...") - self["description"].setText("") - self["date"].setText("") - self.curr = self["list"].getCurrent() - if self.curr and self.curr[LIST_CHANNEL] != ">>>": - self["description"].setText(self.curr[LIST_DESCRIPTION]) - # size = self.curr[LIST_SIZE] - # size_text = "%d MB" % size if size else "" - self["date"].setText( - "%s: %s %s\n%s: %s\n%s: %s" % ( - _("Broadcast time"), self.curr[LIST_DATE], self.curr[LIST_TIME], - _("Duration"), self.curr[LIST_DURATION], - _("Quality"), ", ".join(self.getVideoResolutions(self.curr)) - ) - ) - - def pressOk(self): - self.curr = self["list"].getCurrent() - if self.curr: - if self.curr[LIST_CHANNEL] == ">>>": - self.curr_index = self["list"].getIndex() - logger.debug("curr_index: %s", self.curr_index) - self.postdata["offset"] += int(config.plugins.mediathekcockpit.size.value) - self["list"].list.remove(self.curr) - del self.list[len(self.list) - 1] - self.downloadMovies() - else: - val = int(config.plugins.mediathekcockpit.movie_resolution.value) - url, _resolution = self.getVideoUrl(self.curr, val) - if url: - if url.endswith(("mp4", "flv", "m3u8")): - self.playMovie(url) - else: - logger.error("unsupported url: %s", url) - - def playMovie(self, url, suburi=None): - logger.info("url: %s, suburi: %s", url, suburi) - sref = eServiceReference(eServiceReference.idGST, 0, url.encode("utf-8")) - sref.setName(self.curr[LIST_EVENT_NAME]) - if suburi: - sref.setSuburi(suburi.encode("utf-8")) - self.session.openWithCallback(self.playMovieCallback, MoviePlayer, sref, menuval=None, infoval=(EventView, self.curr)) - - def playMovieCallback(self): - self.session.nav.playService(self.last_service) - - def getVideoResolutions(self, curr): - def checkVideoUrl(was, curr): - return curr[was] and curr[was].startswith("http") - - resolutions = [] - if checkVideoUrl(LIST_URL_VIDEO_LOW, curr): - resolutions.append(_("Low")) - if checkVideoUrl(LIST_URL_VIDEO, curr): - resolutions.append(_("Medium")) - if checkVideoUrl(LIST_URL_VIDEO_HD, curr): - resolutions.append(_("High")) - return resolutions - - def getVideoUrl(self, curr, val): - url = "" - resolution_text = "" - resolutions = [val] + VIDEO_RESOLUTIONS - for resolution in resolutions: - if curr[resolution] and curr[resolution].startswith("http"): - url = curr[resolution] - resolution_text = VIDEO_RESOLUTIONS_DICT[resolution] - break - return url, resolution_text - - def pressRed(self): - self.pressClose() - - def pressGreen(self): - self.openChannelSelection() - - def pressYellow(self): - logger.info("...") - self.curr = self["list"].getCurrent() - movie_dir = config.plugins.mediathekcockpit.movie_dir.value - if self.curr and self.curr[LIST_CHANNEL] != ">>>": - if os.path.exists(movie_dir): - url, resolution = self.getVideoUrl(self.curr, int(config.plugins.mediathekcockpit.movie_resolution.value)) - ext = url[url.rfind("."):] if url.rfind(".") != -1 else ".mp4" - - recording_file = calcRecordingFilename(self.curr[LIST_TIMESTAMP], self.curr[LIST_CHANNEL], self.curr[LIST_EVENT_NAME], movie_dir) + ext - service_ref = getServiceReference(self.curr[LIST_CHANNEL]) - logger.debug("service_ref: %s", service_ref) - if ".m3u8" in url: - file_url = os.path.dirname(url) - ext = os.path.splitext(file_url)[1] - logger.debug("ext: %s", ext) - playlist = m3u8.load(url) - logger.debug("playlist: base_path: %s, base_uri: %s, data: %s", playlist.base_path, playlist.base_uri, playlist.data) - url = playlist.base_uri - playlist = m3u8.load(urljoin(url, playlist.data["playlists"][0]["uri"])) - logger.debug("playlist: base_path: %s, base_uri: %s, data: %s", playlist.base_path, playlist.base_uri, playlist.data) - segments = playlist.data["segments"] - logger.debug("playlist: segments: %s", segments) - else: - segments = [] - self.job_manager.AddJob( - DownloadJob( - url, - segments, - recording_file, - self.curr[LIST_EVENT_NAME], - self.curr[LIST_SHORT_DESCRIPTION], - self.curr[LIST_DESCRIPTION], - self.curr[LIST_TIMESTAMP], - service_ref - ) - ) - self.session.open( - MessageBox, "%s:\n\n%s\n\n%s: %s" % ( - _("Download added"), - self.curr[LIST_EVENT_NAME], - _("Video resolution"), resolution, - ), - type=MessageBox.TYPE_INFO, - timeout=4 - ) - else: - self.session.open(MessageBox, _("Movie directory does not exist") + ":\n\n" + movie_dir, type=MessageBox.TYPE_ERROR) - - else: - self.session.open(MessageBox, _("No movie to download"), type=MessageBox.TYPE_INFO, timeout=4) - - def pressBlue(self): - query = "" - self.curr = self["list"].getCurrent() - if self.curr: - query = self.curr[LIST_TOPIC] - self.close("search", query) - - def pressInfo(self): - self.curr = self["list"].getCurrent() - if self.curr and self.curr[LIST_CHANNEL] != ">>>": - self.session.open(EventView, self.curr) - - def pressClose(self): - logger.info("...") - self.close("exit") diff --git a/src/MyDeferredSemaphore.py b/src/MyDeferredSemaphore.py index d40336e..a7d18de 100644 --- a/src/MyDeferredSemaphore.py +++ b/src/MyDeferredSemaphore.py @@ -57,7 +57,7 @@ def __init__(self, tokens=1): logger.info("...") self._ds = DeferredSemaphore(tokens=tokens) self._deferreds = [] - self._dict = dict() + self._dict = {} def run(self, *args, **kwargs): logger.info("...") diff --git a/src/Search.py b/src/Search.py index c696fdc..0502473 100644 --- a/src/Search.py +++ b/src/Search.py @@ -19,33 +19,31 @@ # . +from Components.config import config from Screens.VirtualKeyBoard import VirtualKeyBoard from .Debug import logger from .__init__ import _ class Search(): - def __init__(self, session, callback): - self.session = session - self.callback = callback + def __init__(self): + self.postdata = { + "sortOrder": "desc", + "sortBy": "timestamp", + "offset": 0, + "size": config.plugins.mediathekcockpit.size.value, + "future": config.plugins.mediathekcockpit.future.value + } def openKeyboard(self, query): logger.info("query: %s", query) self.session.openWithCallback(self.openKeyboardCallback, VirtualKeyBoard, title=_("Enter search text"), text=query) - def openKeyboardCallback(self, result=None): + def openKeyboardCallback(self, result): logger.info("result: %s", result) - if result: - self.search(result) - else: - self.callback() - - def search(self, name="", fields=None): - logger.info("name: %s, fields: %s", name, fields) - if fields is None: - fields = ["topic", "title"] - if name: - self.postdata["offset"] = 0 - self.postdata["queries"] = list() - self.postdata["queries"].append({"fields": fields, "query": name}) - self.callback() + if result is None: + result = "" + fields = ["topic", "title"] + self.postdata["offset"] = 0 + self.postdata["queries"] = [{"fields": fields, "query": result}] + self.downloadMovies() diff --git a/src/Version.py b/src/Version.py index 384fffb..80582cb 100644 --- a/src/Version.py +++ b/src/Version.py @@ -21,6 +21,6 @@ PLUGIN = "MediathekCockpit" ID = "MTC" -VERSION = "2.5.1" +VERSION = "3.0.5" COPYRIGHT = "2018-2024 by dream-alpha" LICENSE = "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version." diff --git a/src/WebRequests.py b/src/WebRequests.py index 5cab3eb..52b193a 100644 --- a/src/WebRequests.py +++ b/src/WebRequests.py @@ -68,6 +68,7 @@ def postContent(self, url, data=None): try: content = requests.post(url, headers=headers, data=json.dumps(data), allow_redirects=True, verify=False) logger.debug("content.url: %s", content.url) + logger.debug("content.status_code: %s", content.status_code) content.raise_for_status() except Exception as e: logger.error("exception: %s", e) @@ -83,6 +84,7 @@ def getContent(self, url, params=None): try: response = requests.get(url, headers=headers, params=params, allow_redirects=True, verify=False) logger.debug("response.url: %s", response.url) + logger.debug("response.status_code: %s", response.status_code) content = response.content response.raise_for_status() # except Exception as e: diff --git a/src/plugin.py b/src/plugin.py index 22b4e39..dd44331 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -30,12 +30,12 @@ def search(session, query, **__kwargs): - MediathekCockpit(session, query) + session.open(MediathekCockpit, query) def main(session, **__kwargs): logger.info("...") - MediathekCockpit(session, "") + session.open(MediathekCockpit, "") def showDownloads(session, event="", service="", **_kwargs): @@ -47,7 +47,7 @@ def showDownloads(session, event="", service="", **_kwargs): event = info.getEvent(0) # 0 = now, 1 = next event_name = event and event.getEventName() or info.getName() or "" logger.info("event_name: %s", event_name) - MediathekCockpit(session, event_name) + session.open(MediathekCockpit, event_name) def autoStart(reason, **kwargs): diff --git a/src/skin/Default-FHD/skin.xml b/src/skin/Default-FHD/skin.xml index 4587ff3..b7b549e 100644 --- a/src/skin/Default-FHD/skin.xml +++ b/src/skin/Default-FHD/skin.xml @@ -17,7 +17,7 @@ - { "template": [ MultiContentEntryText(pos=(65,0),size=(200,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0, color=0xa6781c, color_sel=0xa6781c, backcolor=None), MultiContentEntryPixmapAlphaTest(pos=(5,5),size=(50,50),png=8, backcolor=None), MultiContentEntryText(pos=(65,34),size=(130,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(330,0),size=(930,34),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15, backcolor=None), MultiContentEntryText(pos=(330,34),size=(930,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(205,34),size=(60,34),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(0,67),size=(1259,1),font=0,flags=RT_VALIGN_CENTER,text="", backcolor=0xa0a0a0), ], "fonts": [gFont("Regular",25),gFont("Regular",22),gFont("Regular",28)], "itemHeight": 68 } + { "template": [ MultiContentEntryText(pos=(65,0),size=(200,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0, color=0xa6781c, color_sel=0xa6781c, backcolor=None), MultiContentEntryPixmapAlphaTest(pos=(5,5),size=(50,50),png=8, backcolor=None), MultiContentEntryText(pos=(65,34),size=(130,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(330,0),size=(930,34),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15, backcolor=None), MultiContentEntryText(pos=(330,34),size=(930,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(205,34),size=(60,34),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), ], "fonts": [gFont("Regular",25),gFont("Regular",22),gFont("Regular",28)], "itemHeight": 68 } diff --git a/src/skin/Default-HD/skin.xml b/src/skin/Default-HD/skin.xml index 81b8544..9171f85 100644 --- a/src/skin/Default-HD/skin.xml +++ b/src/skin/Default-HD/skin.xml @@ -17,7 +17,7 @@ - {"template":[MultiContentEntryText(pos=(43,0),size=(133,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0,color=0xa6781c,color_sel=0xa6781c,backcolor=None),MultiContentEntryPixmapAlphaTest(pos=(3,3),size=(33,33),png=8,backcolor=None),MultiContentEntryText(pos=(43,23),size=(87,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(220,0),size=(620,23),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15,backcolor=None),MultiContentEntryText(pos=(220,23),size=(620,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(137,23),size=(40,23),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(0,45),size=(839,1),font=0,flags=RT_VALIGN_CENTER,text="",backcolor=0xa0a0a0),],"fonts":[gFont("Regular",17),gFont("Regular",15),gFont("Regular",19)],"itemHeight":45} + {"template":[MultiContentEntryText(pos=(43,0),size=(133,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0,color=0xa6781c,color_sel=0xa6781c,backcolor=None),MultiContentEntryPixmapAlphaTest(pos=(3,3),size=(33,33),png=8,backcolor=None),MultiContentEntryText(pos=(43,23),size=(87,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(220,0),size=(620,23),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15,backcolor=None),MultiContentEntryText(pos=(220,23),size=(620,23),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(137,23),size=(40,23),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),],"fonts":[gFont("Regular",17),gFont("Regular",15),gFont("Regular",19)],"itemHeight":45} diff --git a/src/skin/Default-WQHD/screen_MediathekCockpit.xmlinc b/src/skin/Default-WQHD/screen_MediathekCockpit.xmlinc index 97bf5d4..be54107 100755 --- a/src/skin/Default-WQHD/screen_MediathekCockpit.xmlinc +++ b/src/skin/Default-WQHD/screen_MediathekCockpit.xmlinc @@ -2,7 +2,7 @@ - {"template":[MultiContentEntryText(pos=(92,0),size=(283,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(71,71),png=8),MultiContentEntryText(pos=(92,48),size=(184,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5),MultiContentEntryText(pos=(467,0),size=(1315,48),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=1),MultiContentEntryText(pos=(467,48),size=(1315,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=2),MultiContentEntryText(pos=(289,48),size=(85,48),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4),MultiContentEntryText(pos=(0,95),size=(1780,1),font=0,flags=RT_VALIGN_CENTER,text="")],"fonts":[gFont("Regular",36),gFont("Regular",31),gFont("Regular",40)],"itemHeight":96} + {"template":[MultiContentEntryText(pos=(92,0),size=(283,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(71,71),png=8),MultiContentEntryText(pos=(92,48),size=(184,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5),MultiContentEntryText(pos=(467,0),size=(1315,48),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15),MultiContentEntryText(pos=(467,48),size=(1315,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16),MultiContentEntryText(pos=(289,48),size=(85,48),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4)],"fonts":[gFont("Regular",36),gFont("Regular",31),gFont("Regular",40)],"itemHeight":96} diff --git a/src/skin/Default-WQHD/skin.xml b/src/skin/Default-WQHD/skin.xml index 66abe1e..2b860c8 100644 --- a/src/skin/Default-WQHD/skin.xml +++ b/src/skin/Default-WQHD/skin.xml @@ -6,7 +6,7 @@ - {"template":[MultiContentEntryText(pos=(92,0),size=(283,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(71,71),png=8),MultiContentEntryText(pos=(92,48),size=(184,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5),MultiContentEntryText(pos=(467,0),size=(1315,48),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=1),MultiContentEntryText(pos=(467,48),size=(1315,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=2),MultiContentEntryText(pos=(289,48),size=(85,48),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4),MultiContentEntryText(pos=(0,95),size=(1780,1),font=0,flags=RT_VALIGN_CENTER,text="")],"fonts":[gFont("Regular",36),gFont("Regular",31),gFont("Regular",40)],"itemHeight":96} + {"template":[MultiContentEntryText(pos=(92,0),size=(283,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(71,71),png=8),MultiContentEntryText(pos=(92,48),size=(184,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5),MultiContentEntryText(pos=(467,0),size=(1315,48),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15),MultiContentEntryText(pos=(467,48),size=(1315,48),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16),MultiContentEntryText(pos=(289,48),size=(85,48),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4)],"fonts":[gFont("Regular",36),gFont("Regular",31),gFont("Regular",40)],"itemHeight":96} diff --git a/src/skin/Other-WQHD/skin.xml b/src/skin/Other-WQHD/skin.xml index e236133..2773906 100644 --- a/src/skin/Other-WQHD/skin.xml +++ b/src/skin/Other-WQHD/skin.xml @@ -17,7 +17,7 @@ - {"template":[MultiContentEntryText(pos=(87,0),size=(267,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0,color=0xa6781c,color_sel=0xa6781c,backcolor=None),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(67,67),png=8,backcolor=None),MultiContentEntryText(pos=(87,45),size=(173,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(440,0),size=(1240,45),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15,backcolor=None),MultiContentEntryText(pos=(440,45),size=(1240,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(273,45),size=(80,45),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(0,89),size=(1679,1),font=0,flags=RT_VALIGN_CENTER,text="",backcolor=0xa0a0a0),],"fonts":[gFont("Regular",33),gFont("Regular",29),gFont("Regular",37)],"itemHeight":91} + {"template":[MultiContentEntryText(pos=(87,0),size=(267,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0,color=0xa6781c,color_sel=0xa6781c,backcolor=None),MultiContentEntryPixmapAlphaTest(pos=(7,7),size=(67,67),png=8,backcolor=None),MultiContentEntryText(pos=(87,45),size=(173,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(440,0),size=(1240,45),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15,backcolor=None),MultiContentEntryText(pos=(440,45),size=(1240,45),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),MultiContentEntryText(pos=(273,45),size=(80,45),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4,color=0xa0a0a0,color_sel=0xa0a0a0,backcolor=None),],"fonts":[gFont("Regular",33),gFont("Regular",29),gFont("Regular",37)],"itemHeight":91} diff --git a/src/skin/Shadow-FHD/screen_MediathekCockpit.xmlinc b/src/skin/Shadow-FHD/screen_MediathekCockpit.xmlinc index b06993f..d8eecf4 100755 --- a/src/skin/Shadow-FHD/screen_MediathekCockpit.xmlinc +++ b/src/skin/Shadow-FHD/screen_MediathekCockpit.xmlinc @@ -8,10 +8,9 @@ MultiContentEntryText(pos=(69,0),size=(212,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0), MultiContentEntryPixmapAlphaTest(pos=(5,5),size=(53,53),png=8), MultiContentEntryText(pos=(69,36),size=(138,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5), - MultiContentEntryText(pos=(350,0),size=(986,36),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=1), - MultiContentEntryText(pos=(350,36),size=(986,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=2), - MultiContentEntryText(pos=(217,36),size=(64,36),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4), - MultiContentEntryText(pos=(0,71),size=(1335,1),font=0,flags=RT_VALIGN_CENTER,text="") + MultiContentEntryText(pos=(350,0),size=(986,36),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15), + MultiContentEntryText(pos=(350,36),size=(986,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16), + MultiContentEntryText(pos=(217,36),size=(64,36),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4) ], "fonts":[gFont("Regular",27),gFont("Regular",23),gFont("Regular",30)], "itemHeight":72 diff --git a/src/skin/Shadow-FHD/skin.xml b/src/skin/Shadow-FHD/skin.xml index 6bd8906..a33c50c 100644 --- a/src/skin/Shadow-FHD/skin.xml +++ b/src/skin/Shadow-FHD/skin.xml @@ -6,7 +6,7 @@ - { "template": [ MultiContentEntryText(pos=(69,0),size=(212,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0), MultiContentEntryPixmapAlphaTest(pos=(5,5),size=(53,53),png=8), MultiContentEntryText(pos=(69,36),size=(138,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5), MultiContentEntryText(pos=(350,0),size=(986,36),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=1), MultiContentEntryText(pos=(350,36),size=(986,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=2), MultiContentEntryText(pos=(217,36),size=(64,36),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4), MultiContentEntryText(pos=(0,71),size=(1335,1),font=0,flags=RT_VALIGN_CENTER,text="") ], "fonts":[gFont("Regular",27),gFont("Regular",23),gFont("Regular",30)], "itemHeight":72 } + { "template": [ MultiContentEntryText(pos=(69,0),size=(212,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=0), MultiContentEntryPixmapAlphaTest(pos=(5,5),size=(53,53),png=8), MultiContentEntryText(pos=(69,36),size=(138,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=5), MultiContentEntryText(pos=(350,0),size=(986,36),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15), MultiContentEntryText(pos=(350,36),size=(986,36),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16), MultiContentEntryText(pos=(217,36),size=(64,36),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4) ], "fonts":[gFont("Regular",27),gFont("Regular",23),gFont("Regular",30)], "itemHeight":72 } diff --git a/src/skin/screen_MediathekCockpit.xmlinc b/src/skin/screen_MediathekCockpit.xmlinc index 62fc334..e381c70 100755 --- a/src/skin/screen_MediathekCockpit.xmlinc +++ b/src/skin/screen_MediathekCockpit.xmlinc @@ -24,7 +24,6 @@ MultiContentEntryText(pos=(330,0),size=(930,34),font=2,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=15, backcolor=None), MultiContentEntryText(pos=(330,34),size=(930,34),font=0,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=16, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), MultiContentEntryText(pos=(205,34),size=(60,34),font=1,flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER,text=4, color=0xa0a0a0, color_sel=0xa0a0a0, backcolor=None), - MultiContentEntryText(pos=(0,67),size=(1259,1),font=0,flags=RT_VALIGN_CENTER,text="", backcolor=0xa0a0a0), ], "fonts": [gFont("Regular",25),gFont("Regular",22),gFont("Regular",28)], "itemHeight": 68