コード例 #1
0
    def list_discoverdir_router(self, **kwargs):
        if kwargs.get('clear_cache') != 'True' and kwargs.get(
                'method') not in ['delete', 'rename']:
            return self.list_discoverdir(**kwargs)

        params = kwargs.copy()
        params.pop('clear_cache', None)
        params.pop('method', None)
        params.pop('idx', None)
        self.container_update = '{},replace'.format(
            encode_url(PLUGINPATH, **params))

        if kwargs.get('clear_cache') == 'True':
            set_search_history('discover', clear_cache=True)

        elif kwargs.get('method') == 'delete':
            idx = try_int(kwargs.get('idx', -1))
            if idx == -1:
                return
            set_search_history('discover', replace=idx)

        elif kwargs.get('method') == 'rename':
            idx = try_int(kwargs.get('idx', -1))
            if idx == -1:
                return
            history = get_search_history('discover')
            try:
                item = history[idx]
            except IndexError:
                return
            if not item:
                return
            item['label'] = xbmcgui.Dialog().input(
                'Rename', defaultt=item.get('label')) or item.get('label')
            set_search_history('discover', item, replace=idx)
コード例 #2
0
def get_collection_properties(v):
    ratings = []
    infoproperties = {}
    year_l, year_h, votes = 9999, 0, 0
    for p, i in enumerate(v):
        infoproperties[u'set.{}.title'.format(p)] = i.get('title', '')
        infoproperties[u'set.{}.tmdb_id'.format(p)] = i.get('id', '')
        infoproperties[u'set.{}.originaltitle'.format(p)] = i.get('original_title', '')
        infoproperties[u'set.{}.plot'.format(p)] = i.get('overview', '')
        infoproperties[u'set.{}.premiered'.format(p)] = i.get('release_date', '')
        infoproperties[u'set.{}.year'.format(p)] = i.get('release_date', '')[:4]
        infoproperties[u'set.{}.rating'.format(p)] = u'{:0,.1f}'.format(try_float(i.get('vote_average')))
        infoproperties[u'set.{}.votes'.format(p)] = i.get('vote_count', '')
        infoproperties[u'set.{}.poster'.format(p)] = get_imagepath_poster(i.get('poster_path', ''))
        infoproperties[u'set.{}.fanart'.format(p)] = get_imagepath_fanart(i.get('backdrop_path', ''))
        year_l = min(try_int(i.get('release_date', '')[:4]), year_l)
        year_h = max(try_int(i.get('release_date', '')[:4]), year_h)
        if i.get('vote_average'):
            ratings.append(i['vote_average'])
        votes += try_int(i.get('vote_count', 0))
    if year_l == 9999:
        year_l = None
    if year_l:
        infoproperties['set.year.first'] = year_l
    if year_h:
        infoproperties['set.year.last'] = year_h
    if year_l and year_h:
        infoproperties['set.years'] = u'{0} - {1}'.format(year_l, year_h)
    if len(ratings):
        infoproperties['set.rating'] = infoproperties['tmdb_rating'] = u'{:0,.1f}'.format(sum(ratings) / len(ratings))
    if votes:
        infoproperties['set.votes'] = infoproperties['tmdb_votes'] = u'{:0,.0f}'.format(votes)
    infoproperties['set.numitems'] = p
    return infoproperties
コード例 #3
0
    def _add_season(self, season, blacklist=[0]):
        number = season.get('season_number', 0)
        folder = u'Season {}'.format(number)

        # Skip blacklisted seasons
        if try_int(number) in blacklist:  # TODO: Optional whitelist also
            self._log._add('tv',
                           self.tv.tmdb_id,
                           'skipped special season',
                           season=number)
            return

        # Skip if we've added season before and it isn't the most recent season
        # We still add most recent season even if we added it before because it might currently be airing
        if self._log._add('tv',
                          self.tv.tmdb_id,
                          self.tv._cache.is_added_season(number),
                          season=number):
            return

        # Add our episodes
        for x, episode in enumerate(self.tv.get_episodes(number), 1):
            self._add_episode(episode, number, folder)
            self._update(x, self.tv.e_total)

        # Store a season value of where we got up to
        if self.tv.e_total > 2 and season.get(
                'air_date') and not is_future_timestamp(
                    season.get('air_date'), "%Y-%m-%d", 10):
            self.tv._cache.my_history['latest_season'] = try_int(number)
