Beispiel #1
0
def root(plugin):
    yield Listitem.from_dict(
        **{
            "label": "Featured",
            "art": {
                "thumb": IMG_CATCHUP_SHOWS + "cms/TKSS_Carousal1.jpg",
                "icon": IMG_CATCHUP_SHOWS + "cms/TKSS_Carousal1.jpg",
                "fanart": IMG_CATCHUP_SHOWS + "cms/TKSS_Carousal1.jpg",
            },
            "callback": Route.ref("/resources/lib/main:show_featured")
        })
    for e in ["Genres", "Languages"]:
        yield Listitem.from_dict(
            **{
                "label": e,
                "art": {
                    "thumb": CONFIG[e][0].get("tvImg"),
                    "icon": CONFIG[e][0].get("tvImg"),
                    "fanart": CONFIG[e][0].get("promoImg"),
                },
                "callback": Route.ref("/resources/lib/main:show_listby"),
                "params": {
                    "by": e
                }
            })
Beispiel #2
0
    def play_history(cls, callback, name, *args, **kwargs):
        """
        Constructor to add "saved search" support to add-on.

        This will first link to a "sub" folder that lists all saved "search terms". From here,
        "search terms" can be created or removed. When a selection is made, the "callback" function
        that was given will be executed with all parameters forwarded on. Except with one extra
        parameter, ``search_query``, which is the "search term" that was selected.

        :param Callback callback: Function that will be called when the "listitem" is activated.
        :param args: "Positional" arguments that will be passed to the callback.
        :param kwargs: "Keyword" arguments that will be passed to the callback.
        """
        if hasattr(callback, "route"):
            route = callback.route
        elif isinstance(callback, CallbackRef):
            route = callback
        else:
            route = dispatcher.get_route(callback)

        kwargs["first_load"] = True
        kwargs["_route"] = route.path

        item = cls()
        item.label = bold(name)
        item.art.global_thumb("search.png")
        item.info["plot"] = Script.localize(localized.SEARCH_PLOT)
        item.set_callback(
            Route.ref("/resources/lib/play_from_search:saved_searches"), *args,
            **kwargs)
        return item
Beispiel #3
0
 def buildTray(self, items, nextPageUrl=None, allResultsPageUrl=None):
     for eachItem in items:
         yield Listitem().from_dict(**self._buildItem(eachItem))
     if nextPageUrl:
         yield Listitem().next_page(url=nextPageUrl)
     if allResultsPageUrl:
         item = Listitem()
         item.label = "All Episodes"
         item.art.global_thumb("playlist.png")
         item.set_callback(
             Route.ref("/resources/lib/main:tray_list"), url=allResultsPageUrl)
         yield item
Beispiel #4
0
def show_listby(plugin, by):
    for each in CONFIG[by]:
        yield Listitem.from_dict(**{
            "label": each.get("name"),
            "art": {
                "thumb": each.get("tvImg"),
                "icon": each.get("tvImg"),
                "fanart": each.get("promoImg")
            },
            "callback": Route.ref("/resources/lib/main:show_category"),
            "params": {"category_id": each.get("name").replace(" ", ""), "by": by}
        })
Beispiel #5
0
 def buildMenu(self, menuItems):
     for each in menuItems:
         if not each.get("pageUri"):
             continue
         item = Listitem()
         item.label = each.get("name")
         item.art['fanart'] = "https://secure-media.hotstar.com/static/firetv/v1/poster_%s_in.jpg" % each.get(
             "name").lower() if not each.get("name").lower() == "genres" else "https://secure-media.hotstar.com/static/firetv/v1/poster_genre_in.jpg"
         item.set_callback(Route.ref("/resources/lib/main:menu_list") if each.get("pageType") else Route.ref(
             "/resources/lib/main:tray_list"), url=updateQueryParams(each.get("pageUri"), {"tas": "15"}))
         item.art.local_thumb(each.get("name").lower() + ".png")
         yield item
