diff --git a/channels/animealtadefinizione.py b/channels/animealtadefinizione.py index f78a9abe..0a64bdc6 100644 --- a/channels/animealtadefinizione.py +++ b/channels/animealtadefinizione.py @@ -85,7 +85,7 @@ def peliculas(item): typeContentDict = {'movie':['movie']} typeActionDict = {'findvideos':['movie']} - def ItemItemlistHook(item, itemlist): + def itemlistHook(itemlist): if item.search: itemlist = [ it for it in itemlist if ' Episodio ' not in it.title ] if len(itemlist) == int(perpage): diff --git a/channels/animeuniverse.py b/channels/animeuniverse.py index 40c34dcf..e872ec01 100644 --- a/channels/animeuniverse.py +++ b/channels/animeuniverse.py @@ -84,12 +84,12 @@ def peliculas(item): if not item.pag: item.pag = 1 anime=True - blacklist=['Altri Hentai'] + # blacklist=['Altri Hentai'] data = support.match(host + '/wp-content/themes/animeuniverse/functions/ajax.php', post='sorter=recent&location=&loop=main+loop&action=sort&numarticles='+perpage+'&paginated='+str(item.pag)+'¤tquery%5B'+query+'%5D='+searchtext+'&thumbnail=1').data.replace('\\','') patron=r']+>\s*(?P[A-Za-z0-9]+)\s*<span.[^>]+>(?P<other>.*?)</ul>' - def ItemItemlistHook(item, itemlist): + def itemlistHook(itemlist): itemlist.insert(0, item.clone(title=support.typo('Tutti','bold'), action='peliculas')) itemlist.append(item.clone(title=support.typo('Cerca...','bold'), action='search', search=True, thumbnail=support.thumb('search.png'))) return itemlist @@ -174,7 +174,7 @@ def peliculas(item): @support.scrape def episodios(item): anime=True - pagination = 50 + pagination = 25 # data = get_data(item) patronBlock= r'<div class="server\s*active\s*"(?P<block>.*?)(?:<div class="server|<link)' patron = r'<li[^>]*>\s*<a.*?href="(?P<url>[^"]+)"[^>]*>(?P<episode>[^<]+)<' diff --git a/channels/paramount.py b/channels/paramount.py index 6a91cf5d..024618cf 100644 --- a/channels/paramount.py +++ b/channels/paramount.py @@ -73,27 +73,28 @@ def peliculas(item): pagination = pagination_values[support.config.get_setting('pagination','paramount')] item.url = host + '/api/search?activeTab=' + Type + '&searchFilter=site&pageNumber=0&rowsPerPage=10000' data = jsontools.load(support.match(item).data)['response']['items'] - + titles = [] for it in data: title = it['meta']['header']['title'] - support.info(title, it) - d = it['meta']['date'].split('/') if it['meta']['date'] else ['0000','00','00'] - date = int(d[2] + d[1] + d[0]) - if item.search.lower() in title.lower() \ - and 'stagione' not in it['url'] \ - and 'season' not in it['url'] \ - and title not in ['Serie TV']: - itemlist.append( - item.clone(title=support.typo(title,'bold'), - action=action, - fulltitle=title, - show=title, - contentTitle=title if it['type'] == 'movie' else '', - contentSerieName=title if it['type'] != 'movie' else '', - plot= it['meta']['description'] if 'description' in it['meta'] else '', - url=host + it['url'], - date=date, - thumbnail='https:' + it['media']['image']['url'] if 'url' in it['media']['image'] else item.thumbnail)) + if title not in titles: + titles.append(title) + d = it['meta']['date'].split('/') if it['meta']['date'] else ['0000','00','00'] + date = int(d[2] + d[1] + d[0]) + if item.search.lower() in title.lower() \ + and 'stagione' not in it['url'] \ + and 'season' not in it['url'] \ + and title not in ['Serie TV']: + itemlist.append( + item.clone(title=support.typo(title,'bold'), + action=action, + fulltitle=title, + show=title, + contentTitle=title if it['type'] == 'movie' else '', + contentSerieName=title if it['type'] != 'movie' else '', + plot= it['meta']['description'] if 'description' in it['meta'] else '', + url=host + it['url'], + date=date, + thumbnail='https:' + it['media']['image']['url'] if 'url' in it['media']['image'] else item.thumbnail)) itemlist.sort(key=lambda item: item.fulltitle) if not item.search: itlist = [] diff --git a/core/scraper.py b/core/scraper.py index 2515a77d..81050a9a 100644 --- a/core/scraper.py +++ b/core/scraper.py @@ -54,70 +54,20 @@ def find_and_set_infoLabels(item): import traceback logger.error(traceback.format_exc()) - while scraper: - # We call the find_and_set_infoLabels function of the selected scraper - scraper_result = scraper.find_and_set_infoLabels(item) - - # Check if there is a 'code' - if scraper_result and item.infoLabels['code']: - # correct code - logger.info("Identificador encontrado: %s" % item.infoLabels['code']) - scraper.completar_codigos(item) - return True - elif scraper_result: - # Content found but no 'code' - msg = config.get_localized_string(60227) % title - else: - # Content not found - msg = config.get_localized_string(60228) % title - - logger.info(msg) - # Show box with other options: - if scrapers_disponibles[scraper_actual] in list_opciones_cuadro: - list_opciones_cuadro.remove(scrapers_disponibles[scraper_actual]) - index = platformtools.dialog_select(msg, list_opciones_cuadro) - - if index < 0: - logger.debug("You have clicked 'cancel' in the window '%s'" % msg) - return False - - elif index == 0: - # Ask the title - title = platformtools.dialog_input(title, config.get_localized_string(60229) % tipo_contenido) - if title: - if item.contentType == "movie": - item.contentTitle = title - else: - item.contentSerieName = title - else: - logger.debug("I clicked 'cancel' in the window 'Enter the correct name'") - return False - - elif index == 1: - # You have to create a dialog box to enter the data - logger.info("Complete information") - if cuadro_completar(item): - # correct code - logger.info("Identifier found: %s" % str(item.infoLabels['code'])) - return True - # raise - - elif list_opciones_cuadro[index] in list(scrapers_disponibles.values()): - # Get the name of the scraper module - for k, v in list(scrapers_disponibles.items()): - if list_opciones_cuadro[index] == v: - if scrapers_disponibles[scraper_actual] not in list_opciones_cuadro: - list_opciones_cuadro.append(scrapers_disponibles[scraper_actual]) - # We import the scraper k - scraper_actual = k - try: - scraper = None - scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual]) - except ImportError: - exec("import core." + scraper_actual + " as scraper_module") - break - - logger.error("Error importing the scraper module %s" % scraper_actual) + # while scraper: + # We call the find_and_set_infoLabels function of the selected scraper + scraper_result = scraper.find_and_set_infoLabels(item) + # from core.support import dbg; dbg() + # Check if there is a 'code' + if scraper_result and item.infoLabels['code']: + # correct code + logger.info("Identifier found: %s " % item.infoLabels['code']) + scraper.completar_codigos(item) + return True + else: + # Content not found + logger.info(logger.info("Identifier not found for: %s " % title)) + return def cuadro_completar(item): diff --git a/core/support.py b/core/support.py index 84e95746..e610c11f 100755 --- a/core/support.py +++ b/core/support.py @@ -351,7 +351,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t quality=quality, url=scraped["url"], infoLabels=infolabels, - thumbnail=item.thumbnail if not scraped["thumb"] else scraped["thumb"], + thumbnail=item.prevthumb if item.prevthumb else item.thumbnail if not scraped["thumb"] else scraped["thumb"], args=item.args, contentSerieName= title if 'movie' not in [contentType] and function != 'episodios' else item.contentSerieName, contentTitle= title if 'movie' in [contentType] and function == 'peliculas' else item.contentTitle, @@ -473,9 +473,6 @@ def scrape(func): if 'itemlistHook' in args: itemlist = args['itemlistHook'](itemlist) - if 'ItemItemlistHook' in args: - itemlist = args['ItemItemlistHook'](item, itemlist) - # if url may be changed and channel has findhost to update if 'findhost' in func.__globals__ and not itemlist: info('running findhost ' + func.__module__) @@ -511,20 +508,23 @@ def scrape(func): url=item.url, args=item.args, page=pag + 1, - thumbnail=thumb())) + thumbnail=thumb(), + prevthumb=item.prevthumb if item.prevthumb else item.thumbnail)) - if anime: + if anime and inspect.stack()[1][3] not in ['find_episodes']: from platformcode import autorenumber - if function == 'episodios' or item.action == 'episodios': autorenumber.renumber(itemlist, item, 'bold') - else: autorenumber.renumber(itemlist) + if (function == 'episodios' or item.action == 'episodios'): autorenumber.start(itemlist, item) + else: autorenumber.start(itemlist) # if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'): # pass # else: - if addVideolibrary and (item.infoLabels["title"] or item.fulltitle): - # item.fulltitle = item.infoLabels["title"] - videolibrary(itemlist, item, function=function) - if function == 'episodios' or function == 'findvideos': - download(itemlist, item, function=function) + if inspect.stack()[1][3] not in ['find_episodes']: + if addVideolibrary and (item.infoLabels["title"] or item.fulltitle): + # item.fulltitle = item.infoLabels["title"] + videolibrary(itemlist, item, function=function) + if function == 'episodios' or function == 'findvideos': + download(itemlist, item, function=function) + if 'patronMenu' in args and itemlist: itemlist = thumb(itemlist, genre=True) diff --git a/core/tmdb.py b/core/tmdb.py index b17ff3f2..b31a6e28 100644 --- a/core/tmdb.py +++ b/core/tmdb.py @@ -528,6 +528,9 @@ def find_and_set_infoLabels(item): if len(results) > 1: from platformcode import platformtools tmdb_result = platformtools.show_video_info(results, item=item, caption= tipo_contenido % title) + if not tmdb_result: + res = platformtools.dialog_info(item, 'tmdb') + if res: return find_and_set_infoLabels(res) elif len(results) > 0: tmdb_result = results[0] diff --git a/core/tvdb.py b/core/tvdb.py index 674125a8..cb435137 100644 --- a/core/tvdb.py +++ b/core/tvdb.py @@ -89,7 +89,7 @@ def find_and_set_infoLabels(item): title = item.contentSerieName # If the title includes the (year) we will remove it - year = scrapertools.find_single_match(title, "^.+?\s*(\(\d{4}\))$") + year = scrapertools.find_single_match(title, r"^.+?\s*(\(\d{4}\))$") if year: title = title.replace(year, "").strip() item.infoLabels['year'] = year[1:-1] @@ -114,6 +114,9 @@ def find_and_set_infoLabels(item): if len(results) > 1: tvdb_result = platformtools.show_video_info(results, item=item, scraper=Tvdb, caption=config.get_localized_string(60298) % title) + if not tvdb_result: + res = platformtools.dialog_info(item, 'tvdb') + if res: return find_and_set_infoLabels(res) elif len(results) > 0: tvdb_result = results[0] @@ -398,19 +401,13 @@ class Tvdb(object): else: params = jsontools.dump(params) try: - req = urllib.request.Request(url, data=params, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() + dict_html = requests.post(url, data=params, headers=DEFAULT_HEADERS).json() except Exception as ex: message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) logger.error("error: %s" % message) else: - dict_html = jsontools.load(html) - # logger.debug("dict_html %s" % dict_html) - if "token" in dict_html: token = dict_html["token"] DEFAULT_HEADERS["Authorization"] = "Bearer " + token @@ -424,17 +421,14 @@ class Tvdb(object): is_success = False url = HOST + "/refresh_token" - try: - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() + req = requests.get(url, headers=DEFAULT_HEADERS) - except urllib.error.HTTPError as err: - logger.error("err.code %s" % err.code) + + except req as err: + logger.error("err.code %s" % err.status_code) # if there is error 401 it is that the token has passed the time and we have to call login again - if err.code == 401: + if err.status_code == 401: cls.__login() else: raise @@ -444,13 +438,15 @@ class Tvdb(object): logger.error("error: %s" % message) else: - dict_html = jsontools.load(html) + dict_html = req.json() # logger.error("tokencito %s" % dict_html) if "token" in dict_html: token = dict_html["token"] DEFAULT_HEADERS["Authorization"] = "Bearer " + token TOKEN = config.set_setting("tvdb_token", token) is_success = True + else: + cls.__login() return is_success @@ -531,18 +527,16 @@ class Tvdb(object): DEFAULT_HEADERS["Accept-Language"] = lang logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() + req = requests.get(url, headers=DEFAULT_HEADERS) except Exception as ex: message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) logger.error("error: %s" % message) else: - dict_html = jsontools.load(html) - + dict_html = req.json() + if 'Error' in dict_html: + logger.debug("code %s " % dict_html['Error']) if "data" in dict_html and "id" in dict_html["data"][0]: self.get_episode_by_id(dict_html["data"][0]["id"], lang) return dict_html["data"] @@ -590,25 +584,12 @@ class Tvdb(object): """ logger.info() - try: - url = HOST + "/series/%s/episodes?page=%s" % (_id, page) - logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() - - except Exception as ex: - message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) - logger.error("error: %s" % message) - - else: - self.list_episodes[page] = jsontools.load(html) - - # logger.info("dict_html %s" % self.list_episodes) - - return self.list_episodes[page] + url = HOST + "/series/%s/episodes?page=%s" % (_id, page) + logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) + js = requests.get(url, headers=DEFAULT_HEADERS).json() + self.list_episodes[page] = js if 'Error' not in js else {} + return self.list_episodes[page] def get_episode_by_id(self, _id, lang=DEFAULT_LANG, semaforo=None): """ @@ -681,24 +662,17 @@ class Tvdb(object): try: DEFAULT_HEADERS["Accept-Language"] = lang logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() + dict_html = requests.get(url, headers=DEFAULT_HEADERS).json except Exception as ex: # if isinstance(ex, urllib).HTTPError: - logger.debug("code %s " % ex.code) - + logger.debug("code %s " % ex) message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) logger.error("error en: %s" % message) else: - dict_html = jsontools.load(html) - dict_html = dict_html.pop("data") - - logger.info("dict_html %s" % dict_html) - self.episodes[_id] = dict_html + # logger.info("dict_html %s" % dict_html) + self.episodes[_id] = dict_html.pop("data") if 'Error' not in dict_html else {} if semaforo: semaforo.release() @@ -730,37 +704,28 @@ class Tvdb(object): """ logger.info() - try: + params = {} + if name: + params["name"] = name + elif imdb_id: + params["imdbId"] = imdb_id + elif zap2it_id: + params["zap2itId"] = zap2it_id - params = {} - if name: - params["name"] = name - elif imdb_id: - params["imdbId"] = imdb_id - elif zap2it_id: - params["zap2itId"] = zap2it_id + params = urllib.parse.urlencode(params) - params = urllib.parse.urlencode(params) + DEFAULT_HEADERS["Accept-Language"] = lang + url = HOST + "/search/series?%s" % params + logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - DEFAULT_HEADERS["Accept-Language"] = lang - url = HOST + "/search/series?%s" % params - logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) + dict_html = requests.get(url, headers=DEFAULT_HEADERS).json() - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - logger.info(html) - response.close() - except Exception as ex: + if 'Error' in dict_html: # if isinstance(ex, urllib.parse).HTTPError: - logger.debug("code %s " % ex.code) - - message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) - logger.error("error: %s" % message) + logger.debug("code %s " % dict_html['Error']) else: - dict_html = jsontools.load(html) if "errors" in dict_html and "invalidLanguage" in dict_html["errors"]: # no hay información en idioma por defecto @@ -834,13 +799,9 @@ class Tvdb(object): try: DEFAULT_HEADERS["Accept-Language"] = lang - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) + req = requests.get(url, headers=DEFAULT_HEADERS) logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - response = urllib.request.urlopen(req) - html = response.read() - response.close() - except Exception as ex: # if isinstance(ex, urllib).HTTPError: logger.debug("code %s " % ex) @@ -849,26 +810,24 @@ class Tvdb(object): logger.error("error: %s" % message) else: - dict_html = jsontools.load(html) - + dict_html = req.json() if "errors" in dict_html and "invalidLanguage" in dict_html["errors"]: return {} - else: - resultado1 = dict_html["data"] - if not resultado1 and from_get_list: - return self.__get_by_id(_id, "en") + resultado1 = dict_html["data"] + if not resultado1 and from_get_list: + return self.__get_by_id(_id, "en") - logger.debug("Result %s" % dict_html) - resultado2 = {"image_poster": [{'keyType': 'poster', 'fileName': 'posters/%s-1.jpg' % _id}]} - resultado3 = {"image_fanart": [{'keyType': 'fanart', 'fileName': 'fanart/original/%s-1.jpg' % _id}]} + logger.debug("Result %s" % dict_html) + resultado2 = {"image_poster": [{'keyType': 'poster', 'fileName': 'posters/%s-1.jpg' % _id}]} + resultado3 = {"image_fanart": [{'keyType': 'fanart', 'fileName': 'fanart/original/%s-1.jpg' % _id}]} - resultado = resultado1.copy() - resultado.update(resultado2) - resultado.update(resultado3) + resultado = resultado1.copy() + resultado.update(resultado2) + resultado.update(resultado3) - logger.debug("total result %s" % resultado) - self.list_results = [resultado] - self.result = resultado + logger.debug("total result %s" % resultado) + self.list_results = [resultado] + self.result = resultado return resultado @@ -909,24 +868,26 @@ class Tvdb(object): url = HOST + "/series/%s/images/query?%s" % (_id, params) logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() + res = requests.get(url, headers=DEFAULT_HEADERS) except Exception as ex: + # if isinstance(ex, urllib).HTTPError: + logger.debug("code %s " % ex) + message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) logger.error("error: %s" % message) - return {} else: - dict_html = jsontools.load(html) + dict_html = res.json() + if 'Error' in dict_html: + # if isinstance(ex, urllib.parse).HTTPError: + logger.debug("code %s " % dict_html['Error']) + else: + dict_html["image_" + image] = dict_html.pop("data") + self.result.update(dict_html) - dict_html["image_" + image] = dict_html.pop("data") - self.result.update(dict_html) - - return dict_html + return dict_html def get_tvshow_cast(self, _id, lang=DEFAULT_LANG): """ @@ -943,15 +904,18 @@ class Tvdb(object): url = HOST + "/series/%s/actors" % _id DEFAULT_HEADERS["Accept-Language"] = lang logger.debug("url: %s, \nheaders: %s" % (url, DEFAULT_HEADERS)) - - req = urllib.request.Request(url, headers=DEFAULT_HEADERS) - response = urllib.request.urlopen(req) - html = response.read() - response.close() - - dict_html = jsontools.load(html) - - dict_html["cast"] = dict_html.pop("data") + try: + req = requests.get(url, headers=DEFAULT_HEADERS) + except Exception as ex: + logger.debug("code %s " % ex) + message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) + logger.error("error en: %s" % message) + else: + dict_html = req.json() + if 'Error' in dict_html: + logger.debug("code %s " % dict_html['Error']) + else: + dict_html["cast"] = dict_html.pop("data") self.result.update(dict_html) def get_id(self): @@ -1034,12 +998,12 @@ class Tvdb(object): if 'data' in thumbs: ret_infoLabels['thumbnail'] = HOST_IMAGE + thumbs['data'][0]['fileName'] elif 'poster' in origen and origen['poster']: - ret_infoLabels['thumbnail'] = origen['poster'] + ret_infoLabels['thumbnail'] = HOST_IMAGE + origen['poster'] fanarts = requests.get(HOST + '/series/' + str(origen['id']) + '/images/query?keyType=fanart').json() if 'data' in fanarts: ret_infoLabels['fanart'] = HOST_IMAGE + fanarts['data'][0]['fileName'] elif 'fanart' in origen and origen['fanart']: - ret_infoLabels['thumbnail'] = origen['fanart'] + ret_infoLabels['fanart'] = HOST_IMAGE + origen['fanart'] if 'overview' in origen and origen['overview']: ret_infoLabels['plot'] = origen['overview'] if 'duration' in origen and origen['duration']: diff --git a/core/videolibrarytools.py b/core/videolibrarytools.py index 9eb647a1..0e195c51 100644 --- a/core/videolibrarytools.py +++ b/core/videolibrarytools.py @@ -1000,17 +1000,17 @@ def add_movie(item): item = generictools.update_title(item) # We call the method that updates the title with tmdb.find_and_set_infoLabels #if item.tmdb_stat: # del item.tmdb_stat # We clean the status so that it is not recorded in the Video Library + if item: + new_item = item.clone(action="findvideos") + insertados, sobreescritos, fallidos, path = save_movie(new_item) - new_item = item.clone(action="findvideos") - insertados, sobreescritos, fallidos, path = save_movie(new_item) - - if fallidos == 0: - platformtools.dialog_ok(config.get_localized_string(30131), - config.get_localized_string(30135) % new_item.contentTitle) # 'has been added to the video library' - else: - filetools.rmdirtree(path) - platformtools.dialog_ok(config.get_localized_string(30131), - config.get_localized_string(60066) % new_item.contentTitle) # "ERROR, the movie has NOT been added to the video library") + if fallidos == 0: + platformtools.dialog_ok(config.get_localized_string(30131), + config.get_localized_string(30135) % new_item.contentTitle) # 'has been added to the video library' + else: + filetools.rmdirtree(path) + platformtools.dialog_ok(config.get_localized_string(30131), + config.get_localized_string(60066) % new_item.contentTitle) # "ERROR, the movie has NOT been added to the video library") def add_tvshow(item, channel=None): @@ -1071,16 +1071,19 @@ def add_tvshow(item, channel=None): # del item.tmdb_stat # We clean the status so that it is not recorded in the Video Library # Get the episode list + # from core.support import dbg;dbg() itemlist = getattr(channel, item.action)(item) if itemlist and not scrapertools.find_single_match(itemlist[0].title, r'(\d+x\d+)'): - from platformcode.autorenumber import select_type, renumber, check + from platformcode.autorenumber import start, check if not check(item): action = item.action - select_type(item) + item.renumber = True + start(item) + item.renumber = False item.action = action return add_tvshow(item, channel) else: - itemlist = renumber(itemlist) + itemlist = getattr(channel, item.action)(item) global magnet_caching magnet_caching = False diff --git a/platformcode/autorenumber.py b/platformcode/autorenumber.py index 40600842..1d20c9df 100644 --- a/platformcode/autorenumber.py +++ b/platformcode/autorenumber.py @@ -1,551 +1,40 @@ # -*- coding: utf-8 -*- # -------------------------------------------------------------------------------- -# autorenumber - Rinomina Automaticamente gli Episodi +# autorenumber - Rinumera Automaticamente gli Episodi # -------------------------------------------------------------------------------- -''' -USO: -1) utilizzare autorenumber.renumber(itemlist) nelle le funzioni peliculas e similari per aggiungere il menu contestuale -2) utilizzare autorenumber.renumber(itemlist, item, typography) nella funzione episodios -3) Aggiungere le seguinti stringhe nel json del canale (per attivare la configurazione di autonumerazione del canale) -{ - "id": "autorenumber", - "type": "bool", - "label": "@70712", - "default": false, - "enabled": true, - "visible": true -}, -{ - "id": "autorenumber_mode", - "type": "bool", - "label": "@70688", - "default": false, - "enabled": true, - "visible": "eq(-1,true)" -} -''' - -try: - import xbmcgui -except: - xbmcgui = None -import re, base64, json, inspect +import xbmcgui, re, base64, inspect, sys from core import jsontools, tvdb, scrapertools, filetools -from core.support import typo +from core.item import Item +from core.support import typo, match, dbg, Item from platformcode import config, platformtools, logger -TAG_TVSHOW_RENUMERATE = "TVSHOW_AUTORENUMBER" -TAG_ID = "ID" -TAG_SEASON = "Season" -TAG_EPISODE = "Episode" -TAG_SPECIAL = "Special" -TAG_MODE = "Mode" -TAG_EPLIST = "EpList" -TAG_CHECK = "ReCheck" -TAG_SPLIST = "SpList" -TAG_TYPE = "Type" - - -def renumber(itemlist, item='', typography=''): - logger.info() - dict_series = load(itemlist[0]) if len(itemlist) > 0 else {} - - if item: - item.channel = item.from_channel if item.from_channel else item.channel - title = item.fulltitle.rstrip() - try: - already_renumbered = scrapertools.find_single_match(itemlist[0].title, r'(\d+\D\d+)') - except: - return - if already_renumbered : - return itemlist - elif item.channel in item.channel_prefs and TAG_TVSHOW_RENUMERATE in item.channel_prefs[item.channel] and title not in dict_series: - from core.videolibrarytools import check_renumber_options - from specials.videolibrary import update_videolibrary - check_renumber_options(item) - update_videolibrary(item) - - elif inspect.stack()[2][3] == 'find_episodes': - return itemlist - - elif title in dict_series and TAG_ID in dict_series[title]: - ID = dict_series[title][TAG_ID] - Episode = dict_series[title][TAG_EPISODE] - Season = dict_series[title][TAG_SEASON] if TAG_SEASON in dict_series[title] else '' - Mode = dict_series[title][TAG_MODE] if TAG_MODE in dict_series[title] else False - Type = dict_series[title][TAG_TYPE] if TAG_TYPE in dict_series[title] else 'auto' - - renumeration(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title, Type) - - else: - if config.get_setting('autorenumber', item.channel): - config_item(item, itemlist, typography, True) - else: - return itemlist - - else: - for item in itemlist: - title = item.fulltitle.rstrip() - if title in dict_series and TAG_ID in dict_series[title]: - ID = dict_series[title][TAG_ID] - exist = True - else: - exist = False - - if item.contentType != 'movie': - if item.context: - context2 = item.context - item.show = item.fulltitle = title - item.context = context(exist) + context2 - else: - item.show = item.fulltitle = title - item.context = context(exist) - - -def config_item(item, itemlist=[], typography='', active=False): - logger.info() - # Configurazione Automatica, Tenta la numerazione Automatica degli episodi - title = item.fulltitle.rstrip() - - dict_series = load(item) - ID = dict_series[title][TAG_ID] if title in dict_series and TAG_ID in dict_series[title] else '' - - # Pulizia del Titolo - if any( word in title.lower() for word in ['specials', 'speciali']): - title = re.sub(r'\sspecials|\sspeciali', '', title.lower()) - tvdb.find_and_set_infoLabels(item) - elif not item.infoLabels['tvdb_id']: - item.contentSerieName= title.rstrip('123456789 ') - tvdb.find_and_set_infoLabels(item) - - if not ID and active: - if item.infoLabels['tvdb_id']: - ID = item.infoLabels['tvdb_id'] - dict_renumerate = {TAG_ID: ID} - dict_series[title] = dict_renumerate - # Trova La Stagione - if any(word in title.lower() for word in ['specials', 'speciali']): - dict_renumerate[TAG_SEASON] = '0' - elif RepresentsInt(title.split()[-1]): - dict_renumerate[TAG_SEASON] = title.split()[-1] - else: dict_renumerate[TAG_SEASON] = '1' - dict_renumerate[TAG_EPISODE] = '' - write(item, dict_series) - return renumber(itemlist, item, typography) - else: - return itemlist - - else: - return renumber(itemlist, item, typography) - - -def semiautomatic_config_item(item): - logger.info() - # Configurazione Semi Automatica, utile in caso la numerazione automatica fallisca - tvdb.find_and_set_infoLabels(item) - item.channel = item.from_channel if item.from_channel else item.channel - dict_series = load(item) - title = item.fulltitle.rstrip() - - # Trova l'ID della serie - while not item.infoLabels['tvdb_id']: - try: - item.show = platformtools.dialog_input(default=item.show, heading=config.get_localized_string(30112)) # <- Enter title to search - tvdb.find_and_set_infoLabels(item) - except: - heading = config.get_localized_string(70704) # <- TMDB ID (0 to cancel) - info = platformtools.dialog_numeric(0, heading) - item.infoLabels['tvdb_id'] = '0' if info == '' else info - - - if item.infoLabels['tvdb_id']: - ID = item.infoLabels['tvdb_id'] - dict_renumerate = {TAG_ID: ID} - dict_series[title] = dict_renumerate - - # Trova la Stagione - if any( word in title.lower() for word in ['specials', 'speciali'] ): - heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for specials) - season = platformtools.dialog_numeric(0, heading, '0') - dict_renumerate[TAG_SEASON] = season - elif RepresentsInt(title.split()[-1]): - heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for season > 1) - season = platformtools.dialog_numeric(0, heading, title.split()[-1]) - dict_renumerate[TAG_SEASON] = season - else: - heading = config.get_localized_string(70686) # <- Enter the number of the starting season (for season 1) - season = platformtools.dialog_numeric(0, heading, '1') - dict_renumerate[TAG_SEASON] = season - - mode = platformtools.dialog_yesno(config.get_localized_string(70687), config.get_localized_string(70688), nolabel=config.get_localized_string(30023), yeslabel=config.get_localized_string(30022)) - if mode == True: - dict_renumerate[TAG_MODE] = False - - if TAG_SPECIAL in dict_series[title]: - specials = dict_renumerate[TAG_SPECIAL] - else: - specials = [] - - write(item, dict_series) - _list = [] - - itemlist = find_episodes(item) - for item in itemlist: - Title = re.sub(r'\d+x\d+ - ', '', item.title) - if item.action == 'findvideos': - _list.append(Title) - - selected = platformtools.dialog_multiselect(config.get_localized_string(70734), _list) - # if len(selected) > 0: - for select in selected: - specials.append(int(scrapertools.find_single_match(_list[select], r'(\d+)'))) - dict_renumerate[TAG_SPECIAL] = specials - - dict_renumerate[TAG_MODE] = False - - dict_renumerate[TAG_TYPE] = 'auto' - dict_renumerate[TAG_EPISODE] = '' - write(item, dict_series) - # xbmc.executebuiltin("Container.Refresh") - - else: - message = config.get_localized_string(60444) - heading = item.fulltitle.strip() - platformtools.dialog_notification(heading, message) - - -def renumeration (itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title, Type): - - # Se ID è 0 salta la rinumerazione - if ID == '0': - return itemlist - - # Numerazione per gli Speciali - elif Season == '0': - EpisodeDict = {} - for item in itemlist: - if config.get_localized_string(30992) not in item.title: - number = scrapertools.find_single_match(item.title, r'\d+') - item.title = typo('0x' + number + ' - ', typography) + item.title - - - # Usa la lista degli Episodi se esiste nel Json - - elif Episode: - EpisodeDict = json.loads(base64.b64decode(Episode)) - - # Controlla che la lista egli Episodi sia della stessa lunghezza di Itemlist - if EpisodeDict == 'none': - return error(itemlist) - if Type == 'manual' and len(EpisodeDict) < len(itemlist): - EpisodeDict = manual_renumeration(item, True) - if len(EpisodeDict) >= len(itemlist) and scrapertools.find_single_match(itemlist[0].title, r'\d+') in EpisodeDict: - for item in itemlist: - if config.get_localized_string(30992) not in item.title: - number = scrapertools.find_single_match(item.title, r'\d+') - number = int(number) # if number !='0': number.lstrip('0') - item.title = typo(EpisodeDict[str(number)] + ' - ', typography) + item.title - else: - make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title) - - else: - make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, Title) - - -def manual_renumeration(item, modify=False): - logger.info() - _list = [] - if item.from_channel: item.channel = item.from_channel - title = item.fulltitle.rstrip() - - dict_series = load(item) - - if title not in dict_series: dict_series[title] = {} - - if TAG_EPISODE in dict_series[title] and dict_series[title][TAG_EPISODE]: - EpisodeDict = json.loads(base64.b64decode(dict_series[title][TAG_EPISODE])) - del dict_series[title][TAG_EPISODE] - else: EpisodeDict = {} - - if TAG_EPLIST in dict_series[title]: del dict_series[title][TAG_EPLIST] - if TAG_MODE in dict_series[title]: del dict_series[title][TAG_MODE] - if TAG_CHECK in dict_series[title]: del dict_series[title][TAG_CHECK] - if TAG_SEASON in dict_series[title]: del dict_series[title][TAG_SEASON] - if TAG_SPECIAL in dict_series[title]: del dict_series[title][TAG_SPECIAL] - dict_series[title][TAG_TYPE] = 'manual' - write(item, dict_series) - - if TAG_ID not in dict_series[title] or (TAG_ID in dict_series[title] and not dict_series[title][TAG_ID]): - tvdb.find_and_set_infoLabels(item) - - # Trova l'ID della serie - while not item.infoLabels['tvdb_id']: - try: - item.show = platformtools.dialog_input(default=item.show, heading=config.get_localized_string(30112)) # <- Enter title to search - tvdb.find_and_set_infoLabels(item) - except: - heading = config.get_localized_string(70704) # <- TMDB ID (0 to cancel) - info = platformtools.dialog_numeric(0, heading) - item.infoLabels['tvdb_id'] = '0' if info == '' else info - - if item.infoLabels['tvdb_id']: - ID = item.infoLabels['tvdb_id'] - dict_renumerate = {TAG_ID: ID} - dict_series[title] = dict_renumerate - - itemlist = find_episodes(item) - for it in itemlist: - Title = re.sub(r'\d+x\d+ - ', '', it.title) - if modify == True: - ep = int(scrapertools.find_single_match(Title, r'(\d+)')) - if it.action == 'findvideos' and str(ep) not in EpisodeDict: - _list.append(Title) - else: - if it.action == 'findvideos': - _list.append(Title) - - count = 1 - preselect = platformtools.dialog_select(config.get_localized_string(70732),[typo(config.get_localized_string(70518),'bold'),typo(config.get_localized_string(70519),'bold')]) - selection = [] - if preselect == 0: - for i in _list: - selection.append(_list.index(i)) - while len(_list) > 0: - selected = platformtools.dialog_multiselect(config.get_localized_string(70734), _list, preselect=selection) - if selected == None: break - season = '' - while not season: - season = platformtools.dialog_numeric(0, config.get_localized_string(70733)) - count = int(platformtools.dialog_numeric(0, config.get_localized_string(70733))) - - for select in selected: - ep = int(scrapertools.find_single_match(_list[select], r'(\d+)')) - if season == '0': - episode = '' - while not episode: - episode = platformtools.dialog_numeric(0, config.get_localized_string(70735) % _list[select] ) - EpisodeDict[str(ep)] = '%sx%s' %(season, episode.zfill(2)) - else: - EpisodeDict[str(ep)] = '%sx%s' %(season, str(count).zfill(2)) - count += 1 - - for select in reversed(selected): - del _list[select] - - - dict_series[title][TAG_TYPE] = 'manual' - EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode()) - dict_series[title][TAG_EPISODE] = EpisodeDict.decode() - write(item, dict_series) - # xbmc.executebuiltin("Container.Refresh") - if modify == True: - return json.loads(base64.b64decode(EpisodeDict)) - - -def delete_renumeration(item): - logger.info() - if item.from_channel: item.channel = item.from_channel - title = item.fulltitle.rstrip() - - dict_series = load(item) - if title in dict_series: del dict_series[title] - write(item, dict_series) - - -def make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title): - logger.info() - exist = True - item.infoLabels['tvdb_id'] = ID - tvdb.set_infoLabels_item(item) - FirstOfSeason= 0 - - EpisodeDict = json.loads(base64.b64decode(Episode)) if Episode else {} - Special = dict_series[title][TAG_SPECIAL] if TAG_SPECIAL in dict_series[title] else [] - EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST])) if TAG_EPLIST in dict_series[title] else [] - Pages = dict_series[title][TAG_CHECK] if TAG_CHECK in dict_series[title] else [1] - - # Ricava Informazioni da TVDB - checkpages = [] - check = True - Page = Pages[-1] - - while exist: - if check: - for page in Pages: - data = tvdb.otvdb_global.get_list_episodes(ID,page) - logger.info('DATA',data) - for episodes in data['data']: - if episodes['firstAired'] and [episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']] not in EpList: - EpList.append([episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']]) - else: - if page not in checkpages: - checkpages.append(page) - check = False - - data = tvdb.otvdb_global.get_list_episodes(ID,Page) - if data: - Page = Page + 1 - for episodes in data['data']: - if episodes['firstAired'] and [episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']] not in EpList: - EpList.append([episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber']]) - else: - if page not in checkpages: - checkpages.append(Page -1) - exist = False - - EpList.sort() - - dict_series[title][TAG_CHECK] = checkpages - EpList = base64.b64encode(json.dumps(EpList).encode()) - dict_series[title][TAG_EPLIST] = EpList.decode() - write(item, dict_series) - - # Crea Dizionari per la numerazione - if EpList: - EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST])) - specials = [] - regular = {} - complete = {} - allep = 1 - ep = 1 - specialep = 0 - for episode in EpList: - complete[allep] = [str(episode[1]) + 'x' + str(episode[2]), episode[0]] - if episode[1] == 0: - specials.append(allep) - specialep = specialep + 1 - else: - regular[ep] = [str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1] - ep = ep + 1 - allep = allep + 1 - - # seleziona l'Episodio di partenza - if int(Season) > 1: - for numbers, data in regular.items(): - if data[0] == Season + 'x1': - FirstOfSeason = numbers - 1 - - if Mode == True: Special = specials - - addiction = 0 - for item in itemlist: - # Otiene Numerazione Episodi - scraped_ep = scrapertools.find_single_match(re.sub(r'\[[^\]]+\]','',item.title), r'\d+') - if scraped_ep: - episode = int(scraped_ep) - number = episode + FirstOfSeason - addiction - count = number + addiction - # Crea Dizionario Episodi - - if episode == 0: - EpisodeDict[str(episode)] = str(complete[regular[FirstOfSeason+1][2]][0]) - elif addiction < len(Special): - if episode in Special: - try: - season = complete[regular[count][2]][0] - EpisodeDict[str(episode)] = str(complete[regular[count][2]][0]) if season.startswith( '0' ) else '0x' + platformtools.dialog_numeric(0, item.title + '?', '') - - except: - EpisodeDict[str(episode)] = '0x' + platformtools.dialog_numeric(0, item.title + '?', '') - addiction = addiction + 1 - elif number <= len(regular): - EpisodeDict[str(episode)] = str(regular[number][0]) - else: - try: EpisodeDict[str(episode)] = str(complete[regular[number+2][2]][0]) - except: EpisodeDict[str(episode)] = '0x0' - elif number <= len(regular) and number in regular: - EpisodeDict[str(episode)] = str(regular[number][0]) - else: - try: EpisodeDict[str(episode)] = str(complete[regular[number+2][2]][0]) - except: EpisodeDict[str(episode)] = '0x0' - - # Aggiunge numerazione agli Episodi - - item.title = typo(EpisodeDict[str(episode)] + ' - ', typography) + item.title - - # Scrive Dizionario Episodi sul json - EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode()) - dict_series[title][TAG_EPISODE] = EpisodeDict.decode() - write(item, dict_series) - - else: - heading = config.get_localized_string(70704) - ID = platformtools.dialog_numeric(0, heading) - dict_series[title][TAG_ID] = ID - write(item, dict_series) - if ID == '0': - return itemlist - else: - return make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title) - - +# Json Var +TVSHOW_RENUMERATE = "TVSHOW_AUTORENUMBER" +ID = "ID" +SEASON = "Season" +EPISODE = "Episode" +SPECIAL = "Special" +MODE = "Mode" +EPLIST = "EpList" +CHECK = "ReCheck" +SPLIST = "SpList" +TYPE = "Type" + +# helper Functions def check(item): logger.info() dict_series = load(item) title = item.fulltitle.rstrip() if title in dict_series: title = dict_series[title] - return True if TAG_ID in title and TAG_EPISODE in title else False - - -def error(itemlist): - message = config.get_localized_string(70713) - heading = itemlist[0].fulltitle.strip() - platformtools.dialog_notification(heading, message) - return itemlist - - -def find_episodes(item): - logger.info() - ch = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel]) - itemlist = ch.episodios(item) - return itemlist - - -def RepresentsInt(s): - # Controllo Numro Stagione - logger.info() - try: - int(s) - return True - except ValueError: - return False - - -def access(): - allow = False - - if config.is_xbmc(): - allow = True - - return allow - - -def context(exist): - if access(): - modify = config.get_localized_string(70714) if exist else '' - _context = [{"title": typo(modify + config.get_localized_string(70585), 'bold'), - "action": "select_type", - "channel": "autorenumber",}] - - return _context - - -def select_type(item): - select = platformtools.dialog_select(config.get_localized_string(70730),[typo(config.get_localized_string(70731),'bold'), typo(config.get_localized_string(70732),'bold'), typo(config.get_localized_string(707433),'bold')]) - if select == 0: semiautomatic_config_item(item) - elif select == 1: manual_renumeration(item) - elif select == 2: return delete_renumeration(item) - else: return - + return True if ID in title and EPISODE in title else False def filename(item): logger.info() name_file = item.channel + "_data.json" path = filetools.join(config.get_data_path(), "settings_channels") fname = filetools.join(path, name_file) - return fname @@ -553,7 +42,7 @@ def load(item): logger.info() try: json_file = open(filename(item), "r").read() - json = jsontools.load(json_file)[TAG_TVSHOW_RENUMERATE] + json = jsontools.load(json_file)[TVSHOW_RENUMERATE] except: json = {} @@ -565,7 +54,669 @@ def write(item, json): logger.info() json_file = open(filename(item), "r").read() js = jsontools.load(json_file) - js[TAG_TVSHOW_RENUMERATE] = json + js[TVSHOW_RENUMERATE] = json with open(filename(item), "w") as file: file.write(jsontools.dump(js)) file.close() + +def b64(json, mode = 'encode'): + if mode == 'encode': + ret = base64.b64encode(json) + else: + ret = jsontools.load(base64.b64decode(json)) + return ret + +def RepresentsInt(s): + # Controllo Numro Stagione + logger.info() + try: + int(s) + return True + except ValueError: + return False + +def find_episodes(item): + logger.info() + ch = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel]) + itemlist = ch.episodios(item) + return itemlist + + + +# Main +def start(itemlist, item=None): + if type(itemlist) == Item: + item = itemlist + if item.channel in ['autorenumber']: + item.channel = item.from_channel + item.action = item.from_action + item.renumber = True + itemlist = find_episodes(item) + return autorenumber(itemlist, item) +class autorenumber(): + def __init__(self, itemlist, item=None): + self.item = item + self.itemlist = itemlist + self.auto = False + self.dictSeries = load(self.itemlist[0]) if self.itemlist else load(item) if item else {} + if self.item: + self.auto = config.get_setting('autorenumber', item.channel) + self.title = self.item.fulltitle.strip() + if match(self.itemlist[0].title, patron=r'(\d+\D\d+)').match: + return itemlist + elif self.item.channel in self.item.channel_prefs and TVSHOW_RENUMERATE in self.item.channel_prefs[item.channel] and self.title not in self.dictSeries: + from core.videolibrarytools import check_renumber_options + from specials.videolibrary import update_videolibrary + check_renumber_options(self.item) + update_videolibrary(self.item) + if self.title in self.dictSeries: + self.id = self.dictSeries[self.title][ID] + self.Episodes = b64(self.dictSeries[self.title][EPISODE], 'decode') + self.Season = self.dictSeries[self.title][SEASON] + self.Mode = self.dictSeries[self.title].get(MODE, False) + self.Type = self.dictSeries[self.title].get(TYPE, False) + if self.item.renumber: + self.config() + else: + self.renumber() + elif self.auto or self.item.renumber: + self.Episodes = {} + self.config() + + else: + for item in self.itemlist: + item.context = [{"title": typo(config.get_localized_string(70585), 'bold'), + "action": "start", + "channel": "autorenumber", + "from_channel": item.channel, + "from_action": item.action}] + + def config(self): + self.id = '' + if self.title in self.dictSeries: + self.id = self.dictSeries[self.title].get(ID,'') + + # Pulizia del Titolo + if any( word in self.title.lower() for word in ['specials', 'speciali']): + self.title = re.sub(r'\s*specials|\s*speciali', '', self.title.lower()) + tvdb.find_and_set_infoLabels(self.item) + elif not self.item.infoLabels['tvdb_id']: + self.item.contentSerieName = self.title.rstrip('123456789 ') + tvdb.find_and_set_infoLabels(self.item) + + # Rinumerazione Automatica + if (not self.id and self.auto) or self.item.renumber: + self.id = self.item.infoLabels['tvdb_id'] if 'tvdb_id' in self.item.infoLabels else '' + if self.id: + self.dictRenumber = {ID: self.id} + self.dictSeries[self.title] = self.dictRenumber + if any(word in self.title.lower() for word in ['specials', 'speciali']): season = '0' + elif RepresentsInt(self.title.split()[-1]): season = self.title.split()[-1] + else: season = '1' + # self.dictRenumber[EPISODE] = {} + self.Season = self.dictRenumber[SEASON] = season + # self.Episodes = self.dictRenumber[EPISODE] + self.renumber() + + def renumber(self): + if not self.item.renumber and self.itemlist and len(self.Episodes) >= len(self.itemlist) and match(self.itemlist[0].title, patron=r'(\d+)').match in self.Episodes: + if '|' in self.Season: + season = int(self.Season.split('|')[0]) + addNumber = int(self.Season.split('|')[-1]) - 1 + else: + season = int(self.Season) + addNumber = 0 + + for item in self.itemlist: + number = match(item.title, patron=r'(\d+)').match + number = number.lstrip('0') + if number: + if number in self.Episodes: + if season > 0: item.title = typo(self.Episodes[number] + ' - ', 'bold') + item.title + else: item.title = typo('0x%s - ' % str(int(number) + addNumber), 'bold') + item.title + else: + self.makelist() + if season > 0: item.title = typo(self.Episodes[number] + ' - ', 'bold') + item.title + else: item.title = typo('0x%s - ' % str(int(number) + addNumber), 'bold') + item.title + else: + self.makelist() + + + def makelist(self): + FirstOfSeason= 0 + self.EpList = b64(self.dictSeries[self.title][EPLIST], 'decode') if EPLIST in self.dictSeries[self.title] else [] + self.Pages = self.dictSeries[self.title].get(CHECK, [1]) + self.Mode = self.dictSeries[self.title].get(MODE, False) + self.Type = self.dictSeries[self.title].get(TYPE, False) + Specials = {} + Seasons = {} + + if '|' in self.Season: + ep = int(self.Season.split('|')[-1]) + season = int(self.Season.split('|')[0]) + else: + season = int(self.Season) + ep = 1 + + # pdialog = platformtools.dialog_progress_bg('Rinumerazione', 'creazione lista episodi') + itemlist = find_episodes(self.item) + + if self.item.renumber: + self.s = season + self.e = 1 + Season, Episode, self.Mode, Specials, Seasons, Exit = SelectreNumeration(self, itemlist) + if Exit: return + if ep != 1: self.Season = '%s|%s' % (Season, Episode) + else: self.Season = str(Season) + + + if self.Mode: + if not Seasons: + self.s = 1 + self.e = 1 + Season, Episode, self.Mode, Specials, Seasons, Exit = SelectreNumeration(self, itemlist, True) + self.Episodes = Seasons + + else: + + # Ricava Informazioni da TVDB + checkpages = [] + exist = True + Page = self.Pages[-1] + + while exist: + data = tvdb.Tvdb(tvdb_id=self.id).get_list_episodes(self.id, Page) + if data: + for episode in data['data']: + if episode['firstAired'] and [episode['firstAired'], episode['airedSeason'], episode['airedEpisodeNumber']] not in self.EpList: + self.EpList.append([episode['firstAired'], episode['airedSeason'], episode['airedEpisodeNumber']]) + Page += 1 + else: + if Page not in checkpages: + checkpages.append(Page -1) + exist = False + self.Pages = [checkpages[-1]] + self.EpList.sort() + + # Crea Dizionari per la Rinumerazione + if self.EpList: + self.specials = [] + self.regular = {} + self.complete = {} + allep = 1 + specialep = 0 + + for episode in self.EpList: + self.complete[allep] = [str(episode[1]) + 'x' + str(episode[2]), episode[0]] + if episode[1] == 0: + self.specials.append(allep) + specialep = specialep + 1 + else: + self.regular[ep] = [str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1] + ep = ep + 1 + allep = allep + 1 + + self.Episodes = {} + if season > 1: + for numbers, data in self.regular.items(): + if data[0] == str(season) + 'x1': + FirstOfSeason = numbers - 1 + else: FirstOfSeason = Episode - 1 + + addiction = 0 + # specialsCount = 1 + # pdialog.update(80, 'rinumerazione') + for item in itemlist: + # Otiene Numerazione Episodi + scraped_ep = match(re.sub(r'\[[^\]]+\]','',item.title), patron=r'(\d+)').match + if scraped_ep: + episode = int(scraped_ep) + number = episode + FirstOfSeason - addiction + if episode == 0: + self.Episodes[str(episode)] = str(self.complete[self.regular[FirstOfSeason+1][2]][0]) + elif episode in Specials: + self.Episodes[str(episode)] = Specials[episode] + addiction += 1 + elif number <= len(self.regular) and number in self.regular: + self.Episodes[str(episode)] = str(self.regular[number][0]) + else: + try: Episodes[str(episode)] = str(self.complete[self.regular[number+2][2]][0]) + except: self.Episodes[str(episode)] = '0x0' + + + self.dictSeries[self.title][EPISODE] = b64(jsontools.dump(self.Episodes)) + self.dictSeries[self.title][EPLIST] = b64(jsontools.dump(self.EpList)) + self.dictSeries[self.title][MODE] = self.Mode + self.dictSeries[self.title][SEASON] = self.Season + self.dictSeries[self.title][CHECK] = self.Pages + write(self.item, self.dictSeries) + # pdialog.close() + if self.auto: self.renumber() + + +def SelectreNumeration(opt, itemlist, manual=False): + opt.itemlist = itemlist + opt.manual = manual + return SelectreNumerationWindow('Renumber.xml', path).start(opt) + +# Select Season +SELECT = 100 +S = 101 +E = 102 +O = 103 +SS = 104 +M = 105 +D = 106 +C = 107 + +# Main +MAIN = 10000 +INFO = 10001 +OK=10002 +CLOSE = 10003 + +# Select Specials +SPECIALS = 200 +POSTER= 201 +LIST = 202 +SELECTED = 203 +BACKGROUND = 208 + +SPECIALCOMMANDS = 204 +SU = 205 +SD = 206 +SR = 207 + +# Select Manual +MANUAL = 300 +MPOSTER= 301 +MLIST = 302 +MSEASONS = 303 +MSEP = 304 +MBACKGROUND = 310 + +MANUALEP = 305 +MS = 306 +ME = 307 +MSS = 308 +MC = 309 + +# Actions +LEFT = 1 +RIGHT = 2 +UP = 3 +DOWN = 4 +EXIT = 10 +BACKSPACE = 92 + +path = config.get_runtime_path() + +class SelectreNumerationWindow(xbmcgui.WindowXMLDialog): + def start(self, opt): + self.episodes = opt.Episodes if opt.Episodes else {} + self.dictSeries = opt.dictSeries + self.item = opt.item + self.title = opt.title + self.season = opt.s + self.episode = opt.e + self.mode = opt.Mode + self.manual = opt.manual + self.offset = 0 + self.Exit = False + + self.itemlist = opt.itemlist + self.count = 1 + self.specials = {} + self.items = [] + self.selected = [] + self.seasons = {} + + self.doModal() + return self.season, self.episode, self.mode, self.specials, self.seasons, self.Exit + + def onInit(self): + # Compatibility with Kodi 18 + if config.get_platform(True)['num_version'] < 18: self.setCoordinateResolution(2) + fanart = self.item.fanart + thumb = self.item.thumbnail + # MANUAL + if self.manual: + self.getControl(SELECT).setVisible(False) + self.getControl(SPECIALS).setVisible(False) + self.getControl(MANUAL).setVisible(True) + self.getControl(MPOSTER).setImage(thumb) + if fanart: self.getControl(MBACKGROUND).setImage(fanart) + self.getControl(INFO).setLabel(typo(config.get_localized_string(70822) + self.title,'bold')) + + self.mode = True + + se = '1' + ep = '1' + position = 0 + for i, item in enumerate(self.itemlist): + title = match(item.title, patron=r'(\d+)').match + it = xbmcgui.ListItem(title) + if int(title) <= len(self.episodes): + se, ep = self.episodes[title].split('x') + else: + if position == 0: position = i + ep = str(int(ep) + 1) + it.setProperties({'season':se, "episode":ep}) + self.items.append(it) + self.makerenumber() + self.addseasons() + season = self.getControl(MSEASONS).getSelectedItem().getLabel() + self.getControl(MSEP).reset() + self.getControl(MSEP).addItems(self.episodes[season]) + self.getControl(MLIST).addItems(self.items) + self.setFocusId(MLIST) + self.getControl(MLIST).selectItem(position) + # SPECIALS + else: + self.getControl(SELECT).setVisible(True) + self.getControl(SPECIALS).setVisible(False) + self.getControl(MANUAL).setVisible(False) + + for i, item in enumerate(self.itemlist): + title = match(item.title, patron=r'(\d+)').match + it = xbmcgui.ListItem(title) + it.setProperty('index', str(i)) + self.items.append(it) + + self.getControl(POSTER).setImage(thumb) + self.getControl(MPOSTER).setImage(thumb) + if fanart: + self.getControl(BACKGROUND).setImage(fanart) + self.getControl(MBACKGROUND).setImage(fanart) + self.getControl(INFO).setLabel(typo(config.get_localized_string(70824) + self.title, 'bold')) + self.getControl(LIST).addItems(self.items) + + self.getControl(S).setLabel(str(self.season)) + # self.getControl(S).setType(1, config.get_localized_string(60385)) + self.getControl(E).setLabel(str(self.episode)) + # self.getControl(E).setType(1, config.get_localized_string(60386)) + + self.setFocusId(O) + + def onFocus(self, focus): + if focus in [S]: self.getControl(108).setLabel(typo(config.get_localized_string(70825), 'bold')) + elif focus in [E]: self.getControl(108).setLabel(typo(config.get_localized_string(70826), 'bold')) + elif focus in [O]: self.getControl(108).setLabel(typo(config.get_localized_string(70001), 'bold')) + elif focus in [SS]: self.getControl(108).setLabel(typo(config.get_localized_string(70827), 'bold')) + elif focus in [M]: self.getControl(108).setLabel(typo(config.get_localized_string(70828), 'bold')) + elif focus in [D]: self.getControl(108).setLabel(typo(config.get_localized_string(70829) + self.title, 'bold')) + elif focus in [C]: self.getControl(108).setLabel(typo(config.get_localized_string(70002), 'bold')) + + + def onAction(self, action): + action = action.getId() + focus = self.getFocusId() + # SEASON SELECT + if 100 < focus < 200: + s = int(self.getControl(S).getLabel()) + e = int(self.getControl(E).getLabel()) + if action in [RIGHT]: + if focus in [C]: self.setFocusId(S) + else: self.setFocusId(focus + 1) + elif action in [LEFT]: + if focus in [S]: self.setFocusId(C) + else: self.setFocusId(focus - 1) + elif action in [UP]: + if focus in [S]: + s += 1 + self.getControl(S).setLabel(str(s)) + elif focus in [E]: + e += 1 + self.getControl(E).setLabel(str(e)) + elif action in [DOWN]: + if focus in [S]: + if s > 0: s -= 1 + self.getControl(S).setLabel(str(s)) + elif focus in [E]: + if e > 0: e -= 1 + self.getControl(E).setLabel(str(e)) + # MANUAL + if focus in [MS, ME]: + s = int(self.getControl(MLIST).getSelectedItem().getProperty('season')) + e = int(self.getControl(MLIST).getSelectedItem().getProperty('episode')) + pos = self.getControl(MLIST).getSelectedPosition() + # Set Season + if focus in [MS] and action in [UP]: s += 1 + elif focus in [MS] and action in [DOWN] and s > 0: s -= 1 + # Set Episode + if focus in [ME] and action in [UP]: e += 1 + elif focus in [ME] and action in [DOWN] and e > 0: e -= 1 + if action in [UP, DOWN]: + if s != self.season: e = 1 + self.season = s + self.episode = e + self.makerenumber(pos) + self.addseasons() + season = self.getControl(MSEASONS).getSelectedItem().getLabel() + self.getControl(MSEP).reset() + self.getControl(MSEP).addItems(self.episodes[season]) + self.getControl(MLIST).reset() + self.getControl(MLIST).addItems(self.items) + self.getControl(MLIST).selectItem(pos) + if focus in [MSEASONS]: + season = self.getControl(MSEASONS).getSelectedItem().getLabel() + self.getControl(MSEP).reset() + self.getControl(MSEP).addItems(self.episodes[season]) + + # EXIT + if action in [EXIT, BACKSPACE]: + self.Exit = True + self.close() + + def onClick(self, control_id): + ## FIRST SECTION + if control_id in [S]: + selected = platformtools.dialog_numeric(0, config.get_localized_string(70825), self.getControl(S).getLabel()) + if selected: s = self.getControl(S).setLabel(selected) + elif control_id in [E]: + selected = platformtools.dialog_numeric(0, config.get_localized_string(70826), self.getControl(E).getLabel()) + if selected: e = self.getControl(E).setLabel(selected) + # OPEN SPECIALS OR OK + if control_id in [O, SS]: + s = self.getControl(S).getLabel() + e = self.getControl(E).getLabel() + self.season = int(s) + self.episode = int(e) + if control_id in [O]: + self.close() + elif control_id in [SS]: + self.getControl(SELECT).setVisible(False) + self.getControl(SPECIALS).setVisible(True) + self.setFocusId(OK) + # OPEN MANUAL + elif control_id in [M]: + self.getControl(INFO).setLabel(typo(config.get_localized_string(70823) + self.title, 'bold')) + self.mode = True + if self.episodes: + items = [] + se = '1' + ep = '1' + for item in self.items: + if int(item.getLabel()) <= len(self.episodes) - 1: + se, ep = self.episodes[item.getLabel()].split('x') + else: + ep = str(int(ep) + 1) + item.setProperties({'season':se, "episode":ep}) + items.append(item) + self.seasons[item.getLabel()] = '%sx%s' %(se, ep) + self.items = items + else: + self.makerenumber() + self.addseasons() + season = self.getControl(MSEASONS).getSelectedItem().getLabel() + self.getControl(MSEP).reset() + self.getControl(MSEP).addItems(self.episodes[season]) + self.getControl(MLIST).addItems(self.items) + self.getControl(SELECT).setVisible(False) + self.getControl(MANUAL).setVisible(True) + self.setFocusId(OK) + # CLOSE + elif control_id in [C]: + self.Exit = True + self.close() + # DELETE + if control_id in [D]: + self.Exit = True + self.dictSeries.pop(self.title) + write(self.item, self.dictSeries) + self.close() + + ## SPECIAL SECTION + # ADD TO SPECIALS + p1 = self.getControl(SELECTED).getSelectedPosition() + if control_id in [LIST]: + item = self.getControl(LIST).getSelectedItem() + it = xbmcgui.ListItem(str(len(self.selected) + 1)) + it.setProperty('title', item.getLabel()) + self.selected.append(it) + index = self.getControl(SELECTED).getSelectedPosition() + self.getControl(SELECTED).reset() + self.getControl(SELECTED).addItems(self.selected) + self.getControl(SELECTED).selectItem(index) + + index = self.getControl(LIST).getSelectedPosition() + self.items.pop(index) + self.getControl(LIST).reset() + self.getControl(LIST).addItems(self.items) + if index == len(self.items): index -= 1 + self.getControl(LIST).selectItem(index) + # MOVE SPECIALS + elif control_id in [SU]: + p2 = p1 - 1 + if p2 > -1: + self.selected[p1], self.selected[p2] = self.selected[p2], self.selected[p1] + for i, it in enumerate(self.selected): + it.setLabel(str(i+1)) + break + self.getControl(SELECTED).reset() + self.getControl(SELECTED).addItems(self.selected) + self.getControl(SELECTED).selectItem(p2) + + elif control_id in [SD]: + p2 = p1 + 1 + if p2 < len(self.selected): + self.selected[p1], self.selected[p2] = self.selected[p2], self.selected[p1] + for i, it in enumerate(self.selected): + it.setLabel(str(i+1)) + break + self.getControl(SELECTED).reset() + self.getControl(SELECTED).addItems(self.selected) + self.getControl(SELECTED).selectItem(p2) + # REMOVE FROM SPECIALS + elif control_id in [SR]: + item = self.getControl(SELECTED).getSelectedItem() + it = xbmcgui.ListItem(item.getProperty('title')) + if int(item.getProperty('title')) < int(self.items[-1].getLabel()): + for i, itm in enumerate(self.items): + if int(itm.getLabel()) > int(item.getProperty('title')): + self.items.insert(i, it) + break + else: + self.items.append(it) + self.getControl(LIST).reset() + self.getControl(LIST).addItems(self.items) + index = self.getControl(SELECTED).getSelectedPosition() + self.selected.pop(index) + self.getControl(SELECTED).reset() + self.getControl(SELECTED).addItems(self.selected) + + if index == len(self.selected): index -= 1 + self.getControl(SELECTED).selectItem(index) + # RELOAD SPECIALS + if control_id in [SELECTED]: + epnumber = platformtools.dialog_numeric(0, config.get_localized_string(60386)) + it = self.getControl(SELECTED).getSelectedItem() + it.setLabel(str(epnumber)) + self.selected.sort(key=lambda it: int(it.getLabel())) + for i, it in enumerate(self.selected): + if it.getLabel() == epnumber: pos = i + self.selected.sort(key=lambda it: int(it.getLabel())) + self.getControl(SELECTED).reset() + self.getControl(SELECTED).addItems(self.selected) + self.getControl(SELECTED).selectItem(pos) + break + if len(self.selected) > 0: self.getControl(SPECIALCOMMANDS).setVisible(True) + else: self.getControl(SPECIALCOMMANDS).setVisible(False) + + ## MANUAL SECTION + # SELECT SEASON EPISODE (MANUAL) + if control_id in [MS, ME]: + s = int(self.getControl(MLIST).getSelectedItem().getProperty('season')) + e = int(self.getControl(MLIST).getSelectedItem().getProperty('episode')) + pos = self.getControl(MLIST).getSelectedPosition() + if control_id in [MS]: + selected = platformtools.dialog_numeric(0, config.get_localized_string(70825), str(s)) + if selected: s = int(selected) + elif control_id in [ME]: + selected = platformtools.dialog_numeric(0, config.get_localized_string(70826), str(e)) + if selected: e = int(selected) + if s != self.season or e != self.episode: + self.season = s + self.episode = 1 if s != self.season else e + self.makerenumber(pos) + self.addseasons() + season = self.getControl(MSEASONS).getSelectedItem().getLabel() + self.getControl(MSEP).reset() + self.getControl(MSEP).addItems(self.episodes[season]) + self.getControl(MLIST).reset() + self.getControl(MLIST).addItems(self.items) + self.getControl(MLIST).selectItem(pos) + # OK + if control_id in [OK]: + for it in self.selected: + self.specials[int(it.getProperty('title'))] = '0x' + it.getLabel() + self.close() + # CLOSE + elif control_id in [CLOSE]: + self.Exit = True + self.close() + + + def makerenumber(self, pos = 0): + items = [] + currentSeason = self.items[pos].getProperty('season') + previousSeason = self.items[pos - 1 if pos > 0 else 0].getProperty('season') + prevEpisode = self.items[pos - 1 if pos > 0 else 0].getProperty('episode') + if currentSeason != str(self.season): + if str(self.season) == previousSeason: + prevEpisode = int(prevEpisode) + 1 + else: + prevEpisode = 1 + else: prevEpisode = self.episode + + for i, item in enumerate(self.items): + if (i >= pos and item.getProperty('season') == currentSeason) or not item.getProperty('season'): + if i > pos: prevEpisode += 1 + item.setProperties({'season':self.season, 'episode':prevEpisode}) + items.append(item) + self.seasons[item.getLabel()] = '%sx%s' % (item.getProperty('season'), item.getProperty('episode')) + self.items = items + logger.info('SELF',self.seasons) + + def addseasons(self): + seasonlist = [] + seasons = [] + self.episodes = {} + for ep, value in self.seasons.items(): + season = value.split('x')[0] + if season not in seasonlist: + item = xbmcgui.ListItem(season) + seasonlist.append(season) + seasons.append(item) + if season in seasonlist: + if season not in self.episodes: + self.episodes[season] = [] + item = xbmcgui.ListItem('%s - Ep. %s' % (value, ep)) + item.setProperty('episode', ep) + self.episodes[season].append(item) + logger.log('EPISODES',self.episodes[season]) + self.episodes[season].sort(key=lambda it: int(it.getProperty('episode'))) + + seasons.sort(key=lambda it: int(it.getLabel())) + self.getControl(MSEASONS).reset() + self.getControl(MSEASONS).addItems(seasons) \ No newline at end of file diff --git a/platformcode/platformtools.py b/platformcode/platformtools.py index fa820aa7..0f1ffc3a 100644 --- a/platformcode/platformtools.py +++ b/platformcode/platformtools.py @@ -178,6 +178,10 @@ def dialog_register(heading, user=False, email=False, password=False, user_defau dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img) return dialog +def dialog_info(item, scraper): + dialog = TitleOrIDWindow('TitleOrIDWindow.xml', config.get_runtime_path()).Start(item, scraper) + return dialog + def itemlist_refresh(): # pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition @@ -1338,3 +1342,108 @@ def get_platform(): ret["arch"] = "arm" return ret + + +class Register(xbmcgui.WindowXMLDialog): + def Start(self, heading, user, email, password, user_default, email_default, password_default, captcha_img): + self.result = {} + self.heading = heading + self.user = user + self.email = email + self.password = password + self.user_default = user_default + self.email_default = email_default + self.password_default = password_default + self.captcha_img = captcha_img + self.doModal() + + return self.result + + def __init__(self, *args, **kwargs): + self.mensaje = kwargs.get("mensaje") + self.imagen = kwargs.get("imagen") + + def onInit(self): + #### Kodi 18 compatibility #### + if config.get_platform(True)['num_version'] < 18: + self.setCoordinateResolution(2) + height = 90 + self.getControl(10002).setText(self.heading) + if self.user: + self.getControl(10003).setText(self.user_default) + height+=70 + else: + self.getControl(10003).setVisible(False) + if self.email: + self.getControl(10004).setText(self.email_default) + height+=70 + else: + self.getControl(10004).setVisible(False) + if self.password: + self.getControl(10005).setText(self.password_default) + height+=70 + else: + self.getControl(10005).setVisible(False) + if self.captcha_img: + + self.getControl(10007).setImage(self.captcha_img) + height+=240 + else: + self.getControl(10005).setVisible(False) + height +=40 + if height < 250: height = 250 + self.getControl(10000).setHeight(height) + self.getControl(10001).setHeight(height) + self.getControl(10000).setPosition(255, (720-height)/2) + self.setFocusId(30000) + + def onClick(self, control): + if control in [10010]: + self.close() + + elif control in [10009]: + if self.user: self.result['user'] = self.getControl(10003).getText() + if self.email: self.result['email'] = self.getControl(10004).getText() + if self.password: self.result['password'] = self.getControl(10005).getText() + if self.captcha_img: self.result['captcha'] = self.getControl(10006).getText() + self.close() + +class TitleOrIDWindow(xbmcgui.WindowXMLDialog): + def Start(self, item, scraper): + self.item = item + self.title = item.show if item.show else item.fulltitle + self.id = item.infoLabels.get('tmdb_id','') if scraper == 'tmdb' else item.infoLabels.get('tvdb_id','') + self.scraper = scraper + self.label = 'TMDB ID:' if scraper == 'tmdb' else 'TVDB ID:' + self.doModal() + return self.item + + def onInit(self): + #### Kodi 18 compatibility #### + if config.get_platform(True)['num_version'] < 18: + self.setCoordinateResolution(2) + self.getControl(10000).setText(config.get_localized_string(60228) % self.title) + self.getControl(10001).setText(self.title) + self.getControl(10002).setLabel(self.label) + self.getControl(10002).setText(self.id) + self.getControl(10002).setType(1, self.label) + self.setFocusId(10001) + + def onClick(self, control): + if control in [10003]: + if self.getControl(10001).getText(): + self.item.contentTitle = self.getControl(10001).getText() + if self.scraper == 'tmdb' and self.getControl(10002).getText(): + self.item.infoLabels['tmdb_id'] = self.getControl(10002).getText() + elif self.scraper == 'tvdb' and self.getControl(10002).getText(): + self.item.infoLabels['tvdb_id'] = self.getControl(10002).getText() + self.close() + + elif control in [10004, 10005]: + self.item = None + self.close() + + def onAction(self, action): + if (action in [92] and self.getFocusId() not in [10001, 10002]) or action in [10]: + self.item = None + self.close() diff --git a/platformcode/xbmc_info_window.py b/platformcode/xbmc_info_window.py index a4452cd3..968e9ab1 100644 --- a/platformcode/xbmc_info_window.py +++ b/platformcode/xbmc_info_window.py @@ -1,14 +1,20 @@ # -*- coding: utf-8 -*- -import xbmcgui +import xbmcgui, sys from core.tmdb import Tmdb from platformcode import config, logger from core import filetools +if sys.version_info[0] >= 3: + from concurrent import futures +else: + from concurrent_py2 import futures BACKGROUND = 30000 LOADING = 30001 SELECT = 30002 +EXIT = 10 +BACKSPACE = 92 def imagepath(image): if len(image.split('.')) == 1: image += '.png' @@ -28,20 +34,27 @@ class InfoWindow(xbmcgui.WindowXMLDialog): logger.info('RESPONSE',self.response) return self.response + def make_items(self, i, result): + infoLabels = self.scraper().get_infoLabels(origen=result) + it = xbmcgui.ListItem(infoLabels['title']) + it.setProperty('fanart', infoLabels.get('fanart', '')) + it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv'))) + it.setProperty('genre', infoLabels.get('genre', 'N/A')) + it.setProperty('rating', str(infoLabels.get('rating', 'N/A'))) + it.setProperty('plot', str(infoLabels.get('plot', ''))) + it.setProperty('year', str(infoLabels.get('year', ''))) + it.setProperty('position', str(i)) + return it + def onInit(self): if config.get_platform(True)['num_version'] < 18: self.setCoordinateResolution(2) - - for result in self.results: - infoLabels = self.scraper().get_infoLabels(origen=result) - it = xbmcgui.ListItem(infoLabels['title']) - it.setProperty('fanart', infoLabels.get('fanart', '')) - it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv'))) - it.setProperty('genre', infoLabels.get('genre', 'N/A')) - it.setProperty('rating', str(infoLabels.get('rating', 'N/A'))) - it.setProperty('plot', str(infoLabels.get('plot', ''))) - it.setProperty('year', str(infoLabels.get('year', ''))) - self.items.append(it) + with futures.ThreadPoolExecutor() as executor: + for i, result in enumerate(self.results): + logger.info(result) + if ('seriesName' in result and result['seriesName']) or ('name' in result and result['name']) or ('title' in result and result['title']): + self.items += [executor.submit(self.make_items, i, result).result()] + self.items.sort(key=lambda it: int(it.getProperty('position'))) self.getControl(SELECT).addItems(self.items) self.getControl(BACKGROUND).setImage(self.items[0].getProperty('fanart')) @@ -53,3 +66,12 @@ class InfoWindow(xbmcgui.WindowXMLDialog): self.response = self.results[self.getControl(SELECT).getSelectedPosition()] self.close() + def onAction(self, action): + if self.getFocusId() in [SELECT]: + fanart = self.getControl(self.getFocusId()).getSelectedItem().getProperty('fanart') + self.getControl(BACKGROUND).setImage(fanart) + if action in [BACKSPACE]: + self.close() + elif action in [EXIT]: + self.close() + diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 02cea72d..ee4ebcb3 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -6086,6 +6086,44 @@ msgctxt "#70821" msgid "Search results" msgstr "" +# RENUMBER +msgctxt "#70822" +msgid "Renumber new episodes of: " +msgstr "" + +msgctxt "#70823" +msgid "Renumber episodes of: " +msgstr "" + +msgctxt "#70824" +msgid "Select the specials of: " +msgstr "" + +msgctxt "#70825" +msgid "Select Season" +msgstr "" + +msgctxt "#70826" +msgid "Select Episode" +msgstr "" + +msgctxt "#70827" +msgid "Select Specials" +msgstr "" + +msgctxt "#70828" +msgid "Manual renumbering" +msgstr "" + +msgctxt "#70829" +msgid "Delete Numbering for: " +msgstr "" + +msgctxt "#70830" +msgid "The series / episode number should only be changed if the series has relative numbering." +msgstr "" + + # DNS start [ settings and declaration ] msgctxt "#707401" msgid "Enable DNS check alert" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index d0a6603e..7ed448ed 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -6087,6 +6087,43 @@ msgctxt "#70821" msgid "Search results" msgstr "Risultati della ricerca" +# RENUMBER +msgctxt "#70822" +msgid "Renumber new episodes of: " +msgstr "Rinumera i nuovi episodi di: " + +msgctxt "#70823" +msgid "Renumber episodes of: " +msgstr "Rinumera gli episodi di: " + +msgctxt "#70824" +msgid "Select the specials of: " +msgstr "Seleziona gli speciali di: " + +msgctxt "#70825" +msgid "Select Season" +msgstr "Seleziona Stagione" + +msgctxt "#70826" +msgid "Select Episode" +msgstr "Seleziona Episodio" + +msgctxt "#70827" +msgid "Select Specials" +msgstr "Seleziona Speciali" + +msgctxt "#70828" +msgid "Manual renumbering" +msgstr "Rinumerazione Manuale" + +msgctxt "#70829" +msgid "Delete Numbering for: " +msgstr "Elimina Numerazione per: " + +msgctxt "#70830" +msgid "The series / episode number should only be changed if the series has relative numbering." +msgstr "Il numero della serie / episodio deve essere modificato solo se la serie ha una numerazione relativa." + # DNS start [ settings and declaration ] msgctxt "#707401" msgid "Enable DNS check alert" diff --git a/resources/skins/Default/720p/InfoWindow.xml b/resources/skins/Default/720p/InfoWindow.xml index 6c3d099d..ad013bf6 100644 --- a/resources/skins/Default/720p/InfoWindow.xml +++ b/resources/skins/Default/720p/InfoWindow.xml @@ -56,7 +56,7 @@ <viewtype>wrap</viewtype> <orientation>horizontal</orientation> <scrolltime tween="cubic" easing="out">300</scrolltime> - <itemlayout height="640" width="180"> + <itemlayout width="180"> <!-- Poster --> <control type="image"> <bottom>0</bottom> @@ -68,12 +68,12 @@ <bordersize>10</bordersize> </control> </itemlayout> - <focusedlayout height="640" width="480"> + <focusedlayout width="427"> <!-- Title --> <control type="textbox"> - <left>500</left> + <left>447</left> <top>10</top> - <width>730</width> + <width>783</width> <height>30</height> <font>font30_title</font> <textcolor>FFFFFFFF</textcolor> @@ -84,9 +84,9 @@ </control> <!-- info --> <control type="textbox"> - <left>500</left> + <left>447</left> <top>50</top> - <width>730</width> + <width>783</width> <height>30</height> <font>font13</font> <textcolor>FFFFFFFF</textcolor> @@ -96,9 +96,9 @@ </control> <!-- Plot --> <control type="textbox"> - <left>500</left> + <left>447</left> <top>90</top> - <width>730</width> + <width>783</width> <height>250</height> <font>font13</font> <textcolor>FFFFFFFF</textcolor> @@ -111,7 +111,7 @@ <control type="image"> <bottom>0</bottom> <left>0</left> - <width>480</width> + <width>427</width> <height>640</height> <texture>$INFO[ListItem.Property(thumbnail)]</texture> <aspectratio>scale</aspectratio> diff --git a/resources/skins/Default/720p/Renumber.xml b/resources/skins/Default/720p/Renumber.xml new file mode 100644 index 00000000..6571b407 --- /dev/null +++ b/resources/skins/Default/720p/Renumber.xml @@ -0,0 +1,631 @@ +<?xml version="1.0" encoding="utf-8"?> +<window> + <allowoverlays>false</allowoverlays> + <animation type="WindowOpen" reversible="false"> + <effect type="fade" start="0" end="100" time="300" /> + </animation> + <animation type="WindowClose" reversible="false"> + <effect type="fade" start="100" end="0" time="300" /> + </animation> + <controls> + <!-- MAIN SELECTION --> + <control type='group' id='100'> + <height>100%</height> + <width>100%</width> + <!-- Background --> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="CC232323">white.png</texture> + </control> + <control type="textbox"> + <top>60</top> + <left>370</left> + <height>140</height> + <width>540</width> + <align>center</align> + <aligny>center</aligny> + <textcolor>80FFFFFF</textcolor> + <label>$ADDON[plugin.video.kod 70830]</label> + </control> + <!-- main selection window --> + <control type="group"> + <top>288.5</top> + <left>370</left> + <height>140</height> + <width>540</width> + <!-- Beckground --> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="FF232323">white.png</texture> + </control> + <control type="button" id="101"> + <top>30</top> + <left>20</left> + <height>60</height> + <width>100</width> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <texturefocus colordiffuse="FFFFFFFF" border="-20,0,-20,0">updn.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF" border="-20,0,-20,0">updn.png</texturenofocus> + </control> + <!-- divider --> + <control type="textbox"> + <top>30</top> + <left>120</left> + <height>60</height> + <width>20</width> + <textcolor>FFFFFFFF</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>[B]X[/B]</label> + </control> + <control type="button" id="102"> + <top>30</top> + <left>140</left> + <height>60</height> + <width>100</width> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <focusedcolor>FFFFFFFF</focusedcolor> + <texturefocus colordiffuse="FFFFFFFF" border="-20,0,-20,0">updn.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF" border="-20,0,-20,0">updn.png</texturenofocus> + </control> + <!-- ok --> + <control type="button" id="103"> + <top>35</top> + <left>260</left> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">ok.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">ok.png</texturenofocus> + </control> + <!-- Select Specials --> + <control type="button" id="104"> + <top>35</top> + <left>310</left> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">specials.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">specials.png</texturenofocus> + </control> + <!-- Manual renumeration --> + <control type="button" id="105"> + <top>35</top> + <left>360</left> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">manual.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">manual.png</texturenofocus> + </control> + <!-- delete --> + <control type="button" id="106"> + <top>35</top> + <left>410</left> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">delete.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">delete.png</texturenofocus> + </control> + <!-- annulla --> + <control type="button" id="107"> + <top>35</top> + <left>460</left> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus> + </control> + <control type="label" id="108"> + <bottom>5</bottom> + <width>100%</width> + <height>30</height> + <textcolor>FFFFFFFF</textcolor> + <align>center</align> + <aligny>center</aligny> + </control> + </control> + </control> + <!-- END MAIN SELECTION --> + + <!-- SPECIALS --> + <control type='group' id='200'> + <height>100%</height> + <width>100%</width> + + <!-- BACKGROUND --> + <control type="image" id="208"> + <top>0</top> + <left>0</left> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="FF232323">white.png</texture> + </control> + + <!-- POSTER --> + <control type="image" id="201"> + <top>0</top> + <left>0</left> + <height>720</height> + <width>480</width> + <texture/> + </control> + + <!-- EPISODES LIST --> + <control type="list" id="202"> + <top>140</top> + <left>520</left> + <height>540</height> + <width>340</width> + <onleft>10002</onleft> + <onright>203</onright> + <itemlayout width="340" height="60"> + <control type="label"> + <height>100%</height> + <width>300</width> + <left>20</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]Episodio $INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + </itemlayout> + <focusedlayout width="340" height="60"> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="22FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">Control.HasFocus(202)</visible> + </control> + <control type="image"> + <top>10</top> + <right>10</right> + <height>40</height> + <width>40</width> + <texture colordiffuse="FFFFFFFF">add.png</texture> + <visible allowhiddenfocus="true">Control.HasFocus(202)</visible> + </control> + <control type="label"> + <height>100%</height> + <width>300</width> + <left>20</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]Episodio $INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + </focusedlayout> + </control> + + <!-- SPECIALS LIST --> + <control type='group'> + <top>140</top> + <left>900</left> + <height>540</height> + <width>340</width> + <control type="list" id="203"> + <height>540</height> + <width>340</width> + <onleft>202</onleft> + <onright>204</onright> + <itemlayout width="340" height="60"> + <!-- EP NUMBER --> + <control type="label"> + <left>20</left> + <height>60</height> + <width>140</width> + <textcolor>80FFFFFF</textcolor> + <aligny>center</aligny> + <label>[B]0x$INFO[ListItem.Label()] - Ep. $INFO[ListItem.Property(title)][/B]</label> + </control> + </itemlayout> + <focusedlayout width="340" height="60"> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="22FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">!Control.HasFocus(202)</visible> + </control> + <!-- EP NUMBER --> + <control type="label"> + <left>20</left> + <height>60</height> + <width>140</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <label>[B]0x$INFO[ListItem.Label()] - Ep. $INFO[ListItem.Property(title)][/B]</label> + </control> + </focusedlayout> + </control> + + <!-- ITEM ACTIONS --> + <control type="group" id='204'> + <visible allowhiddenfocus="true">Integer.IsGreater(Container(203).Position,-1)</visible> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,0)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,1)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,2)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,3)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,4)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,5)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,6)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(203).Position,7)">Conditional</animation> + <!-- move up --> + <control type="button" id="205"> + <top>10</top> + <right>90</right> + <height>40</height> + <width>40</width> + <onleft>203</onleft> + <onright>206</onright> + <onup>Control.Move(203,-1)</onup> + <ondown>Control.Move(203,1)</ondown> + <texturefocus colordiffuse="FFFFFFFF">up.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">up.png</texturenofocus> + </control> + <!-- move down --> + <control type="button" id="206"> + <top>10</top> + <right>50</right> + <height>40</height> + <width>40</width> + <onleft>205</onleft> + <onright>207</onright> + <onup>Control.Move(203,-1)</onup> + <ondown>Control.Move(203,1)</ondown> + <texturefocus colordiffuse="FFFFFFFF">down.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">down.png</texturenofocus> + </control> + <!-- remove --> + <control type="button" id="207"> + <top>10</top> + <right>10</right> + <height>40</height> + <width>40</width> + <onleft>206</onleft> + <onright>10002</onright> + <onup>Control.Move(203,-1)</onup> + <ondown>Control.Move(203,1)</ondown> + <texturefocus colordiffuse="FFFFFFFF">delete.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">delete.png</texturenofocus> + </control> + </control> + </control> + </control> + <!-- END SPECIALS --> + + <!-- MANUAL --> + <control type='group' id='300'> + <height>100%</height> + <width>100%</width> + + <!-- BACKGROUND --> + <control type="image" id="310"> + <top>0</top> + <left>0</left> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="FF232323">white.png</texture> + </control> + + <!-- POSTER --> + <control type="image" id="301"> + <top>0</top> + <left>0</left> + <height>720</height> + <width>480</width> + </control> + + <!-- EPISODES LIST --> + <control type='group'> + <top>140</top> + <left>520</left> + <height>540</height> + <width>340</width> + <onleft>10002</onleft> + <onright>306</onright> + <control type="list" id="302"> + <height>100%</height> + <width>100%</width> + <onleft>10002</onleft> + <onright>306</onright> + <itemlayout width="340" height="60"> + <control type="label"> + <height>100%</height> + <width>120</width> + <left>20</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]Episodio $INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + <!-- first season number --> + <control type="textbox"> + <right>100</right> + <height>60</height> + <width>60</width> + <onleft>302</onleft> + <onright>307</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>80FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(season)][/B]</label> + </control> + <!-- divider --> + <control type="textbox"> + <right>80</right> + <height>60</height> + <width>20</width> + <textcolor>80FFFFFF</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>[B]X[/B]</label> + </control> + <!-- first episode number --> + <control type="textbox"> + <right>20</right> + <height>60</height> + <width>60</width> + <onleft>306</onleft> + <onright>308</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>80FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(episode)][/B]</label> + </control> + </itemlayout> + <focusedlayout width="340" height="60"> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="22FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">Control.HasFocus(302)</visible> + </control> + <control type="label"> + <height>100%</height> + <width>120</width> + <left>20</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]Episodio $INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + <!-- first season number --> + <control type="textbox"> + <right>100</right> + <height>60</height> + <width>60</width> + <onleft>302</onleft> + <onright>307</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(season)][/B]</label> + </control> + <!-- divider --> + <control type="textbox"> + <right>80</right> + <height>60</height> + <width>20</width> + <textcolor>FFFFFFFF</textcolor> + <align>center</align> + <aligny>center</aligny> + <label>[B]X[/B]</label> + </control> + <!-- first episode number --> + <control type="textbox"> + <right>20</right> + <height>60</height> + <width>60</width> + <onleft>306</onleft> + <onright>308</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Property(episode)][/B]</label> + </control> + </focusedlayout> + </control> + + <!-- MANUAL EPISODE CONTROL --> + <control type='group' id='305'> + <visible allowhiddenfocus="true">Integer.IsGreater(Container(302).Position,-1)</visible> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,0)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,1)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,2)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,3)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,4)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,5)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,6)">Conditional</animation> + <animation effect="slide" end="0,60" condition="Integer.IsGreater(Container(302).Position,7)">Conditional</animation> + <!-- first season number --> + <control type="button" id="306"> + <right>100</right> + <height>60</height> + <width>60</width> + <onleft>302</onleft> + <onright>307</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <texturefocus colordiffuse="FFFFFFFF">updn.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">updn.png</texturenofocus> + </control> + <!-- first episode number --> + <control type="button" id="307"> + <right>20</right> + <height>60</height> + <width>60</width> + <onleft>306</onleft> + <onright>303</onright> + <align>center</align> + <aligny>center</aligny> + <textcolor>FFFFFFFF</textcolor> + <texturefocus colordiffuse="FFFFFFFF">updn.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">updn.png</texturenofocus> + </control> + </control> + </control> + + <!-- SEASONS LIST --> + <control type='list' id='303'> + <top>140</top> + <left>880</left> + <height>540</height> + <width>80</width> + <onleft>302</onleft> + <onright>304</onright> + <itemlayout width="80" height="60"> + <control type="label"> + <height>100%</height> + <width>100%</width> + <textcolor>80FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label()][/B]</label> + <align>center</align> + <aligny>center</aligny> + </control> + </itemlayout> + <focusedlayout width="80" height="60"> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="22FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">Control.HasFocus(303)</visible> + </control> + <control type="label"> + <height>100%</height> + <width>100%</width> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label()][/B]</label> + <align>center</align> + <aligny>center</aligny> + <visible allowhiddenfocus="true">Control.HasFocus(303)</visible> + </control> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="11FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">!Control.HasFocus(303)</visible> + </control> + <control type="label"> + <height>100%</height> + <width>100%</width> + <textcolor>80FFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label()][/B]</label> + <align>center</align> + <aligny>center</aligny> + <visible allowhiddenfocus="true">!Control.HasFocus(303)</visible> + </control> + </focusedlayout> + </control> + + <control type="image"> + <top>140</top> + <left>960</left> + <height>540</height> + <height>100%</height> + <width>290</width> + <texture colordiffuse="11FFFFFF">white.png</texture> + </control> + + <!-- EPISODES LIST --> + <control type='list' id='304'> + <top>140</top> + <left>970</left> + <height>540</height> + <width>270</width> + <onleft>303</onleft> + <onright>10002</onright> + <itemlayout width="270" height="60"> + <control type="label"> + <height>100%</height> + <width>200</width> + <left>40</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + </itemlayout> + <focusedlayout width="270" height="60"> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="22FFFFFF">white.png</texture> + <visible allowhiddenfocus="true">Control.HasFocus(304)</visible> + </control> + <control type="label"> + <height>100%</height> + <width>200</width> + <left>40</left> + <textcolor>FFFFFFFF</textcolor> + <label>[B]$INFO[ListItem.Label()][/B]</label> + <aligny>center</aligny> + </control> + </focusedlayout> + </control> + </control> + <!-- END MANUAL --> + + <!-- MAIN ACTIONS --> + <control type='group' id='10000'> + <visible allowhiddenfocus="true">Control.IsVisible(200) | Control.IsVisible(300)</visible> + <!-- info --> + <control type="label" id="10001"> + <top>40</top> + <left>540</left> + <height>50</height> + <width>560</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + </control> + <!-- ok --> + <control type="button" id="10002"> + <top>40</top> + <right>90</right> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">ok.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">ok.png</texturenofocus> + <ondown condition="Control.IsVisible(200)">202</ondown> + <ondown condition="Control.IsVisible(300)">302</ondown> + <onleft>10003</onleft> + <onright>10003</onright> + </control> + <!-- annulla --> + <control type="button" id="10003"> + <top>40</top> + <right>40</right> + <height>50</height> + <width>50</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus colordiffuse="FFFFFFFF">close.png</texturefocus> + <texturenofocus colordiffuse="80FFFFFF">close.png</texturenofocus> + <ondown condition="Control.IsVisible(200)">202</ondown> + <ondown condition="Control.IsVisible(300)">302</ondown> + <onleft>10002</onleft> + <onright>10002</onright> + </control> + </control> + <!-- END MAIN ACTIONS --> + + </controls> +</window> diff --git a/resources/skins/Default/720p/TitleOrIDWindow.xml b/resources/skins/Default/720p/TitleOrIDWindow.xml new file mode 100644 index 00000000..3e6b2b39 --- /dev/null +++ b/resources/skins/Default/720p/TitleOrIDWindow.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8"?> +<window> + <allowoverlays>false</allowoverlays> + <animation type="WindowOpen" reversible="false"> + <effect type="fade" start="0" end="100" time="300" /> + </animation> + <animation type="WindowClose" reversible="false"> + <effect type="fade" start="100" end="0" time="300" /> + </animation> + <controls> + <control type="button" id="10005"> + <top>0</top> + <left>0</left> + <height>100%</height> + <width>100%</width> + <texturefocus colordiffuse="80232323">white.png</texturefocus> + <texturenofocus colordiffuse="80232323">white.png</texturenofocus> + </control> + <control type="group"> + <top>210</top> + <left>175</left> + <height>300</height> + <width>930</width> + <!-- Beckground --> + <control type="image"> + <height>100%</height> + <width>100%</width> + <texture colordiffuse="FF232323">white.png</texture> + </control> + <!-- Header --> + <control type="textbox" id="10000"> + <top>40</top> + <left>40</left> + <height>40</height> + <width>850</width> + <font>font30_title</font> + <textcolor>FFFFFFFF</textcolor> + <label></label> + </control> + <!-- divisor --> + <control type="image"> + <top>90</top> + <left>40</left> + <height>1</height> + <width>850</width> + <texture colordiffuse="FFFFFFFF">white.png</texture> + </control> + <!-- titolo --> + <control type="edit" id="10001"> + <top>120</top> + <left>40</left> + <height>60</height> + <width>630</width> + <textcolor>FFFFFFFF</textcolor> + <texturefocus colordiffuse="FF0082C2">white.png</texturefocus> + <texturenofocus colordiffuse="FF232323">white.png</texturenofocus> + <aligny>center</aligny> + <label>$ADDON[plugin.video.kod 60230]</label> + <ondown>10002</ondown> + <onright>10003</onright> + </control> + <!-- id --> + <control type="edit" id="10002"> + <top>200</top> + <left>40</left> + <height>60</height> + <width>630</width> + <textcolor>FFFFFFFF</textcolor> + <texturefocus colordiffuse="FF0082C2">white.png</texturefocus> + <texturenofocus colordiffuse="FF232323">white.png</texturenofocus> + <aligny>center</aligny> + <label></label> + <onup>10001</onup> + <onright>10003</onright> + </control> + <!-- ok --> + <control type="button" id="10003"> + <top>120</top> + <left>690</left> + <label>$ADDON[plugin.video.kod 70001]</label> + <height>60</height> + <width>200</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus border="10" colordiffuse="FF0082C2">white.png</texturefocus> + <texturenofocus border="10" colordiffuse="FF232323">white.png</texturenofocus> + <ondown>10004</ondown> + <onleft>10001</onleft> + </control> + <!-- annulla --> + <control type="button" id="10004"> + <top>200</top> + <left>690</left> + <label>$ADDON[plugin.video.kod 70002]</label> + <height>60</height> + <width>200</width> + <textcolor>FFFFFFFF</textcolor> + <aligny>center</aligny> + <align>center</align> + <texturefocus border="10" colordiffuse="FF0082C2">white.png</texturefocus> + <texturenofocus border="10" colordiffuse="FF232323">white.png</texturenofocus> + <onup>10003</onup> + <onleft>10001</onleft> + </control> + </control> + </controls> +</window> diff --git a/resources/skins/Default/media/add.png b/resources/skins/Default/media/add.png new file mode 100644 index 00000000..36e84450 Binary files /dev/null and b/resources/skins/Default/media/add.png differ diff --git a/resources/skins/Default/media/close.png b/resources/skins/Default/media/close.png index 0eb9e133..b647ddca 100644 Binary files a/resources/skins/Default/media/close.png and b/resources/skins/Default/media/close.png differ diff --git a/resources/skins/Default/media/delete.png b/resources/skins/Default/media/delete.png new file mode 100644 index 00000000..f8105582 Binary files /dev/null and b/resources/skins/Default/media/delete.png differ diff --git a/resources/skins/Default/media/down.png b/resources/skins/Default/media/down.png new file mode 100644 index 00000000..c43ed16b Binary files /dev/null and b/resources/skins/Default/media/down.png differ diff --git a/resources/skins/Default/media/exit.png b/resources/skins/Default/media/exit.png new file mode 100644 index 00000000..b2dc396c Binary files /dev/null and b/resources/skins/Default/media/exit.png differ diff --git a/resources/skins/Default/media/left.png b/resources/skins/Default/media/left.png new file mode 100644 index 00000000..fc853099 Binary files /dev/null and b/resources/skins/Default/media/left.png differ diff --git a/resources/skins/Default/media/manual.png b/resources/skins/Default/media/manual.png new file mode 100644 index 00000000..df30ed0c Binary files /dev/null and b/resources/skins/Default/media/manual.png differ diff --git a/resources/skins/Default/media/ok.png b/resources/skins/Default/media/ok.png new file mode 100644 index 00000000..d9292366 Binary files /dev/null and b/resources/skins/Default/media/ok.png differ diff --git a/resources/skins/Default/media/pause.png b/resources/skins/Default/media/pause.png new file mode 100644 index 00000000..c6510af6 Binary files /dev/null and b/resources/skins/Default/media/pause.png differ diff --git a/resources/skins/Default/media/play.png b/resources/skins/Default/media/play.png new file mode 100644 index 00000000..94a92ade Binary files /dev/null and b/resources/skins/Default/media/play.png differ diff --git a/resources/skins/Default/media/right.png b/resources/skins/Default/media/right.png new file mode 100644 index 00000000..4e5c97fe Binary files /dev/null and b/resources/skins/Default/media/right.png differ diff --git a/resources/skins/Default/media/specials.png b/resources/skins/Default/media/specials.png new file mode 100644 index 00000000..17c187e1 Binary files /dev/null and b/resources/skins/Default/media/specials.png differ diff --git a/resources/skins/Default/media/stop.png b/resources/skins/Default/media/stop.png new file mode 100644 index 00000000..07b7d8d3 Binary files /dev/null and b/resources/skins/Default/media/stop.png differ diff --git a/resources/skins/Default/media/up.png b/resources/skins/Default/media/up.png new file mode 100644 index 00000000..e2de1263 Binary files /dev/null and b/resources/skins/Default/media/up.png differ diff --git a/resources/skins/Default/media/updn.png b/resources/skins/Default/media/updn.png new file mode 100644 index 00000000..884b049e Binary files /dev/null and b/resources/skins/Default/media/updn.png differ