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