コード例 #4
0
 def get_info(
         self, info, dbid=None, imdb_id=None, originaltitle=None, title=None, year=None, season=None,
         episode=None, fuzzy_match=False, tmdb_id=None, tvdb_id=None):
     if not self.database or not info:
         return
     yearcheck = False
     index_list = find_dict_in_list(self.database, 'dbid', dbid) if dbid else []
     if not index_list and season:
         index_list = find_dict_in_list(self.database, 'season', try_int(season))
     if not index_list and imdb_id:
         index_list = find_dict_in_list(self.database, 'imdb_id', imdb_id)
     if not index_list and tmdb_id:
         index_list = find_dict_in_list(self.database, 'tmdb_id', str(tmdb_id))
     if not index_list and tvdb_id:
         index_list = find_dict_in_list(self.database, 'tvdb_id', str(tvdb_id))
     if not index_list:
         yearcheck = str(year) or 'dummynull'  # Also use year if matching by title to be certain we have correct item. Dummy value for True value that will always fail comparison check.
     if not index_list and originaltitle:
         index_list = find_dict_in_list(self.database, 'originaltitle', originaltitle)
     if not index_list and title:
         index_list = find_dict_in_list(self.database, 'title', title)
     for i in index_list:
         if season and episode:
             if try_int(episode) == self.database[i].get('episode'):
                 return self.database[i].get(info)
         elif not yearcheck or yearcheck in str(self.database[i].get('year')):
             return self.database[i].get(info)
     if index_list and fuzzy_match and not season and not episode:
         """ Fuzzy Match """
         i = index_list[0]
         return self.database[i].get(info)
コード例 #5
0
def _get_language_item(tmdb_type,
                       tmdb_id,
                       season=None,
                       episode=None,
                       language=None,
                       year=None):
    item = _get_language_details(tmdb_type, tmdb_id, language=language)
    if not item:
        return

    item['showname'] = item['clearname'] = item['tvshowtitle'] = item.get(
        'title')
    item['name'] = u'{} ({})'.format(
        item['title'], year) if item.get('title') and year else None
    if season is None or episode is None:
        return item

    episode = _get_language_details(tmdb_type,
                                    tmdb_id,
                                    season,
                                    episode,
                                    language=language)
    if not episode:
        return item

    item['title'] = episode.get('title')
    item['plot'] = episode.get('plot') or item.get('plot')
    item['name'] = u'{0} S{1:02d}E{2:02d}'.format(
        item['showname'], try_int(season),
        try_int(episode)) if item.get('showname') else None
    return item
コード例 #6
0
 def _get_tmdb_id(self, tmdb_type, imdb_id, tvdb_id, query, year, episode_year, raw_data, **kwargs):
     func = self.get_request_sc
     if not tmdb_type:
         return
     request = None
     if tmdb_type == 'genre' and query:
         return TMDB_GENRE_IDS.get(query, '')
     elif imdb_id:
         request = func('find', imdb_id, language=self.req_language, external_source='imdb_id')
         request = request.get('{0}_results'.format(tmdb_type), [])
     elif tvdb_id:
         request = func('find', tvdb_id, language=self.req_language, external_source='tvdb_id')
         request = request.get('{0}_results'.format(tmdb_type), [])
     elif query:
         query = query.split(' (', 1)[0]  # Scrub added (Year) or other cruft in parentheses () added by Addons or TVDb
         if tmdb_type == 'tv':
             request = func('search', tmdb_type, language=self.req_language, query=query, first_air_date_year=year)
         else:
             request = func('search', tmdb_type, language=self.req_language, query=query, year=year)
         request = request.get('results', [])
     if not request:
         return
     if raw_data:
         return request
     if tmdb_type == 'tv' and episode_year and len(request) > 1:
         for i in sorted(request, key=lambda k: k.get('first_air_date', ''), reverse=True):
             if not i.get('first_air_date'):
                 continue
             if try_int(i.get('first_air_date', '9999')[:4]) <= try_int(episode_year):
                 if query in [i.get('name'), i.get('original_name')]:
                     return i.get('id')
     return request[0].get('id')
コード例 #7
0
 def __init__(self, trakt_type, unique_id, season=None, episode=None, id_type=None):
     self.trakt_type = trakt_type
     self.unique_id = unique_id
     self.season = try_int(season) if season is not None else None
     self.episode = try_int(episode) if episode is not None else None
     self.id_type = id_type
     self.trakt_api = TraktAPI()
