def play_external(self, playerindex=-1, force_dialog=False):
        playerindex = self.player_getnewindex(playerindex, force_dialog=force_dialog)

        # User cancelled dialog
        if not playerindex > -1:
            utils.kodi_log(u'Player -- User cancelled', 2)
            return False

        # Run through player actions
        player = self.player_resolveurl(self.actions[playerindex])

        # Previous player failed so ask user to select a new one
        if player == -1:
            return self.play_external(playerindex, force_dialog=force_dialog)

        # Play/Search found item
        if player and player[1]:
            action = string_format_map(player[1], self.item)
            if player[0] and (action.endswith('.strm') or self.identifierlist[playerindex] == 'play_kodi'):  # Action is play and is a strm/local so PlayMedia
                utils.kodi_log(u'Player -- Found strm or local.\nAttempting PLAYMEDIA({})'.format(action), 1)
                xbmc.executebuiltin(utils.try_decode_string(u'PlayMedia(\"{0}\")'.format(action)))
            elif player[0]:  # Action is play and not a strm so play with player
                utils.kodi_log(u'Player -- Found file.\nAttempting to PLAY: {}'.format(action), 2)
                xbmcgui.Window(10000).setProperty('TMDbHelper.PlayerInfoString', self.playerstring) if self.playerstring else None
                xbmc.Player().play(action, ListItem(library='video', **self.details).set_listitem())
            else:
                action = u'Container.Update({0})'.format(action) if xbmc.getCondVisibility("Window.IsMedia") else u'ActivateWindow(videos,{0},return)'.format(action)
                utils.kodi_log(u'Player -- Found folder.\nAttempting to OPEN: {}'.format(action), 2)
                xbmc.executebuiltin(utils.try_encode_string(utils.try_decode_string(action)))
            return action
 def set_url_props(self, url, prefix='Item'):
     for k, v in url.items():
         if not k or not v:
             continue
         try:
             self.infoproperties[u'{}.{}'.format(
                 prefix, utils.try_decode_string(k))] = u'{}'.format(
                     utils.try_decode_string(v))
         except Exception as exc:
             utils.kodi_log(
                 u'ERROR in ListItem set_url_props\nk:{} v:{}'.format(
                     utils.try_decode_string(k),
                     utils.try_decode_string(v)), 1)
             utils.kodi_log(exc, 1)