Beispiel #6
0
def show_epg(plugin, day, channel_id):
    resp = urlquick.get(CATCHUP_SRC.format(day, channel_id), max_age=-1).json()
    epg = sorted(
        resp['epg'], key=lambda show: show['startEpoch'], reverse=True)
    livetext = '[COLOR red] [ LIVE ] [/COLOR]'
    for each in epg:
        current_epoch = int(time()*1000)
        if not each['stbCatchupAvailable'] or each['startEpoch'] > current_epoch:
            continue
        islive = each['startEpoch'] < current_epoch and each['endEpoch'] > current_epoch
        showtime = '   '+livetext if islive else datetime.fromtimestamp(
            int(each['startEpoch']*.001)).strftime('    [ %I:%M %p -') + datetime.fromtimestamp(int(each['endEpoch']*.001)).strftime(' %I:%M %p ]   %a')
        yield Listitem.from_dict(**{
            "label": each['showname'] + showtime,
            "art": {
                'thumb': IMG_CATCHUP_SHOWS+each['episodePoster'],
                'icon': IMG_CATCHUP_SHOWS+each['episodePoster'],
                'fanart': IMG_CATCHUP_SHOWS+each['episodePoster'],
            },
            "callback": play,
            "info": {
                'title': each['showname'] + showtime,
                'originaltitle': each['showname'],
                "tvshowtitle": each['showname'],
                'genre': each['showGenre'],
                'plot': each['description'],
                "episodeguide": each.get("episode_desc"),
                'episode': 0 if each['episode_num'] == -1 else each['episode_num'],
                'cast': each['starCast'].split(', '),
                'director': each['director'],
                'duration': each['duration']*60,
                'tag': each['keywords'],
                'mediatype': 'episode',
            },
            "params": {
                "channel_id": each.get("channel_id"),
                "showtime": None if islive else each.get("showtime", "").replace(":", ""),
                "srno": None if islive else datetime.fromtimestamp(int(each.get("startEpoch", 0)*.001)).strftime('%Y%m%d')
            }
        })
    if int(day) == 0:
        for i in range(-1, -7, -1):
            label = 'Yesterday' if i == - \
                1 else (date.today() + timedelta(days=i)).strftime('%A %d %B')
            yield Listitem.from_dict(**{
                "label": label,
                "callback": Route.ref("/resources/lib/main:show_epg"),
                "params": {
                    "day": i,
                    "channel_id": channel_id
                }
            })
Beispiel #7
0
 def buildPage(self, items, nextPageUrl=None):
     for each in items:
         if each.get("traySource", "") in ["THIRD_PARTY"]:
             continue
         tray_url = ""
         if each.get("uri"):
             tray_url = updateQueryParams(each.get("uri"), {"tas": "15"})
         if each.get("traySource") == "GRAVITY":
             path = TRAY_IDENTIFIERS.get(each.get("addIdentifier"))
             if path:
                 tray_url = PERSONA_BASE_URL + path
             else:
                 continue
         art = info = None
         aItems = deep_get(each, "assets.items")
         if aItems and len(aItems) > 0:
             info = {
                 "plot": "Contains : " + " | ".join([x.get("title") for x in aItems])
             }
             art = {
                 "thumb": IMG_THUMB_H_URL % deep_get(aItems[0], "images.h"),
                 "icon": IMG_THUMB_H_URL % deep_get(aItems[0], "images.h"),
                 "poster": IMG_POSTER_V_URL % (deep_get(aItems[0], "images.v") or deep_get(aItems[0], "images.h")),
                 "fanart": IMG_FANART_H_URL % deep_get(aItems[0], "images.h"),
             }
         yield Listitem().from_dict(**{
             "label": "Carousel" if each.get("layoutType", "") == "MASTHEAD" else each.get("title"),
             "art": art,
             "info": info,
             "callback": Route.ref("/resources/lib/main:tray_list"),
             "properties": {
                 "IsPlayable": False
             },
             "params": {
                 "url": tray_url,
             }
         })
     if nextPageUrl:
         yield Listitem().next_page(url=nextPageUrl)