コード例 #8
0
def _translate_discover_params(tmdb_type, params):
    lookup_keyword = None if params.get('with_id') and params.get('with_id') != 'False' else 'keyword'
    lookup_company = None if params.get('with_id') and params.get('with_id') != 'False' else 'company'
    lookup_person = None if params.get('with_id') and params.get('with_id') != 'False' else 'person'
    lookup_genre = None if params.get('with_id') and params.get('with_id') != 'False' else 'genre'
    with_separator = params.get('with_separator')

    if params.get('with_genres'):
        params['with_genres'] = TMDb().get_translated_list(
            split_items(params.get('with_genres')), lookup_genre, separator=with_separator)

    if params.get('without_genres'):
        params['without_genres'] = TMDb().get_translated_list(
            split_items(params.get('without_genres')), lookup_genre, separator=with_separator)

    if params.get('with_keywords'):
        params['with_keywords'] = TMDb().get_translated_list(
            split_items(params.get('with_keywords')), lookup_keyword, separator=with_separator)

    if params.get('without_keywords'):
        params['without_keywords'] = TMDb().get_translated_list(
            split_items(params.get('without_keywords')), lookup_keyword, separator=with_separator)

    if params.get('with_companies'):
        params['with_companies'] = TMDb().get_translated_list(
            split_items(params.get('with_companies')), lookup_company, separator='NONE')

    if params.get('with_people'):
        params['with_people'] = TMDb().get_translated_list(
            split_items(params.get('with_people')), lookup_person, separator=with_separator)

    if params.get('with_cast'):
        params['with_cast'] = TMDb().get_translated_list(
            split_items(params.get('with_cast')), lookup_person, separator=with_separator)

    if params.get('with_crew'):
        params['with_crew'] = TMDb().get_translated_list(
            split_items(params.get('with_crew')), lookup_person, separator=with_separator)

    if params.get('with_release_type'):
        params['with_release_type'] = TMDb().get_translated_list(
            split_items(params.get('with_release_type')), None, separator='OR')

    # Translate relative dates based upon today's date
    for i in RELATIVE_DATES:
        datecode = params.get(i, '')
        datecode = datecode.lower()
        if not datecode or all(x not in datecode for x in ['t-', 't+']):
            continue  # No value or not a relative date so skip
        elif 't-' in datecode:
            days = try_int(datecode.replace('t-', ''))
            date = get_datetime_now() - get_timedelta(days=days)
        elif 't+' in datecode:
            days = try_int(datecode.replace('t+', ''))
            date = get_datetime_now() + get_timedelta(days=days)
        params[i] = date.strftime("%Y-%m-%d")

    return params
コード例 #9
0
 def get_basic_list(self, path, tmdb_type, key='results', params=None, base_tmdb_type=None, **kwargs):
     response = self.get_request_sc(path, **kwargs)
     results = response.get(key, []) if response else []
     items = [
         self.mapper.get_info(i, tmdb_type, definition=params, base_tmdb_type=base_tmdb_type)
         for i in results if i]
     if try_int(response.get('page', 0)) < try_int(response.get('total_pages', 0)):
         items.append({'next_page': try_int(response.get('page', 0)) + 1})
     return items
コード例 #10
0
 def get_calendar_episodes(self, startdate=0, days=1, user=True):
     # Broaden date range in case utc conversion bumps into different day
     mod_date = try_int(startdate) - 1
     mod_days = try_int(days) + 2
     date = get_datetime_today() + get_timedelta(days=mod_date)
     return self.get_calendar('shows',
                              user,
                              start_date=date.strftime('%Y-%m-%d'),
                              days=mod_days)
コード例 #11
0
 def get_episode_playcount(self, unique_id, id_type, season, episode):
     season = try_int(season, fallback=-2)  # Make fallback -2 to prevent matching on 0
     episode = try_int(episode, fallback=-2)  # Make fallback -2 to prevent matching on 0
     for i in self.get_sync('watched', 'show', id_type).get(unique_id, {}).get('seasons', []):
         if i.get('number', -1) != season:
             continue
         for j in i.get('episodes', []):
             if j.get('number', -1) == episode:
                 return j.get('plays', 1)