def action(action, tmdb_id=None, tmdb_type=None, season=None, episode=None, label=None, cache_refresh=False):
    _traktapi = TraktAPI()

    if action == 'history':
        func = _traktapi.sync_history
    elif action == 'collection':
        func = _traktapi.sync_collection
    elif action == 'watchlist':
        func = _traktapi.sync_watchlist
    elif action == 'add_to_userlist':
        return sync_userlist()
    elif action == 'remove_from_userlist':
        return sync_userlist(remove_item=True)
    elif action == 'library_userlist':
        return library_userlist()
    elif action == 'library':
        return library()
    elif action == 'play':
        return play()
    elif action == 'open':
        return browse()
    else:
        return

    with utils.busy_dialog():
        if tmdb_type == 'episode' and (not season or not episode):
            return
        elif tmdb_id and tmdb_type:
            dbtype = utils.type_convert(tmdb_type, 'dbtype')
            label = label or 'this {}'.format(utils.type_convert(tmdb_type, 'trakt'))
        else:
            label = sys.listitem.getLabel()
            dbtype = sys.listitem.getVideoInfoTag().getMediaType()
            tmdb_id = sys.listitem.getProperty('tmdb_id') if not dbtype == 'episode' else sys.listitem.getProperty('tvshow.tmdb_id')
            season = sys.listitem.getVideoInfoTag().getSeason() if dbtype == 'episode' else None
            episode = sys.listitem.getVideoInfoTag().getEpisode() if dbtype == 'episode' else None
        tmdb_type = 'movie' if dbtype == 'movie' else 'tv'
        trakt_ids = func(utils.type_convert(tmdb_type, 'trakt'), 'tmdb', cache_refresh=cache_refresh)
        boolean = 'remove' if int(tmdb_id) in trakt_ids else 'add'

    dialog_header = 'Trakt {0}'.format(action.capitalize())
    dialog_text = xbmcaddon.Addon().getLocalizedString(32065) if boolean == 'add' else xbmcaddon.Addon().getLocalizedString(32064)
    dialog_text = dialog_text.format(utils.try_decode_string(label), action.capitalize(), tmdb_type, tmdb_id)
    dialog_text = dialog_text + ' Season: {}  Episode: {}'.format(season, episode) if dbtype == 'episode' else dialog_text
    if not xbmcgui.Dialog().yesno(dialog_header, dialog_text):
        return

    with utils.busy_dialog():
        trakt_type = 'episode' if dbtype == 'episode' else utils.type_convert(tmdb_type, 'trakt')
        slug_type = 'show' if dbtype == 'episode' else trakt_type
        slug = _traktapi.get_traktslug(slug_type, 'tmdb', tmdb_id)
        item = _traktapi.get_details(slug_type, slug, season=season, episode=episode)
        items = {trakt_type + 's': [item]}
        func(slug_type, mode=boolean, items=items)

    dialog_header = 'Trakt {0}'.format(action.capitalize())
    dialog_text = xbmcaddon.Addon().getLocalizedString(32062) if boolean == 'add' else xbmcaddon.Addon().getLocalizedString(32063)
    dialog_text = dialog_text.format(tmdb_id, action.capitalize())
    xbmcgui.Dialog().ok(dialog_header, dialog_text)
    xbmc.executebuiltin('Container.Refresh')
 def get_cur_item(self):
     self.dbtype = self.get_dbtype()
     self.dbid = self.get_infolabel('DBID')
     self.imdb_id = self.get_infolabel('IMDBNumber')
     self.query = self.get_infolabel('TvShowTitle') or self.get_infolabel('Title') or self.get_infolabel('Label')
     self.year = self.get_infolabel('year')
     self.season = self.get_infolabel('Season') if self.dbtype == 'episodes' else ''
     self.episode = self.get_infolabel('Episode') if self.dbtype == 'episodes' else ''
     self.query = utils.try_decode_string(self.query)
     return u'{0}.{1}.{2}.{3}.{4}'.format(self.imdb_id, self.query, self.year, self.season, self.episode)
 def add_query(self):
     with utils.busy_dialog():
         query = utils.try_decode_string(self.params.get('add_query', ''))
         item = utils.dialog_select_item(query)
         if not item:
             return
         tmdb_id = self.tmdb.get_tmdb_id(self.params.get('type'), query=item, selectdialog=True)
         if not tmdb_id:
             utils.kodi_log(u'Unable to find TMDb ID!\nQuery: {0} Type: {1}'.format(self.params.get('add_query'), self.params.get('type')), 1)
             return
         url = 'plugin://plugin.video.skin.info.provider/?info=details&type={0}&tmdb_id={1}'.format(self.params.get('type'), tmdb_id)
         if url == self.home.getProperty(self.prefixcurrent):
             return  # Already added so let's quit as user probably clicked twice
         self.position = self.get_position() + 1
         self.set_props(self.position, url)
         self.lock_path(self.params.get('prevent_del'))
     self.call_auto()
    def get_playingitem(self):
        if not self.isPlayingVideo():
            return  # Not a video so don't get info
        if self.getVideoInfoTag().getMediaType() not in ['movie', 'episode']:
            return  # Not a movie or episode so don't get info TODO Maybe get PVR details also?
        self.playerstring = _homewindow.getProperty('TMDbHelper.PlayerInfoString')
        self.playerstring = loads(self.playerstring) if self.playerstring else None

        self.totaltime = self.getTotalTime()
        self.dbtype = self.getVideoInfoTag().getMediaType()
        self.dbid = self.getVideoInfoTag().getDbId()
        self.imdb_id = self.getVideoInfoTag().getIMDBNumber()
        self.query = self.getVideoInfoTag().getTVShowTitle() if self.dbtype == 'episode' else self.getVideoInfoTag().getTitle()
        self.year = self.getVideoInfoTag().getYear() if self.dbtype == 'movie' else None
        self.season = self.getVideoInfoTag().getSeason() if self.dbtype == 'episodes' else None
        self.episode = self.getVideoInfoTag().getEpisode() if self.dbtype == 'episodes' else None
        self.query = utils.try_decode_string(self.query)

        self.tmdbtype = 'movie' if self.dbtype == 'movie' else 'tv'
        self.tmdb_id = self.get_tmdb_id(self.tmdbtype, self.imdb_id, self.query, self.year)
        self.details = self.tmdb.get_detailed_item(self.tmdbtype, self.tmdb_id, season=self.season, episode=self.episode)

        if not self.details:
            return self.reset_properties()  # No self.details so lets clear everything

        if xbmc.getCondVisibility("!Skin.HasSetting(TMDbHelper.DisableRatings)"):
            self.details = self.get_omdb_ratings(self.details)
            self.details = self.get_top250_rank(self.details) if self.tmdbtype == 'movie' else self.details
            self.details = self.get_trakt_ratings(self.details, self.tmdbtype, self.tmdb_id, self.season, self.episode) if self.tmdbtype in ['movie', 'tv'] else self.details
            self.set_iter_properties(self.details.get('infoproperties', {}), _setprop_ratings)

        if xbmc.getCondVisibility("!Skin.HasSetting(TMDbHelper.DisableArtwork)"):
            self.details = self.get_fanarttv_artwork(self.details, self.tmdbtype) if self.addon.getSettingBool('service_fanarttv_lookup') else self.details
            self.details = self.get_kodi_artwork(self.details, self.dbtype, self.dbid) if self.addon.getSettingBool('local_db') else self.details
            self.set_iter_properties(self.details, _setmain_artwork)

        self.set_properties(self.details)
    def play_external(self, force_dialog=False, playerindex=-1):
        if playerindex > -1:  # Previous iteration didn't find an item to play so remove it and retry
            xbmcgui.Dialog().notification(
                self.itemlist[playerindex].getLabel(),
                self.addon.getLocalizedString(32040))
            del self.actions[
                playerindex]  # Item not found so remove the player's action list
            del self.itemlist[
                playerindex]  # Item not found so remove the player's select dialog entry
            del self.identifierlist[
                playerindex]  # Item not found so remove the player's index

        playerindex = self.get_playerindex(force_dialog=force_dialog)

        # User cancelled dialog
        if not playerindex > -1:
            return False

        player = self.actions[playerindex]
        if not player or not player[1]:
            return False

        # External player has list of actions so let's iterate through them to find our item
        resolve_url = False
        if isinstance(player[1], list):
            actionlist = player[1]
            player = (False, actionlist[0])
            for d in actionlist[1:]:
                if player[0]:
                    break  # Playable item was found in last action so let's break and play it
                folder = KodiLibrary().get_directory(
                    string_format_map(
                        player[1],
                        self.item))  # Get the next folder from the plugin

                if d.get(
                        'dialog'
                ):  # Special option to show dialog of items to select from
                    d_items = []
                    for f in folder:  # Create our list of items
                        if not f.get('label') or f.get('label') == 'None':
                            continue
                        lb_list = []
                        label_a = f.get('label')
                        if f.get('year') and f.get('year') != 1601:
                            label_a = u'{} ({})'.format(label_a, f.get('year'))
                        if utils.try_parse_int(f.get(
                                'season', 0)) > 0 and utils.try_parse_int(
                                    f.get('episode', 0)) > 0:
                            label_a = u'{}x{}. {}'.format(
                                f.get('season'), f.get('episode'), label_a)
                        if f.get('streamdetails'):
                            sdv_list = f.get('streamdetails', {}).get(
                                'video', [{}]) or [{}]
                            sda_list = f.get('streamdetails', {}).get(
                                'audio', [{}]) or [{}]
                            sdv, sda = sdv_list[0], sda_list[0]
                            if sdv.get('width') or sdv.get('height'):
                                lb_list.append(u'{}x{}'.format(
                                    sdv.get('width'), sdv.get('height')))
                            if sdv.get('codec'):
                                lb_list.append(u'{}'.format(
                                    sdv.get('codec', '').upper()))
                            if sda.get('codec'):
                                lb_list.append(u'{}'.format(
                                    sda.get('codec', '').upper()))
                            if sda.get('channels'):
                                lb_list.append(u'{} CH'.format(
                                    sda.get('channels', '')))
                            for i in sda_list:
                                if i.get('language'):
                                    lb_list.append(u'{}'.format(
                                        i.get('language', '').upper()))
                            if sdv.get('duration'):
                                lb_list.append(u'{} mins'.format(
                                    utils.try_parse_int(sdv.get('duration', 0))
                                    // 60))
                        if f.get('size'):
                            lb_list.append(u'{}'.format(
                                utils.normalise_filesize(f.get('size', 0))))
                        label_b = ' | '.join(lb_list) if lb_list else ''
                        d_items.append(
                            ListItem(label=label_a,
                                     label2=label_b,
                                     icon=f.get('thumbnail')).set_listitem())
                    if d_items:
                        idx = 0
                        if d.get('dialog',
                                 '').lower() != 'auto' or len(d_items) != 1:
                            idx = xbmcgui.Dialog().select('Select Item',
                                                          d_items,
                                                          useDetails=True)
                        if idx == -1:  # User exited the dialog so return and do nothing
                            return
                        resolve_url = True if folder[idx].get(
                            'filetype'
                        ) == 'file' else False  # Set true for files so we can play
                        player = (resolve_url, folder[idx].get('file')
                                  )  # Set the folder path to open/play
                        break  # Move onto next action
                    else:  # Ask user to select a different player if no items in dialog
                        return self.play_external(force_dialog=force_dialog,
                                                  playerindex=playerindex)

                x = 0
                for f in folder:  # Iterate through plugin folder looking for a matching item
                    x += 1  # Keep an index for position matching
                    for k, v in d.items(
                    ):  # Iterate through our key (infolabel) / value (infolabel must match) pairs of our action
                        if k == 'position':  # We're looking for an item position not an infolabel
                            if utils.try_parse_int(
                                    string_format_map(v, self.item)
                            ) != x:  # Format our position value
                                break  # Not the item position we want so let's go to next item in folder
                        elif not f.get(k) or string_format_map(
                                v, self.item
                        ) not in u'{}'.format(
                                f.get(k, '')
                        ):  # Format our value and check if it matches the infolabel key
                            break  # Item's key value doesn't match value we are looking for so let's got to next item in folder
                    else:  # Item matched our criteria so let's open it up
                        resolve_url = True if f.get(
                            'filetype'
                        ) == 'file' else False  # Set true for files so we can play
                        player = (resolve_url, f.get('file')
                                  )  # Get ListItem.FolderPath for item
                        break  # Move onto next action (either open next folder or play file)
                else:
                    return self.play_external(
                        force_dialog=force_dialog, playerindex=playerindex
                    )  # Ask user to select a different player

        # Play/Search found item
        if player and player[1]:
            action = string_format_map(player[1], self.item)
            if player[0] and action.endswith(
                    '.strm'):  # Action is play and is a strm so PlayMedia
                xbmc.executebuiltin(
                    utils.try_decode_string(u'PlayMedia({0})'.format(action)))
            elif player[
                    0]:  # Action is play and not a strm so play with player
                xbmc.Player().play(
                    action,
                    ListItem(library='video', **self.details).set_listitem())
            else:
                action = u'Container.Update({0})'.format(
                    action) if xbmc.getCondVisibility(
                        "Window.IsMedia"
                    ) else u'ActivateWindow(videos,{0},return)'.format(action)
                xbmc.executebuiltin(utils.try_decode_string(action))
            return action
def action(action, tmdb_id=None, tmdb_type=None, season=None, episode=None, label=None):
    _traktapi = TraktAPI()

    if action == 'history':
        func = _traktapi.sync_history
    elif action == 'collection':
        func = _traktapi.sync_collection
    elif action == 'watchlist':
        func = _traktapi.sync_watchlist
    elif action == 'add_to_userlist':
        return sync_userlist()
    elif action == 'remove_from_userlist':
        return sync_userlist(remove_item=True)
    elif action == 'library_userlist':
        return library_userlist()
    elif action == 'library':
        return library()
    elif action == 'refresh_item':
        return refresh_item()
    elif action == 'play':
        return play()
    elif action == 'open':
        return browse()
    else:
        return

    with utils.busy_dialog():
        if tmdb_id and tmdb_type:  # Passed details via script
            dbtype = utils.type_convert(tmdb_type, 'dbtype')
            label = label or 'this {}'.format(utils.type_convert(tmdb_type, 'trakt'))
            parent_tmdb_id = tmdb_id
        else:  # Context menu so retrieve details from listitem
            label = sys.listitem.getLabel()
            dbtype = sys.listitem.getVideoInfoTag().getMediaType()
            tmdb_id = sys.listitem.getProperty('tmdb_id')
            parent_tmdb_id = sys.listitem.getProperty('tvshow.tmdb_id') if dbtype == 'episode' else tmdb_id
            season = sys.listitem.getVideoInfoTag().getSeason() if dbtype == 'episode' else None
            episode = sys.listitem.getVideoInfoTag().getEpisode() if dbtype == 'episode' else None

        if tmdb_type == 'episode':  # Passed episode details via script
            if not season or not episode:  # Need season and episode for episodes
                return  # Need season and episode if run from script so leave
            # Retrieve episode details so that we can get tmdb_id for episode
            episode_details = _plugin.tmdb.get_detailed_item(tmdb_type, parent_tmdb_id, season=season, episode=episode)
            tmdb_id = episode_details.get('infoproperties', {}).get('imdb_id')

        if dbtype == 'movie':
            tmdb_type = 'movie'
        elif dbtype == 'tvshow':
            tmdb_type = 'tv'
        elif dbtype == 'episode':
            tmdb_type = 'episode'
        else:
            return

        # Check if we're adding or removing the item and confirm with the user that they want to do that
        trakt_ids = func(utils.type_convert(tmdb_type, 'trakt'), 'tmdb', cache_refresh=True)
        boolean = 'remove' if int(tmdb_id) in trakt_ids else 'add'
        dialog_header = 'Trakt {0}'.format(action.capitalize())
        dialog_text = xbmcaddon.Addon().getLocalizedString(32065) if boolean == 'add' else xbmcaddon.Addon().getLocalizedString(32064)
        dialog_text = dialog_text.format(utils.try_decode_string(label), action.capitalize(), tmdb_type, tmdb_id)
        dialog_text = dialog_text + ' Season: {}  Episode: {}'.format(season, episode) if dbtype == 'episode' else dialog_text
        if not xbmcgui.Dialog().yesno(dialog_header, dialog_text):
            return

        with utils.busy_dialog():
            slug_type = 'show' if tmdb_type == 'episode' else utils.type_convert(tmdb_type, 'trakt')
            trakt_type = utils.type_convert(tmdb_type, 'trakt')
            slug = _traktapi.get_traktslug(slug_type, 'tmdb', parent_tmdb_id)
            item = _traktapi.get_details(slug_type, slug, season=season, episode=episode)
            items = {trakt_type + 's': [item]}
            func(slug_type, mode=boolean, items=items)

        dialog_header = 'Trakt {0}'.format(action.capitalize())
        dialog_text = xbmcaddon.Addon().getLocalizedString(32062) if boolean == 'add' else xbmcaddon.Addon().getLocalizedString(32063)
        dialog_text = dialog_text.format(tmdb_id, action.capitalize())
        xbmcgui.Dialog().ok(dialog_header, dialog_text)
        xbmc.executebuiltin('Container.Refresh')
Beispiel #9
0
    def play_external(self, force_dialog=False):
        itemindex = self.get_itemindex(force_dialog=force_dialog)

        # User cancelled dialog
        if not itemindex > -1:
            return False

        player = self.actions[itemindex]
        if not player or not player[1]:
            return False

        # External player has list of actions so let's iterate through them to find our item
        resolve_url = False
        if isinstance(player[1], list):
            actionlist = player[1]
            player = (False, actionlist[0])
            with utils.busy_dialog():
                for d in actionlist[1:]:
                    if player[0]:
                        break  # Playable item was found in last action so let's break and play it
                    folder = KodiLibrary().get_directory(
                        string_format_map(
                            player[1],
                            self.item))  # Get the next folder from the plugin
                    x = 0
                    for f in folder:  # Iterate through plugin folder looking for a matching item
                        x += 1  # Keep an index for position matching
                        for k, v in d.items(
                        ):  # Iterate through our key (infolabel) / value (infolabel must match) pairs of our action
                            if k == 'position':  # We're looking for an item position not an infolabel
                                if utils.try_parse_int(
                                        string_format_map(v, self.item)
                                ) != x:  # Format our position value
                                    break  # Not the item position we want so let's go to next item in folder
                            elif not f.get(k) or string_format_map(
                                    v, self.item
                            ) not in u'{}'.format(
                                    f.get(k, '')
                            ):  # Format our value and check if it matches the infolabel key
                                break  # Item's key value doesn't match value we are looking for so let's got to next item in folder
                        else:  # Item matched our criteria so let's open it up
                            resolve_url = True if f.get(
                                'filetype'
                            ) == 'file' else False  # Set true for files so we can play
                            player = (resolve_url, f.get('file')
                                      )  # Get ListItem.FolderPath for item
                            break  # Move onto next action (either open next folder or play file)
                    else:
                        xbmcgui.Dialog().notification(
                            self.itemlist[itemindex].getLabel(),
                            self.addon.getLocalizedString(32040))
                        del self.actions[
                            itemindex]  # Item not found so remove the player's action list
                        del self.itemlist[
                            itemindex]  # Item not found so remove the player's select dialog entry
                        return self.play_external(
                            force_dialog=True
                        )  # Ask user to select a different player

        # Play/Search found item
        if player and player[1]:
            action = string_format_map(player[1], self.item)
            if player[0]:  # Action is play so let's play the item and return
                xbmc.Player().play(
                    action,
                    ListItem(library='video', **self.details).set_listitem())
                return action
            # Action is search so let's load the plugin path
            action = u'Container.Update({0})'.format(
                action) if xbmc.getCondVisibility(
                    "Window.IsMedia"
                ) else u'ActivateWindow(videos,{0},return)'.format(action)
            xbmc.executebuiltin(utils.try_decode_string(action))
            return action