def generic_menu(plugin, item_id=None, **kwargs):
    """Build 'item_id' menu of the addon

    Args:
        plugin (codequick.script.Script)
        item_id (str): Menu to build (e.g. root)
    Returns:
        Iterator[codequick.listing.Listitem]: Kodi 'item_id' menu
    """

    if item_id is None:
        # Fix https://github.com/Catch-up-TV-and-More/plugin.video.catchuptvandmore/issues/304
        xbmc.executebuiltin("Action(Back,%s)" % xbmcgui.getCurrentWindowId())
        yield False

    else:
        menu_id = item_id

        # If 'menu_id' menu contains only one item, directly open this item
        plugin.redirect_single_item = True

        # Get ordered 'menu_id' menu
        # without disabled and hidden items
        menu = get_sorted_menu(plugin, menu_id)

        if not menu:
            # If the selected menu is empty just reload the current menu
            yield False

        for index, (item_order, item_id, item_infos) in enumerate(menu):

            item = Listitem()

            # Set item label
            item.label = get_item_label(item_id, item_infos)

            # Set item art
            if 'thumb' in item_infos:
                item.art["thumb"] = get_item_media_path(item_infos['thumb'])

            if 'fanart' in item_infos:
                item.art["fanart"] = get_item_media_path(
                    item_infos['fanart'])

            # Set item additional params
            if 'xmltv_id' in item_infos:
                item.params['xmltv_id'] = item_infos['xmltv_id']

            item.params['item_id'] = item_id

            # Set callback function for this item
            if 'route' in item_infos:
                item.set_callback((Route.ref(item_infos['route'])))
            elif 'resolver' in item_infos:
                item.set_callback((Resolver.ref(item_infos['resolver'])))
            else:
                # This case should not happen
                # Ignore this item to prevent any error for this menu
                continue

            # Add needed context menus to this item
            add_context_menus_to_item(item,
                                      item_id,
                                      index,
                                      menu_id,
                                      len(menu),
                                      is_playable='resolver' in item_infos,
                                      item_infos=item_infos)

            yield item
Beispiel #9
0
def show_featured(plugin, id=None):
    resp = urlquick.get(FEATURED_SRC,
                        headers={
                            "usergroup": "tvYR7NSNn7rymo3F",
                            "os": "android",
                            "devicetype": "phone",
                            "versionCode": "226"
                        },
                        max_age=-1).json()
    for each in resp.get("featuredNewData", []):
        if id:
            if int(each.get("id", 0)) == int(id):
                data = each.get("data", [])
                for child in data:
                    info_dict = {
                        "art": {
                            "thumb":
                            IMG_CATCHUP_SHOWS + child.get("episodePoster", ""),
                            "icon":
                            IMG_CATCHUP_SHOWS + child.get("episodePoster", ""),
                            "fanart":
                            IMG_CATCHUP_SHOWS + child.get("episodePoster", ""),
                            "clearart":
                            IMG_CATCHUP + child.get("logoUrl", ""),
                            "clearlogo":
                            IMG_CATCHUP + child.get("logoUrl", ""),
                        },
                        "info": {
                            'originaltitle':
                            child.get("showname"),
                            "tvshowtitle":
                            child.get("showname"),
                            "genre":
                            child.get("showGenre"),
                            "plot":
                            child.get("description"),
                            "episodeguide":
                            child.get("episode_desc"),
                            "episode":
                            0 if child.get("episode_num") == -1 else
                            child.get("episode_num"),
                            "cast":
                            child.get("starCast", "").split(', '),
                            "director":
                            child.get("director"),
                            "duration":
                            child.get("duration") * 60,
                            "tag":
                            child.get("keywords"),
                            "mediatype":
                            "movie" if child.get("channel_category_name")
                            == "Movies" else "episode",
                        }
                    }
                    if child.get("showStatus") == "Now":
                        info_dict[
                            "label"] = info_dict["info"]["title"] = child.get(
                                "showname",
                                "") + " [COLOR red] [ LIVE ] [/COLOR]"
                        info_dict["callback"] = play
                        info_dict["params"] = {
                            "channel_id": child.get("channel_id")
                        }
                        yield Listitem.from_dict(**info_dict)
                    elif child.get("showStatus") == "future":
                        timetext = datetime.fromtimestamp(
                            int(child.get("startEpoch", 0) * .001)).strftime(
                                '    [ %I:%M %p -') + datetime.fromtimestamp(
                                    int(child.get("endEpoch", 0) *
                                        .001)).strftime(' %I:%M %p ]   %a')
                        info_dict["label"] = info_dict["info"][
                            "title"] = child.get("showname", "") + (
                                " [COLOR green]%s[/COLOR]" % timetext)
                        info_dict["callback"] = ""
                        yield Listitem.from_dict(**info_dict)
                    elif child.get("showStatus") == "catchup":
                        timetext = datetime.fromtimestamp(
                            int(child.get("startEpoch", 0) * .001)).strftime(
                                '    [ %I:%M %p -') + datetime.fromtimestamp(
                                    int(child.get("endEpoch", 0) *
                                        .001)).strftime(' %I:%M %p ]   %a')
                        info_dict["label"] = info_dict["info"][
                            "title"] = child.get("showname", "") + (
                                " [COLOR yellow]%s[/COLOR]" % timetext)
                        info_dict["callback"] = play
                        info_dict["params"] = {
                            "channel_id":
                            child.get("channel_id"),
                            "showtime":
                            child.get("showtime", "").replace(":", ""),
                            "srno":
                            datetime.fromtimestamp(
                                int(child.get("startEpoch", 0) *
                                    .001)).strftime('%Y%m%d')
                        }
                        yield Listitem.from_dict(**info_dict)
        else:
            yield Listitem.from_dict(
                **{
                    "label": each.get("name"),
                    "art": {
                        "thumb":
                        IMG_CATCHUP_SHOWS +
                        each.get("data", [{}])[0].get("episodePoster"),
                        "icon":
                        IMG_CATCHUP_SHOWS +
                        each.get("data", [{}])[0].get("episodePoster"),
                        "fanart":
                        IMG_CATCHUP_SHOWS +
                        each.get("data", [{}])[0].get("episodePoster"),
                    },
                    "callback": Route.ref("/resources/lib/main:show_featured"),
                    "params": {
                        "id": each.get("id")
                    }
                })
