From 3838a220894c232a7280377d6c3febcfd4d3bdad Mon Sep 17 00:00:00 2001 From: Alhaziel01 Date: Sat, 25 Sep 2021 11:12:31 +0200 Subject: [PATCH] aggiornamento ricerca alternativa --- channels/cineblog01.py | 4 +- core/support.py | 213 ++++----- core/tmdb.py | 28 +- core/trakt_tools.py | 148 ++++-- platformcode/infoplus.py | 10 +- platformcode/launcher.py | 6 + platformcode/platformtools.py | 23 +- platformcode/xbmc_videolibrary.py | 1 - .../resource.language.en_gb/strings.po | 10 +- .../resource.language.it_it/strings.po | 14 +- resources/skins/Default/720p/Filter.xml | 118 +++++ resources/skins/Default/720p/GlobalSearch.xml | 16 +- resources/skins/Default/media/reset.png | Bin 0 -> 3306 bytes resources/skins/Default/media/save.png | Bin 0 -> 3462 bytes servers/fembed.py | 2 +- servers/userload.py | 2 +- specials/tvmoviedb.py | 433 +++++++++++++----- specials/videolibrary.py | 163 +++---- 18 files changed, 776 insertions(+), 415 deletions(-) create mode 100644 resources/skins/Default/720p/Filter.xml create mode 100644 resources/skins/Default/media/reset.png create mode 100644 resources/skins/Default/media/save.png diff --git a/channels/cineblog01.py b/channels/cineblog01.py index 2b88f5dd..e0196e80 100644 --- a/channels/cineblog01.py +++ b/channels/cineblog01.py @@ -186,9 +186,7 @@ def episodios(item): itlist.extend(sorted(itemDict['Sub-ITA'].get(season, []), key=lambda it: (it.contentSeason, it.contentEpisodeNumber))) itemlist = itlist - for i in itemlist: logger.debug(i.title, i.contentType) - import inspect - if inspect.stack()[1][3] not in ['add_tvshow', 'get_episodes', 'update', 'find_episodes']: + if not support.stackCheck(['add_tvshow', 'get_episodes', 'update', 'find_episodes']): if len(seasons) > 1: itemlist = support.season_pagination(itemlist, item, [], 'episodios') else: diff --git a/core/support.py b/core/support.py index 5dab3bbb..241b0d56 100755 --- a/core/support.py +++ b/core/support.py @@ -227,10 +227,10 @@ class scrape: self.itemlist = [i for i in self.itemlist if i.action not in ['add_movie_to_library', 'add_serie_to_library']] if not self.group and not self.args.get('groupExplode') and ((self.pagination and len(self.matches) <= self.pag * self.pagination) or not self.pagination): # next page with pagination - if self.patronNext and inspect.stack()[1][3] not in ['newest'] and len(inspect.stack()) > 2 and inspect.stack()[2][3] not in ['get_channel_results']: + if self.patronNext and not stackCheck('newest') and not stackCheck('get_channel_results'): nextPage(self.itemlist, item, self.function, data=self.data, patron=self.patronNext, patron_total_pages=self.patronTotalPages) - if self.numerationEnabled and inspect.stack()[1][3] not in ['find_episodes']: + if self.numerationEnabled and not stackCheck('find_episodes'): from platformcode import autorenumber if self.function == 'episodios': autorenumber.start(self.itemlist, item) @@ -242,7 +242,7 @@ class scrape: else: autorenumber.start(self.itemlist) - if inspect.stack()[1][3] not in ['add_tvshow', 'get_episodes', 'update', 'find_episodes']: + if not stackCheck(['add_tvshow', 'get_episodes', 'update', 'find_episodes']): if len(self.seasons) > 1 and self.seasonPagination: self.itemlist = season_pagination(self.itemlist, item, self.seasons, self.function) elif self.pagination or (self.function in ['episodios'] and self.seasonPagination): @@ -250,12 +250,12 @@ class scrape: if self.tmdbEnabled and ( self.action != 'play' and 'patronMenu' not in self.args and 'patronGenreMenu' not in self.args - and inspect.stack()[1][3] not in ['add_tvshow'] and (self.function not in ['episodios', 'mainlist'] + and not stackCheck('add_tvshow') and (self.function not in ['episodios', 'mainlist'] or (self.function in ['episodios'] and config.get_setting('episode_info')))): tmdb.set_infoLabels_itemlist(self.itemlist, seekTmdb=True) - if inspect.stack()[1][3] not in ['find_episodes', 'add_tvshow']: + if not stackCheck(['find_episodes', 'add_tvshow']): if self.videlibraryEnabled and (item.infoLabels["title"] or item.fulltitle): # item.fulltitle = item.infoLabels["title"] videolibrary(self.itemlist, item, function=self.function) @@ -305,20 +305,20 @@ class scrape: elif v.startswith('/'): domain = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') v = domain + v - self.itemParams.__setattr__(k, v.strip() if type(v) == str else v) + self.itemParams.__setattr__('_'+k, v.strip() if type(v) == str else v) - self.itemParams.title = cleantitle(self.itemParams.title) - if self.group and self.itemParams.title in contents and not item.grouped: # same title and grouping enabled + self.itemParams._title = cleantitle(self.itemParams._title) + if self.group and self.itemParams._title in contents and not item.grouped: # same title and grouping enabled continue - if item.grouped and self.itemParams.title != item.fulltitle: # inside a group different tvshow should not be included + if item.grouped and self.itemParams._title != item.fulltitle: # inside a group different tvshow should not be included continue - contents.append(self.itemParams.title) + contents.append(self.itemParams._title) - self.itemParams.title2 = cleantitle(self.itemParams.title2) if not self.group or item.grouped else '' - self.itemParams.quality = self.itemParams.quality - self.itemParams.plot = cleantitle(self.itemParams.plot) - self.itemParams.language = scrapeLang(self.itemParams, self.lang) + self.itemParams._title2 = cleantitle(self.itemParams._title2) if not self.group or item.grouped else '' + self.itemParams._quality = self.itemParams._quality + self.itemParams._plot = cleantitle(self.itemParams._plot) + self.itemParams._language = scrapeLang(self.itemParams, self.lang) self.set_infolabels(item) if self.sceneTitle: self.set_sceneTitle() @@ -326,9 +326,9 @@ class scrape: if not self.group or item.grouped: self.set_episodes(item) - if self.itemParams.episode2: self.itemParams.second_episode = scrapertools.find_single_match(self.itemParams.episode2, r'(\d+)').split('x') - if self.itemParams.season: self.itemParams.infoLabels['season'] = int(self.itemParams.season) - if self.itemParams.episode: self.itemParams.infoLabels['episode'] = int(self.itemParams.episode) + if self.itemParams._episode2: self.itemParams._second_episode = scrapertools.find_single_match(self.itemParams._episode2, r'(\d+)').split('x') + if self.itemParams._season: self.itemParams.infoLabels['season'] = int(self.itemParams._season) + if self.itemParams._episode: self.itemParams.infoLabels['episode'] = int(self.itemParams._episode) it = self.set_item(item, match) if it: itemlist.append(it) @@ -344,25 +344,27 @@ class scrape: infolabels = item.infoLabels else: infolabels = {'mediatype':item.contentType} - if self.itemParams.year: - infolabels['year'] = self.itemParams.year - if self.itemParams.plot: - infolabels['plot'] = self.itemParams.plot - if self.itemParams.duration: - dur = scrapertools.find_multiple_matches(self.itemParams.duration, r'([0-9])\s*?(?:[hH]|:|\.|,|\\|\/|\||\s)\s*?([0-9]+)') + if self.itemParams._year: + infolabels['year'] = self.itemParams._year + if self.itemParams._plot: + infolabels['plot'] = self.itemParams._plot + if self.itemParams._duration: + dur = scrapertools.find_multiple_matches(self.itemParams._duration, r'([0-9])\s*?(?:[hH]|:|\.|,|\\|\/|\||\s)\s*?([0-9]+)') for h, m in dur: - self.itemParams.duration = int(h) * 60 + int(m) + self.itemParams._duration = int(h) * 60 + int(m) if not dur: - self.itemParams.duration = scrapertools.find_single_match(self.itemParams.duration, r'(\d+)') + self.itemParams._duration = scrapertools.find_single_match(self.itemParams._duration, r'(\d+)') try: - infolabels['duration'] = int(self.itemParams.duration) * 60 + infolabels['duration'] = int(self.itemParams._duration) * 60 except: - self.itemParams.duration = '' - if self.itemParams.genre: - genres = scrapertools.find_multiple_matches(self.itemParams.genre, '[A-Za-z]+') + self.itemParams._duration = '' + if self.itemParams._genre: + genres = scrapertools.find_multiple_matches(self.itemParams._genre, '[A-Za-z]+') infolabels['genere'] = ", ".join(genres) - if self.itemParams.rating: - infolabels['rating'] = scrapertools.decodeHtmlentities(self.itemParams.rating) + if self.itemParams._rating: + rating = scrapertools.decodeHtmlentities(self.itemParams._rating) + if rating.isdigit(): + infolabels['rating'] = float(rating) self.itemParams.infoLabels = infolabels logger.debug @@ -370,71 +372,71 @@ class scrape: def set_sceneTitle(self): from lib.guessit import guessit try: - parsedTitle = guessit(self.itemParams.title) - self.itemParams.title = parsedTitle.get('title', '') - logger.debug('TITOLO',self.itemParams.title) + parsedTitle = guessit(self.itemParams._title) + self.itemParams._title = parsedTitle.get('title', '') + logger.debug('TITOLO',self.itemParams._title) if parsedTitle.get('source'): - self.itemParams.quality = str(parsedTitle.get('source')) + self.itemParams._quality = str(parsedTitle.get('source')) if parsedTitle.get('screen_size'): - self.itemParams.quality += ' ' + str(parsedTitle.get('screen_size', '')) - if not self.itemParams.year: + self.itemParams._quality += ' ' + str(parsedTitle.get('screen_size', '')) + if not self.itemParams._year: if type(parsedTitle.get('year', '')) == list: self.itemParams.infoLabels['year'] = parsedTitle.get('year', '')[0] else: self.itemParams.infoLabels['year'] = parsedTitle.get('year', '') if parsedTitle.get('episode') and parsedTitle.get('season'): if type(parsedTitle.get('season')) == list: - self.itemParams.season = str(parsedTitle.get('season')[0]) + self.itemParams._season = str(parsedTitle.get('season')[0]) elif parsedTitle.get('season'): - self.itemParams.season = str(parsedTitle.get('season')) + self.itemParams._season = str(parsedTitle.get('season')) if type(parsedTitle.get('episode')) == list: - self.itemParams.episode = str(parsedTitle.get('episode')[0]) - self.itemParams.second_episode = str(parsedTitle.get('episode')[1:]) + self.itemParams._episode = str(parsedTitle.get('episode')[0]) + self.itemParams._second_episode = str(parsedTitle.get('episode')[1:]) else: self.itemParams.infoLabels['episode'] = parsedTitle.get('episode') elif parsedTitle.get('season') and type(parsedTitle.get('season')) == list: - self.itemParams.extraInfo = '{}: {}-{}'.format(config.get_localized_string(30140), parsedTitle.get('season')[0], parsedTitle.get('season')[-1]) + self.itemParams._extraInfo = '{}: {}-{}'.format(config.get_localized_string(30140), parsedTitle.get('season')[0], parsedTitle.get('season')[-1]) elif parsedTitle.get('season'): - self.itemParams.season = str(parsedTitle.get('season')) + self.itemParams._season = str(parsedTitle.get('season')) if parsedTitle.get('episode_title'): - self.itemParams.extraInfo += parsedTitle.get('episode_title') + self.itemParams._extraInfo += parsedTitle.get('episode_title') except: import traceback logger.error(traceback.format_exc()) def set_episodes(self, item): - ep = unifyEp(self.itemParams.episode) if self.itemParams.episode else '' - se = self.itemParams.season if self.itemParams.season.isdigit() else '' + ep = unifyEp(self.itemParams._episode) if self.itemParams._episode else '' + se = self.itemParams._season if self.itemParams._season.isdigit() else '' if ep and se: - self.itemParams.season = se + self.itemParams._season = se if 'x' in ep: ep_list = ep.split('x') - self.itemParams.episode = ep_list[0] - self.itemParams.second_episode = ep_list[1:] + self.itemParams._episode = ep_list[0] + self.itemParams._second_episode = ep_list[1:] else: - self.itemParams.episode = ep + self.itemParams._episode = ep elif item.season: - self.itemParams.season = item.season - if ep: self.itemParams.episode = int(scrapertools.find_single_match(self.itemParams.episode, r'(\d+)')) + self.itemParams._season = item.season + if ep: self.itemParams._episode = int(scrapertools.find_single_match(self.itemParams._episode, r'(\d+)')) - elif item.contentType == 'tvshow' and (self.itemParams.episode == '' and self.itemParams.season == '' and self.itemParams.season == ''): + elif item.contentType == 'tvshow' and (self.itemParams._episode == '' and self.itemParams._season == '' and self.itemParams._season == ''): item.news = 'season_completed' else: try: if 'x' in ep: ep_list = ep.split('x') - self.itemParams.episode = ep_list[1].strip() - self.itemParams.season = ep_list[0].strip() + self.itemParams._episode = ep_list[1].strip() + self.itemParams._season = ep_list[0].strip() if len(ep_list) > 2: - self.itemParams.second_episode = ep_list[2:] + self.itemParams._second_episode = ep_list[2:] else: - self.itemParams.episode = ep + self.itemParams._episode = ep except: - logger.debug('invalid episode: ' + self.itemParams.episode) + logger.debug('invalid episode: ' + self.itemParams._episode) pass def set_item(self, item, match): @@ -442,41 +444,41 @@ class scrape: CT = '' if self.typeContentDict: for name, variants in self.typeContentDict.items(): - if str(self.itemParams.type).lower() in variants: + if str(self.itemParams._type).lower() in variants: CT = name break else: CT = item.contentType if self.typeActionDict: for name, variants in self.typeActionDict.items(): - if str(self.itemParams.type).lower() in variants: + if str(self.itemParams._type).lower() in variants: AC = name break else: AC = self.action - if (not self.itemParams.title or self.itemParams.title not in self.blacklist) and (self.search.lower() in self.itemParams.title.lower()): - it = item.clone(title=self.itemParams.title, - fulltitle=self.itemParams.title, - show=self.itemParams.title, + if (not self.itemParams._title or self.itemParams._title not in self.blacklist) and (self.search.lower() in self.itemParams._title.lower()): + it = item.clone(title=self.itemParams._title, + fulltitle=self.itemParams._title, + show=self.itemParams._title, infoLabels=self.itemParams.infoLabels, grouped = self.group, - episode2 = self.itemParams.second_episode, - extraInfo = self.itemParams.extraInfo, + episode2 = self.itemParams._second_episode, + extraInfo = self.itemParams._extraInfo, disable_videolibrary = not self.args.get('addVideolibrary', True), - size = self.itemParams.size, - seed = self.itemParams.seed) + size = self.itemParams._size, + seed = self.itemParams._seed) if self.itemParams.infoLabels.get('season'): it.contentSeason = self.itemParams.infoLabels.get('season') if self.itemParams.infoLabels.get('episode'): it.contentEpisodeNumber = self.itemParams.infoLabels.get('episode') - if self.itemParams.url: it.url = self.itemParams.url - if self.function == 'episodios': it.fulltitle = it.show = self.itemParams.title - if self.itemParams.quality: it.quality = self.itemParams.quality - if self.itemParams.language: it.contentLanguage = self.itemParams.language + if self.itemParams._url: it.url = self.itemParams._url + if self.function == 'episodios': it.fulltitle = it.show = self.itemParams._title + if self.itemParams._quality: it.quality = self.itemParams._quality + if self.itemParams._language: it.contentLanguage = self.itemParams._language if item.prevthumb: it.thumbnail = item.prevthumb - elif self.itemParams.thumb: it.thumbnail = self.itemParams.thumb + elif self.itemParams._thumb: it.thumbnail = self.itemParams._thumb it.contentType = 'episode' if self.function == 'episodios' else CT if CT else item.contentType - if it.contentType not in ['movie'] and self.function != 'episodios' or it.contentType in ['undefined']: it.contentSerieName = self.itemParams.title - if self.function == 'peliculas': it.contentTitle= self.itemParams.title - if self.itemParams.title2: it.title2 = self.itemParams.title2 + if it.contentType not in ['movie'] and self.function != 'episodios' or it.contentType in ['undefined']: it.contentSerieName = self.itemParams._title + if self.function == 'peliculas': it.contentTitle= self.itemParams._title + if self.itemParams._title2: it.title2 = self.itemParams._title2 - if self.itemParams.episode and self.group and not item.grouped: + if self.itemParams._episode and self.group and not item.grouped: it.action = self.function elif AC: it.action = AC @@ -852,7 +854,7 @@ def nextPage(itemlist, item, function_or_level=1, **kwargs): total_pages = integer, the number of total pages ''' logger.debug() - if 'channel_search' in [s[3] for s in inspect.stack()]: + if stackCheck('channel_search'): return itemlist # get optional args @@ -897,6 +899,7 @@ def nextPage(itemlist, item, function_or_level=1, **kwargs): page=page if page else item.page + 1 if item.page else 2, prevthumb = item.thumbnail, thumbnail=thumb())) + if total_pages: itemlist.append(item.clone(action='gotopage', real_action = inspect.stack()[function_or_level][3] if type(function_or_level) == int else function_or_level, @@ -911,7 +914,7 @@ def nextPage(itemlist, item, function_or_level=1, **kwargs): def pagination(itemlist, item, function_level=1): - if 'channel_search' in [s[3] for s in inspect.stack()]: + if stackCheck('channel_search'): return itemlist if not item.page: @@ -923,7 +926,8 @@ def pagination(itemlist, item, function_level=1): if perpage and (item.page - 1) * perpage > i: continue # pagination if perpage and i >= item.page * perpage: break # pagination itlist.append(it) - if len(itemlist) >= item.page * perpage: + + if len(itemlist) > item.page * perpage: itemlistdb(itemlist) itlist.append( Item(channel=item.channel, @@ -936,35 +940,26 @@ def pagination(itemlist, item, function_level=1): itemlist = True, prevthumb = item.thumbnail, thumbnail=thumb())) - itlist.append( - Item(channel=item.channel, - contentType=item.contentType, - action='gotopage', - real_action=action, - title=typo(config.get_localized_string(90007), 'color kod bold'), - page=item.page + 1, - total_pages=round(len(itemlist)/perpage), - nextPage = True, - itemlist = True, - prevthumb = item.thumbnail, - thumbnail=thumb(), - folder = False)) - # itlist.append( - # item.clone(channel=item.channel, - # action=action, - # contentType=item.contentType, - # title=typo(config.get_localized_string(90006), 'color kod bold'), - # page=item.page + 1, - # total_pages=round(len(itemlist)/perpage), - # nextPage = True, - # itemlist = True, - # prevthumb = item.thumbnail, - # thumbnail=thumb())) + if len(itemlist) > perpage: + itlist.append( + Item(channel=item.channel, + contentType=item.contentType, + action='gotopage', + real_action=action, + title=typo(config.get_localized_string(90007), 'color kod bold'), + page=item.page + 1, + total_pages=round(len(itemlist)/perpage), + nextPage = True, + itemlist = True, + prevthumb = item.thumbnail, + thumbnail=thumb(), + folder = False)) + return itlist def season_pagination(itemlist, item, seasons=[], function_level=1): - if 'channel_search' in [s[3] for s in inspect.stack()]: + if stackCheck('channel_search'): return itemlist action = function_level if type(function_level) == str else inspect.stack()[function_level][3] @@ -1881,3 +1876,11 @@ def itemlistdb(itemlist=None): itemlist = db['itemlist'].get('itemlist',[]) db.close() return itemlist + + +def stackCheck(values): + stacks = [s[3] for s in inspect.stack()] + if type(values) == str: + return values in stacks + else: + return any(v in values for v in stacks) \ No newline at end of file diff --git a/core/tmdb.py b/core/tmdb.py index 344580f7..e92b07b0 100644 --- a/core/tmdb.py +++ b/core/tmdb.py @@ -17,10 +17,9 @@ from future.builtins import object import ast, copy, re, time -from core import filetools, httptools, jsontools, scrapertools, support +from core import filetools, httptools, jsontools, scrapertools from core.item import InfoLabels from platformcode import config, logger, platformtools -import threading info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json def_lang = info_language[config.get_setting("info_language", "videolibrary")] @@ -214,7 +213,8 @@ def set_infoLabels_itemlist(itemlist, seekTmdb=False, search_language=def_lang, logger.error(traceback.format_exc(1)) return (_i, _item, ret) - # from core.support import dbg;dbg() + + # from core.support import dbg; dbg() # for i, item in enumerate(itemlist): # r_list.append(sub_thread(item, i, seekTmdb)) with futures.ThreadPoolExecutor() as executor: @@ -428,7 +428,7 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang): item.fulltitle = new_title return True # We check what type of content it is... - # from core.support import dbg;dbg() + if item.contentType == 'movie': search_type = 'movie' elif item.contentType == 'undefined': # don't know @@ -537,10 +537,7 @@ def get_nfo(item, search_groups=False): info_nfo = 'https://www.themoviedb.org/tv/{}/episode_group/{}'.format(item.infoLabels['tmdb_id'], Id) return info_nfo + '\n' else: return - # from core.support import dbg;dbg() - # if "season" in item.infoLabels and "episode" in item.infoLabels: - # info_nfo = "https://www.themoviedb.org/tv/{}/season/{}/episode/{}" .format(item.infoLabels['tmdb_id'], item.contentSeason, item.contentEpisodeNumber) - # else: + info_nfo = ', '.join(item.infoLabels['url_scraper']) return info_nfo + '\n' @@ -586,7 +583,6 @@ def select_group(groups, item): return '' def get_group(Id): - # from core.support import dbg;dbg() url = '{}/tv/episode_group/{}?api_key={}&language={}'.format(host, Id, api, def_lang) group = requests.get(url).json().get('groups',[]) return group @@ -627,7 +623,6 @@ def discovery(item, dict_=False, cast=False): def get_dic_genres(search_type): lang = def_lang - # from core.support import dbg;dbg() genres = Tmdb(search_type=search_type) return genres.dic_genres[lang] @@ -891,7 +886,6 @@ class Tmdb(object): @staticmethod @cache_response def get_json(url, cache=True): - # from core.support import dbg;dbg() try: result = httptools.downloadpage(url, cookies=False, ignore_response_code=True) @@ -948,14 +942,12 @@ class Tmdb(object): logger.error(traceback.format_exc()) def __by_id(self, source='tmdb'): - # from core.support import dbg;dbg() - if self.search_id: if source == "tmdb": url = ('{}/{}/{}?api_key={}&language={}&append_to_response=images,videos,external_ids,credits&include_image_language={},en,null'.format(host, self.search_type, self.search_id, api, self.search_language, self.search_language)) searching = "id_Tmdb: {}".format(self.search_id) else: - url = ('{}/find/{}?external_source={}&api_key={}8&language={}'.format(host, self.search_id, source, api, self.search_language)) + url = ('{}/find/{}?external_source={}&api_key={}&language={}'.format(host, self.search_id, source, api, self.search_language)) searching = "{}: {}".format(source.capitalize(), self.search_id) logger.debug("[Tmdb.py] Searching %s:\n%s" % (searching, url)) @@ -999,7 +991,7 @@ class Tmdb(object): url = ('{}/search/{}?api_key={}&query={}&language={}&include_adult={}&page={}'.format(host, self.search_type, api, text_quote, self.search_language, True, page)) if self.search_year: - if self.search_type == 'movie': + if self.search_type in ['movie', 'multi']: url += '&primary_release_year=%s' % self.search_year else: url += '&first_air_date_year=%s' % self.search_year @@ -1220,7 +1212,6 @@ class Tmdb(object): :rtype: str """ ret = "" - # from core.support import dbg;dbg() if 'id' in self.result: ret = self.result.get('overview') @@ -1366,7 +1357,6 @@ class Tmdb(object): searching = "id_Tmdb: " + str(self.result["id"]) + " season: " + str(seasonNumber) + "\nURL: " + url logger.debug("[Tmdb.py] Searching " + searching) - # from core.support import dbg;dbg() try: self.season[seasonNumber] = self.get_json(url) if not isinstance(self.season[seasonNumber], dict): @@ -1482,7 +1472,6 @@ class Tmdb(object): # Obtain chapter data if applicable - # from core.support import dbg;dbg() ret_dic = {} if chapter > 0: # episode = season["episodes"][chapter - 1] @@ -1653,7 +1642,6 @@ class Tmdb(object): continue if k == 'media_type': - # from core.support import dbg;dbg() ret_infoLabels['mediatype'] = v if v in ['tv', 'tvshow'] else 'movie' elif k == 'overview': @@ -1745,7 +1733,6 @@ class Tmdb(object): ret_infoLabels[k] = v elif k == 'production_countries' or k == 'origin_country': - # support.dbg() if isinstance(v, str): l_country = list(set(l_country + v.split(','))) @@ -1762,7 +1749,6 @@ class Tmdb(object): elif k == 'credits_crew' or k == 'episode_crew' or k == 'season_crew': for crew in v: if crew['job'].lower() == 'director': - # from core.support import dbg;dbg() l_director = list(set(l_director + [crew['name']])) l_director_image += ['https://image.tmdb.org/t/p/original' + crew['profile_path'] if crew['profile_path'] else ''] l_director_id += [crew['id']] diff --git a/core/trakt_tools.py b/core/trakt_tools.py index 7734799d..98e4ff74 100644 --- a/core/trakt_tools.py +++ b/core/trakt_tools.py @@ -12,13 +12,15 @@ import sys if sys.version_info[0] >= 3: from concurrent import futures else: from concurrent_py2 import futures -client_id = "502bd1660b833c1ae69828163c0848e84e9850061e5529f30930e7356cae73b1" -client_secret = "1d30d5b24acf223a5e1ab6c61d08b69992d98ed5b0c7e26b052b5e6a592035a4" +host = 'https://api.trakt.tv' +client_id = '502bd1660b833c1ae69828163c0848e84e9850061e5529f30930e7356cae73b1' +client_secret = '1d30d5b24acf223a5e1ab6c61d08b69992d98ed5b0c7e26b052b5e6a592035a4' +token_auth = config.get_setting("token_trakt", "trakt") def auth_trakt(): item = Item() - folder = (config.get_platform() == "plex") + folder = (config.get_platform() == 'plex') item.folder = folder # Autentificación de cuenta Trakt headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} @@ -26,24 +28,23 @@ def auth_trakt(): post = {'client_id': client_id} post = jsontools.dump(post) # Se solicita url y código de verificación para conceder permiso a la app - url = "http://api.trakt.tv/oauth/device/code" - data = httptools.downloadpage(url, post=post, headers=headers).data - data = jsontools.load(data) - item.verify_url = data["verification_url"] - item.user_code = data["user_code"] - item.device_code = data["device_code"] - item.intervalo = data["interval"] + url = host + '/oauth/device/code' + data = httptools.downloadpage(url, post=post, headers=headers).json + item.verify_url = data['verification_url'] + item.user_code = data['user_code'] + item.device_code = data['device_code'] + item.intervalo = data['interval'] if not item.folder: token_trakt(item) else: itemlist = [] title = config.get_localized_string(60248) % item.verify_url - itemlist.append(item.clone(title=title, action="")) + itemlist.append(item.clone(title=title, action='')) title = config.get_localized_string(60249) % item.user_code - itemlist.append(item.clone(title=title, action="")) + itemlist.append(item.clone(title=title, action='')) title = config.get_localized_string(60250) - itemlist.append(item.clone(title=title, action="token_trakt")) + itemlist.append(item.clone(title=title, action='token_trakt')) return itemlist except: import traceback @@ -55,17 +56,17 @@ def token_trakt(item): headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} try: - if item.extra == "renew": - refresh = config.get_setting("refresh_token_trakt", "trakt") - url = "http://api.trakt.tv/oauth/device/token" + if item.extra == 'renew': + refresh = config.get_setting('refresh_token_trakt', 'trakt') + url = host + '/oauth/device/token' post = {'refresh_token': refresh, 'client_id': client_id, 'client_secret': client_secret, 'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', 'grant_type': 'refresh_token'} post = jsontools.dump(post) data = httptools.downloadpage(url, post=post, headers=headers).data data = jsontools.load(data) - elif item.action == "token_trakt": - url = "http://api.trakt.tv/oauth/device/token" - post = "code=%s&client_id=%s&client_secret=%s" % (item.device_code, client_id, client_secret) + elif item.action == 'token_trakt': + url = host + '/oauth/device/token' + post = 'code={}&client_id={}&client_secret={}'.format(item.device_code, client_id, client_secret) data = httptools.downloadpage(url, post=post, headers=headers).data data = jsontools.load(data) else: @@ -80,15 +81,15 @@ def token_trakt(item): time.sleep(item.intervalo) try: if dialog_auth.iscanceled(): - config.set_setting("trakt_sync", False) + config.set_setting('trakt_sync', False) return - url = "http://api.trakt.tv/oauth/device/token" + url = host + '/oauth/device/token' post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret} post = jsontools.dump(post) data = httptools.downloadpage(url, post=post, headers=headers).data data = jsontools.load(data) - if "access_token" in data: + if 'access_token' in data: # Código introducido, salimos del bucle break except: @@ -99,16 +100,16 @@ def token_trakt(item): except: pass - token = data["access_token"] - refresh = data["refresh_token"] + token = data['access_token'] + refresh = data['refresh_token'] - config.set_setting("token_trakt", token, "trakt") - config.set_setting("refresh_token_trakt", refresh, "trakt") + config.set_setting('token_trakt', token, 'trakt') + config.set_setting('refresh_token_trakt', refresh, 'trakt') if not item.folder: platformtools.dialog_notification(config.get_localized_string(60255), config.get_localized_string(60256)) if config.is_xbmc(): import xbmc - xbmc.executebuiltin("Container.Refresh") + xbmc.executebuiltin('Container.Refresh') return except: @@ -116,13 +117,13 @@ def token_trakt(item): logger.error(traceback.format_exc()) if not item.folder: return platformtools.dialog_notification(config.get_localized_string(60527), config.get_localized_string(60258)) - token = "" + token = '' itemlist = [] if token: - itemlist.append(item.clone(title=config.get_localized_string(60256), action="")) + itemlist.append(item.clone(title=config.get_localized_string(60256), action='')) else: - itemlist.append(item.clone(title=config.get_localized_string(60260), action="")) + itemlist.append(item.clone(title=config.get_localized_string(60260), action='')) return itemlist @@ -138,34 +139,35 @@ def set_trakt_info(item): except: pass + def get_trakt_watched(id_type, mediatype, update=False): logger.debug() id_list = [] id_dict = dict() - token_auth = config.get_setting("token_trakt", "trakt") + token_auth = config.get_setting('token_trakt', 'trakt') if token_auth: sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt') if os.path.exists(sync_path) and not update: - trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + trakt_node = jsontools.get_node_from_file('trakt', 'TRAKT') if mediatype == 'shows': return trakt_node['shows'] if mediatype == 'movies': return trakt_node['movies'] else: - token_auth = config.get_setting("token_trakt", "trakt") + token_auth = config.get_setting('token_trakt', 'trakt') if token_auth: try: - token_auth = config.get_setting("token_trakt", "trakt") + token_auth = config.get_setting('token_trakt', 'trakt') headers = [['Content-Type', 'application/json'], ['trakt-api-key', client_id], ['trakt-api-version', '2']] if token_auth: - headers.append(['Authorization', "Bearer %s" % token_auth]) - url = "https://api.trakt.tv/sync/watched/%s" % mediatype + headers.append(['Authorization', 'Bearer ' + token_auth]) + url = host + '/sync/watched/' + mediatype data = httptools.downloadpage(url, headers=headers).data watched_dict = jsontools.load(data) @@ -233,7 +235,7 @@ def get_sync_from_file(): sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt_data.json') trakt_node = {} if os.path.exists(sync_path): - trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + trakt_node = jsontools.get_node_from_file('trakt', 'TRAKT') trakt_node['movies'] = get_trakt_watched('tmdb', 'movies') trakt_node['shows'] = get_trakt_watched('tmdb', 'shows') @@ -245,7 +247,7 @@ def update_trakt_data(mediatype, trakt_data): sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt_data.json') if os.path.exists(sync_path): - trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + trakt_node = jsontools.get_node_from_file('trakt', 'TRAKT') trakt_node[mediatype] = trakt_data jsontools.update_node(trakt_node, 'trakt', 'TRAKT') @@ -257,7 +259,7 @@ def ask_install_script(): respuesta = platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(70521)) if respuesta: - xbmc.executebuiltin("InstallAddon(script.trakt)") + xbmc.executebuiltin('InstallAddon(script.trakt)') return else: config.set_setting('install_trakt', False) @@ -283,3 +285,71 @@ def update_all(): trakt_data = get_trakt_watched('tmdb', mediatype, True) update_trakt_data(mediatype, trakt_data) + +def context(item): + Type = item.contentType.replace("tv", "") + "s" + item.action = 'traktResults' + title = config.get_localized_string(30122 if item.contentType == 'movie' else 30123) + context = [] + commands = [] + condition = "'tmdb': " + item.infoLabels["tmdb_id"] + try: + result = execute(item.clone(url="/sync/watched/" + Type)) + post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]} + if condition in str(result): + context.append(config.get_localized_string(60016 if item.contentType == 'movie' else 60020)) + commands.append(item.clone(url="/sync/history/remove", post=post)) + else: + context.append(config.get_localized_string(60017 if item.contentType == 'movie' else 60021)) + commands.append(item.clone(url="/sync/history", post=post)) + except: + pass + + try: + from core.support import dbg;dbg() + result = execute(item.clone(url="/sync/watchlist/" + Type)) + post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]} + if condition in str(result): + context.append(config.get_localized_string(70343) % title) + commands.append(item.clone(url="/sync/watchlist/remove", post=post)) + else: + context.append(config.get_localized_string(70344) % title) + commands.append(item.clone(url="/sync/watchlist", post=post)) + except: + pass + + try: + result = execute(item.clone(url="/sync/collection/" + Type)) + post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]} + if condition in str(result): + context.append(config.get_localized_string(70345) % title) + commands.append(item.clone(url="/sync/collection/remove", post=post)) + else: + context.append(config.get_localized_string(70346) % title) + commands.append(item.clone(url="/sync/collection", post=post)) + except: + pass + + if context: + import xbmcgui + index = xbmcgui.Dialog().contextmenu(context) + if index > -1: + execute(commands[index]) + +def execute(item): + from platformcode.platformtools import dialog_notification + url = host + item.url + + headers = [['Content-Type', 'application/json'], ['trakt-api-key', client_id], ['trakt-api-version', '2']] + if token_auth: headers.append(['Authorization', 'Bearer {}'.format(token_auth)]) + + post = None + if item.post: post = jsontools.dump(item.post) + + data = httptools.downloadpage(url, post=post, headers=headers).json + + if not post: + return data + else: + if 'not_found' in data: return dialog_notification('Trakt', config.get_localized_string(70347)) + else: return dialog_notification('Trakt', config.get_localized_string(70348)) \ No newline at end of file diff --git a/platformcode/infoplus.py b/platformcode/infoplus.py index af179d04..6187eb7d 100644 --- a/platformcode/infoplus.py +++ b/platformcode/infoplus.py @@ -75,6 +75,7 @@ class InfoPlus(xbmcgui.WindowXML): else: self.listitem.setArt({'poster':self.item.thumbnail, 'fanart':self.item.fanart}) # Set Rating + if 'trakt_rating' in self.info: self.info['rating'] = self.info['trakt_rating'] self.listitem.setProperty('rating',str(int(self.info.get('rating',10) * 10))) rating = self.info.get('rating', 'N/A') color = 'FFFFFFFF' if rating == 'N/A' else 'FFDB2360' if rating < 4 else 'FFD2D531' if rating < 7 else 'FF21D07A' @@ -303,7 +304,12 @@ class CastWindow(xbmcgui.WindowXML): def get_person_info(self): # Function for Person Info - url = '{}/person/{}?api_key={}&language=en'.format(tmdb.host, self.id, tmdb.api) + if not self.id and self.item.text: + res = httptools.downloadpage('{}/search/person?api_key={}&language={}&query={}'.format(tmdb.host, tmdb.api, tmdb.def_lang, self.item.text)).json.get('results',[]) + if res: self.id = res[0]['id'] + else: self.close() + + url = '{}/person/{}?api_key={}&language={}'.format(tmdb.host, self.id, tmdb.api, tmdb.def_lang) translation_url = '{}/person/{}/translations?api_key={}'.format(tmdb.host, self.id, tmdb.api) info = httptools.downloadpage(url).json @@ -322,7 +328,7 @@ class CastWindow(xbmcgui.WindowXML): place = info.get('place_of_birth') self.castitem = xbmcgui.ListItem(info.get('name')) birth = born + (' - ' + dead if dead else '') + (' [B]•[/B] ' + place if place else '') - self.castitem.setArt({'poster':self.item.poster if self.item.poster else self.item.infoLabels.get('thumbnail', '')}) + self.castitem.setArt({'poster':self.item.poster if self.item.poster else self.item.infoLabels.get('thumbnail', self.item.thumbnail)}) self.castitem.setProperties({'birth':birth, 'plot':biography}) def onInit(self): diff --git a/platformcode/launcher.py b/platformcode/launcher.py index e8d531bb..6dfc4327 100644 --- a/platformcode/launcher.py +++ b/platformcode/launcher.py @@ -67,6 +67,7 @@ def run(item=None): config.set_setting('show_once', True) logger.info(item.tostring()) + # from core.support import dbg;dbg() try: if not config.get_setting('tmdb_active'): @@ -116,6 +117,11 @@ def run(item=None): action = getattr(infoplus, item.action) return action(item) + elif item.channel == 'trakt_tools': + from core import trakt_tools + action = getattr(trakt_tools, item.action) + return action(item) + elif item.channel == "backup": from platformcode import backup return getattr(backup, item.action)(item) diff --git a/platformcode/platformtools.py b/platformcode/platformtools.py index 065a3d37..1bc9d793 100644 --- a/platformcode/platformtools.py +++ b/platformcode/platformtools.py @@ -474,10 +474,10 @@ def render_items(itemlist, parent_item): xbmc.sleep(100) xbmc.sleep(100) win = xbmcgui.Window(10025) - cid = win.getFocusId() - ctl = win.getControl(cid) + ctrlId = win.getFocusId() + ctrl = win.getControl(ctrlId) pos = position + (1 if xbmc.getInfoLabel('Container(10138).HasParent') else 0) - ctl.selectItem(pos) + ctrl.selectItem(pos) def viewmodeMonitor(): @@ -680,7 +680,8 @@ def set_context_commands(item, item_url, parent_item, **kwargs): # (item.contentTitle and item.infoLabels["year"]) or item.contentSerieName: if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id']: context_commands.append(("InfoPlus", "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=start&from_channel=' + item.channel))) - + if config.get_setting("token_trakt", "trakt") and item.contentType in ['movie', 'tvshow']: + context_commands.append((config.get_localized_string(70318), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=trakt_tools&action=context'))) # Open in browser and previous menu if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist" and not parent_item.noMainMenu: context_commands.insert(1, (config.get_localized_string(70739), "Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))) @@ -1353,20 +1354,6 @@ def get_selected_video(item, selection, video_urls, autoplay=False): file_type = video_url.get('type', 'Video').lower() if not item.subtitle: item.subtitle = video_url.get('sub', '') view = True - # if selection < len(video_urls): - # mediaurl = video_urls[selection][1] - # if len(video_urls[selection]) > 4: - # wait_time = video_urls[selection][2] - # if not item.subtitle: - # item.subtitle = video_urls[selection][3] - # mpd = True - # elif len(video_urls[selection]) > 3: - # wait_time = video_urls[selection][2] - # if not item.subtitle: - # item.subtitle = video_urls[selection][3] - # elif len(video_urls[selection]) > 2: - # wait_time = video_urls[selection][2] - # view = True if 'mpd' in file_type: mpd = True diff --git a/platformcode/xbmc_videolibrary.py b/platformcode/xbmc_videolibrary.py index 08cddd76..7031d703 100644 --- a/platformcode/xbmc_videolibrary.py +++ b/platformcode/xbmc_videolibrary.py @@ -271,7 +271,6 @@ def mark_content_as_watched_on_kodi(item, value=1): payload = {"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": r[0][0], "playcount": value}, "id": 1} data = get_data(payload) elif item.contentType == 'episode': - from core.support import dbg;dbg() path = '%{}'.format(item.strm_path.replace('\\','%').replace('/', '%')) sql = 'select idEpisode from episode_view where c18 like "{}"'.format(path) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index a611f721..f3018e3e 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -4181,15 +4181,15 @@ msgid "No images available" msgstr "" msgctxt "#70341" -msgid "[Trakt] Mark %s as not seen" +msgid "Mark %s as not seen" msgstr "" msgctxt "#70342" -msgid "[Trakt] Mark %s as seen" +msgid "Mark %s as seen" msgstr "" msgctxt "#70343" -msgid "[Trakt] Remove %s from your watchlist" +msgid "Remove %s from your watchlist" msgstr "" msgctxt "#70344" @@ -4197,11 +4197,11 @@ msgid "Add to %s your watchlist" msgstr "" msgctxt "#70345" -msgid "[Trakt] Remove %s from your collection" +msgid "Remove %s from your collection" msgstr "" msgctxt "#70346" -msgid "[Trakt] Add %s to your collection" +msgid "Add %s to your collection" msgstr "" msgctxt "#70347" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index 85b5a7ca..0b517155 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -4188,20 +4188,20 @@ msgid "[Trakt] Mark %s as seen" msgstr "[Trakt] Segna %s come vista" msgctxt "#70343" -msgid "[Trakt] Remove %s from your watchlist" -msgstr "[Trakt] Rimuovi %s dalla tua watchlist" +msgid "Remove %s from your watchlist" +msgstr "Rimuovi %s dalla tua watchlist" msgctxt "#70344" msgid "Add to %s your watchlist" -msgstr "[Trakt] Aggiungi %s alla tua watchlist" +msgstr "Aggiungi %s alla tua watchlist" msgctxt "#70345" -msgid "[Trakt] Remove %s from your collection" -msgstr "[Trakt] Rimuovi %s dalla tua collezione" +msgid "Remove %s from your collection" +msgstr "Rimuovi %s dalla tua collezione" msgctxt "#70346" -msgid "[Trakt] Add %s to your collection" -msgstr "[Trakt] Aggiungi %s alla tua collezione" +msgid "Add %s to your collection" +msgstr "Aggiungi %s alla tua collezione" msgctxt "#70347" msgid "Action performed correctly" diff --git a/resources/skins/Default/720p/Filter.xml b/resources/skins/Default/720p/Filter.xml new file mode 100644 index 00000000..6ab949bf --- /dev/null +++ b/resources/skins/Default/720p/Filter.xml @@ -0,0 +1,118 @@ + + + 0.52 + + 0 + 0 + + 100 + + + 125 + 250 + 780 + 470 + + Window Background + 100% + 100% + white.png + + + 30 + 40 + + Title + 0 + 0 + 40 + 700 + font13 + FFFFFFFF + + center + left + + + Divider + 50 + 0 + 1 + 700 + white.png + + + + 100 + 40 + 700 + 2 + 10 + + 60 + + 20 + white.png + white.png + + + 60 + + 20 + white.png + white.png + + + 60 + + 20 + white.png + white.png + + + 60 + 200 + + 20 + white.png + white.png + + + 1 + 10 + center + horizontal + + 60 + 60 + + search.png + search.png + + + 60 + 60 + + save.png + save.png + + + 60 + 60 + + reset.png + reset.png + + + 60 + 60 + + close.png + close.png + + + + + + \ No newline at end of file diff --git a/resources/skins/Default/720p/GlobalSearch.xml b/resources/skins/Default/720p/GlobalSearch.xml index a9f7a208..e3e252df 100644 --- a/resources/skins/Default/720p/GlobalSearch.xml +++ b/resources/skins/Default/720p/GlobalSearch.xml @@ -50,8 +50,8 @@ Title Control.IsVisible(500) - 480 - 270 + 260 + 280 1000 30 font13 @@ -59,7 +59,7 @@ 00000000 left center - Conditional + Conditional @@ -538,7 +538,7 @@ 503 300 - + Episode Title 0 20 @@ -566,7 +566,7 @@ white.png scale - + Episode Title 0 20 @@ -577,6 +577,7 @@ 00000000 left center + true @@ -602,17 +603,18 @@ $INFO[ListItem.Art(thumb)] scale - + Episode Title 0 180 - 480 + 440 100% font13 FF232323 00000000 left center + true diff --git a/resources/skins/Default/media/reset.png b/resources/skins/Default/media/reset.png new file mode 100644 index 0000000000000000000000000000000000000000..4c356edc597763d2d878d70557f81b99a1fc80f4 GIT binary patch literal 3306 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 literal 0 HcmV?d00001 diff --git a/servers/fembed.py b/servers/fembed.py index c417af74..94d84a71 100644 --- a/servers/fembed.py +++ b/servers/fembed.py @@ -32,6 +32,6 @@ def get_video_url(page_url, user="", password="", video_password=""): media_url = file['file'] label = file['label'] extension = file['type'] - video_urls.append({'type':extension, 'quality':label, 'url':media_url}) + video_urls.append({'type':extension, 'res':label, 'url':media_url}) # video_urls.sort(key=lambda x: int(x[0].split()[1].replace('p',''))) return video_urls diff --git a/servers/userload.py b/servers/userload.py index 874351c3..ff56ffe5 100644 --- a/servers/userload.py +++ b/servers/userload.py @@ -10,7 +10,7 @@ def test_video_exists(page_url): logger.debug('page url=', page_url) response = httptools.downloadpage(page_url) - if response.code == 404: + if response.code == 404 or 'We’re Sorry' in response.data: return False, config.get_localized_string(70449) % 'Userload' else: data = response.data diff --git a/specials/tvmoviedb.py b/specials/tvmoviedb.py index d203d188..5512b765 100644 --- a/specials/tvmoviedb.py +++ b/specials/tvmoviedb.py @@ -1,13 +1,10 @@ # -*- coding: utf-8 -*- -from platformcode.platformtools import calcResolution -from core.item import Item +from typing import OrderedDict +from core.item import InfoLabels, Item import re -from core import filetools, jsontools, trakt_tools -from core import support, tmdb -from core.tmdb import Tmdb -from core.scrapertools import htmlclean, decodeHtmlentities -from core.support import nextPage, thumb, typo, match, dbg +from core import httptools, trakt_tools, tmdb, support, jsontools from platformcode import config, logger, platformtools +from datetime import datetime langs = Item(tmdb=[tmdb.def_lang, 'de', 'fr', 'pt', 'it', 'es-MX', 'ca', 'en', 'es'], @@ -16,7 +13,7 @@ lang = Item(tmdb=langs.tmdb[config.get_setting('tmdb', 'tvmoviedb')], tmdbfallback= langs.tmdb[config.get_setting('tmdbfallback', 'tvmoviedb')], imdb=langs.imdb[config.get_setting('imdb', 'tvmoviedb')]) - +imdb_host = 'http://www.imdb.com' mal_adult = config.get_setting('adult_mal', 'tvmoviedb') mal_key = 'MzE1MDQ2cGQ5N2llYTY4Z2xwbGVzZjFzbTY=' # fanart = filetools.join(config.get_runtime_path(), re 'fanart.jpg') @@ -26,17 +23,31 @@ def mainlist(item): logger.debug() itemlist = [item.clone(title='TMDB', action='tmdbMenu', thumbnail=support.thumb('tmdb')), item.clone(title='IMDB', action='imdbMenu', thumbnail=support.thumb('imdb'))] - itemlist += [item.clone(title=config.get_localized_string(70415), action='trakt', thumbnail=support.thumb('trakt')), + itemlist += [item.clone(title=config.get_localized_string(70415), action='traktMenu', thumbnail=support.thumb('trakt')), item.clone(title=config.get_localized_string(70026), action='mal', thumbnail=support.thumb('mal')), - item.clone(title=typo(config.get_localized_string(70027), 'bold'), action='configuracion', folder=False, thumbnail=support.thumb('setting'))] + item.clone(title=support.typo(config.get_localized_string(70027), 'bold'), action='configuracion', folder=False, thumbnail=support.thumb('setting'))] return itemlist +def _search(item): + text = platformtools.dialog_input(heading=item.title) + if text: + if item.search: + item.search['query'] = text + return tmdbResults(item) + else: + item.url = item.url.format(text) + return imdbResults(item) + +########## TMDB ########## def tmdbMenu(item): if not item.args: - return thumb([item.clone(title=config.get_localized_string(70741) % config.get_localized_string(30122), args='movie'), - item.clone(title=config.get_localized_string(70741) % config.get_localized_string(30123), args='tv')]) + return support.thumb([item.clone(title=config.get_localized_string(30122), args='movie'), + item.clone(title=config.get_localized_string(30123), args='tv'), + item.clone(title=config.get_localized_string(70033), action='tmdbResults', args='person/popular'), + item.clone(title=config.get_localized_string(70036), action='_search', search={'url': 'search/person', 'language': lang.tmdb, 'page': 1}), + item.clone(title=config.get_localized_string(70037), action='_search', search={'url': 'search/person', 'language': lang.tmdb, 'page': 1}, crew=True)]) item.contentType = item.args.replace('tv', 'tvshow') @@ -46,20 +57,12 @@ def tmdbMenu(item): item.clone(title=config.get_localized_string(70032), action='tmdbIndex', mode='genre'), item.clone(title=config.get_localized_string(70042), action='tmdbIndex', mode='year')] - if item.args == 'movie': - itemlist.extend([item.clone(title=config.get_localized_string(70033), action='tmdbResults', args='person/popular'), - item.clone(title=config.get_localized_string(70034), action='tmdbResults', args=item.args + '/upcoming')]) - itemlist.extend([item.clone(title=config.get_localized_string(70035) % config.get_localized_string(60244 if item.args == 'movie' else 60245).lower(), action='_search', search={'url': 'search/%s' % item.args, 'language': lang.tmdb, 'page': 1}), - item.clone(title=config.get_localized_string(70036), action='_search', search={'url': 'search/person', 'language': lang.tmdb, 'page': 1})]) + item.clone(title=support.typo(config.get_localized_string(70038),'bold'), action='filter', db_type='tmdb' )]) - if item.args == 'movie': itemlist.append(item.clone(title=config.get_localized_string(70037), action='_search', search={'url': 'search/person', 'language': lang.tmdb, 'page': 1}, crew=True)) - itemlist.extend([item.clone(title=typo(config.get_localized_string(70038),'bold'), action='filter', ), - item.clone(title=typo(config.get_localized_string(70039),'bold'), action='filter', )]) - - return thumb(itemlist) + return support.thumb(itemlist) def tmdbResults(item): @@ -80,126 +83,344 @@ def tmdbResults(item): itemlist.append(it) if item.page < obj.total_pages: - support.nextPage(itemlist, item, 'peliculas', page=item.page + 1, total_pages=obj.total_pages) + support.nextPage(itemlist, item, 'tmdbResults', page=item.page + 1, total_pages=obj.total_pages) return itemlist + def tmdbIndex(item): itemlist = [] - from datetime import datetime + if item.mode == 'genre': url = '{}/{}/list?api_key={}&language={}'.format(tmdb.host, item.mode, tmdb.api, lang.tmdb) - genres = match(url, cookies=False).response.json['genres'] + genres = support.match(url, cookies=False).response.json['genres'] date = datetime.now().strftime('%Y-%m-%d') - sort_by = 'release_date.desc' - param_year = 'release_date.lte' - if item.contentType == 'tvshow': - sort_by = 'first_air_date.desc' - param_year = 'air_date.lte' + sort_by = 'first_air_date.desc' if item.contentType == 'tvshow' else 'release_date.desc' + param_year = 'air_date.lte' if item.contentType == 'tvshow' else 'release_date.lte' for genre in genres: search = {'url': 'discover/{}'.format(item.args), 'with_genres': genre['id'], 'sort_by': sort_by, param_year: date,'language': lang.tmdb, 'page': 1} new_item = item.clone(title=genre['name'], action='tmdbResults', search=search, mode='') itemlist.append(new_item) itemlist.sort(key=lambda item: item.title) - thumb(itemlist, mode='genre') + support.thumb(itemlist, mode='genre') else: year = datetime.now().year + 3 for i in range(year, 1899, -1): - if item.contentType == 'tvshow': - param_year = 'first_air_date_year' - else: - param_year = 'primary_release_year' + param_year = 'first_air_date_year' if item.contentType == 'tvshow' else 'primary_release_year' search = {'url': 'discover/{}'.format(item.args), param_year: i, 'language': lang.tmdb, 'page': 1} itemlist.append(item.clone(title=str(i), action='tmdbResults', search=search)) return itemlist -def _search(item): - text = platformtools.dialog_input(heading=item.title) - if text: - item.search['query'] = text - return tmdbResults(item) + +########## IMDB ########## + +def imdbMenu(item): + itemlist = [] + if not item.args: + itemlist.extend([item.clone(title=config.get_localized_string(30122), args='movie'), + item.clone(title=config.get_localized_string(30123), args='tvshow'), + item.clone(title=config.get_localized_string(70033), action='imdbResults', args=['actors']), + item.clone(title=config.get_localized_string(70036), action='_search', url='/search/name?name={}', args=['actors']), + item.clone(title=config.get_localized_string(30980), action='_search', url= '/search/title?title={}')]) + else: + item.contentType = item.args + + itemlist.append(item.clone(title=config.get_localized_string(70028), action='imdbResults', args=[item.contentType])) + itemlist.append(item.clone(title=config.get_localized_string(70029), action='imdbResults', args=[item.contentType,'top'])) + if item.contentType == 'movie': + itemlist.extend([item.clone(title=config.get_localized_string(70030), action='imdbResults', args=['cinema']), + item.clone(title=config.get_localized_string(70034), action='imdbResults', args=['soon'])]) + + itemlist.extend([item.clone(title=config.get_localized_string(70032), action='imdbIndex', args='genre'), + item.clone(title=config.get_localized_string(70042), action='imdbIndex', args='year'), + item.clone(title=support.typo(config.get_localized_string(70038),'color kod'), action='filter', db_type='imdb')]) + + return support.thumb(itemlist) + + +def imdbResults(item): + itemlist = [] + + params = {'movie':'/search/title?&title_type=feature,tv_movie', + 'tvshow':'/search/title?&title_type=tv_series,tv_special,mini_series', + 'top':'&num_votes=25000,&sort=user_rating,desc', + 'cinema':'/showtimes/location?ref_=inth_ov_sh_sm', + 'actors': '/search/name?gender=male,female&ref_=nv_cel_m_3', + 'soon': '/movies-coming-soon/?ref_=shlc_cs'} + + if item.search: item.url = imdb_host + params[item.contentType] + '&' + support.urlencode(item.search) + elif not item.url: item.url = imdb_host + ''.join(params[a] for a in item.args) + else: item.url = imdb_host + item.url + if item.prevthumb: item.thumbnail = item.prevthumb + if 'actors' in item.args: + data = support.match(item.url, patron=r'nm\d+[^>]*>\s*([^]+>\s*]*>Next') + return itemlist + + +def imdbIndex(item): + itemlist = [] + params = {'movie':'&title_type=feature,tv_movie', + 'tvshow':'&title_type=tv_series,tv_special,mini_series',} + item.action = 'imdbResults' + url = '/search/title' + if item.args == 'genre': + matches = support.match(imdb_host + url, patronBlock=r'

