def tv(): response = KinoPubClient("tv/index").get() for ch in response["channels"]: li = xbmcgui.ListItem(ch["title"].encode("utf-8"), iconImage=ch["logos"]["s"]) xbmcplugin.addDirectoryItem(request.handle, ch["stream"], li, False) xbmcplugin.endOfDirectory(request.handle)
def update_device_info(force=False): from client import KinoPubClient # Update device info deviceInfoUpdate = __settings__.getSetting("device_info_update") if force or not deviceInfoUpdate or int(deviceInfoUpdate) + 1800 < int(time.time()): infoLabels = [ '"System.BuildVersion"', '"System.FriendlyName"', '"System.KernelVersion"' ] result = "Busy" payload = { "jsonrpc": "2.0", "method": "XBMC.GetInfoLabels", "id": 1, "params": {"labels": [",".join(infoLabels)]} } while "Busy" in result: result = xbmc.executeJSONRPC(json.dumps(payload)) result = json.loads(result)["result"] title = result.get("System.FriendlyName") hardware = result.get("System.KernelVersion") software = "Kodi/{}".format(result.get("System.BuildVersion")) KinoPubClient("device/notify").post(data={ "title": title, "hardware": hardware, "software": software }) __settings__.setSetting("device_info_update", str(int(float(time.time()))))
def create_bookmarks_folder(): kbd = xbmc.Keyboard() kbd.setHeading("Имя папки закладок") kbd.doModal() if kbd.isConfirmed(): title = kbd.getText() KinoPubClient("bookmarks/create").post(data={"title": title})
def index(): """Main screen - show type list""" if not auth.access_token: li = xbmcgui.ListItem("Активировать устройство") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("login"), li, False) xbmcplugin.endOfDirectory(request.handle) else: response = KinoPubClient("types").get() xbmc.executebuiltin("Container.SetViewMode(0)") add_default_headings() li = xbmcgui.ListItem("[COLOR FFFFF000]ТВ[/COLOR]") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("tv"), li, True) li = xbmcgui.ListItem("[COLOR FFFFF000]Закладки[/COLOR]") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("bookmarks"), li, True) li = xbmcgui.ListItem("[COLOR FFFFF000]Я смотрю[/COLOR]") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("watching"), li, True) li = xbmcgui.ListItem("[COLOR FFFFF000]Подборки[/COLOR]") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("collections"), li, True) for i in response["items"]: li = xbmcgui.ListItem(i["title"].encode("utf-8")) link = get_internal_link("item_index", type=i["id"]) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def toggle_watchlist(**kwargs): added = int(kwargs.pop("added")) KinoPubClient("watching/togglewatchlist").get(data=kwargs) if added: notice('Сериал добавлен в список "Буду смотреть"') else: notice('Сериал удалён из списка "Буду смотреть"')
def episodes(id): response = KinoPubClient("items/{}".format(id)).get() item = response["item"] xbmcplugin.setContent(request.handle, "episodes") for video_number, video in enumerate(item["videos"], 1): episode_title = "e{:02d}".format(video_number) if video["title"]: episode_title = "{} | {}".format(episode_title, video["title"].encode("utf-8")) li = xbmcgui.ListItem(episode_title, iconImage=video["thumbnail"], thumbnailImage=video["thumbnail"]) li.setInfo( "Video", video_info( item, { "season": 1, "episode": video_number, "playcount": video["watched"], "mediatype": "episode" })) li.setArt({"poster": item["posters"]["big"]}) li.setProperty("id", str(item["id"])) li.setProperty("isPlayable", "true") qp = { "id": item["id"], "title": episode_title, "episode_number": video_number, "video_data": json.dumps(video) } link = get_internal_link("play", **qp) context_menu.add_items(li) xbmcplugin.addDirectoryItem(request.handle, link, li, False) xbmcplugin.endOfDirectory(request.handle)
def season_episodes(id, season_number): response = KinoPubClient("items/{}".format(id)).get() item = response["item"] watching_info = KinoPubClient("watching").get( data={"id": item["id"]})["item"] season_number = int(season_number) season = item["seasons"][season_number - 1] watching_season = watching_info["seasons"][season_number - 1] selectedEpisode = False xbmcplugin.setContent(request.handle, "episodes") for episode in season["episodes"]: episode_title = "s{:02d}e{:02d}".format(season_number, episode["number"]) if episode["title"]: episode_title = "{} | {}".format(episode_title, episode["title"].encode("utf-8")) li = xbmcgui.ListItem(episode_title, iconImage=episode["thumbnail"], thumbnailImage=episode["thumbnail"]) li.setInfo( "Video", video_info( item, { "season": season_number, "episode": episode["number"], "duration": episode["duration"], "playcount": episode["watched"], "mediatype": "episode" })) li.setArt({"poster": item["posters"]["big"]}) li.setProperty("id", str(item["id"])) li.setProperty("isPlayable", "true") status = watching_season["episodes"][episode["number"] - 1]["status"] if status < 1 and not selectedEpisode: selectedEpisode = True li.select(selectedEpisode) qp = { "id": item["id"], "title": episode_title, "season_number": season["number"], "episode_number": episode["number"], "video_data": json.dumps(episode) } link = get_internal_link("play", **qp) context_menu.add_items(li) xbmcplugin.addDirectoryItem(request.handle, link, li, False) xbmcplugin.endOfDirectory(request.handle)
def toggle_watchlist(**kwargs): added = int(kwargs.pop("added")) KinoPubClient("watching/togglewatchlist").get(data=kwargs) if added: notice('Сериал добавлен в список "Буду смотреть"') else: notice('Сериал удалён из списка "Буду смотреть"') xbmc.executebuiltin("Container.Refresh")
def similar(item_id=None, title=""): response = KinoPubClient("items/similar").get(data={"id": item_id}) if not response["items"]: dialog = xbmcgui.Dialog() dialog.ok("Похожие фильмы: {0}".format(title), u"Пока тут пусто") else: show_items(response["items"]) xbmcplugin.endOfDirectory(request.handle, cacheToDisk=False)
def genres(type): response = KinoPubClient("genres").get(data={"type": type}) add_default_headings(type) for genre in response["items"]: li = ExtendedListItem(genre["title"].encode("utf-8")) link = get_internal_link("items", type=type, genre=genre["id"]) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def items(type, **kwargs): """List items with pagination""" kwargs["type"] = type shortcut = kwargs.pop("shortcut", "") response = KinoPubClient("items{}".format(shortcut)).get(data=kwargs) pagination = response["pagination"] xbmcplugin.setContent(request.handle, "{}s".format(mediatype_map.get(type, "video"))) show_items(response["items"]) show_pagination(pagination, "items", **kwargs)
def profile(): user_data = KinoPubClient("user").get()["user"] reg_date = date.fromtimestamp(user_data["reg_date"]) dialog = xbmcgui.Dialog() dialog.ok( "Информация о профиле", "Имя пользователя: [B]{}[/B]".format(user_data["username"]), "Дата регистрации: [B]{0:%d} {0:%B} {0:%Y}[/B]".format(reg_date), "Остаток дней подписки: [B]{}[/B]".format( int(user_data["subscription"]["days"])))
def items(type, page=None, **kwargs): """List items with pagination""" kwargs["type"] = type if page: kwargs["page"] = page response = KinoPubClient("items").get(data=kwargs) pagination = response["pagination"] add_default_headings(type, fmt="s") show_items(response["items"]) show_pagination(pagination, "items", type=type)
def seasons(id): response = KinoPubClient("items/{}".format(id)).get() item = response["item"] watching_info = KinoPubClient("watching").get( data={"id": item["id"]})["item"] selectedSeason = False xbmcplugin.setContent(request.handle, "tvshows") for season in item["seasons"]: season_title = "Сезон {}".format(season["number"]) watching_season = watching_info["seasons"][season["number"] - 1] li = xbmcgui.ListItem(season_title) li.setInfo("Video", video_info(item, {"season": season["number"]})) li.setArt({"poster": item["posters"]["big"]}) if watching_season["status"] < 1 and not selectedSeason: selectedSeason = True li.select(selectedSeason) qp = {"id": id, "season_number": season["number"]} link = get_internal_link("view_season_episodes", **qp) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def trailer(id, sid=None): response = KinoPubClient("items/trailer").get(data={"id": id}) trailer = response["trailer"] if "files" in trailer: url = get_mlink(trailer, quality=__settings__.getSetting("video_quality"), streamType=__settings__.getSetting("stream_type")) elif sid is not None: url = "plugin://plugin.video.youtube/?path=/root/video&action=play_video&videoid={}" url = url.format(sid) li = ExtendedListItem("Трейлер", path=url) xbmcplugin.setResolvedUrl(request.handle, True, li)
def episodes(id): item = KinoPubClient("items/{}".format(id)).get()["item"] watching_info = KinoPubClient("watching").get(data={"id": id})["item"] xbmcplugin.setContent(request.handle, "episodes") playback_data = {} for video in item["videos"]: watching_episode = watching_info["videos"][video["number"] - 1] episode_title = "e{:02d}".format(video["number"]) if video["title"]: episode_title = "{} | {}".format(episode_title, video["title"].encode("utf-8")) info = extract_video_info( item, { "episode": video["number"], "tvshowtitle": video["title"], "time": watching_episode["time"], "duration": watching_episode["duration"], "playcount": video["watched"], "mediatype": "episode" }) li = ExtendedListItem(episode_title, thumbnailImage=video["thumbnail"], video_info=info, poster=item["posters"]["big"], properties={ "id": item["id"], "isPlayable": "true" }, addContextMenuItems=True) link = get_internal_link("play", id=item["id"], index=video["number"]) playback_data[video["number"]] = { "video_data": video, "video_info": info, "poster": item["posters"]["big"], "title": episode_title } xbmcplugin.addDirectoryItem(request.handle, link, li, False) set_window_property(playback_data) xbmcplugin.endOfDirectory(request.handle, cacheToDisc=False)
def edit_bookmarks(item_id=None): item_folders_resp = KinoPubClient("bookmarks/get-item-folders").get( data={"item": item_id}) all_folders_resp = KinoPubClient("bookmarks").get() all_folders = [f["title"] for f in all_folders_resp["items"]] item_folders = [f["title"] for f in item_folders_resp["folders"]] preselect = [all_folders.index(f) for f in item_folders] dialog = xbmcgui.Dialog() indexes = dialog.multiselect("Папки закладок", all_folders, preselect=preselect) # Cancel button was pressed if indexes is None: return chosen_folders = [all_folders[i] for i in indexes] folders_to_add = list(set(chosen_folders) - set(item_folders)) folders_to_remove = list(set(item_folders) - set(chosen_folders)) # Ok button was pressed but nothing changed if not folders_to_add and not folders_to_remove: return def get_folder_id(title): for folder in all_folders_resp["items"]: if folder["title"] == title: return folder["id"] for folder in folders_to_add: KinoPubClient("bookmarks/add").post(data={ "item": item_id, "folder": get_folder_id(folder) }) for folder in folders_to_remove: KinoPubClient("bookmarks/remove-item").post( data={ "item": item_id, "folder": get_folder_id(folder) }) notice("Закладки для видео изменены") xbmc.executebuiltin("Container.Refresh")
def watching_movies(): xbmcplugin.setContent(request.handle, "movies") playback_data = {} for i, item in enumerate(KinoPubClient("watching/movies").get()["items"]): li = ExtendedListItem( item["title"].encode("utf-8"), poster=item["posters"]["big"], properties={"id": item["id"]}, video_info={"mediatype": mediatype_map[item["type"]]}, addContextMenuItems=True) if item["subtype"] == "multi": link = get_internal_link("view_episodes", id=item["id"]) isdir = True else: response = KinoPubClient("items/{}".format(item["id"])).get() watching_info = KinoPubClient("watching").get( data={"id": item["id"]})["item"]["videos"] watching_info = watching_info[0] video_info = extract_video_info( response["item"], { "time": watching_info["time"], "duration": watching_info["duration"], "playcount": watching_info["status"], }) li.setInfo("video", video_info) li.setProperty("isPlayable", "true") li.setResumeTime(watching_info["time"]) link = get_internal_link("play", id=item["id"], index=i) playback_data[i] = { "video_info": video_info, "poster": item["posters"]["big"], "title": item["title"].encode("utf-8") } isdir = False xbmcplugin.addDirectoryItem(request.handle, link, li, isdir) xbmcgui.Window(10000).setProperty("video.kino.pub-playback_data", json.dumps(playback_data)) xbmcplugin.endOfDirectory(request.handle, cacheToDisc=False)
def play(id, index): properties = {} if ("hls" in __settings__.getSetting("stream_type") and __settings__.getSetting("inputstream_helper_enabled") == "true"): helper = inputstreamhelper.Helper("hls") if not helper.check_inputstream(): return else: properties.update({ "inputstreamaddon": helper.inputstream_addon, "inputstream.adaptive.manifest_type": "hls" }) playback_data = get_window_property(index) video_data = playback_data.get("video_data") video_info = playback_data["video_info"] if not video_data: response = KinoPubClient("items/{}".format(id)).get() video_data = response["item"]["videos"][0] video_info = extract_video_info(response["item"], video_info) if "files" not in video_data: notice("Видео обновляется и временно не доступно!", "Видео в обработке", time=8000) return url = get_mlink(video_data, quality=__settings__.getSetting("video_quality"), stream_type=__settings__.getSetting("stream_type"), ask_quality=__settings__.getSetting("ask_quality")) properties.update({ "id": id, "play_duration": video_info["duration"], "play_resumetime": video_info["time"], "video_number": video_info.get("episode", 1), "season_number": video_info.get("season", ""), "playcount": video_info["playcount"], "imdbnumber": video_info["imdbnumber"] }) li = ExtendedListItem( playback_data["title"], path=url, properties=properties, poster=playback_data["poster"], subtitles=[subtitle["url"] for subtitle in video_data["subtitles"]], ) player = Player(list_item=li) xbmcplugin.setResolvedUrl(request.handle, True, li) while player.is_playing: player.set_marktime() xbmc.sleep(1000)
def watching(): response = KinoPubClient("watching/serials").get(data={"subscribed": 1}) xbmcplugin.setContent(request.handle, "tvshows") for item in response["items"]: li = xbmcgui.ListItem("{} : [COLOR FFFFF000]+{}[/COLOR]".format( item["title"].encode("utf-8"), str(item["new"]))) li.setLabel2(str(item["new"])) li.setArt({"poster": item["posters"]["big"]}) li.setProperty("id", str(item["id"])) li.setProperty("in_watchlist", "1") li.setInfo("Video", {"mediatype": mediatype_map[item["type"]]}) link = get_internal_link("view_seasons", id=item["id"]) context_menu.add_items(li) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def comments(item_id=None): response = KinoPubClient("items/comments").get(data={"id": item_id}) comments = response["comments"] title = response["item"]["title"].encode("utf-8") message = "" if comments else "Пока тут пусто" for i in comments: if int(i["rating"]) > 0: rating = " [COLOR FF00B159](+{})[/COLOR]".format(i["rating"]) elif int(i["rating"]) < 0: rating = " [COLOR FFD11141]({})[/COLOR]".format(i["rating"]) else: rating = "" message = u"{}[COLOR FFFFF000]{}[/COLOR]{}: {}\n\n".format( message, i["user"]["name"], rating, i["message"].replace("\n", " ")) dialog = xbmcgui.Dialog() dialog.textviewer('Комментарии "{}"'.format(title), message)
def watching(): response = KinoPubClient("watching/serials").get(data={"subscribed": 1}) xbmcplugin.setContent(request.handle, "tvshows") for item in response["items"]: title = "{} : [COLOR FFFFF000]+{}[/COLOR]".format( item["title"].encode("utf-8"), str(item["new"])) li = ExtendedListItem( title, str(item["new"]), poster=item["posters"]["big"], properties={ "id": str(item["id"]), "in_watchlist": "1" }, video_info={"mediatype": mediatype_map[item["type"]]}, addContextMenuItems=True) link = get_internal_link("view_seasons", id=item["id"]) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def collections(sort=None): handle = request.handle response = KinoPubClient("collections/index").get(data={"sort": sort}) xbmcplugin.setContent(handle, "movies") li = xbmcgui.ListItem("[COLOR FFFFF000]Последние[/COLOR]") link = get_internal_link("collections", sort="-created") xbmcplugin.addDirectoryItem(handle, link, li, True) li = xbmcgui.ListItem("[COLOR FFFFF000]Просматриваемые[/COLOR]") link = get_internal_link("collections", sort="-watchers") xbmcplugin.addDirectoryItem(handle, link, li, True) li = xbmcgui.ListItem("[COLOR FFFFF000]Популярные[/COLOR]") link = get_internal_link("collections", sort="-views") xbmcplugin.addDirectoryItem(handle, link, li, True) for item in response["items"]: li = xbmcgui.ListItem(item["title"].encode("utf-8")) li.setThumbnailImage(item["posters"]["medium"]) link = get_internal_link("collection_view", id=item["id"]) xbmcplugin.addDirectoryItem(handle, link, li, True) show_pagination(response["pagination"], "collections", sort=sort) xbmcplugin.endOfDirectory(handle)
def update_device_info(force=False): from client import KinoPubClient # Update device info deviceInfoUpdate = __settings__.getSetting("device_info_update") if force or not deviceInfoUpdate or int(deviceInfoUpdate) + 1800 < int( time.time()): result = {"build_version": "Busy", "friendly_name": "Busy"} while "Busy" in result.values(): result = { "build_version": xbmc.getInfoLabel("System.BuildVersion"), "friendly_name": xbmc.getInfoLabel("System.FriendlyName") } software = "Kodi {}".format(result["build_version"].split()[0]) KinoPubClient("device/notify").post( data={ "title": result["friendly_name"], "hardware": platform.machine(), "software": software }) __settings__.setSetting("device_info_update", str(int(float(time.time()))))
def collections(sort=None, page=None): response = KinoPubClient("collections/index").get(data={ "sort": sort, "page": page }) xbmcplugin.setContent(request.handle, "movies") li = ExtendedListItem("Последние") link = get_internal_link("collections", sort="-created") xbmcplugin.addDirectoryItem(request.handle, link, li, True) li = ExtendedListItem("Просматриваемые") link = get_internal_link("collections", sort="-watchers") xbmcplugin.addDirectoryItem(request.handle, link, li, True) li = ExtendedListItem("Популярные") link = get_internal_link("collections", sort="-views") xbmcplugin.addDirectoryItem(request.handle, link, li, True) for item in response["items"]: li = ExtendedListItem(item["title"].encode("utf-8"), thumbnailImage=item["posters"]["medium"]) link = get_internal_link("collection_view", id=item["id"]) xbmcplugin.addDirectoryItem(request.handle, link, li, True) show_pagination(response["pagination"], "collections", sort=sort)
def index(): """Main screen - show type list""" if not auth.access_token: li = ExtendedListItem("Активировать устройство") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("login"), li, False) else: response = KinoPubClient("types").get() li = ExtendedListItem("Профиль") xbmcplugin.addDirectoryItem(request.handle, get_internal_link("profile"), li, False) for menu_item in main_menu_items: if menu_item.is_displayed: li = ExtendedListItem(menu_item.title) xbmcplugin.addDirectoryItem(request.handle, menu_item.link, li, menu_item.is_dir) for i in response["items"]: if __settings__.getSetting("show_{}".format(i["id"])) != "false": li = ExtendedListItem(i["title"].encode("utf-8")) link = get_internal_link("item_index", type=i["id"]) xbmcplugin.addDirectoryItem(request.handle, link, li, True) xbmcplugin.endOfDirectory(request.handle)
def play(id, title, video_info, video_data=None, poster=None, url=None): if not video_data: response = KinoPubClient("items/{}".format(id)).get() video_data = response["item"]["videos"][0] video_info = extract_video_info(response["item"], json.loads(video_info)) video_data = json.loads(video_data) if isinstance(video_data, str) else video_data video_info = json.loads(video_info) if isinstance(video_info, str) else video_info if "files" not in video_data: notice("Видео обновляется и временно не доступно!", "Видео в обработке", time=8000) return if not url: url = get_mlink(video_data, quality=__settings__.getSetting("video_quality"), stream_type=__settings__.getSetting("stream_type"), ask_quality=__settings__.getSetting("ask_quality")) li = ExtendedListItem( title, path=url, properties={ "id": id, "play_duration": video_info["duration"], "play_resumetime": video_info["time"], "video_number": video_info.get("episode", 1), "season_number": video_info.get("season", ""), "playcount": video_info["playcount"] }, poster=poster, subtitles=[subtitle["url"] for subtitle in video_data["subtitles"]], ) player = Player(list_item=li) xbmcplugin.setResolvedUrl(request.handle, True, li) while player.is_playing: player.set_marktime() xbmc.sleep(1000)
def show_items(items, add_indexes=False): xbmc.log("{} : show_items. Total items: {}".format(__plugin__, str(len(items)))) xbmcplugin.setContent(request.handle, "movies") # Fill list with items for index, item in enumerate(items, 1): title = item["title"].encode("utf-8") li = xbmcgui.ListItem(title) if add_indexes: li.setLabel("{}. {}".format(index, li.getLabel())) li.setArt({"poster": item["posters"]["big"]}) li.setProperty("id", str(item["id"])) if "in_watchlist" in item: li.setProperty("in_watchlist", str(int(item["in_watchlist"]))) extra_info = { "trailer": trailer_link(item), "mediatype": mediatype_map[item["type"]] } # If not serials or multiseries movie, create playable item if item["type"] not in ["serial", "docuserial", "tvshow" ] and not item["subtype"]: watched = KinoPubClient("watching").get( data={"id": item["id"]})["item"] extra_info.update({"playcount": watched["status"]}) link = get_internal_link("play", id=item["id"], title=title) li.setProperty("isPlayable", "true") isdir = False elif item["subtype"] == "multi": link = get_internal_link("view_episodes", id=item["id"]) isdir = True else: link = get_internal_link("view_seasons", id=item["id"]) isdir = True li.setInfo("Video", video_info(item, extra_info)) context_menu.add_items(li) xbmcplugin.addDirectoryItem(request.handle, link, li, isdir)
def remove_bookmark_folder(folder_id): KinoPubClient("bookmarks/remove-folder").post(data={"folder": folder_id}) xbmc.executebuiltin("Container.Refresh")
def toggle_watched(**data): KinoPubClient("watching/toggle").get(data=data) if "video" in data: data["time"] = 0 KinoPubClient("watching/marktime").get(data=data) xbmc.executebuiltin("Container.Refresh")