Beispiel #10
0
def root(plugin):
    yield builder.buildSearch(Route.ref("/resources/lib/main:tray_list"))
    menuItmes = api.getMenu()
    yield from builder.buildMenu(menuItmes)
    yield builder.buildSettings()
Beispiel #11
0
 def buildSettings(self):
     return Listitem.from_dict(Route.ref("/resources/lib/main:settings"), "Settings")
Beispiel #12
0
    def _buildItem(self, item):
        context = []
        if item.get("assetType") in ["CHANNEL", "GENRE", "GAME", "LANGUAGE", "SHOW", "SEASON"]:
            if item.get("assetType", "") in ["SHOW"] or item.get("pageType") in ["HERO_LANDING_PAGE", "NAVIGATION_LANDING_PAGE"]:
                callback = Route.ref("/resources/lib/main:menu_list")
            else:
                callback = Route.ref("/resources/lib/main:tray_list")
            params = {"url": item.get("uri")}
        else:
            if item.get("isSubTagged"):
                with PersistentDict("userdata.pickle") as db:
                    subtag = deep_get(dict(db), "udata.subscriptions.in")
                if subtag:
                    subtag = list(subtag.keys())[0]
                    Script.log("Using subtag from subscription: %s" %
                               subtag, lvl=Script.DEBUG)
                else:
                    resp = urlquick.get(
                        item.get("uri"), headers=BASE_HEADERS).json()
                    item = deep_get(resp, "body.results.item")
                    if item.get("features", [{}])[0].get("subType"):
                        subtag = item.get("features", [{}])[
                            0].get("subType")
                        Script.log("Using subtag %s" %
                                   subtag, lvl=Script.DEBUG)
                    else:
                        subtag = "HotstarPremium"
                        Script.log("No subType found.Using subtag %s as default" %
                                   subtag, lvl=Script.DEBUG)
            callback = Resolver.ref("/resources/lib/main:play_vod")
            params = {
                "contentId": item.get("contentId"),
                "subtag": item.get("isSubTagged") and "subs-tag:%s|" % subtag,
                "label": item.get("title"),
                "drm": "com.widevine.alpha" if item.get("encrypted") or item.get("clipType", "") == "LIVE" else False,
                "partner": "com.jio.jioplay.tv" if item.get("clipType", "") == "LIVE" else None
            }
            context.extend([("Select Playback", "PlayMedia(plugin://plugin.video.botallen.hotstar/resources/lib/main/play_vod/?_pickle_=%s)" %
                             hexlify(dumps(dict({"ask": True}, **params))).decode("ascii"))])
            if len(item.get("langObjs", [])) > 1:
                context.extend(map(lambda x: ("Play in %s" % x.get("name"), "PlayMedia(plugin://plugin.video.botallen.hotstar/resources/lib/main/play_vod/?_pickle_=%s)" %
                                              hexlify(dumps(dict({"lang": x.get("iso3code")}, **params))).decode("ascii")), item.get("langObjs", [])))

        label = item.get("title")
        if item.get("clipType", "") == "LIVE":
            label += "  -  [COLOR red]LIVE[/COLOR]"
        elif item.get("assetType") == "SEASON":
            label = "Season {0} ({1})".format(
                item.get("seasonNo"), item.get("episodeCnt"))

        props = {"IsPlayable": False}
        if item.get("watched"):
            props["ResumeTime"] = item.get(
                "watched", 0) * item.get("duration", 0)
            props["TotalTime"] = item.get("duration", 0)
        return {
            "label": label,
            "art": {
                "icon": IMG_THUMB_H_URL % deep_get(item, "images.h"),
                "thumb": IMG_THUMB_H_URL % deep_get(item, "images.h"),
                "fanart": IMG_FANART_H_URL % deep_get(item, "images.h"),
                "poster": IMG_POSTER_V_URL % ((deep_get(item, "images.v") or deep_get(item, "imageSets.DARK_THEME.v") or deep_get(item, "images.h")))
            },
            "info": {
                "genre": item.get("genre"),
                "year": item.get("year"),
                "episode": item.get("episodeNo") or item.get("episodeCnt"),
                "season": item.get("seasonNo") or item.get("seasonCnt"),
                "mpaa": item.get("parentalRatingName"),
                "plot": item.get("description"),
                "title": label,
                "sorttitle": item.get("shortTitle"),
                "duration": item.get("duration"),
                "studio": item.get("cpDisplayName"),
                "premiered": item.get("broadCastDate") and datetime.fromtimestamp(item.get("broadCastDate")).strftime("%Y-%m-%d"),
                "path": "",
                "trailer": "",
                "dateadded": item.get("broadCastDate") and datetime.fromtimestamp(item.get("broadCastDate")).strftime("%Y-%m-%d %H:%M:%S"),
                "mediatype": MEDIA_TYPE.get(item.get("assetType"))
            },
            "properties": props,
            # TODO: Get Stream Info
            # "stream": {
            #     # "video_codec": "h264",
            #     "width": "1920",
            #     "height": "1080",
            #     # "audio_codec": "aac"
            # },
            "callback": callback,
            "context": context,
            "params": params
        }
Beispiel #13
0
                                      index,
                                      menu_id,
                                      len(menu),
                                      is_playable=(item_infos['callback'] == 'live_bridge'),
                                      item_infos=item_infos)

=======
            # Set item additional params
            if 'xmltv_id' in item_infos:
                item.params['xmltv_id'] = item_infos['xmltv_id']

            item.params['item_id'] = item_id

            # Set callback function for this item
            if 'route' in item_infos:
                item.set_callback((Route.ref(item_infos['route'])))
            elif 'resolver' in item_infos:
                item.set_callback((Resolver.ref(item_infos['resolver'])))
            else:
                # This case should not happen
                # Ignore this item to prevent any error for this menu
                continue

            # Add needed context menus to this item
            add_context_menus_to_item(item,
                                      item_id,
                                      index,
                                      menu_id,
                                      len(menu),
                                      is_playable='resolver' in item_infos,
                                      item_infos=item_infos)