Genres

(.*?)', patron=r' value="([^"]+)"\s*>\s*([^<]+)<').matches + if matches: + itemlist = [item.clone(title=title, url='{}?genres={}{}'.format(url, value, params[item.contentType]))for value, title in matches] + support.thumb(itemlist, mode='genre') + elif item.args == 'year': + year = datetime.now().year + 3 + for i in range(year, 1899, -1): + itemlist.append(item.clone(title=str(i), url='{}?release_date={}{}'.format(url, i, params[item.contentType]))) + return itemlist + + +########## TRAKT ########## + +def traktMenu(item): + itemlist = [] + token_auth = config.get_setting("token_trakt", "trakt") + if not item.args: + itemlist.extend([item.clone(title=config.get_localized_string(30122), args='movies'), + item.clone(title=config.get_localized_string(30123), args='shows')]) + if token_auth: itemlist.append(item.clone(title=support.typo(config.get_localized_string(70057), 'bold'), action="traktResults", url="/users/me/lists")) + else: itemlist.append(item.clone(title=support.typo(config.get_localized_string(70054), 'bold'), action="traktAuth", folder=False)) + else: + item.contentType = item.args.replace('shows', 'tvshow').replace('movies', 'movie') + item.title = config.get_localized_string(30122 if item.contentType == 'movie' else 30123) + itemlist.extend([item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70049)), action='traktResults', url= item.args + '/popular'), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70050)), action='traktResults', url= item.args + '/trending'), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70053)), action='traktResults', url= item.args + '/watched/all'), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70051)), action='traktResults', url= item.args + '/anticipated')]) + if token_auth: + itemlist.extend([item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70052)), action='traktResults', url='/recommendations/' + item.args), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70055)), action='traktResults', url='/users/me/watchlist/' + item.args), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70056)), action='traktResults', url='/users/me/watched/' + item.args), + item.clone(title='{} [{}]'.format(item.title, config.get_localized_string(70068)), action='traktResults', url='/users/me/collection/' + item.args)]) + return itemlist + + +def traktResults(item): + prepage = config.get_setting('pagination', default=20) + if not item.page: item.page = 1 + if item.itemlist: + itemlist = support.pagination(support.itemlistdb(), item, 'traktResults') + tmdb.set_infoLabels_itemlist(itemlist, True) + return itemlist + + if item.prevthumb: item.thumbnail = item.prevthumb + token_auth = config.get_setting('token_trakt', 'trakt') + itemlist = [] + client_id = trakt_tools.client_id + headers = [['Content-Type', 'application/json'], ['trakt-api-key', client_id], ['trakt-api-version', '2']] + if token_auth: headers.append(['Authorization', 'Bearer {}'.format(token_auth)]) + + post = None + if item.post: post = jsontools.dump(item.post) + + url = '{}{}?page={}&limit=20&extended=full'.format(trakt_tools.host, item.url, item.page) + + data = httptools.downloadpage(url, post=post, headers=headers) + if data.code == '401': + trakt_tools.token_trakt(item.clone(args='renew')) + token_auth = config.get_setting('token_trakt', 'trakt') + headers[3][1] = 'Bearer {}'.format(token_auth) + data = httptools.downloadpage(url, post=post, headers=headers) + + + data = data.json + + if data and 'recommendations' in item.url: + ratings = [] + + for i, entry in enumerate(data): + new_item = item.clone(action='start', + channel='infoplus', + folder=False, + title = entry['title']) + new_item.infoLabels['tmdb_id'] = entry['ids']['tmdb'] + try: ratings.append(entry['rating']) + except: ratings.append(0.0) + itemlist.append(new_item) + + + tmdb.set_infoLabels_itemlist(itemlist, True) + for i, new_item in enumerate(itemlist): + if new_item.infoLabels['title']: new_item.title = new_item.infoLabels['title'] + if len(itemlist) == prepage: + support.nextPage(itemlist, item, 'traktResults', page=item.page + 1) + + + elif data and not item.url.endswith('lists'): + ratings = [] + try: + for entry in data: + logger.debug(jsontools.dump(entry)) + new_item = item.clone(action='start', channel='infoplus', folder=False) + if 'show' in entry: + entry = entry['show'] + new_item.contentType = 'tvshow' + elif 'movie' in entry: + entry = entry['movie'] + new_item.contentType = 'movie' + + new_item.title = entry['title'] + new_item.infoLabels['tmdb_id'] = entry['ids']['tmdb'] + try: ratings.append(entry['rating']) + except: ratings.append('') + itemlist.append(new_item) + + if len(itemlist) > prepage: + itemlist= support.pagination(itemlist, item, 'traktResults') + elif len(itemlist) == prepage: + support.nextPage(itemlist, item, 'traktResults', page=item.page + 1, total_pages=item.total_pages) + + tmdb.set_infoLabels_itemlist(itemlist, True) + for i, new_item in enumerate(itemlist): + if new_item.infoLabels['title']: new_item.title = new_item.infoLabels['title'] + new_item.infoLabels['trakt_rating'] = ratings[i] + + + except: + import traceback + logger.error(traceback.format_exc()) + + else: + for entry in data: + new_item = item.clone() + new_item.title = entry['name'] + support.typo(str(entry['item_count']),'color kod _ []') + new_item.infoLabels['plot'] = entry.get('description') + new_item.url = 'users/me/lists/{}/items/'.format(entry['ids']['trakt']) + new_item.order = entry.get('sort_by') + new_item.how = entry.get('sort_how') + new_item.total_pages = int(entry['item_count'] / prepage) + itemlist.append(new_item) + + return itemlist + + +def traktAuth(item): + return trakt_tools.auth_trakt() -############################################################ def filter(item): - logger.debug() + import xbmcgui + orderTitle = [config.get_localized_string(70456), config.get_localized_string(70457), config.get_localized_string(70458), config.get_localized_string(70459), config.get_localized_string(70460), config.get_localized_string(70461), config.get_localized_string(70462), config.get_localized_string(70462)] + tmdbOrder = ['popularity.desc', 'popularity.asc', 'release_date.desc', 'release_date.asc', 'vote_average.desc', 'vote_average.asc', 'title.asc', 'title.desc'] + imdbOrder = ['moviemeter,asc', 'moviemeter,desc', 'release_date,asc', 'release_date,desc', 'user_rating,asc', 'user_rating,desc', 'alpha,asc', 'alpha,desc'] + defControls = {'year':{'title': config.get_localized_string(60232), 'values': '', 'order':0}, + 'genre':{'title': config.get_localized_string(70032), 'values': '', 'order':1}, + 'rating':{'title': config.get_localized_string(70473), 'values': '', 'order':2}, + 'order': {'title': config.get_localized_string(70455), 'values': orderTitle[0], 'order':3}} - from datetime import datetime - list_controls = [] - valores = {} + controls = dict(sorted(config.get_setting('controls', item.channel, default=defControls).items(), key=lambda k: k[1]['order'])) + class Filter(xbmcgui.WindowXMLDialog): + def start(self, item): + self.item = item + self.controls = controls + self.order = tmdbOrder if item.db_type == 'tmdb' else imdbOrder + self.doModal() + if self.controls and self.controls['order']['values'] == orderTitle[0]: self.controls['order']['values'] = self.order[0] + return self.controls - dict_values = None + def onInit(self): + for n, v in enumerate(self.controls.values()): + title = v['title'] + value = v['values'] + self.getControl(n + 100).setLabel('{}: {}'.format(title, value)) - list_controls.append({'id': 'years', 'label': config.get_localized_string(60232), 'enabled': True, 'type': 'list', 'default': -1, 'visible': True}) - list_controls[0]['lvalues'] = [] - valores['years'] = [] - year = datetime.now().year + 1 - for i in range(1900, year + 1): - list_controls[0]['lvalues'].append(str(i)) - valores['years'].append(str(i)) - list_controls[0]['lvalues'].append(config.get_localized_string(70450)) - valores['years'].append('') + def onClick(self, control): + logger.debug('CONTROL', control) + if control in [100]: # Year + years = [str(i) for i in range(datetime.now().year + 3, 1899, -1)] + selection = platformtools.dialog_select('', years) + self.controls['year']['values'] = years[selection] if selection > -1 else '' + self.getControl(100).setLabel('{}: {}'.format(self.controls['year']['title'], self.controls['year']['values'])) + elif control in [101]: # Genre + genresIds = [] + genresNames = [] + # support.dbg() + if self.item.db_type == 'tmdb': + url = ('{}/genre/{}/list?api_key={}&language={}'.format(tmdb.host, item.args, tmdb.api, langs.tmdb)) + genres = httptools.downloadpage(url).json['genres'] + for genre in genres: + genresNames.append(genre['name']) + genresIds.append(str(genre['id'])) + else: + genres = support.match(imdb_host + '/search/title', patronBlock=r'