コード例 #12
0
    def _player_dialog_select(self, folder, auto=False):
        d_items = []
        for f in folder:

            # Skip items without labels as probably not worth playing
            if not f.get('label') or f.get('label') == 'None':
                continue

            # Get the label of the item
            label_a = f.get('label')

            # Add year to our label if exists and not special value of 1601
            if f.get('year') and f.get('year') != 1601:
                label_a = u'{} ({})'.format(label_a, f.get('year'))

            # Add season and episode numbers to label
            if try_int(f.get('season', 0)) > 0 and try_int(f.get('episode', 0)) > 0:
                label_a = u'{}x{}. {}'.format(f.get('season'), f.get('episode'), label_a)

            # Add various stream details to ListItem.Label2 (aka label_b)
            label_b_list = []
            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'):
                    label_b_list.append(u'{}x{}'.format(sdv.get('width'), sdv.get('height')))
                if sdv.get('codec'):
                    label_b_list.append(u'{}'.format(sdv.get('codec', '').upper()))
                if sda.get('codec'):
                    label_b_list.append(u'{}'.format(sda.get('codec', '').upper()))
                if sda.get('channels'):
                    label_b_list.append(u'{} CH'.format(sda.get('channels', '')))
                for i in sda_list:
                    if i.get('language'):
                        label_b_list.append(u'{}'.format(i.get('language', '').upper()))
                if sdv.get('duration'):
                    label_b_list.append(u'{} mins'.format(try_int(sdv.get('duration', 0)) // 60))
            if f.get('size'):
                label_b_list.append(u'{}'.format(normalise_filesize(f.get('size', 0))))
            label_b = ' | '.join(label_b_list) if label_b_list else ''

            # Add item to select dialog list
            d_items.append(ListItem(label=label_a, label2=label_b, art={'thumb': f.get('thumbnail')}).get_listitem())

        if not d_items:
            return -1  # No items so ask user to select new player

        # If autoselect enabled and only 1 item choose that otherwise ask user to choose
        idx = 0 if auto and len(d_items) == 1 else xbmcgui.Dialog().select(ADDON.getLocalizedString(32236), d_items, useDetails=True)

        if idx == -1:
            return  # User exited the dialog so return nothing

        is_folder = False if folder[idx].get('filetype') == 'file' else True
        return (folder[idx].get('file'), is_folder)  # Return the player
コード例 #13
0
def get_person_stats(person):
    infoproperties = {}
    infoproperties['numitems.dbid.movies'] = get_num_credits('movie', person)
    infoproperties['numitems.dbid.tvshows'] = get_num_credits('tvshow', person)
    infoproperties['numitems.dbid.episodes'] = get_num_credits('episode', person)
    infoproperties['numitems.dbid.total'] = (
        try_int(infoproperties.get('numitems.dbid.movies'))
        + try_int(infoproperties.get('numitems.dbid.tvshows'))
        + try_int(infoproperties.get('numitems.dbid.episodes')))
    return infoproperties
コード例 #14
0
 def set_episode_label(self,
                       format_label=u'{season}x{episode:0>2}. {label}'):
     season = try_int(self.infolabels.get('season', 0))
     episode = try_int(self.infolabels.get('episode', 0))
     if not season or not episode:
         return
     self.label = format_label.format(season=season,
                                      episode=episode,
                                      label=self.infolabels.get(
                                          'title', ''))
コード例 #15
0
def get_detailed_item(tmdb_type,
                      tmdb_id,
                      season=None,
                      episode=None,
                      details=None):
    details = details or get_item_details(tmdb_type, tmdb_id, season, episode)
    if not details:
        return None
    item = defaultdict(lambda: '+')
    item['id'] = item['tmdb'] = tmdb_id
    item['imdb'] = details.unique_ids.get('imdb')
    item['tvdb'] = details.unique_ids.get('tvdb')
    item['trakt'] = details.unique_ids.get('trakt')
    item['slug'] = details.unique_ids.get('slug')
    item['season'] = season
    item['episode'] = episode
    item['originaltitle'] = details.infolabels.get('originaltitle')
    item['title'] = details.infolabels.get(
        'tvshowtitle') or details.infolabels.get('title')
    item['showname'] = item['clearname'] = item['tvshowtitle'] = item.get(
        'title')
    item['year'] = details.infolabels.get('year')
    item['name'] = u'{} ({})'.format(item.get('title'), item.get('year'))
    item['premiered'] = item['firstaired'] = item[
        'released'] = details.infolabels.get('premiered')
    item['plot'] = details.infolabels.get('plot')
    item['cast'] = item['actors'] = " / ".join(
        [i.get('name') for i in details.cast if i.get('name')])
    item['thumbnail'] = details.art.get('thumb')
    item['poster'] = details.art.get('poster')
    item['fanart'] = details.art.get('fanart')
    item['now'] = get_datetime_now().strftime('%Y%m%d%H%M%S%f')

    if tmdb_type == 'tv' and season is not None and episode is not None:
        item['id'] = item['epid'] = item['eptvdb'] = item.get('tvdb')
        item['title'] = details.infolabels.get('title')  # Set Episode Title
        item['name'] = u'{0} S{1:02d}E{2:02d}'.format(item.get('showname'),
                                                      try_int(season),
                                                      try_int(episode))
        item['season'] = season
        item['episode'] = episode
        item['showpremiered'] = details.infoproperties.get('tvshow.premiered')
        item['showyear'] = details.infoproperties.get('tvshow.year')
        item['eptmdb'] = details.unique_ids.get('tmdb')
        item['epimdb'] = details.unique_ids.get('imdb')
        item['eptrakt'] = details.unique_ids.get('trakt')
        item['epslug'] = details.unique_ids.get('slug')
        item['tmdb'] = details.unique_ids.get('tvshow.tmdb')
        item['imdb'] = details.unique_ids.get('tvshow.imdb')
        item['tvdb'] = details.unique_ids.get('tvshow.tvdb')
        item['trakt'] = details.unique_ids.get('tvshow.trakt')
        item['slug'] = details.unique_ids.get('tvshow.slug')

    return _url_encode_item(item)
コード例 #16
0
def sync_trakt_item(trakt_type,
                    unique_id,
                    season=None,
                    episode=None,
                    id_type=None):
    menu = _Menu(items=_menu_items(),
                 trakt_type=trakt_type,
                 unique_id=unique_id,
                 id_type=id_type,
                 season=try_int(season, fallback=None),
                 episode=try_int(episode, fallback=None))
    menu.select()
コード例 #17
0
 def _get_best_artwork(self, ftv_id, ftv_type, artwork_type):
     artwork = self.get_artwork_type(ftv_id, ftv_type, artwork_type)
     best_like = -1
     best_item = None
     for i in artwork:
         if i.get('lang', '') == self.language:
             return i.get('url', '')
         if (i.get('lang', '') == 'en' or not i.get('lang')) and try_int(
                 i.get('likes', 0)) > try_int(best_like):
             best_item = i.get('url', '')
             best_like = i.get('likes', 0)
     return best_item
コード例 #18
0
 def set_playcount(self, playcount):
     playcount = try_int(playcount)
     if not try_int(self.infolabels.get('episode')):
         return
     ip, il = self.infoproperties, self.infolabels
     ip['watchedepisodes'] = playcount
     ip['totalepisodes'] = try_int(il.get('episode'))
     ip['unwatchedepisodes'] = ip.get('totalepisodes') - try_int(ip.get('watchedepisodes'))
     if not playcount or ip.get('unwatchedepisodes'):
         return
     il['playcount'] = playcount
     il['overlay'] = 5
コード例 #19
0
    def _add_episode(self, episode, season, folder):
        number = episode.get('episode_number')
        filename = validify_filename(u'S{:02d}E{:02d} - {}'.format(
            try_int(season), try_int(number), episode.get('name')))
        self.tv._cache.my_history['episodes'].append(filename)

        # Skip episodes we added in the past
        if self._log._add('tv',
                          self.tv.tmdb_id,
                          self.tv._cache.is_added_episode(filename),
                          season=season,
                          episode=number):
            return

        # Skip future episodes
        if self.hide_unaired and is_future_timestamp(episode.get('air_date'),
                                                     "%Y-%m-%d", 10):
            self.tv._cache.my_history['skipped'].append(filename)
            self._log._add('tv',
                           self.tv.tmdb_id,
                           'unaired episode',
                           season=season,
                           episode=number,
                           air_date=episode.get('air_date'))
            return

        # Check if item has already been added
        file = self.tv.get_episode_db_info(season, number, info='file')
        if file:
            self._log._add('tv',
                           self.tv.tmdb_id,
                           'found in library',
                           season=season,
                           episode=number,
                           path=file)
            return

        # Add our strm file
        file = create_file(STRM_EPISODE.format(self.tv.tmdb_id, season,
                                               number),
                           filename,
                           self.tv.name,
                           folder,
                           basedir=BASEDIR_TV)
        self._log._add('tv',
                       self.tv.tmdb_id,
                       'added strm file',
                       season=season,
                       episode=number,
                       path=file)
コード例 #20
0
 def list_trakt_calendar(self, info, startdate, days, page=None, library=False, **kwargs):
     kodi_db = get_kodi_library('tv') if library else None
     items = self.trakt_api.get_calendar_episodes_list(
         try_int(startdate),
         try_int(days),
         kodi_db=kodi_db,
         user=False if library else True,
         page=page)
     self.kodi_db = kodi_db or self.get_kodi_database('tv')
     self.tmdb_cache_only = False
     self.library = 'video'
     self.container_content = 'episodes'
     self.plugin_category = get_calendar_name(startdate=try_int(startdate), days=try_int(days))
     return items
コード例 #21
0
    def refresh_token(self):
        # Check we haven't attempted too many refresh attempts
        refresh_attempts = try_int(get_property('TraktRefreshAttempts')) + 1
        if refresh_attempts > 5:
            kodi_log(
                'Trakt Unauthorised!\nExceeded refresh_token attempt limit\nSuppressing retries for 10 minutes',
                1)
            get_property('TraktRefreshTimeStamp', set_timestamp(600))
            get_property('TraktRefreshAttempts', 0)  # Reset refresh attempts
            return
        get_property('TraktRefreshAttempts', refresh_attempts)

        kodi_log('Attempting to refresh Trakt token', 2)
        if not self.authorization or not self.authorization.get(
                'refresh_token'):
            kodi_log('Trakt refresh token not found!', 1)
            return
        postdata = {
            'refresh_token': self.authorization.get('refresh_token'),
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
            'grant_type': 'refresh_token'
        }
        self.authorization = self.get_api_request_json(
            'https://api.trakt.tv/oauth/token', postdata=postdata)
        if not self.authorization or not self.authorization.get(
                'access_token'):
            kodi_log('Failed to refresh Trakt token!', 2)
            return
        self.on_authenticated(auth_dialog=False)
        kodi_log('Trakt token refreshed', 1)
        return self.authorization
コード例 #22
0
def _is_updating(container_id):
    is_updating = xbmc.getCondVisibility(
        "Container({}).IsUpdating".format(container_id))
    is_numitems = try_int(
        xbmc.getInfoLabel("Container({}).NumItems".format(container_id)))
    if is_updating or not is_numitems:
        return True
コード例 #23
0
 def get_custom_list(self,
                     list_slug,
                     user_slug=None,
                     page=1,
                     limit=20,
                     params=None,
                     authorize=False,
                     sort_by=None,
                     sort_how=None,
                     extended=None):
     if authorize and not self.authorize():
         return
     path = 'users/{}/lists/{}/items'.format(user_slug or 'me', list_slug)
     # Refresh cache on first page for user list because it might've changed
     cache_refresh = True if try_int(page, fallback=1) == 1 else False
     sorted_items = self.get_sorted_list(
         path,
         sort_by,
         sort_how,
         extended,
         permitted_types=['movie', 'show', 'person'],
         cache_refresh=cache_refresh) or {}
     paginated_items = PaginatedItems(items=sorted_items.get('items', []),
                                      page=page,
                                      limit=limit)
     return {
         'items': paginated_items.items,
         'movies': sorted_items.get('movies', []),
         'shows': sorted_items.get('shows', []),
         'persons': sorted_items.get('persons', []),
         'next_page': paginated_items.next_page
     }
コード例 #24
0
 def get_episodes_watchcount(
         self, unique_id, id_type, season=None, exclude_specials=True,
         tvshow=None, count_progress=False):
     """
     Get the number of episodes watched in a show or season
     Pass tvshow dict directly for speed otherwise will look-up ID from watched sync list
     Use count_progress to check progress against reset_at value rather than just count watched
     """
     season = try_int(season) if season is not None else None
     if not tvshow and id_type and unique_id:
         tvshow = self.get_sync('watched', 'show', id_type).get(unique_id)
     if not tvshow:
         return
     reset_at = None
     if count_progress and tvshow.get('reset_at'):
         reset_at = convert_timestamp(tvshow['reset_at'])
     count = 0
     for i in tvshow.get('seasons', []):
         if season is not None and i.get('number', -1) != season:
             continue
         if exclude_specials and i.get('number') == 0:
             continue
         # Reset_at is None so just count length of watched episode list
         if not reset_at:
             count += len(i.get('episodes', []))
             continue
         # Reset_at has a value so check progress rather than just watched count
         for j in i.get('episodes', []):
             if convert_timestamp(j.get('last_watched_at')) >= reset_at:
                 continue
             count += 1
     return count
コード例 #25
0
 def _get_calendar_episode_item(self, i):
     air_date = convert_timestamp(i.get('first_aired'), utc_convert=True)
     item = get_empty_item()
     item['label'] = i.get('episode', {}).get('title')
     item['infolabels'] = {
         'mediatype': 'episode',
         'premiered': air_date.strftime('%Y-%m-%d'),
         'year': air_date.strftime('%Y'),
         'title': item['label'],
         'episode': i.get('episode', {}).get('number'),
         'season': i.get('episode', {}).get('season'),
         'tvshowtitle': i.get('show', {}).get('title'),
         'duration': try_int(i.get('episode', {}).get('runtime', 0)) * 60,
         'plot': i.get('episode', {}).get('overview'),
         'mpaa': i.get('show', {}).get('certification')}
     item['infoproperties'] = {
         'air_date': get_region_date(air_date, 'datelong'),
         'air_time': get_region_date(air_date, 'time'),
         'air_day': air_date.strftime('%A'),
         'air_day_short': air_date.strftime('%a'),
         'air_date_short': air_date.strftime('%d %b')}
     item['unique_ids'] = {u'tvshow.{}'.format(k): v for k, v in viewitems(i.get('show', {}).get('ids', {}))}
     item['params'] = {
         'info': 'details',
         'tmdb_type': 'tv',
         'tmdb_id': i.get('show', {}).get('ids', {}).get('tmdb'),
         'episode': i.get('episode', {}).get('number'),
         'season': i.get('episode', {}).get('season')}
     return item
コード例 #26
0
def get_property(name,
                 set_property=None,
                 clear_property=False,
                 window_id=None,
                 prefix=None,
                 is_type=None):
    if prefix != -1:
        prefix = prefix or 'TMDbHelper'
        name = '{}.{}'.format(prefix, name)
    if window_id == 'current':
        window = xbmcgui.Window(xbmcgui.getCurrentWindowId())
    elif window_id:
        window = xbmcgui.Window(window_id)
    else:
        window = xbmcgui.Window(10000)
    if clear_property:
        window.clearProperty(name)
        return
    elif set_property is not None:
        window.setProperty(name, u'{}'.format(set_property))
        return set_property
    if is_type == int:
        return try_int(window.getProperty(name))
    if is_type == float:
        return try_float(window.getProperty(name))
    return window.getProperty(name)
コード例 #27
0
    def list_userdiscover(self, tmdb_type, **kwargs):
        method = kwargs.get('method')

        # Method routing
        if not method or method == 'clear':
            _clear_properties()
        elif method == 'save':
            _save_rules(tmdb_type)
        elif method == 'edit':
            _edit_rules(idx=try_int(kwargs.get('idx'), fallback=-1))
        else:
            _add_rule(tmdb_type, method)

        # Build directory items
        basedir_items = []
        basedir_items += _get_basedir_top(tmdb_type)
        basedir_items += _get_basedir_add(tmdb_type)
        basedir_items += _get_basedir_end(tmdb_type)

        self.update_listing = True if method and method != 'edit' else False
        self.container_content = 'files'

        items = [_get_formatted_item(i) for i in basedir_items]
        items[0]['params'] = _get_discover_params(tmdb_type)
        return items
コード例 #28
0
    def play(self, folder_path=None, reset_focus=None, handle=None):
        # Get some info about current container for container update hack
        if not folder_path:
            folder_path = xbmc.getInfoLabel("Container.FolderPath")
        if not reset_focus and folder_path:
            containerid = xbmc.getInfoLabel("System.CurrentControlID")
            current_pos = xbmc.getInfoLabel("Container({}).CurrentItem".format(containerid))
            reset_focus = 'SetFocus({},{},absolute)'.format(containerid, try_int(current_pos) - 1)

        # Get the resolved path
        listitem = self.get_resolved_path()

        # Reset folder hack
        self._update_listing_hack(folder_path=folder_path, reset_focus=reset_focus)

        # Check we have an actual path to open
        if not listitem.getPath() or listitem.getPath() == PLUGINPATH:
            return

        action = self.configure_action(listitem, handle)

        # Kodi launches busy dialog on home screen that needs to be told to close
        # Otherwise the busy dialog will prevent window activation for folder path
        xbmc.executebuiltin('Dialog.Close(busydialog)')

        # If a folder we need to resolve to dummy and then open folder
        if listitem.getProperty('is_folder') == 'true':
            if self.is_strm or not ADDON.getSettingBool('only_resolve_strm'):
                resolve_to_dummy(handle, self.dummy_duration, self.dummy_delay)
            xbmc.executebuiltin(action)
            kodi_log(['lib.player - finished executing action\n', action], 1)
            return

        # Set our playerstring for player monitor to update kodi watched status
        if self.playerstring:
            get_property('PlayerInfoString', set_property=self.playerstring)

        # If PlayMedia method chosen re-route to Player() unless expert settings on
        if action:
            if self.is_strm or not ADDON.getSettingBool('only_resolve_strm'):
                resolve_to_dummy(handle, self.dummy_duration, self.dummy_delay)  # If we're calling external we need to resolve to dummy
            xbmc.Player().play(action, listitem) if self.force_xbmcplayer else xbmc.executebuiltin(u'PlayMedia({})'.format(action))
            kodi_log([
                'lib.player - playing path with {}\n'.format('xbmc.Player()' if self.force_xbmcplayer else 'PlayMedia'),
                listitem.getPath()], 1)
            return

        # Otherwise we have a url we can resolve to
        xbmcplugin.setResolvedUrl(handle, True, listitem)
        kodi_log(['lib.player - finished resolving path to url\n', listitem.getPath()], 1)

        # Re-send local files to player due to "bug" (or maybe "feature") of setResolvedUrl
        # Because setResolvedURL doesn't set id/type (sets None, "unknown" instead) to player for plugins
        # If id/type not set to Player.GetItem things like Trakt don't work correctly.
        # Looking for better solution than this hack.
        if ADDON.getSettingBool('trakt_localhack') and listitem.getProperty('is_local') == 'true':
            xbmc.Player().play(listitem.getPath(), listitem) if self.force_xbmcplayer else xbmc.executebuiltin(u'PlayMedia({})'.format(listitem.getPath()))
            kodi_log([
                'Finished executing {}\n'.format('xbmc.Player()' if self.force_xbmcplayer else 'PlayMedia'),
                listitem.getPath()], 1)
コード例 #29
0
    def run(self):
        self.xbmc_monitor.waitForAbort(
            600)  # Wait 10 minutes before doing updates to give boot time
        if self.xbmc_monitor.abortRequested():
            del self.xbmc_monitor
            return

        self.next_time = datetime.datetime.combine(
            datetime.datetime.today(),
            datetime.time(try_int(self.update_hour)))  # Get today at hour
        self.last_time = xbmc.getInfoLabel(
            'Skin.String(TMDbHelper.AutoUpdate.LastTime)')  # Get last update
        self.last_time = convert_timestamp(
            self.last_time) if self.last_time else None
        if self.last_time and self.last_time > self.next_time:
            self.next_time += datetime.timedelta(
                hours=24)  # Already updated today so set for tomorrow

        while not self.xbmc_monitor.abortRequested(
        ) and not self.exit and self.poll_time:
            if ADDON.getSettingBool('library_autoupdate'):
                if datetime.datetime.now(
                ) > self.next_time:  # Scheduled time has past so lets update
                    xbmc.executebuiltin(
                        'RunScript(plugin.video.themoviedb.helper,library_autoupdate)'
                    )
                    xbmc.executebuiltin(
                        'Skin.SetString(TMDbHelper.AutoUpdate.LastTime,{})'.
                        format(datetime.datetime.now().strftime(
                            "%Y-%m-%dT%H:%M:%S")))
                    self.next_time += datetime.timedelta(
                        hours=24)  # Set next update for tomorrow
            self.xbmc_monitor.waitForAbort(self.poll_time)

        del self.xbmc_monitor
コード例 #30
0
 def add_items(self, items=None, pagination=True, parent_params=None, property_params=None, kodi_db=None, tmdb_cache_only=True):
     if not items:
         return
     check_is_aired = parent_params.get('info') not in NO_LABEL_FORMATTING
     for i in items:
         if not pagination and 'next_page' in i:
             continue
         if self.item_is_excluded(i):
             continue
         li = ListItem(parent_params=parent_params, **i)
         li.set_details(details=self.get_tmdb_details(li, cache_only=tmdb_cache_only))  # Quick because only get cached
         li.set_episode_label()
         if check_is_aired and li.is_unaired():
             continue
         li.set_details(details=self.get_ftv_artwork(li), reverse=True)  # Slow when not cache only
         li.set_details(details=self.get_kodi_details(li), reverse=True)  # Quick because local db
         li.set_playcount(playcount=self.get_playcount_from_trakt(li))  # Quick because of agressive caching of Trakt object and pre-emptive dict comprehension
         if self.hide_watched and try_int(li.infolabels.get('playcount')) != 0:
             continue
         li.set_context_menu()  # Set the context menu items
         li.set_uids_to_info()  # Add unique ids to properties so accessible in skins
         li.set_params_reroute(self.ftv_forced_lookup, self.flatten_seasons)  # Reroute details to proper end point
         li.set_params_to_info(self.plugin_category)  # Set path params to properties for use in skins
         li.infoproperties.update(property_params or {})
         xbmcplugin.addDirectoryItem(
             handle=self.handle,
             url=li.get_url(),
             listitem=li.get_listitem(),
             isFolder=li.is_folder)