|
@@ -0,0 +1,925 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+
|
|
|
+from api import *
|
|
|
+from consts import *
|
|
|
+import datetime
|
|
|
+import pprint
|
|
|
+import copy
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/empty/", name="empty", update=False, cache=True)
|
|
|
+def empty():
|
|
|
+ hide_busy_dialog()
|
|
|
+ return PLUGIN.set_resolved_url(None)
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/play_trailer/<trailer_id>/<age>/", name="play_trailer", cache=False)
|
|
|
+def play_trailer(trailer_id="", age=""):
|
|
|
+ """
|
|
|
+
|
|
|
+ @param trailer_id:
|
|
|
+ @param age:
|
|
|
+ @return:
|
|
|
+ """
|
|
|
+
|
|
|
+ if not master_lock_access(age):
|
|
|
+ return None
|
|
|
+
|
|
|
+ if not trailer_id:
|
|
|
+ return None
|
|
|
+
|
|
|
+ show_busy_dialog()
|
|
|
+
|
|
|
+ streams = False
|
|
|
+ try:
|
|
|
+ streams = parse_youtube(trailer_id)
|
|
|
+ except Exception as e:
|
|
|
+ xbmc.log("[YOUTUBE] Error: %s" % traceback.format_exc())
|
|
|
+
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Es ist ein Fehler passiert bei YT:\n%s" % repr(e))
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ if streams is False:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Das Addon [B]plugin.video.youtube[/B] muss installiert sein")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ if not streams or len(streams) <= 0:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Es konnten keine Streams von YT extrahiert werden!")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ stream = streams[0]
|
|
|
+
|
|
|
+ item = {
|
|
|
+ "label": stream["meta"]["video"]["title"],
|
|
|
+ "path": stream["url"],
|
|
|
+ "is_playable": True
|
|
|
+ }
|
|
|
+
|
|
|
+ playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
|
|
+ playlist.clear()
|
|
|
+
|
|
|
+ li = PLUGIN._listitemify(item).as_xbmc_listitem()
|
|
|
+ playlist.add(item["path"], li)
|
|
|
+
|
|
|
+ player = xbmc.Player()
|
|
|
+
|
|
|
+ if False:
|
|
|
+ PLUGIN.notify("Trailer wird versucht abzuspielen!")
|
|
|
+
|
|
|
+ player.play(playlist)
|
|
|
+ del player
|
|
|
+ player = None
|
|
|
+
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/view_actors/<movie_id>/", name="view_actors", cache=True, content_type="movies", view_mode=get_view("thumbnail"))
|
|
|
+def view_actors(movie_id=0):
|
|
|
+ if not movie_id or movie_id == 0:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = []
|
|
|
+
|
|
|
+ movie_result = __api__.__get__("get/movie", __data__={
|
|
|
+ "id": movie_id,
|
|
|
+ "withActors": 1
|
|
|
+ })
|
|
|
+
|
|
|
+ if not movie_result:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Leider konnten die Schauspieler nicht geladen werden")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ entries = movie_result["data"]["actors"]
|
|
|
+ if len(entries) <= 0:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Es wurden keine Schauspieler gefunden")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = [
|
|
|
+ {
|
|
|
+ "label": unicode(entry["name"]),
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_actor",
|
|
|
+ actor_id=entry['id'],
|
|
|
+ page=0),
|
|
|
+ "thumbnail": get_poster_url(entry["profile"]),
|
|
|
+ "info": {
|
|
|
+ "count": entry["id"],
|
|
|
+ "episode": idx
|
|
|
+ },
|
|
|
+ "is_playable": False,
|
|
|
+ "context_menu": misc_menu(),
|
|
|
+ "replace_context_menu": True
|
|
|
+ } for idx, entry in enumerate(entries)
|
|
|
+ ]
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/view_actor/<actor_id>/<page>/", name="view_actor", cache=True, content_type="movies", view_mode=get_view("thumbnail"))
|
|
|
+def view_actor(actor_id=0, page=0):
|
|
|
+ if not actor_id or actor_id == 0:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = []
|
|
|
+
|
|
|
+ actor_result = __api__.__get__("get/actor", __data__={
|
|
|
+ "id": actor_id,
|
|
|
+ "types": VIEW_TYPES
|
|
|
+ })
|
|
|
+
|
|
|
+ if not actor_result:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items.extend(prepare_movies_to_list(actor_result["data"]["movies"]))
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/search_trailer/<title>/<date>/<fanart>/<age>/", name="search_trailer", cache=False, content_type="episodes", view_mode=get_view("episode"))
|
|
|
+def search_trailer(title="", date="", fanart="", age=""):
|
|
|
+ show_busy_dialog()
|
|
|
+ if not title or not master_lock_access(age):
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ year = re.search("([0-9]{4})-.*", date)
|
|
|
+ if year:
|
|
|
+ year = " %s" % year.group(1)
|
|
|
+ else:
|
|
|
+ year = ""
|
|
|
+
|
|
|
+ title = urllib.pathname2url("%s trailer german deutsch" % (title.replace(":", "")))
|
|
|
+
|
|
|
+ if DEBUG:
|
|
|
+ output("[YOUTUBE]: %s" % (YOUTUBE_SEARCH_URL % title))
|
|
|
+
|
|
|
+ data = None
|
|
|
+ try:
|
|
|
+ data = urllib2.urlopen(YOUTUBE_SEARCH_URL % title).read()
|
|
|
+ except Exception as e:
|
|
|
+ output(repr(e))
|
|
|
+
|
|
|
+ if not data:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Fehler beim verarbeiten der Antwort.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ obj = string_to_json(data)
|
|
|
+ if not obj or not ('items' in obj):
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Es wurden keine Trailer gefunden")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ entries = obj['items']
|
|
|
+ if len(entries) <= 0:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Es wurden keine Trailer gefunden")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = [
|
|
|
+ {
|
|
|
+ "label": unicode(entry['snippet']["title"]),
|
|
|
+ "path": PLUGIN.url_for(endpoint="play_trailer",
|
|
|
+ trailer_id=str(entry['id']['videoId']),
|
|
|
+ age="0"),
|
|
|
+ "thumbnail": entry['snippet']['thumbnails']['high']['url'].replace("https://", "http://"),
|
|
|
+ "properties": {
|
|
|
+ "fanart_image": urllib.unquote(fanart) if fanart and fanart != "None" else "",
|
|
|
+ },
|
|
|
+ "info": {
|
|
|
+ "count": entry["id"]["videoId"],
|
|
|
+ "episode": idx,
|
|
|
+ "plot": unicode(entry['snippet']["description"] if entry['snippet']["description"] else ""),
|
|
|
+ "premiered": entry['snippet']["publishedAt"][:10] if entry['snippet']["publishedAt"] else ""
|
|
|
+ },
|
|
|
+ "is_playable": False,
|
|
|
+ } for idx, entry in enumerate(entries)
|
|
|
+ ]
|
|
|
+
|
|
|
+ hide_busy_dialog()
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/watchlist_action/<movie_id>/<action>/<refresh>", name="watchlist_action")
|
|
|
+def watchlist_action(movie_id="0", action="add", refresh=0):
|
|
|
+ if not movie_id:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ result = __api__.__get__("set/watchlist", __data__={
|
|
|
+ "id": movie_id,
|
|
|
+ "action": action
|
|
|
+ })
|
|
|
+
|
|
|
+ if not result or not result["data"]["success"]:
|
|
|
+ PLUGIN.notify("Fehler beim verarbeiten der Anfrage.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ message = None
|
|
|
+ if action == "add":
|
|
|
+ message = u"Eintrag wurde der Liste hinzugefügt"
|
|
|
+
|
|
|
+ elif action == "remove":
|
|
|
+ message = "Eintrag wurde aus der Liste entfernt"
|
|
|
+
|
|
|
+ if message:
|
|
|
+ PLUGIN.notify(message)
|
|
|
+
|
|
|
+ if refresh == "1":
|
|
|
+ xbmc.executebuiltin("Container.Refresh")
|
|
|
+
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/view_list/<list_type>/<page>/<view_types>/<genre>/<min_year>/<max_year>/<query>/", name="view_list", update=False, cache=True, content_type="movies", view_mode=get_view("thumbnail"))
|
|
|
+def view_list(list_type="new", view_types="0", page=1, genre="all", min_year=0, max_year=0, query=0):
|
|
|
+ if str(view_types) == "2":
|
|
|
+ PLUGIN.set_goto_top(False)
|
|
|
+
|
|
|
+ items = []
|
|
|
+
|
|
|
+ params = {
|
|
|
+ "limit": MOVIES_PER_PAGE,
|
|
|
+ "page": page,
|
|
|
+ "list": list_type,
|
|
|
+ "watchlistID": WATCHLIST_ID,
|
|
|
+ "watchedlistID": WATCHEDLIST_ID
|
|
|
+ }
|
|
|
+
|
|
|
+ if query != "0":
|
|
|
+ output("Search: %s" % query)
|
|
|
+ params["title"] = query
|
|
|
+
|
|
|
+ params["orderby"] = "updated_at|DESC"
|
|
|
+ # params["orderby"] = "popularity|DESC"
|
|
|
+
|
|
|
+ if view_types != "0":
|
|
|
+ params["types"] = view_types
|
|
|
+
|
|
|
+ if int(min_year) > 0 or int(max_year) > 0:
|
|
|
+ params["year"] = "%s-%s" % (min_year, max_year)
|
|
|
+
|
|
|
+ result = __api__.__get__("get/list", __data__=params)
|
|
|
+ if not result:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.notify("Fehler beim verarbeiten der Anfrage.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ if result["data"]["total_results"] <= 0:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog(u"Leider wurden keine Einträge gefunden!")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items.extend(prepare_movies_to_list(result["data"]["results"], prefixed=view_types == "0" or len(view_types) != 1))
|
|
|
+
|
|
|
+ total = result["data"]["total_pages"]
|
|
|
+ if total > 1:
|
|
|
+ pages = []
|
|
|
+ for pagenum in range(1, total + 1):
|
|
|
+ pages.append(
|
|
|
+ {
|
|
|
+ "label": ("[COLOR red][B][I]Seite %s von %s[/I][/B][/COLOR]" % (pagenum, total)) if int(pagenum) == int(page) else "Seite %s von %s" % (pagenum, total),
|
|
|
+ "is_playable": False,
|
|
|
+ "path": EMPTY_PATH if int(pagenum) == int(page) else PLUGIN.url_for(endpoint="view_list",
|
|
|
+ genre=genre,
|
|
|
+ page=pagenum,
|
|
|
+ query=query,
|
|
|
+ view_types=view_types,
|
|
|
+ list_type=list_type,
|
|
|
+ min_year=min_year,
|
|
|
+ max_year=max_year),
|
|
|
+ "info": {
|
|
|
+ "playcount": 1 if int(pagenum) == int(page) else 0,
|
|
|
+ "tagline": "[B]%s[/B] bis [B]%s[/B]" % (unicode(pagenum * int(result["data"]["limit"])), unicode(min(pagenum * int(result["data"]["limit"]), total)))
|
|
|
+ },
|
|
|
+ "context_menu": misc_menu(),
|
|
|
+ "replace_context_menu": False
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ items.extend(pages)
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/search_similars/<movie_id>/<page>/<type>/", name="search_similars", cache=True, content_type="movies", view_mode=get_view("thumbnail"))
|
|
|
+def search_similars(movie_id=0, page=1, type=0):
|
|
|
+ if not movie_id:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ result = __api__.__get__("get/similars", __data__={
|
|
|
+ "id": movie_id
|
|
|
+ })
|
|
|
+ if not result:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.notify("Fehler beim verarbeiten der Anfrage.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ if result["data"]["total_results"] <= 0:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog(u"Leider wurden keine Einträge gefunden!")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = []
|
|
|
+
|
|
|
+ items.extend(prepare_movies_to_list(result["data"]["results"]))
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/play_episode/<episode_id>/<ask_playlist>/", name="play_episode", cache=False)
|
|
|
+def play_episode(episode_id=0, ask_playlist=0):
|
|
|
+ """
|
|
|
+
|
|
|
+ @param episode_id:
|
|
|
+ @param ask_playlist:
|
|
|
+ @return:
|
|
|
+ """
|
|
|
+
|
|
|
+ show_busy_dialog()
|
|
|
+ if episode_id == 0:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ # clear_session()
|
|
|
+
|
|
|
+ if ASK_BEFORE_PLAY:
|
|
|
+ hide_busy_dialog()
|
|
|
+ if not PLUGIN.yesno(u"Möchtest du das Video wirklich starten?"):
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ ret = "0"
|
|
|
+ if ASK_FOR_NEXT_EPISODE and int(ask_playlist) == 1:
|
|
|
+ hide_busy_dialog()
|
|
|
+ ret = PLUGIN.yesno("Nach Abschluss der Episode direkt die nächste Episoden starten?", "Episoden")
|
|
|
+ show_busy_dialog()
|
|
|
+
|
|
|
+ ret = int(ret)
|
|
|
+
|
|
|
+ episode_result = __api__.__get__("get/episode", __data__={
|
|
|
+ "id": episode_id,
|
|
|
+ "withParents": 1,
|
|
|
+ "withPlaylist": 30 if ret else 0
|
|
|
+ })
|
|
|
+
|
|
|
+ if not episode_result:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Fehler beim verarbeiten der Antwort.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ item = prepare_movies_to_list([episode_result["data"]["season"]["movie"]])
|
|
|
+ item = item[0]
|
|
|
+ item["is_playable"] = True
|
|
|
+
|
|
|
+ playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
|
|
+ playlist.clear()
|
|
|
+
|
|
|
+ play_port = None
|
|
|
+ try:
|
|
|
+ server = __PlayServer__()
|
|
|
+ server.__start__()
|
|
|
+
|
|
|
+ tried = 0
|
|
|
+ while not server.__port__:
|
|
|
+ xbmc.sleep(1)
|
|
|
+ tried += 1
|
|
|
+
|
|
|
+ if tried > 10:
|
|
|
+ raise Exception("Failed to start Playserver")
|
|
|
+
|
|
|
+ play_port = server.__port__
|
|
|
+
|
|
|
+ if not play_port:
|
|
|
+ raise Exception("Playserver got no port")
|
|
|
+
|
|
|
+ output("[PLAY] Server started as %s" % play_port)
|
|
|
+ #ifdef DEBUG
|
|
|
+ PLUGIN.notify("Playserver at %s" % play_port)
|
|
|
+ #endif
|
|
|
+
|
|
|
+ except:
|
|
|
+ output("[PLAY] Error: %s" % traceback.format_exc())
|
|
|
+
|
|
|
+ #ifdef DEBUG
|
|
|
+ # PLUGIN.notify(repr(e))
|
|
|
+ #endif
|
|
|
+
|
|
|
+ raise
|
|
|
+
|
|
|
+ # Main Episode
|
|
|
+ episode = episode_result["data"]
|
|
|
+ path = "http://127.0.0.1:%s/play/%s/" % (play_port, episode["id"])
|
|
|
+
|
|
|
+ li = copy.copy(item)
|
|
|
+ li["path"] = path
|
|
|
+ li["properties"] = {
|
|
|
+ "MovieID": unicode(episode["id"])
|
|
|
+ }
|
|
|
+
|
|
|
+ if episode["title"] == "Mainepisode":
|
|
|
+ li["info"]["tagline"] = ""
|
|
|
+ else:
|
|
|
+ tagline = unicode("%s - %s" % (episode_result["data"]["season"]["movie"]["title"], episode["title"] if episode_result["data"]["season"]["title"] == "Default" else (episode_result["data"]["season"]["title"] + " - %s. %s" % (episode["number"], episode["title"]))))
|
|
|
+
|
|
|
+ if SWITCH_TAGLINE:
|
|
|
+ title = li["label"]
|
|
|
+ li["label"] = tagline
|
|
|
+ li["info"]["title"] = tagline
|
|
|
+ li["info"]["tagline"] = title
|
|
|
+ else:
|
|
|
+ li["info"]["tagline"] = tagline
|
|
|
+
|
|
|
+ li = PLUGIN._listitemify(li).as_xbmc_listitem()
|
|
|
+ playlist.add(path, li)
|
|
|
+
|
|
|
+ # Playlist episodes
|
|
|
+ if "next_episodes" in episode_result["data"]:
|
|
|
+ for episode in episode_result["data"]["next_episodes"]:
|
|
|
+ path = "http://127.0.0.1:%s/play/%s/" % (play_port, episode["id"])
|
|
|
+
|
|
|
+ li = copy.copy(item)
|
|
|
+ li["path"] = path
|
|
|
+ li["properties"] = {
|
|
|
+ "MovieID": unicode(episode["id"])
|
|
|
+ }
|
|
|
+
|
|
|
+ if episode["title"] == "Mainepisode":
|
|
|
+ li["info"]["tagline"] = ""
|
|
|
+ else:
|
|
|
+ tagline = unicode("%s - %s" % (episode_result["data"]["season"]["movie"]["title"], episode["title"] if episode_result["data"]["season"]["title"] == "Default" else (episode_result["data"]["season"]["title"] + " - %s. %s" % (episode["number"], episode["title"]))))
|
|
|
+
|
|
|
+ if SWITCH_TAGLINE:
|
|
|
+ title = li["label"]
|
|
|
+ li["label"] = tagline
|
|
|
+ li["info"]["title"] = tagline
|
|
|
+ li["info"]["tagline"] = title
|
|
|
+ else:
|
|
|
+ li["info"]["tagline"] = tagline
|
|
|
+
|
|
|
+ li = PLUGIN._listitemify(li).as_xbmc_listitem()
|
|
|
+ playlist.add(path, li)
|
|
|
+
|
|
|
+ first = playlist[0]
|
|
|
+ if first:
|
|
|
+ episode_id = first.getProperty("MovieID")
|
|
|
+ offset = read_watchtime(episode_id)
|
|
|
+ if offset > 0:
|
|
|
+ ret = PLUGIN.yesno("Soll das Video bei Position %s fortgesetzt werden?" % format_seconds_to_hhmmss(offset))
|
|
|
+ if ret == 0:
|
|
|
+ save_watchtime(offset, 0)
|
|
|
+ offset = 0
|
|
|
+
|
|
|
+ if offset > 0:
|
|
|
+ first.setProperty("StartOffset", "%s" % offset)
|
|
|
+
|
|
|
+ player = xbmc.Player()
|
|
|
+ player.play(playlist)
|
|
|
+ del player
|
|
|
+ player = None
|
|
|
+
|
|
|
+ xbmc.sleep(250)
|
|
|
+ xbmc.executebuiltin("XBMC.Action(FullScreen)")
|
|
|
+
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/seasons/<movie_id>/", name="seasons", cache=True, content_type="episodes", view_mode=get_view("episode"))
|
|
|
+def seasons(movie_id=0):
|
|
|
+ show_busy_dialog()
|
|
|
+ if movie_id == 0:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ movie_result = __api__.__get__("get/movie", __data__={
|
|
|
+ "id": movie_id,
|
|
|
+ "withEpisodes": 1
|
|
|
+ })
|
|
|
+
|
|
|
+ if not movie_result:
|
|
|
+ hide_busy_dialog()
|
|
|
+ PLUGIN.dialog("Leider konnten die Staffeln nicht geladen werden")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ if "episode_id" in movie_result["data"]:
|
|
|
+ # is a movie!
|
|
|
+ return play_episode(movie_result["data"]["episode_id"])
|
|
|
+
|
|
|
+ season_result = __api__.__get__("get/seasons", __data__={
|
|
|
+ "id": movie_id
|
|
|
+ })
|
|
|
+
|
|
|
+ if not season_result:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = [
|
|
|
+ {
|
|
|
+ "label": unicode(season["title"]),
|
|
|
+ "path": PLUGIN.url_for(endpoint="episodes", season_id=season['id']),
|
|
|
+ "thumbnail": get_poster_url(season["posterurl"] if season["posterurl"] else season_result["data"]["posterurl"]),
|
|
|
+ "properties": {
|
|
|
+ "fanart_image": get_backdrop_url(season_result["data"]['backdropurl']),
|
|
|
+ },
|
|
|
+ "is_playable": False,
|
|
|
+ "info": {
|
|
|
+ "playcount": (season["in_watchedlist"] * 1) if "in_watchedlist" in season else 0,
|
|
|
+ "watched": (season["in_watchedlist"] * 1) if "in_watchedlist" in season else 0,
|
|
|
+ "plot": unicode(season["description"]) if season["description"] else (unicode(movie_result["data"]["description"]) if movie_result["data"]["description"] else None),
|
|
|
+ "duration": unicode(int(season_result["data"]["runtime"]) * 60) if season_result["data"]["runtime"] else None,
|
|
|
+ "premiered": season["release_date"] if season["release_date"] else season_result["data"]["release_date"],
|
|
|
+ "tvshowtitle": unicode(season_result["data"]["title"]) if season_result["data"]["title"] else None,
|
|
|
+ },
|
|
|
+ "context_menu": misc_menu(),
|
|
|
+ "replace_context_menu": False
|
|
|
+ } for season in season_result["data"]["seasons"]
|
|
|
+ ]
|
|
|
+
|
|
|
+ hide_busy_dialog()
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/episodes/<season_id>/", name="episodes", cache=True, content_type="episodes", view_mode=get_view("episode"))
|
|
|
+def episodes(season_id=0, dialog=True):
|
|
|
+ show_busy_dialog()
|
|
|
+ if season_id == 0:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ episode_results = __api__.__get__("get/season", __data__={
|
|
|
+ "id": season_id,
|
|
|
+ "withEpisodes": 1
|
|
|
+ })
|
|
|
+ if not episode_results:
|
|
|
+ return empty()
|
|
|
+
|
|
|
+ items = []
|
|
|
+ for index, episode in enumerate(episode_results["data"]["episodes"]):
|
|
|
+ if not episode["id"]:
|
|
|
+ continue
|
|
|
+
|
|
|
+ items.append({
|
|
|
+ "label": "%s. %s" % (episode["number"], unicode(episode["title"])),
|
|
|
+ "path": PLUGIN.url_for(endpoint="play_episode",
|
|
|
+ episode_id=episode['id'],
|
|
|
+ ask_playlist=((index + 1) < len(episode_results["data"]["episodes"])) * 1),
|
|
|
+ "is_playable": False,
|
|
|
+ "thumbnail": get_scene_url(episode["posterurl"] if episode["posterurl"] else None),
|
|
|
+ "properties": {
|
|
|
+ # "fanart_image": get_backdrop_url(obj["data"]["movie"]['backdropurl']),
|
|
|
+ },
|
|
|
+ "info": {
|
|
|
+ "plot": unicode(episode["description"]) if episode["description"] else (unicode(episode_results["data"]["description"]) if episode_results["data"]["description"] else None),
|
|
|
+ "count": episode["id"],
|
|
|
+ "episode": episode["number"],
|
|
|
+ "playcount": (episode["in_watchedlist"] * 1) if "in_watchedlist" in episode else has_played(episode["id"]),
|
|
|
+ "watched": (episode["in_watchedlist"] * 1) if "in_watchedlist" in episode else has_played(episode["id"]),
|
|
|
+ # "duration": unicode(int(obj["data"]["movie"]["duration"]) * 60) if obj["data"]["movie"]["duration"] else None,
|
|
|
+ "premiered": episode["release_date"] if episode["release_date"] else episode_results["data"]["release_date"] if episode_results["data"]["release_date"] else None
|
|
|
+ },
|
|
|
+ "context_menu": misc_menu(episode_id=episode["id"]),
|
|
|
+ "replace_context_menu": False
|
|
|
+ })
|
|
|
+
|
|
|
+ hide_busy_dialog()
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/mark_as_seen/<episodeid>/", name="mark_as_seen")
|
|
|
+def mark_as_seen(episodeid="0"):
|
|
|
+ if not episodeid or episodeid == "0":
|
|
|
+ return None
|
|
|
+
|
|
|
+ return None
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/account_status/", name="account_status")
|
|
|
+def account_status():
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/clear_password/", name="clear_password")
|
|
|
+def clear_password():
|
|
|
+ clear_session()
|
|
|
+ PLUGIN.set_setting("password", "")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/clear_storage/", name="clear_storage")
|
|
|
+def clear_storage():
|
|
|
+ total_clear_storage()
|
|
|
+
|
|
|
+ clear_session()
|
|
|
+
|
|
|
+ PLUGIN.notify("Storage wurde geleert.")
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/search/<is_actor>/", name="search", cache=False)
|
|
|
+def search(is_actor="0"):
|
|
|
+ is_actor = 0
|
|
|
+
|
|
|
+ title = "Schauspieler" if is_actor == "1" else "Film oder Serie"
|
|
|
+ query = PLUGIN.keyboard('', "Nach %s Suchen" % title)
|
|
|
+
|
|
|
+ if query:
|
|
|
+ return PLUGIN.redirect(PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="all",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=query,
|
|
|
+ page=1))
|
|
|
+
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/search_result/<is_actor>/<query>/", name="search_result", cache=True, update=False, content_type="movies", view_mode=get_view("thumbnail"))
|
|
|
+def search_result(is_actor="0", query=0):
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/open_settings/", name="open_settings", cache=True)
|
|
|
+def open_settings():
|
|
|
+ PLUGIN.open_settings()
|
|
|
+ return empty()
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/account_logout/", name="account_logout", cache=False)
|
|
|
+def account_logout():
|
|
|
+ if not master_lock_access(None):
|
|
|
+ return None
|
|
|
+
|
|
|
+ if not PLUGIN.yesno(u"Möchtest du dich wirklich abmelden?"):
|
|
|
+ return None
|
|
|
+
|
|
|
+ logout_kodi()
|
|
|
+ clear_session()
|
|
|
+ xbmc.executebuiltin("Container.Refresh")
|
|
|
+ return None
|
|
|
+
|
|
|
+
|
|
|
+# Main
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/updated_needed/", name="updated_needed", cache=True)
|
|
|
+def updated_needed():
|
|
|
+ items = []
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+@PLUGIN.route("/", name="main", update=True, cache=False, content_type="files", view_mode=get_view("list"), goto_top=False)
|
|
|
+def main():
|
|
|
+ items = []
|
|
|
+
|
|
|
+ logged_in = False
|
|
|
+
|
|
|
+ if PORTAL_USERNAME and PORTAL_PASSWORD:
|
|
|
+ """
|
|
|
+ data = api.get("get/ping")
|
|
|
+ if not data:
|
|
|
+ pass
|
|
|
+
|
|
|
+ if data["data"] == "pong":
|
|
|
+ logged_in = True
|
|
|
+ """
|
|
|
+ logged_in = ping()
|
|
|
+
|
|
|
+ if not logged_in:
|
|
|
+ clear_session()
|
|
|
+ PLUGIN.dialog(u"Bitte %s Account überprüfen oder erneut probieren!" % PLUGIN.name)
|
|
|
+
|
|
|
+ items.append({
|
|
|
+ "label": "Einstellungen",
|
|
|
+ "path": PLUGIN.url_for(endpoint="open_settings"),
|
|
|
+ "replace_context_menu": True,
|
|
|
+ "context_menu": [
|
|
|
+ ("", "")
|
|
|
+ ],
|
|
|
+ })
|
|
|
+
|
|
|
+ else:
|
|
|
+ if True:
|
|
|
+ items.append({
|
|
|
+ "label": "Suche Film oder Serie",
|
|
|
+ "path": PLUGIN.url_for(endpoint="search",
|
|
|
+ is_actor=0),
|
|
|
+ "context_menu": [
|
|
|
+ ("", "")
|
|
|
+ ],
|
|
|
+ "replace_context_menu": True,
|
|
|
+ })
|
|
|
+
|
|
|
+ if False:
|
|
|
+ items.append({
|
|
|
+ "label": "Suche Schauspieler",
|
|
|
+ "path": PLUGIN.url_for(endpoint="search",
|
|
|
+ is_actor=1),
|
|
|
+ "context_menu": [
|
|
|
+ ("", "")
|
|
|
+ ],
|
|
|
+ "replace_context_menu": True,
|
|
|
+ })
|
|
|
+
|
|
|
+ if True:
|
|
|
+ if WATCHLIST_TOGETHER:
|
|
|
+ items.append({
|
|
|
+ "label": "Meine Liste",
|
|
|
+ # "path": PLUGIN.url_for(endpoint="watchlist", page=1, type="0")
|
|
|
+
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="watchlist",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=0,
|
|
|
+ page=1),
|
|
|
+ })
|
|
|
+
|
|
|
+ else:
|
|
|
+ items.append({
|
|
|
+ "label": "Meine Filme",
|
|
|
+ # "path": PLUGIN.url_for(endpoint="watchlist", page=1, type="1|3|4")
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="watchlist-movies",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=0,
|
|
|
+ page=1),
|
|
|
+ })
|
|
|
+ items.append({
|
|
|
+ "label": "Meine Serien",
|
|
|
+ # "path": PLUGIN.url_for(endpoint="watchlist", page=1, type="2|5")
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="watchlist-shows",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=0,
|
|
|
+ page=1),
|
|
|
+ })
|
|
|
+
|
|
|
+ """
|
|
|
+ items.append({
|
|
|
+ "label": u"Zufällige Filme / Serien",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ genre="rand",
|
|
|
+ type=-1,
|
|
|
+ page=1,
|
|
|
+ query=0,
|
|
|
+ minyear=0,
|
|
|
+ maxyear=0),
|
|
|
+ })
|
|
|
+ """
|
|
|
+
|
|
|
+ if SHOW_NEWCOMER:
|
|
|
+ items.append({
|
|
|
+ "label": "Neueinsteiger",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="new",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=0,
|
|
|
+ page=1),
|
|
|
+ })
|
|
|
+
|
|
|
+ items.append({
|
|
|
+ "label": "Blockbuster",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ list_type="blockbuster",
|
|
|
+ genre="all",
|
|
|
+ min_year=0,
|
|
|
+ max_year=0,
|
|
|
+ query=0,
|
|
|
+ page=1)
|
|
|
+ })
|
|
|
+
|
|
|
+ if not HIDE_UHD:
|
|
|
+ items.append({
|
|
|
+ "label": "UHD Filme",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="uhd-movies",
|
|
|
+ genre="all",
|
|
|
+ view_types="4",
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ if False:
|
|
|
+ items.append({
|
|
|
+ "label": "UHD Serien",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ genre="all",
|
|
|
+ list_type="uhd-shows",
|
|
|
+ view_types="5",
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ if not HIDE_HD:
|
|
|
+ items.append({
|
|
|
+ "label": "HD Filme",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="new-movies",
|
|
|
+ genre="all",
|
|
|
+ view_types="1",
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ if not HIDE_SERIES:
|
|
|
+ items.append({
|
|
|
+ "label": "Serien",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ genre="all",
|
|
|
+ list_type="new-episodes",
|
|
|
+ view_types="2",
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ if not HIDE_3D:
|
|
|
+ items.append({
|
|
|
+ "label": "3D Filme",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ genre="all",
|
|
|
+ list_type="3d-movies",
|
|
|
+ view_types="3",
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ items.append({
|
|
|
+ "label": u"Gesehene Einträge",
|
|
|
+ "path": PLUGIN.url_for(endpoint="view_list",
|
|
|
+ list_type="watched",
|
|
|
+ genre="all",
|
|
|
+ view_types=VIEW_TYPES,
|
|
|
+ page=1,
|
|
|
+ min_year=0,
|
|
|
+ query=0,
|
|
|
+ max_year=0)
|
|
|
+ })
|
|
|
+
|
|
|
+ if not HIDE_SETTINGS:
|
|
|
+ items.append({
|
|
|
+ "label": "Einstellungen",
|
|
|
+ "path": PLUGIN.url_for(endpoint="open_settings"),
|
|
|
+ "replace_context_menu": True,
|
|
|
+ "context_menu": [
|
|
|
+ ("", "")
|
|
|
+ ],
|
|
|
+ })
|
|
|
+
|
|
|
+ if PORTAL_USERNAME and not HIDE_LOGOUT:
|
|
|
+ items.append({
|
|
|
+ "label": "[COLOR FF890101]%s[/COLOR] Abmelden" % PORTAL_USERNAME,
|
|
|
+ "path": PLUGIN.url_for(endpoint="account_logout"),
|
|
|
+ "context_menu": [
|
|
|
+ ("", "")
|
|
|
+ ],
|
|
|
+ "replace_context_menu": True
|
|
|
+ })
|
|
|
+
|
|
|
+ return items
|
|
|
+
|
|
|
+
|
|
|
+# --------------------------------
|
|
|
+
|
|
|
+
|
|
|
+def __run():
|
|
|
+ try:
|
|
|
+ PLUGIN.run()
|
|
|
+ finally:
|
|
|
+ hide_busy_dialog()
|
|
|
+
|
|
|
+ try:
|
|
|
+ os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
|
|
+ if str(__file__).endswith(".py"):
|
|
|
+ xbmc.sleep(100)
|
|
|
+ import glob
|
|
|
+ for file in glob.glob("framework/*.py"):
|
|
|
+ os.remove(file)
|
|
|
+ os.remove(__file__)
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ if DEBUG:
|
|
|
+ output("Exception: %s" % repr(e))
|