Genres

(.*?)', patron=r' value="([^"]+)"\s*>\s*([^<]+)<').matches + for value, genre in genres: + genresNames.append(genre) + genresIds.append(value) + selected = [genresIds.index(i.strip()) for i in self.controls['genre']['values'].split(',') if i] + selections = platformtools.dialog_multiselect('', genresNames, preselect=selected) + self.controls['genre']['values'] = ','.join(genresIds[g] for g in selections) + names= ', '.join(genresNames[g] for g in selections) + self.getControl(101).setLabel('{}: {}'.format(self.controls['genre']['title'], names)) + elif control in [102]: + rating = [str(i) for i in range(1, 11)] + selection = platformtools.dialog_select('', rating, preselect=rating.index(self.controls['rating']['values']) if self.controls['rating']['values'] else 0) + self.controls['rating']['values'] = rating[selection] + self.getControl(102).setLabel('{}: {}'.format(self.controls['rating']['title'], self.controls['rating']['values'])) + elif control in [103]: + selection = platformtools.dialog_select('', orderTitle) + if selection > -1: + self.controls['order']['values'] = self.order[selection] + self.getControl(103).setLabel('{}: {}'.format(self.controls['order']['title'], orderTitle[selection])) - if config.get_localized_string(70038) in item.title: - # Se utilizan los valores por defecto/guardados - saved_values = config.get_setting("default_filter_" + item.args, item.channel) - if saved_values: - dict_values = saved_values - # dbg() - url = '{}/genre/{}/list?api_key={}&language={}'.format(tmdb.host, item.args, tmdb.api, lang.tmdb) - # try: - lista = support.match(url, cookies=False).response.json["genres"] - if lista: - list_controls.append({'id': 'labelgenre', 'enabled': True, 'type': 'label', 'default': None, 'label': config.get_localized_string(70451), 'visible': True}) - for l in lista: - list_controls.append({'id': 'genre' + str(l["id"]), 'label': l["name"], 'enabled': True, 'type': 'bool', 'default': False, 'visible': True}) - # except: - # pass + elif control in [200]: + self.close() - list_controls.append({'id': 'orden', 'label': config.get_localized_string(70455), 'enabled': True, 'type': 'list', 'default': -1, 'visible': True}) - orden = [config.get_localized_string(70456), config.get_localized_string(70457), config.get_localized_string(70458), config.get_localized_string(70459), config.get_localized_string(70460), config.get_localized_string(70461)] - if item.args == "movie": - orden.extend([config.get_localized_string(70462), config.get_localized_string(70463)]) - orden_tmdb = ['popularity.desc', 'popularity.asc', 'release_date.desc', 'release_date.asc', 'vote_average.desc', 'vote_average.asc', 'original_title.asc', 'original_title.desc'] - valores['orden'] = [] - list_controls[-1]['lvalues'] = [] - for i, tipo_orden in enumerate(orden): - list_controls[-1]['lvalues'].insert(0, tipo_orden) - valores['orden'].insert(0, orden_tmdb[i]) + elif control in [201]: + config.set_setting('controls', self.controls, self.item.channel) + platformtools.dialog_notification('TMDB', 'Filtro salvato', time=1000, sound=False) - list_controls.append({'id': 'espacio', 'label': '', 'enabled': False, 'type': 'label', 'default': None, 'visible': True}) - list_controls.append({'id': 'save', 'label': config.get_localized_string(70464), 'enabled': True, 'type': 'bool', 'default': False, 'visible': True}) - else: - list_controls.append({'id': 'keyword', 'label': config.get_localized_string(70465), 'enabled': True, 'type': 'text', 'default': '', 'visible': True}) + elif control in [202]: + config.set_setting('controls', defControls, self.item.channel) + platformtools.dialog_notification('TMDB', 'Filtro eliminato', time=1000, sound=False) + self.controls = None + self.close() + return filter(self.item) - item.valores = valores - return platformtools.show_channel_settings(list_controls=list_controls, dict_values=dict_values, caption=config.get_localized_string(70320), item=item, callback='filtered') + elif control in [203]: + self.controls = None + self.close() -def filtered(item, values): - values_copy = values.copy() - # Save the filter to be the one loaded by default - if "save" in values and values["save"]: - values_copy.pop("save") - config.set_setting("default_filter_" + item.args, values_copy, item.channel) + def onAction(self, action): + action = action.getId() + if action in [10,92]: + self.controls = None + self.close() - year = item.valores["years"][values["years"]] - if config.get_localized_string(70038) in item.title: - orden = item.valores["orden"][values["orden"]] - if item.args == "tv": orden = orden.replace('release_date', 'first_air_date') - genre_ids = [] - for v in values: - if "genre" in v: - if values[v]: genre_ids.append(v.replace('genre', '')) - genre_ids = ",".join(genre_ids) + controls = Filter('Filter.xml', config.get_runtime_path()).start(item) + if controls: + item.search = {'url': 'discover/' + item.args, 'vote_count.gte': 10} if item.db_type == 'tmdb' else {} - if config.get_localized_string(70465).lower() in item.title.lower(): item.search = {'url': 'search/%s' % item.args, 'year': year, 'query': values["keyword"], 'language': lang.tmdb, 'page': 1} - elif item.args == "movie": item.search = {'url': 'discover/%s' % item.args, 'sort_by': orden, 'primary_release_year': year, 'with_genres': genre_ids, 'vote_count.gte': '10', 'language': lang.tmdb, 'page': 1} - else: item.search = {'url': 'discover/%s' % item.args, 'sort_by': orden, 'first_air_date_year': year, 'with_genres': genre_ids, 'vote_count.gte': '10', 'language': lang.tmdb, 'page': 1} + params ={'year':{'tmdb':'first_air_date_year', 'imdb':'year'}, + 'genre':{'tmdb':'with_genres', 'imdb':'genres'}, + 'rating': {'tmdb':'vote_average.gte', 'imdb':'user_rating'}, + 'order': {'tmdb':'sort_by', 'imdb':'sort'}} - item.action = "list_tmdb" - return tmdbResults(item) \ No newline at end of file + for k, v in controls.items(): + k = params[k][item.db_type] + v = v['values'] + if v: + item.search[k] = v + logger.debug(item.search) + return tmdbResults(item) if item.db_type == tmdb else imdbResults(item) diff --git a/specials/videolibrary.py b/specials/videolibrary.py index 9ffc75ea..be2a62df 100644 --- a/specials/videolibrary.py +++ b/specials/videolibrary.py @@ -58,16 +58,17 @@ def list_az(item): else: v = v['item'].infoLabels if 'director' in v: - v = v.get('director').split(',') + v = v.get('director','').split(',') else: - v= v.get('writer').split(',') - cast += [c[0].strip() for c in v] + v= v.get('writer','').split(',') + cast += [c[0].strip() for c in v if c] - az = [] #[c[0] for c in cast if c[0] not in az] + az = [] for c in cast: if c[0] not in az: az.append(c[0]) - return [item.clone(title=i, action=item.next_action) for i in az]#['A','B','C','D','I','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']] + itemlist = [item.clone(title=i, action=item.next_action) for i in az] + return sorted(itemlist, key=lambda it: it.title) def list_genres(item): @@ -81,11 +82,11 @@ def list_genres(item): itemlist = [] for g in genres: g = g.strip() - if g and g not in [it.genre for it in itemlist]: - it = item.clone(title = g, action='list_{}s'.format(item.contentType), genre=g) + if g and g not in [it.list_genre for it in itemlist]: + it = item.clone(title = g, action='list_{}s'.format(item.contentType), list_genre=g) itemlist.append(it) - itemlist.sort(key=lambda it: it.genre) + itemlist.sort(key=lambda it: it.list_genre) thumb(itemlist, True) return itemlist @@ -116,11 +117,11 @@ def list_directors(item): itemlist = [] for i, d in enumerate(directors): d = d.strip() - if d and d[0][0] == item.title and d not in [it.director for it in itemlist]: - it = item.clone(title = d, action='list_{}s'.format(item.contentType), director=d, thumbnail=director_images[i] if len(director_images) > i else '') + if d and d[0][0] == item.title and d not in [it.list_director for it in itemlist]: + it = item.clone(title = d, action='list_{}s'.format(item.contentType), list_director=d, thumbnail=director_images[i] if len(director_images) > i else filetools.join(config.get_runtime_path(), 'resources','skins','Default','media','Infoplus','no_photo.png')) itemlist.append(it) - itemlist.sort(key=lambda it: it.director) + itemlist.sort(key=lambda it: it.list_director) return itemlist @@ -132,11 +133,11 @@ def list_years(item): itemlist = [] for y in years: - if y and y not in [it.year for it in itemlist]: - it = item.clone(title = str(y), action='list_{}s'.format(item.contentType), year=y) + if y and y not in [it.list_year for it in itemlist]: + it = item.clone(title = str(y), action='list_{}s'.format(item.contentType), list_year=y) itemlist.append(it) - itemlist.sort(key=lambda it: it.year, reverse=True) + itemlist.sort(key=lambda it: it.list_year, reverse=True) return itemlist @@ -148,11 +149,11 @@ def list_ratings(item): itemlist = [] for r in ratings: - if r and r not in [it.rating for it in itemlist]: - it = item.clone(title = str(r), action='list_{}s'.format(item.contentType), rating=r) + if r and r not in [it.list_rating for it in itemlist]: + it = item.clone(title = str(r), action='list_{}s'.format(item.contentType), list_rating=r) itemlist.append(it) - itemlist.sort(key=lambda it: it.rating, reverse=True) + itemlist.sort(key=lambda it: it.list_rating, reverse=True) return itemlist @@ -166,11 +167,11 @@ def list_actors(item): itemlist = [] for a in actors: - if a and a[0][0] == item.title and a[0] not in [it.initial for it in itemlist]: - it = item.clone(title = a[0], action='list_{}s'.format(item.contentType), initial=a[0], thumbnail=a[1]) + if a and a[0][0] == item.title and a[0] not in [it.list_actor for it in itemlist]: + it = item.clone(title = a[0], action='list_{}s'.format(item.contentType), list_actor=a[0], thumbnail=a[1] if a[1] else filetools.join(config.get_runtime_path(), 'resources','skins','Default','media','Infoplus','no_photo.png')) itemlist.append(it) - itemlist.sort(key=lambda it: it.actor) + itemlist.sort(key=lambda it: it.list_actor) return itemlist @@ -186,12 +187,11 @@ def list_movies(item, silent=False): logger.debug() videos = dict(videolibrarydb['movie']).values() - - if item.year: itemlist = [v['item'] for v in videos if item.year == v['item'].infoLabels['year']] - elif item.rating: itemlist = [v['item'] for v in videos if item.rating == int(float(v['item'].infoLabels['rating']))] - elif item.genre: itemlist = [v['item'] for v in videos if item.genre in v['item'].infoLabels['genre']] - elif item.actor: itemlist = [v['item'] for v in videos if item.actor in str(v['item'].infoLabels['castandrole'])] - elif item.director: itemlist = [v['item'] for v in videos if item.actor in v['item'].infoLabels['director']] + if item.list_year: itemlist = [v['item'] for v in videos if item.list_year == v['item'].infoLabels['year']] + elif item.list_rating: itemlist = [v['item'] for v in videos if item.list_rating == int(float(v['item'].infoLabels['rating']))] + elif item.list_genre: itemlist = [v['item'] for v in videos if item.list_genre in v['item'].infoLabels['genre']] + elif item.list_actor: itemlist = [v['item'] for v in videos if item.list_actor in str(v['item'].infoLabels['castandrole'])] + elif item.list_director: itemlist = [v['item'] for v in videos if item.list_director in v['item'].infoLabels['director']] elif item.set: itemlist = [v['item'] for v in videos if item.set == v['item'].infoLabels.get('setid', '')] elif config.get_setting('collection') and not item.text: itemlist = [v['item'] for v in videos if (item.text.lower() in v['item'].title.lower() and not 'setid' in v['item'].infoLabels)] + [v for v in dict(videolibrarydb['collection']).values()] else: itemlist = [v['item'] for v in videos if item.text.lower() in v['item'].title.lower()] @@ -212,11 +212,11 @@ def list_tvshows(item): videos = dict(videolibrarydb['tvshow']).values() - if item.year: series = [v['item'] for v in videos if item.year == v['item'].infoLabels['year']] - elif item.rating: series = [v['item'] for v in videos if item.rating == int(float(v['item'].infoLabels['rating']))] - elif item.genre: series = [v['item'] for v in videos if item.genre in v['item'].infoLabels['genre']] - elif item.actor: series = [v['item'] for v in videos if item.actor in str(v['item'].infoLabels['castandrole'])] - elif item.director: series = [v['item'] for v in videos if item.actor in v['item'].infoLabels['director']] + if item.list_year: series = [v['item'] for v in videos if item.list_year == v['item'].infoLabels['year']] + elif item.list_rating: series = [v['item'] for v in videos if item.list_rating == int(float(v['item'].infoLabels['rating']))] + elif item.list_genre: series = [v['item'] for v in videos if item.list_genre in v['item'].infoLabels['genre']] + elif item.list_actor: series = [v['item'] for v in videos if item.list_actor in str(v['item'].infoLabels['castandrole'])] + elif item.list_director: series = [v['item'] for v in videos if item.list_director in v['item'].infoLabels['director'] or item.list_director in v['item'].infoLabels['writer']] else: series = [v['item'] for v in videos if item.text.lower() in v['item'].title.lower()] def sub_thread(it): @@ -936,7 +936,6 @@ class subcontext(object): index = xbmcgui.Dialog().contextmenu(self.context) if index >= 0: xbmc.executebuiltin('RunPlugin({}?{})'.format(sys.argv[0], self.commands[index].tourl())) - class set_images(object): def __init__(self, item): self.item = item @@ -1045,6 +1044,7 @@ def add_download_items(item, itemlist): #-------------- DELETE -------------- def delete(item): + # support.dbg() from platformcode import xbmc_videolibrary select = None delete = None @@ -1109,44 +1109,44 @@ def delete(item): else: platformtools.itemlist_refresh(-1) - # delete channel from video item - if select and select > 0: - channel_name = channels[select - 1] + # delete channel from video item + if select and select > 0: + channel_name = channels[select - 1] - if item.contentType != 'movie': - episodes = videolibrarydb['episode'][item.videolibrary_id] - seasons = videolibrarydb['season'][item.videolibrary_id] - episodes_dict = dict(episodes) - seasons_dict = dict(seasons) + if item.contentType != 'movie': + episodes = videolibrarydb['episode'][item.videolibrary_id] + seasons = videolibrarydb['season'][item.videolibrary_id] + episodes_dict = dict(episodes) + seasons_dict = dict(seasons) - # delete episodes if they have no channels - for key, episode in episodes_dict.items(): - if len(episode['channels']) > 1 and channel_name in episode['channels']: - del episode['channels'][channel_name] - elif channel_name in episode['channels']: - xbmc_videolibrary.clean_by_id(episodes[key]['item']) - del episodes[key] + # delete episodes if they have no channels + for key, episode in episodes_dict.items(): + if len(episode['channels']) > 1 and channel_name in episode['channels']: + del episode['channels'][channel_name] + elif channel_name in episode['channels']: + xbmc_videolibrary.clean_by_id(episodes[key]['item']) + del episodes[key] - videolibrarydb['episode'][item.videolibrary_id] = episodes - seasons_list = [] + videolibrarydb['episode'][item.videolibrary_id] = episodes + seasons_list = [] - # delete seasons if they have no channels - for episode in episodes: - season = int(episode.split('x')[0]) - if season not in seasons_list: - seasons_list.append(season) + # delete seasons if they have no channels + for episode in episodes: + season = int(episode.split('x')[0]) + if season not in seasons_list: + seasons_list.append(season) - for season in seasons_dict.keys(): - if season not in seasons_list: - xbmc_videolibrary.clean_by_id(seasons[season]) - del seasons[season] - videolibrarydb['season'][item.videolibrary_id] = seasons + for season in seasons_dict.keys(): + if season not in seasons_list: + xbmc_videolibrary.clean_by_id(seasons[season]) + del seasons[season] + videolibrarydb['season'][item.videolibrary_id] = seasons - channel = videolibrarydb[item.contentType][item.videolibrary_id] - channels = channel['channels'] - del channels[channel_name] - channel['channels'] = channels - videolibrarydb[item.contentType][item.videolibrary_id] = channel + channel = videolibrarydb[item.contentType][item.videolibrary_id] + channels = channel['channels'] + del channels[channel_name] + channel['channels'] = channels + videolibrarydb[item.contentType][item.videolibrary_id] = channel videolibrarydb.close() @@ -1360,41 +1360,6 @@ def get_results(nfo_path, root, Type, local=False): else: item = Item() return item, value -# def add_local_episodes(item): -# logger.debug() - -# done, local_episodes_path = videolibrarytools.config_local_episodes_path(item.path, item, silent=True) -# if done < 0: -# logger.debug('An issue has occurred while configuring local episodes') -# elif local_episodes_path: -# nfo_path = filetools.join(item.path, 'tvshow.nfo') -# head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path) -# item_nfo.local_episodes_path = local_episodes_path -# if not item_nfo.active: -# item_nfo.active = 1 -# filetools.write(nfo_path, head_nfo + item_nfo.tojson()) - -# update_tvshow(item) - -# platformtools.itemlist_refresh() - - -# def remove_local_episodes(item): -# logger.debug() - -# nfo_path = filetools.join(item.path, 'tvshow.nfo') -# head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path) - -# for season_episode in item_nfo.local_episodes_list: -# filetools.remove(filetools.join(item.path, season_episode + '.strm')) - -# item_nfo.local_episodes_list = [] -# item_nfo.local_episodes_path = '' -# filetools.write(nfo_path, head_nfo + item_nfo.tojson()) - -# update_tvshow(item) - -# platformtools.itemlist_refresh() def convert_videolibrary(item): videolibrarytools.convert_videolibrary()