From 048abf9a2db7733cecb9b97705d4a2f08c62be02 Mon Sep 17 00:00:00 2001 From: greko17 <50103632+greko17@users.noreply.github.com> Date: Tue, 30 Apr 2019 12:52:12 +0200 Subject: [PATCH 01/62] Altadefinizione01 L speriamo...io me la cavo! --- channels/altadefinizione01_link.json | 86 ++++++++ channels/altadefinizione01_link.py | 317 +++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 channels/altadefinizione01_link.json create mode 100644 channels/altadefinizione01_link.py diff --git a/channels/altadefinizione01_link.json b/channels/altadefinizione01_link.json new file mode 100644 index 00000000..55dc2a9c --- /dev/null +++ b/channels/altadefinizione01_link.json @@ -0,0 +1,86 @@ +{ + "id": "altadefinizione01_link", + "name": "Altadefinizione01 L", + "active": true, + "adult": false, + "language": ["ita"], + "fanart": "", + "thumbnail": "", + "banner": "http://altadefinizione01.link/templates/Dark/img/logonyy.png", + "fix" : "reimpostato url e modificato file per KOD", + "change_date": "2019-30-04", + "categories": [ + "movie" + ], + "settings": [ + { + "id": "modo_grafico", + "type": "bool", + "label": "Buscar información extra", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_newest_film", + "type": "bool", + "label": "Includi in Novità", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_global_search", + "type": "bool", + "label": "Includi ricerca globale", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces", + "type": "bool", + "label": "Verifica se i link esistono", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces_num", + "type": "list", + "label": "Numero de link da verificare", + "default": 1, + "enabled": true, + "visible": "eq(-1,true)", + "lvalues": [ "5", "10", "15", "20" ] + }, + { + "id": "filter_languages", + "type": "list", + "label": "Mostra link in lingua...", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Non filtrare", + "IT" + ] + }, + { + "id": "perfil", + "type": "list", + "label": "profilo dei colori", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Sin color", + "Perfil 5", + "Perfil 4", + "Perfil 3", + "Perfil 2", + "Perfil 1" + ] + } + ] +} diff --git a/channels/altadefinizione01_link.py b/channels/altadefinizione01_link.py new file mode 100644 index 00000000..a30ce9f2 --- /dev/null +++ b/channels/altadefinizione01_link.py @@ -0,0 +1,317 @@ +# -*- coding: utf-8 -*- +# -*- Channel Altadefinizione01L Film - Serie -*- +# -*- Creato per Alfa-addon -*- +# -*- e adattato for KOD -*- +# -*- By Greko -*- +# -*- change 30/04/2019 + +from channelselector import get_thumb +from channels import autoplay +from channels import filtertools +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from core import channeltools +from core import tmdb +from platformcode import config, logger + +__channel__ = "altadefinizione01_link" + +host = "https://altadefinizione01.link/" #riaggiornato al 29 aprile 2019 +#host = "http://altadefinizione01.art/" # aggiornato al 22 marzo 2019 +#host = "https://altadefinizione01.network/" #aggiornato al 22 marzo 2019 + +# ======== def per utility INIZIO ============================= +try: + __modo_grafico__ = config.get_setting('modo_grafico', __channel__) + __perfil__ = int(config.get_setting('perfil', __channel__)) +except: + __modo_grafico__ = True + __perfil__ = 0 + +# Fijar perfil de color +perfil = [['0xFFFFE6CC', '0xFFFFCE9C', '0xFF994D00', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFFA5F6AF', '0xFF5FDA6D', '0xFF11811E', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFF58D3F7', '0xFF2E9AFE', '0xFF2E64FE', '0xFFFE2E2E', '0xFFFFD700']] + +if __perfil__ < 3: + color1, color2, color3, color4, color5 = perfil[__perfil__] +else: + color1 = color2 = color3 = color4 = color5 = "" + +__comprueba_enlaces__ = config.get_setting('comprueba_enlaces', __channel__) +__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', __channel__) + +headers = [['User-Agent', 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'], + ['Referer', host]]#,['Accept-Language','it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3']] + + +IDIOMAS = {'Italiano': 'ITA'} +list_language = IDIOMAS.values() +list_servers = []#'openload', 'streamcherry', 'youtube','rapidvideo', 'streamango'] +list_quality = []#'default'] + +# =========== home menu =================== + +def mainlist(item): + """ + Creo il menu principale del canale + :param item: + :return: itemlist [] + """ + logger.info("%s mainlist log: %s" % (__channel__, item)) + itemlist = [] + title = '' + + autoplay.init(item.channel, list_servers, list_quality) + + itemlist = [ + # new upload + Item(channel=__channel__, title="Ultimi Arrivi", action="peliculas", + url="%s" % host, text_color=color4, extra="film", # color4 = red + thumbnail=get_thumb(title, auto = True) + ), + # x to Cinema + Item(channel=__channel__, title="Al Cinema", action="peliculas", + url="%sfilm-del-cinema" % host, text_color=color4, extra="", + thumbnail=get_thumb(title, auto = True) + ), + # Popolari + Item(channel=__channel__, title="Popolari", action="peliculas", + url="%spiu-visti.html" % host, text_color=color4, extra="", + thumbnail=get_thumb(title, auto = True) + ), + # x Sub-ita + Item(channel=__channel__, title="Sottotitolati", action="peliculas", + url="%sfilm-sub-ita/" % host, text_color=color4, extra="", + thumbnail=get_thumb(title, auto = True) + ), + # x mi sento fortunato - Prende solo film con player a pagamento + Item(channel=__channel__, title="Mi Sento Fortunato", action="categorie", + url="%s" % host, text_color=color4, extra="lucky", + thumbnail=""), + # x Category + Item(channel=__channel__, title="Generi", action="categorie", + url="%s" % host, text_color=color4, extra="genres", + viewcontent='movies', + thumbnail=get_thumb(title, auto = True) + ), + # x year + Item(channel=__channel__, title="Anno", action="categorie", + url="%s" % host, text_color=color4, extra="year", + thumbnail=get_thumb(title, auto = True) + ), + # x quality + Item(channel=__channel__, title="Qualità", action="categorie", + url="%s" % host, text_color=color4, extra="quality", + thumbnail=get_thumb(title, auto = True) + ), + # Search + Item(channel=__channel__, title="Cerca Film...", action="search", + text_color=color4, extra="", + thumbnail=get_thumb(title, auto = True) + ), + ] + + autoplay.show_option(item.channel, itemlist) + + return itemlist + +# ======== def in ordine di menu =========================== + +def peliculas(item): + logger.info("%s mainlist peliculas log: %s" % (__channel__, item)) + itemlist = [] + # scarico la pagina + data = httptools.downloadpage(item.url, headers=headers).data + + # da qui fare le opportuni modifiche + patron = 'class="innerImage">.*?href="([^"]+)".*?src="([^"]+)".*?'\ + 'class="ml-item-title">([^"]+)'\ + '(.*?)<.*?class="ml-item-label">.*?class="ml-item-label">(.*?)") + if not next_page: + next_page = scrapertools.find_single_match(data, '\d ') + + if next_page != "": + itemlist.append( + Item(channel=item.channel, + action="peliculas", + title=config.get_localized_string(30992), + url=next_page, + extra=item.extra, + text_color=color4, + thumbnail= get_thumb('nextpage', auto = True) + )) + + return itemlist + +# =========== def pagina categorie ====================================== + +def categorie(item): + logger.info("%s mainlist categorie log: %s" % (__channel__, item)) + itemlist = [] + # scarico la pagina + data = httptools.downloadpage(item.url, headers=headers).data + + # da qui fare le opportuni modifiche + if item.extra == 'genres': + bloque = scrapertools.find_single_match(data, '') + elif item.extra == 'year': + bloque = scrapertools.find_single_match(data, '') + elif item.extra == 'quality': + bloque = scrapertools.find_single_match(data, '') + elif item.extra == 'lucky': # sono i titoli random nella pagina, alcuni rimandano solo a server a pagamento + bloque = scrapertools.find_single_match(data, 'FILM RANDOM.*?class="listSubCat">(.*?)') + patron = '
  • (.*?)<' + matches = scrapertools.find_multiple_matches(bloque, patron) + + if item.extra == 'lucky': + bloque = scrapertools.find_single_match(data, 'FILM RANDOM.*?class="listSubCat">(.*?)') + patron = '
  • (.*?)<' + matches = scrapertools.find_multiple_matches(bloque, patron) + + for scrapurl, scraptitle in sorted(matches): + if item.extra != 'lucky': + url = host+scrapurl + action="peliculas" + else: + url = scrapurl + action = "findvideos_film" + itemlist.append(Item( + channel=item.channel, + action=action, + title = scraptitle, + url=url, + #extra = '', + text_color=color4, + thumbnail=get_thumb(scraptitle, auto = True), + Folder = True, + )) + + return itemlist + + +# =========== def pagina del film con i server per verderlo ============= +# da sistemare che ne da solo 1 come risultato + +def findvideos_film(item): + logger.info("%s mainlist findvideos_film log: %s" % (__channel__, item)) + itemlist = [] + # scarico la pagina + #data = scrapertools.cache_page(item.url) #non funziona più? + data = httptools.downloadpage(item.url, headers=headers).data + # da qui fare le opportuni modifiche + patron = '' + matches = scrapertools.find_multiple_matches(data, patron) + #logger.info("altadefinizione01_linkMATCHES: %s " % matches) + for scrapedurl in matches: + #if 'vodexor' and 'megadrive' not in scrapedurl: + #data = httptools.downloadpage(scrapedurl, headers=headers).data + try: + itemlist = servertools.find_video_items(data=data) + + for videoitem in itemlist: + logger.info("Videoitemlist2: %s" % videoitem) + videoitem.title = "%s [%s]" % (item.contentTitle, videoitem.title)#"[%s] %s" % (videoitem.server, item.title) #"[%s]" % (videoitem.title) + videoitem.show = item.show + videoitem.contentTitle = item.contentTitle + videoitem.contentType = item.contentType + videoitem.channel = item.channel + videoitem.text_color = color5 + #videoitem.language = item.language + videoitem.year = item.infoLabels['year'] + videoitem.infoLabels['plot'] = item.infoLabels['plot'] + except AttributeError: + logger.error("data doesn't contain expected URL") + + # Controlla se i link sono validi + if __comprueba_enlaces__: + itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__) + + # Requerido para FilterTools + itemlist = filtertools.get_links(itemlist, item, list_language) + + # Requerido para AutoPlay + autoplay.start(itemlist, item) + + # Opción "Añadir esta película a la biblioteca de KODI" + if item.extra != "library": + + itemlist.append(Item(channel=__channel__, title="Aggiungi alla Videoteca", text_color="green", + action="add_pelicula_to_library", url=item.url, + thumbnail= get_thumb('videolibrary', auto = True), + contentTitle=item.contentTitle, infoLabels = item.infoLabels + )) + + return itemlist + +# =========== def per cercare film/serietv ============= +#host+/index.php?do=search&story=avatar&subaction=search +def search(item, text): + logger.info("%s mainlist search log: %s %s" % (__channel__, item, text)) + itemlist = [] + text = text.replace(" ", "+") + item.url = host+"/index.php?do=search&story=%s&subaction=search" % (text) + #item.extra = "search" + try: + return peliculas(item) + # Se captura la excepciÛn, para no interrumpir al buscador global si un canal falla + except: + import sys + for line in sys.exc_info(): + logger.info("%s mainlist search log: %s" % (__channel__, line)) + return [] + +# =========== def per le novità nel menu principale ============= + +def newest(categoria): + logger.info("%s mainlist search log: %s" % (__channel__, categoria)) + itemlist = [] + item = Item() + #item.extra = 'film' + try: + if categoria == "film": + item.url = host + item.action = "peliculas" + itemlist = peliculas(item) + + + if itemlist[-1].action == "peliculas": + itemlist.pop() + + # Continua la ricerca in caso di errore + except: + import sys + for line in sys.exc_info(): + logger.error("{0}".format(line)) + return [] + + return itemlist From 784e8c82a7551918ffd07b664d5ab7152d9dc626 Mon Sep 17 00:00:00 2001 From: greko17 <50103632+greko17@users.noreply.github.com> Date: Tue, 30 Apr 2019 13:00:29 +0200 Subject: [PATCH 02/62] eurostreaming Sostituiscono gli attuali che hanno i seguenti problemi: 1. Non aprono tutte le serie, in quanto nella pagina del sito si deve cliccare su una voce per aprire la lista degli episodi 2. Quando si aggiungono una serie nella videoteca e si hanno episodi in italiano e sottotitolati, vengono aggiunti correttamente i titoli in italiano ma i video sono sottotitolati. --- channels/eurostreaming.json | 114 ++++++--- channels/eurostreaming.py | 459 ++++++++++++++++++++++++------------ 2 files changed, 388 insertions(+), 185 deletions(-) diff --git a/channels/eurostreaming.json b/channels/eurostreaming.json index d1502022..d972d2b8 100644 --- a/channels/eurostreaming.json +++ b/channels/eurostreaming.json @@ -1,44 +1,82 @@ { "id": "eurostreaming", "name": "Eurostreaming", - "language": ["ita"], - "active": true, + "active": true, "adult": false, - "thumbnail": "https://raw.githubusercontent.com/Zanzibar82/images/master/posters/eurostreaming.png", - "banner": "https://raw.githubusercontent.com/Zanzibar82/images/master/posters/eurostreaming.png", + "language": ["ita"], + "thumbnail": "", + "bannermenu": "", "categories": ["tvshow","anime"], - "settings": [ - { - "id": "include_in_global_search", - "type": "bool", - "label": "Includi ricerca globale", - "default": true, - "enabled": true, - "visible": true - }, - { - "id": "include_in_newest_series", - "type": "bool", - "label": "Includi in Novità - Serie TV", - "default": true, - "enabled": true, - "visible": true - }, - { - "id": "include_in_newest_anime", - "type": "bool", - "label": "Includi in Novità - Anime", - "default": false, - "enabled": false, - "visible": false - }, - { - "id": "include_in_newest_italiano", - "type": "bool", - "label": "Includi in Novità - Italiano", - "default": true, - "enabled": true, - "visible": true - } - ] + "settings": [ + { + "id": "include_in_global_search", + "type": "bool", + "label": "Includi ricerca globale", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "modo_grafico", + "type": "bool", + "label": "Buscar información extra", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_newest_series", + "type": "bool", + "label": "Includi in novità - Serie TV", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces", + "type": "bool", + "label": "Verifica se i link esistono", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces_num", + "type": "list", + "label": "Numero de link da verificare", + "default": 1, + "enabled": true, + "visible": "eq(-1,true)", + "lvalues": [ "5", "10", "15", "20" ] + }, + { + "id": "filter_languages", + "type": "list", + "label": "Mostra link in lingua...", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Non filtrare", + "ITA", + "SUB ITA" + ] + }, + { + "id": "perfil", + "type": "list", + "label": "profilo dei colori", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Sin color", + "Perfil 5", + "Perfil 4", + "Perfil 3", + "Perfil 2", + "Perfil 1" + ] + } + ] } diff --git a/channels/eurostreaming.py b/channels/eurostreaming.py index 33f83ab0..94fad807 100644 --- a/channels/eurostreaming.py +++ b/channels/eurostreaming.py @@ -1,65 +1,115 @@ # -*- coding: utf-8 -*- -# ------------------------------------------------------------ -# Ringraziamo Icarus crew -# Canale per eurostreaming -# ------------------------------------------------------------ -import re, urlparse +# -*- Created or modificated for Alfa-Addon -*- +# -*- adpted for KOD -*- +# -*- By Greko -*- -from channels import autoplay -from core import scrapertools, httptools, servertools, tmdb, scrapertoolsV2 -from core.item import Item +#import base64 +import re +import urlparse +# gli import sopra sono da includere all'occorrenza +# per url con ad.fly from lib import unshortenit -from platformcode import logger, config -from channelselector import thumb -host = "https://eurostreaming.cafe" +from channelselector import get_thumb +from channels import autoplay +from channels import filtertools +from core import httptools +from core import scrapertoolsV2 +from core import servertools +from core.item import Item +from core import channeltools +from core import tmdb +from platformcode import config, logger + +__channel__ = "eurostreaming" #stesso di id nel file json + +#host = "https://eurostreaming.zone/" +#host = "https://eurostreaming.black/" +host = "https://eurostreaming.cafe/" #aggiornato al 30-04-2019 + +# ======== def per utility INIZIO ============================= +try: + __modo_grafico__ = config.get_setting('modo_grafico', __channel__) + __perfil__ = int(config.get_setting('perfil', __channel__)) +except: + __modo_grafico__ = True + __perfil__ = 0 + +# Fijar perfil de color +perfil = [['0xFFFFE6CC', '0xFFFFCE9C', '0xFF994D00', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFFA5F6AF', '0xFF5FDA6D', '0xFF11811E', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFF58D3F7', '0xFF2E9AFE', '0xFF2E64FE', '0xFFFE2E2E', '0xFFFFD700']] + +if __perfil__ < 3: + color1, color2, color3, color4, color5 = perfil[__perfil__] +else: + color1 = color2 = color3 = color4 = color5 = "" + +__comprueba_enlaces__ = config.get_setting('comprueba_enlaces', __channel__) +__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', __channel__) + +headers = [['User-Agent', 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'], + ['Referer', host]]#,['Accept-Language','it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3']] + +parameters = channeltools.get_channel_parameters(__channel__) +fanart_host = parameters['fanart'] +thumbnail_host = parameters['thumbnail'] + +IDIOMAS = {'Italiano': 'IT', 'VOSI':'SUB ITA'} +list_language = IDIOMAS.values() +# per l'autoplay list_servers = ['openload', 'speedvideo', 'wstream', 'streamango' 'flashx', 'nowvideo'] -list_quality = ['default'] +list_quality = ['default'] +# =========== home menu =================== def mainlist(item): - logger.info("kod.eurostreaming mainlist") - autoplay.init(item.channel, list_servers, list_quality) - + logger.info("icarus.eurostreaming mainlist") + itemlist = [] + title = '' + itemlist = [ - Item( - channel=item.channel, - title="[B]Serie TV[/B]", - action="serietv", - extra="tvshow", + Item(channel=__channel__, title="Serie TV", + contentTitle = __channel__, action="serietv", + #extra="tvshow", + text_color=color4, url="%s/category/serie-tv-archive/" % host, - thumbnail= - "http://orig03.deviantart.net/6889/f/2014/079/7/b/movies_and_popcorn_folder_icon_by_matheusgrilo-d7ay4tw.png" - ), - Item( - channel=item.channel, - title="[B]Anime / Cartoni[/B]", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + Item(channel=__channel__, title="Ultimi Aggiornamenti", + contentTitle = __channel__, action="elenco_aggiornamenti_serietv", + text_color=color4, url="%saggiornamento-episodi/" % host, + #category = __channel__, + extra="tvshow", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + Item(channel=__channel__, + title="Anime / Cartoni", action="serietv", extra="tvshow", + text_color=color4, url="%s/category/anime-cartoni-animati/" % host, - thumbnail= - "http://orig09.deviantart.net/df5a/f/2014/169/2/a/fist_of_the_north_star_folder_icon_by_minacsky_saya-d7mq8c8.png" - ), - Item( - channel=item.channel, - title="[COLOR blue]Cerca...[/COLOR]", + thumbnail= get_thumb(title, auto = True) + ), + Item(channel=__channel__, + title="[COLOR yellow]Cerca...[/COLOR]", action="search", extra="tvshow", - thumbnail= - "http://dc467.4shared.com/img/fEbJqOum/s7/13feaf0c8c0/Search") + text_color=color4, + thumbnail= get_thumb(title, auto = True) + ), ] - autoplay.show_option(item.channel, itemlist) - - itemlist = thumb(itemlist) - return itemlist +# ======== def in ordine di menu =========================== def serietv(item): - logger.info("kod.eurostreaming peliculas") + + logger.info("%s serietv log: %s" % (__channel__, item)) itemlist = [] - # Carica la pagina data = httptools.downloadpage(item.url).data @@ -68,29 +118,30 @@ def serietv(item): matches = re.compile(patron, re.DOTALL).findall(data) for scrapedurl, scrapedtitle, scrapedthumbnail in matches: - scrapedplot = "" - scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle.replace("Streaming", "")) + #scrapedplot = "" + scrapedtitle = scrapertoolsV2.decodeHtmlentities(scrapedtitle)#.replace("Streaming", "")) if scrapedtitle.startswith("Link to "): scrapedtitle = scrapedtitle[8:] - # num = scrapertools.find_single_match(scrapedurl, '(-\d+/)') - # if num: - # scrapedurl = scrapedurl.replace(num, "-episodi/") + num = scrapertoolsV2.find_single_match(scrapedurl, '(-\d+/)') + if num: + scrapedurl = scrapedurl.replace(num, "-episodi/") itemlist.append( - Item( - channel=item.channel, + Item(channel=item.channel, action="episodios", - contentType="tvshow", + #contentType="tvshow", + contentSerieName = scrapedtitle, title=scrapedtitle, - fulltitle=scrapedtitle, - text_color="azure", + #text_color="azure", url=scrapedurl, thumbnail=scrapedthumbnail, - plot=scrapedplot, - show=scrapedtitle, + #plot=scrapedplot, + show=item.show, extra=item.extra, - folder=True)) + folder=True + )) - tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + # locandine e trama e altro da tmdb se presente l'anno migliora la ricerca + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True, idioma_busqueda='it') # Paginazione patronvideos = '' @@ -102,17 +153,125 @@ def serietv(item): Item( channel=item.channel, action="serietv", - title="[COLOR blue]" + config.get_localized_string(30992) + "[/COLOR]", + title="[COLOR lightgreen]" + config.get_localized_string(30992) + "[/COLOR]", url=scrapedurl, - thumbnail=thumb(), + thumbnail= + "http://2.bp.blogspot.com/-fE9tzwmjaeQ/UcM2apxDtjI/AAAAAAAAeeg/WKSGM2TADLM/s1600/pager+old.png", extra=item.extra, folder=True)) return itemlist +def episodios(item): + #logger.info("%s episodios log: %s" % (__channel__, item)) + itemlist = [] + + if not(item.lang): + lang_season = {'ITA':0, 'SUB ITA' :0} + # Download pagina + data = httptools.downloadpage(item.url).data + #======== + if 'clicca qui per aprire' in data.lower(): + logger.info("%s CLICCA QUI PER APRIRE GLI EPISODI log: %s" % (__channel__, item)) + item.url = scrapertoolsV2.find_single_match(data, '"go_to":"(.*?)"') + item.url = item.url.replace("\\","") + # Carica la pagina + data = httptools.downloadpage(item.url).data + #logger.info("%s FINE CLICCA QUI PER APRIRE GLI EPISODI log: %s" % (__channel__, item)) + elif 'clicca qui' in data.lower(): + logger.info("%s inizio CLICCA QUI log: %s" % (__channel__, item)) + item.url = scrapertoolsV2.find_single_match(data, '

    ') + data = httptools.downloadpage(item.url).data + #logger.info("%s fine CLICCA QUI log: %s" % (__channel__, item)) + #========= + data = scrapertoolsV2.decodeHtmlentities(data) + bloque = scrapertoolsV2.find_single_match(data, '
    (.*?)
    ') + patron = '(.*?)
    ' + matches = scrapertoolsV2.find_multiple_matches(bloque, patron) + for scrapedseason in matches: + #logger.info("%s scrapedseason log: %s" % (__channel__, scrapedseason)) + if "(SUB ITA)" in scrapedseason.upper(): + lang = "SUB ITA" + lang_season['SUB ITA'] +=1 + else: + lang = "ITA" + lang_season['ITA'] +=1 + #logger.info("%s lang_dict log: %s" % (__channel__, lang_season)) + + for lang in sorted(lang_season): + if lang_season[lang] > 0: + itemlist.append( + Item(channel = item.channel, + action = "episodios", + #contentType = "episode", + contentSerieName = item.title, + title = '%s (%s)' % (item.title, lang), + url = item.url, + fulltitle = item.title, + data = data, + lang = lang, + show = item.show, + folder = True, + )) + + # locandine e trama e altro da tmdb se presente l'anno migliora la ricerca + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True, idioma_busqueda='it') + + return itemlist + + else: + # qui ci vanno le puntate delle stagioni + html = item.data + logger.info("%s else log: [%s]" % (__channel__, item)) + + if item.lang == 'SUB ITA': + item.lang = '\(SUB ITA\)' + logger.info("%s item.lang log: %s" % (__channel__, item.lang)) + bloque = scrapertoolsV2.find_single_match(html, '
    (.*?)
    ') + patron = '.*?'+item.lang+'
    (.*?)' # leggo tutte le stagioni + #logger.info("%s patronpatron log: %s" % (__channel__, patron)) + matches = scrapertoolsV2.find_multiple_matches(bloque, patron) + for scrapedseason in matches: + #logger.info("%s scrapedseasonscrapedseason log: %s" % (__channel__, scrapedseason)) + scrapedseason = scrapedseason.replace('','').replace('','') + patron = '(\d+)×(\d+)(.*?)<(.*?)
    ' # stagione - puntanta - titolo - gruppo link + matches = scrapertoolsV2.find_multiple_matches(scrapedseason, patron) + for scrapedseason, scrapedpuntata, scrapedtitolo, scrapedgroupurl in matches: + #logger.info("%s finale log: %s" % (__channel__, patron)) + scrapedtitolo = scrapedtitolo.replace('–','') + itemlist.append(Item(channel = item.channel, + action = "findvideos", + contentType = "episode", + #contentSerieName = item.contentSerieName, + contentTitle = scrapedtitolo, + title = '%sx%s %s' % (scrapedseason, scrapedpuntata, scrapedtitolo), + url = scrapedgroupurl, + fulltitle = item.fulltitle, + #show = item.show, + #folder = True, + )) + + logger.info("%s itemlistitemlist log: %s" % (__channel__, itemlist)) + + # Opción "Añadir esta película a la biblioteca de KODI" + if item.extra != "library": + if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findvideos': + itemlist.append(Item(channel=item.channel, title="%s" % config.get_localized_string(30161), + text_color="green", extra="episodios", + action="add_serie_to_library", url=item.url, + thumbnail= get_thumb('videolibrary', auto = True), + contentTitle=item.contentSerieName, lang = item.lang, + show=item.show, data = html + #, infoLabels = item.infoLabels + )) + + return itemlist + +# =========== def ricerca ============= def search(item, texto): - logger.info("[eurostreaming.py] " + item.url + " search " + texto) - item.url = "%s/?s=%s" % (host, texto) + #logger.info("[eurostreaming.py] " + item.url + " search " + texto) + logger.info("%s search log: %s" % (__channel__, item)) + item.url = "%s?s=%s" % (host, texto) try: return serietv(item) # Continua la ricerca in caso di errore @@ -122,116 +281,122 @@ def search(item, texto): logger.error("%s" % line) return [] - -def episodios(item): - def load_episodios(html, item, itemlist, lang_title): - patron = '((?:.*?]+>[^<][^<]+<(?:b|\/)[^>]+>)+)' - matches = re.compile(patron).findall(html) - for data in matches: - # Estrazione - - scrapedtitle = data.split('
    ]*>', '', scrapedtitle).strip() - if scrapedtitle != 'Categorie': - scrapedtitle = scrapedtitle.replace('×', 'x') - scrapedtitle = scrapedtitle.replace('×', 'x') - itemlist.append( - Item(channel=item.channel, - action="findvideos", - contentType="episode", - title="[COLOR azure]%s[/COLOR]" % (scrapedtitle + " (" + lang_title + ")"), - url=data, - thumbnail=item.thumbnail, - extra=item.extra, - fulltitle=scrapedtitle + " (" + lang_title + ")" + ' - ' + item.show, - show=item.show)) - - logger.info("[eurostreaming.py] episodios") - +# =========== def novità in ricerca globale ============= +def newest(categoria): + logger.info("%s newest log: %s" % (__channel__, categoria)) itemlist = [] + item = Item() + try: + + item.url = "%saggiornamento-episodi/" % host + item.action = "elenco_aggiornamenti_serietv" + itemlist = elenco_aggiornamenti_serietv(item) - # Download pagina - data = httptools.downloadpage(item.url).data - data = scrapertools.decodeHtmlentities(data) - link = False + if itemlist[-1].action == "elenco_aggiornamenti_serietv": + itemlist.pop() - if scrapertoolsV2.find_single_match(data, '
    .*?var nano_ajax_object =.*?"go_to":"(.*?)"').replace('\\', '') - link = True - else: - match = scrapertoolsV2.find_single_match(data, '

    .*?.{0,5}

    ') - if match != '': - item.url = match - link = True - if link: - data = httptools.downloadpage(item.url).data - data = scrapertools.decodeHtmlentities(data) - - data = scrapertoolsV2.find_single_match(data, '
    (.+?)
    ') - - lang_titles = [] - starts = [] - patron = r"STAGIONE.*?ITA" - matches = re.compile(patron, re.IGNORECASE).finditer(data) - - for match in matches: - season_title = match.group() - - if season_title != '': - lang_titles.append('SUB ITA' if 'SUB' in season_title.upper() else 'ITA') - starts.append(match.end()) - - i = 1 - len_lang_titles = len(lang_titles) - - while i <= len_lang_titles: - inizio = starts[i - 1] - fine = starts[i] if i < len_lang_titles else -1 - - html = data[inizio:fine] - lang_title = lang_titles[i - 1] - - load_episodios(html, item, itemlist, lang_title) - - i += 1 - - if config.get_videolibrary_support() and len(itemlist) != 0: - itemlist.append( - Item(channel=item.channel, - title="[COLOR lightblue]%s[/COLOR]" % config.get_localized_string(30161), - url=item.url, - action="add_serie_to_library", - extra="episodios", - show=item.show)) + # Continua la ricerca in caso di errore + except: + import sys + for line in sys.exc_info(): + logger.error("{0}".format(line)) + return [] return itemlist +# =========== def pagina aggiornamenti ============= + +# ======== Ultimi Aggiornamenti =========================== +def elenco_aggiornamenti_serietv(item): + """ + def per la lista degli aggiornamenti + """ + logger.info("%s elenco_aggiornamenti_serietv log: %s" % (__channel__, item)) + itemlist = [] + + # Carica la pagina + data = httptools.downloadpage(item.url).data + + # Estrae i contenuti + #bloque = scrapertoolsV2.get_match(data, '
    (.*?)
    ') + bloque = scrapertoolsV2.find_single_match(data, '
    (.*?)
    ') + patron = '(.*?)<.*?href="(.*?)".*?>(.*?)<' + matches = scrapertoolsV2.find_multiple_matches(bloque, patron) + + for scrapedtitle, scrapedurl, scrapedepisodies in matches: + if "(SUB ITA)" in scrapedepisodies.upper(): + lang = "SUB ITA" + scrapedepisodies = scrapedepisodies.replace('(SUB ITA)','') + else: + lang = "ITA" + scrapedepisodies = scrapedepisodies.replace(lang,'') + #num = scrapertoolsV2.find_single_match(scrapedepisodies, '(-\d+/)') + #if num: + # scrapedurl = scrapedurl.replace(num, "-episodi/") + scrapedtitle = scrapedtitle.replace("–", "").replace('\xe2\x80\x93 ','').strip() + scrapedepisodies = scrapedepisodies.replace('\xe2\x80\x93 ','').strip() + itemlist.append( + Item( + channel=item.channel, + action="episodios", + contentType="tvshow", + title = "%s" % scrapedtitle, # %s" % (scrapedtitle, scrapedepisodies), + fulltitle = "%s %s" % (scrapedtitle, scrapedepisodies), + text_color = color5, + url = scrapedurl, + #show = "%s %s" % (scrapedtitle, scrapedepisodies), + extra=item.extra, + #lang = lang, + #data = data, + folder=True)) + + # locandine e trama e altro da tmdb se presente l'anno migliora la ricerca + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True, idioma_busqueda='it') + + return itemlist + +# =========== def per trovare i video ============= def findvideos(item): - logger.info("kod.eurostreaming findvideos") + logger.info("%s findvideos log: %s" % (__channel__, item)) itemlist = [] # Carica la pagina data = item.url - matches = re.findall(r'
    ]*>[^<]+', data, re.DOTALL) + matches = re.findall(r'a href="([^"]+)"[^>]*>[^<]+', data, re.DOTALL) data = [] for url in matches: url, c = unshortenit.unshorten(url) data.append(url) - itemlist = servertools.find_video_items(data=str(data)) + try: + itemlist = servertools.find_video_items(data=str(data)) - for videoitem in itemlist: - videoitem.title = item.title + videoitem.title - videoitem.fulltitle = item.fulltitle - videoitem.thumbnail = item.thumbnail - videoitem.show = item.show - videoitem.plot = item.plot - videoitem.channel = item.channel - videoitem.contentType = item.contentType + for videoitem in itemlist: + logger.info("Videoitemlist2: %s" % videoitem) + videoitem.title = "%s [%s]" % (item.contentTitle, videoitem.title)#"[%s] %s" % (videoitem.server, item.title) #"[%s]" % (videoitem.title) + videoitem.show = item.show + videoitem.contentTitle = item.contentTitle + videoitem.contentType = item.contentType + videoitem.channel = item.channel + videoitem.text_color = color5 + #videoitem.language = item.language + videoitem.year = item.infoLabels['year'] + videoitem.infoLabels['plot'] = item.infoLabels['plot'] + except AttributeError: + logger.error("data doesn't contain expected URL") + # Controlla se i link sono validi + if __comprueba_enlaces__: + itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__) + + # Requerido para FilterTools + itemlist = filtertools.get_links(itemlist, item, list_language) + + # Requerido para AutoPlay autoplay.start(itemlist, item) + return itemlist From 0de146c2e6d2cb2834652765e005ce9f6ec6f92b Mon Sep 17 00:00:00 2001 From: greko17 <50103632+greko17@users.noreply.github.com> Date: Tue, 30 Apr 2019 13:53:26 +0200 Subject: [PATCH 03/62] Update unify.py Proposta per italianizzare le thumb! --- platformcode/unify.py | 141 ++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 54 deletions(-) diff --git a/platformcode/unify.py b/platformcode/unify.py index 40db14af..657df0d6 100644 --- a/platformcode/unify.py +++ b/platformcode/unify.py @@ -17,119 +17,152 @@ from core.item import Item from core import scrapertools from platformcode import logger -thumb_dict = {"movies": "https://s10.postimg.cc/fxtqzdog9/peliculas.png", - "tvshows": "https://s10.postimg.cc/kxvslawe1/series.png", - "all": "https://s10.postimg.cc/h1igpgw0p/todas.png", - "genres": "https://s10.postimg.cc/6c4rx3x1l/generos.png", - "search": "https://s10.postimg.cc/v985e2izd/buscar.png", - "quality": "https://s10.postimg.cc/9bbojsbjd/calidad.png", - "audio": "https://s10.postimg.cc/b34nern7d/audio.png", - "newest": "https://s10.postimg.cc/g1s5tf1bt/novedades.png", - "last": "https://s10.postimg.cc/i6ciuk0eh/ultimas.png", - "hot": "https://s10.postimg.cc/yu40x8q2x/destacadas.png", - "year": "https://s10.postimg.cc/atzrqg921/a_o.png", - "alphabet": "https://s10.postimg.cc/4dy3ytmgp/a-z.png", - "recomended": "https://s10.postimg.cc/7xk1oqccp/recomendadas.png", - "more watched": "https://s10.postimg.cc/c6orr5neh/masvistas.png", - "more voted": "https://s10.postimg.cc/lwns2d015/masvotadas.png", - "favorites": "https://s10.postimg.cc/rtg147gih/favoritas.png", - "colections": "https://s10.postimg.cc/ywnwjvytl/colecciones.png", - "categories": "https://s10.postimg.cc/v0ako5lmh/categorias.png", - "premieres": "https://s10.postimg.cc/sk8r9xdq1/estrenos.png", - "documentaries": "https://s10.postimg.cc/68aygmmcp/documentales.png", - "language": "https://s10.postimg.cc/6wci189ft/idioma.png", - "new episodes": "https://s10.postimg.cc/fu4iwpnqh/nuevoscapitulos.png", - "country": "https://s10.postimg.cc/yz0h81j15/pais.png", - "adults": "https://s10.postimg.cc/s8raxc51l/adultos.png", - "recents": "https://s10.postimg.cc/649u24kp5/recents.png", - "updated" : "https://s10.postimg.cc/46m3h6h9l/updated.png", - "actors": "https://i.postimg.cc/tC2HMhVV/actors.png", - "cast": "https://i.postimg.cc/qvfP5Xvt/cast.png", - "lat": "https://i.postimg.cc/Gt8fMH0J/lat.png", - "vose": "https://i.postimg.cc/kgmnbd8h/vose.png", +thumb_dict = { + "numbers": "http://icons.iconarchive.com/icons/custom-icon-design/pretty-office-10/256/Numbers-icon.png", + "a": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-A-black-icon.png", "accion": "https://s14.postimg.cc/sqy3q2aht/action.png", + "actors": "https://i.postimg.cc/tC2HMhVV/actors.png", "adolescente" : "https://s10.postimg.cc/inq7u4p61/teens.png", "adultos": "https://s10.postimg.cc/s8raxc51l/adultos.png", + "adults": "https://s10.postimg.cc/s8raxc51l/adultos.png", + "alcinema": "http://icons.iconarchive.com/icons/chromatix/aerial/256/movie-icon.png", #"http://icons.iconarchive.com/icons/itzikgur/my-seven/256/Movies-Films-icon.png", + "all": "https://s10.postimg.cc/h1igpgw0p/todas.png", + "alphabet": "https://s10.postimg.cc/4dy3ytmgp/a-z.png", "animacion": "https://s14.postimg.cc/vl193mupd/animation.png", "anime" : "https://s10.postimg.cc/n9mc2ikzt/anime.png", "artes marciales" : "https://s10.postimg.cc/4u1v51tzt/martial_arts.png", "asiaticas" : "https://i.postimg.cc/Xq0HXD5d/asiaticas.png", - "aventura": "https://s14.postimg.cc/ky7fy5he9/adventure.png", + "audio": "https://s10.postimg.cc/b34nern7d/audio.png", + "aventura": "http://icons.iconarchive.com/icons/sirubico/movie-genre/256/Adventure-2-icon.png",#"https://s14.postimg.cc/ky7fy5he9/adventure.png", + "b": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-B-black-icon.png", "belico": "https://s14.postimg.cc/5e027lru9/war.png", "biografia" : "https://s10.postimg.cc/jq0ecjxnt/biographic.png", + "c": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-C-black-icon.png", "carreras": "https://s14.postimg.cc/yt5qgdr69/races.png", + "cast": "https://i.postimg.cc/qvfP5Xvt/cast.png", + "categories": "https://s10.postimg.cc/v0ako5lmh/categorias.png", "ciencia ficcion": "https://s14.postimg.cc/8kulr2jy9/scifi.png", "cine negro" : "https://s10.postimg.cc/6ym862qgp/noir.png", + "colections": "https://s10.postimg.cc/ywnwjvytl/colecciones.png", "comedia": "https://s14.postimg.cc/9ym8moog1/comedy.png", "cortometraje" : "https://s10.postimg.cc/qggvlxndl/shortfilm.png", + "country": "https://s10.postimg.cc/yz0h81j15/pais.png", "crimen": "https://s14.postimg.cc/duzkipjq9/crime.png", + "d": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-D-black-icon.png", "de la tv": "https://s10.postimg.cc/94gj0iwh5/image.png", "deporte": "https://s14.postimg.cc/x1crlnnap/sports.png", "destacadas": "https://s10.postimg.cc/yu40x8q2x/destacadas.png", "documental": "https://s10.postimg.cc/68aygmmcp/documentales.png", + "documentaries": "https://s10.postimg.cc/68aygmmcp/documentales.png", "doramas":"https://s10.postimg.cc/h4dyr4nfd/doramas.png", "drama": "https://s14.postimg.cc/fzjxjtnxt/drama.png", + "e": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-E-black-icon.png", "erotica" : "https://s10.postimg.cc/dcbb9bfx5/erotic.png", "espanolas" : "https://s10.postimg.cc/x1y6zikx5/spanish.png", "estrenos" : "https://s10.postimg.cc/sk8r9xdq1/estrenos.png", "extranjera": "https://s10.postimg.cc/f44a4eerd/foreign.png", + "f": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-F-black-icon.png", "familiar": "https://s14.postimg.cc/jj5v9ndsx/family.png", "fantasia": "https://s14.postimg.cc/p7c60ksg1/fantasy.png", "fantastico" : "https://s10.postimg.cc/tedufx5eh/fantastic.png", + "favorites": "https://s10.postimg.cc/rtg147gih/favoritas.png", + "g": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-G-black-icon.png", + "genres": "https://s10.postimg.cc/6c4rx3x1l/generos.png", + "h": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-H-black-icon.png", "historica": "https://s10.postimg.cc/p1faxj6yh/historic.png", "horror" : "https://s10.postimg.cc/8exqo6yih/horror2.png", + "hot": "https://s10.postimg.cc/yu40x8q2x/destacadas.png", + "i": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-I-black-icon.png", "infantil": "https://s14.postimg.cc/4zyq842mp/childish.png", "intriga": "https://s14.postimg.cc/5qrgdimw1/intrigue.png", + "j": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-J-black-icon.png", + "k": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-K-black-icon.png", + "l": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-L-black-icon.png", + "language": "https://s10.postimg.cc/6wci189ft/idioma.png", + "last": "https://s10.postimg.cc/i6ciuk0eh/ultimas.png", + "lat": "https://i.postimg.cc/Gt8fMH0J/lat.png", "latino" : "https://s10.postimg.cc/swip0b86h/latin.png", + "m": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-M-black-icon.png", "mexicanas" : "https://s10.postimg.cc/swip0b86h/latin.png", "misterio": "https://s14.postimg.cc/3m73cg8ep/mistery.png", + "more voted": "https://s10.postimg.cc/lwns2d015/masvotadas.png", + "more watched": "https://s10.postimg.cc/c6orr5neh/masvistas.png", + "movies": "https://s10.postimg.cc/fxtqzdog9/peliculas.png", "musical": "https://s10.postimg.cc/hy7fhtecp/musical.png", + "n": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-N-black-icon.png", + "new episodes": "https://s10.postimg.cc/fu4iwpnqh/nuevoscapitulos.png", + "newest": "http://icons.iconarchive.com/icons/laurent-baumann/creme/128/Location-News-icon.png", #"http://icons.iconarchive.com/icons/uiconstock/ios8-setting/128/news-icon.png", + "nextpage": "http://icons.iconarchive.com/icons/custom-icon-design/pretty-office-5/256/navigate-right-icon.png", #"http://icons.iconarchive.com/icons/custom-icon-design/office/256/forward-icon.png", #"http://icons.iconarchive.com/icons/ahmadhania/spherical/128/forward-icon.png", + "o": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-O-black-icon.png", + "others": "http://icons.iconarchive.com/icons/limav/movie-genres-folder/128/Others-icon.png", + "p": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-P-black-icon.png", "peleas" : "https://s10.postimg.cc/7a3ojbjwp/Fight.png", "policial" : "https://s10.postimg.cc/wsw0wbgbd/cops.png", + "premieres": "https://s10.postimg.cc/sk8r9xdq1/estrenos.png", + "q": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-Q-black-icon.png", + "quality": "https://s10.postimg.cc/9bbojsbjd/calidad.png", + "r": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-R-black-icon.png", + "recents": "https://s10.postimg.cc/649u24kp5/recents.png", "recomendadas": "https://s10.postimg.cc/7xk1oqccp/recomendadas.png", + "recomended": "https://s10.postimg.cc/7xk1oqccp/recomendadas.png", "religion" : "https://s10.postimg.cc/44j2skquh/religion.png", "romance" : "https://s10.postimg.cc/yn8vdll6x/romance.png", "romantica": "https://s14.postimg.cc/8xlzx7cht/romantic.png", + "s": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-S-black-icon.png", + "search": "http://icons.iconarchive.com/icons/jamespeng/movie/256/database-icon.png", "suspenso": "https://s10.postimg.cc/7peybxdfd/suspense.png", + "t": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-T-black-icon.png", "telenovelas": "https://i.postimg.cc/QCXZkyDM/telenovelas.png", "terror": "https://s14.postimg.cc/thqtvl52p/horror.png", "thriller": "https://s14.postimg.cc/uwsekl8td/thriller.png", - "western": "https://s10.postimg.cc/5wc1nokjt/western.png" + "tvshows": "https://s10.postimg.cc/kxvslawe1/series.png", + "u": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-U-black-icon.png", + "ultimiarrivi" : "http://icons.iconarchive.com/icons/saki/snowish/128/Extras-internet-download-icon.png", + "updated" : "https://s10.postimg.cc/46m3h6h9l/updated.png", + "v": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-V-black-icon.png", + "vose": "https://i.postimg.cc/kgmnbd8h/vose.png", + "w": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-W-black-icon.png", + "western": "https://s10.postimg.cc/5wc1nokjt/western.png", + "x": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-X-black-icon.png", + "y": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-Y-black-icon.png", + "year": "https://s10.postimg.cc/atzrqg921/a_o.png", + "z": "http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/256/Letter-Z-black-icon.png" } def set_genre(string): #logger.info() - genres_dict = {'accion':['accion', 'action', 'accion y aventura', 'action & adventure'], - 'adultos':['adultos', 'adultos +', 'adulto'], - 'animacion':['animacion', 'animacion e infantil', 'dibujos animados'], - 'adolescente':['adolescente', 'adolescentes', 'adolescencia', 'adolecentes'], - 'aventura':['aventura', 'aventuras'], - 'belico':['belico', 'belica', 'belicas', 'guerra', 'belico guerra'], - 'biografia':['biografia', 'biografias', 'biografica', 'biograficas', 'biografico'], + genres_dict = {'accion':['azione'], + 'adultos':['adulto','adulti'], + 'animacion':['animazione'], + 'adolescente':['adolescente', 'adolescenti'], + 'aventura':['avventura'], + 'belico':['guerra','guerriglia'], + 'biografia':['biografia', 'biografie', 'biografico'], 'ciencia ficcion':['ciencia ficcion', 'cienciaficcion', 'sci fi', 'c ficcion'], - 'cine negro':['film noir', 'negro'], - 'comedia':['comedia', 'comedias'], - 'cortometraje':['cortometraje', 'corto', 'cortos'], - 'de la tv':['de la tv', 'television', 'tv'], + 'cine negro':['film noir'], + 'comedia':['commedia', 'commedie'], + 'cortometraje':['cortometraggio', 'corto', 'corti'], + 'de la tv':['della tv', 'televisione', 'tv'], 'deporte':['deporte', 'deportes'], 'destacadas':['destacada', 'destacadas'], - 'documental':['documental', 'documentales'], + 'documental':['documentario', 'documentari'], 'erotica':['erotica', 'erotica +', 'eroticas', 'eroticas +', 'erotico', 'erotico +'], 'estrenos':['estrenos', 'estrenos'], 'extranjera':['extrajera', 'extrajeras', 'foreign'], - 'familiar':['familiar', 'familia'], - 'fantastico':['fantastico', 'fantastica', 'fantasticas'], - 'historica':['historica', 'historicas', 'historico', 'historia'], - 'infantil':['infantil', 'kids'], - 'musical':['musical', 'musicales', 'musica'], - 'policial':['policial', 'policiaco', 'policiaca'], - 'recomendadas':['recomedada', 'recomendadas'], - 'religion':['religion', 'religiosa', 'religiosas'], - 'romantica':['romantica', 'romanticas', 'romantico'], + 'familiar':['familiare', 'famiglia'], + 'fantastico':['fantastico', 'fantastica', 'fantastici'], + 'historica':['storico', 'storia'], + 'infantil':['bambini', 'infanzia'], + 'musical':['musicale', 'musical', 'musica'], + 'numbers': ['0','1','2','3','4','5','6','7','8','9'], + 'policial':['politico', 'politici', 'politica'], + 'recomendadas':['raccomandato', 'raccomandati'], + 'religion':['religione', 'religioso', 'religiosa','religiosi'], + 'romantica':['romantica', 'romantico', 'romantici'], 'suspenso':['suspenso', 'suspense'], 'thriller':['thriller', 'thrillers'], - 'western':['western', 'westerns', 'oeste western'] + 'western':['western', 'westerns'] } string = re.sub(r'peliculas de |pelicula de la |peli |cine ','', string) for genre, variants in genres_dict.items(): From 15d600dd6a7ee97669b39b17923f61377c5e1321 Mon Sep 17 00:00:00 2001 From: greko17 <50103632+greko17@users.noreply.github.com> Date: Tue, 30 Apr 2019 23:40:37 +0200 Subject: [PATCH 04/62] Add files via upload --- channels/altadefinizione01_club.json | 92 +++++++ channels/altadefinizione01_club.py | 372 +++++++++++++++++++++++++++ 2 files changed, 464 insertions(+) create mode 100644 channels/altadefinizione01_club.json create mode 100644 channels/altadefinizione01_club.py diff --git a/channels/altadefinizione01_club.json b/channels/altadefinizione01_club.json new file mode 100644 index 00000000..4c4d2fa3 --- /dev/null +++ b/channels/altadefinizione01_club.json @@ -0,0 +1,92 @@ +{ + "id": "altadefinizione01_club", + "name": "Altadefinizione01 C", + "active": true, + "adult": false, + "language": ["ita"], + "fanart": "https://www.altadefinizione01.vision/templates/Darktemplate/images/logo.png", + "thumbnail": "https://www.altadefinizione01.vision/templates/Darktemplate/images/logo.png", + "banner": "https://www.altadefinizione01.vision/templates/Darktemplate/images/logo.png", + "categories": [ + "movie" + ], + "settings": [ + { + "id": "modo_grafico", + "type": "bool", + "label": "Buscar información extra", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_newest_film", + "type": "bool", + "label": "Includi in Novità", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_newest_italiano", + "type": "bool", + "label": "Includi in Novità - Italiano", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "include_in_global_search", + "type": "bool", + "label": "Includi ricerca globale", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces", + "type": "bool", + "label": "Verifica se i link esistono", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "comprueba_enlaces_num", + "type": "list", + "label": "Numero de link da verificare", + "default": 1, + "enabled": true, + "visible": "eq(-1,true)", + "lvalues": [ "5", "10", "15", "20" ] + }, + { + "id": "filter_languages", + "type": "list", + "label": "Mostra link in lingua...", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Non filtrare", + "IT" + ] + }, + { + "id": "perfil", + "type": "list", + "label": "profilo dei colori", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "Sin color", + "Perfil 5", + "Perfil 4", + "Perfil 3", + "Perfil 2", + "Perfil 1" + ] + } + ] +} diff --git a/channels/altadefinizione01_club.py b/channels/altadefinizione01_club.py new file mode 100644 index 00000000..9f769a2c --- /dev/null +++ b/channels/altadefinizione01_club.py @@ -0,0 +1,372 @@ +# -*- coding: utf-8 -*- +# -*- Channel Altadefinizione01C Film -*- +# -*- Created for IcarusbyGreko -*- +# -*- By Greko -*- + +from channelselector import get_thumb +from channels import autoplay +from channels import filtertools +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from core import channeltools +from core import tmdb +from platformcode import config, logger + +__channel__ = "altadefinizione01_club" + +#host = "https://www.altadefinizione01.club/" # host da cambiare +#host = "https://www.altadefinizione01.team/" #aggiornato al 22 marzo 2019 +host = "https://www.altadefinizione01.vision/" #aggiornato al 30-04-209 +# ======== def per utility INIZIO ============================= +try: + __modo_grafico__ = config.get_setting('modo_grafico', __channel__) + __perfil__ = int(config.get_setting('perfil', __channel__)) +except: + __modo_grafico__ = True + __perfil__ = 0 + +# Fijar perfil de color +perfil = [['0xFFFFE6CC', '0xFFFFCE9C', '0xFF994D00', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFFA5F6AF', '0xFF5FDA6D', '0xFF11811E', '0xFFFE2E2E', '0xFFFFD700'], + ['0xFF58D3F7', '0xFF2E9AFE', '0xFF2E64FE', '0xFFFE2E2E', '0xFFFFD700']] + +if __perfil__ < 3: + color1, color2, color3, color4, color5 = perfil[__perfil__] +else: + color1 = color2 = color3 = color4 = color5 = "" + +__comprueba_enlaces__ = config.get_setting('comprueba_enlaces', __channel__) +__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', __channel__) + +headers = [['User-Agent', 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'], + ['Referer', host]] + +#parameters = channeltools.get_channel_parameters(__channel__) +#fanart_host = parameters['fanart'] +#thumbnail_host = parameters['thumbnail'] + +IDIOMAS = {'Italiano': 'IT'} +list_language = IDIOMAS.values() +list_servers = ['openload','verystream','rapidvideo','streamango'] # per l'autoplay +list_quality = ['default'] #'rapidvideo', 'streamango', 'openload', 'streamcherry'] # per l'autoplay + + +# =========== home menu =================== + +def mainlist(item): + """ + Creo il menu principale del canale + :param item: + :return: itemlist [] + """ + logger.info("%s mainlist log: %s" % (__channel__, item)) + itemlist = [] + title = '' + + autoplay.init(item.channel, list_servers, list_quality) + + itemlist = [ + # new upload + Item(channel=__channel__, title="Ultimi Arrivi", action="peliculas", + url="%s" % host, text_color=color4, extra="film", + infoLabels={'plot': item.category}, + thumbnail=get_thumb(title, auto = True) + ), + # x to Cinema + Item(channel=__channel__, title="Al Cinema", action="peliculas", + url="%scinema/" % host, text_color=color4, extra="film", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + # x Sub-ita + Item(channel=__channel__, title="Sottotitolati", action="peliculas", + url="%ssub-ita/" % host, text_color=color4, extra="film", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + # x Category + Item(channel=__channel__, title="Generi", action="categorie", + url="%s" % host, text_color=color4, extra="genres", + viewcontent='movies', + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + # x year + Item(channel=__channel__, title="Anno", action="categorie", + url="%s" % host, text_color=color4, extra="year", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + # x lettera + Item(channel=__channel__, title="Lettera", action="categorie", + url="%scatalog/a/" % host, text_color=color4, extra="orderalf", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + # Search + Item(channel=__channel__, title="Cerca Film...", action="search", + text_color=color4, extra="", + infoLabels={'plot': item.category}, + thumbnail = get_thumb(title, auto = True) + ), + ] + + autoplay.show_option(item.channel, itemlist) + + return itemlist + +# ======== def in ordine di menu =========================== +# =========== def per vedere la lista dei film ============= + +def peliculas(item): + logger.info("%s mainlist peliculas log: %s" % (__channel__, item)) + itemlist = [] + # scarico la pagina + data = httptools.downloadpage(item.url, headers=headers).data + # da qui fare le opportuni modifiche + if item.extra != 'orderalf': + if item.extra == 'film' or item.extra == 'year': + bloque = scrapertools.find_single_match(data, '
    (.*?)
    ') + elif item.extra == "search": + bloque = scrapertools.find_single_match(data, '
    (.*?)') + else: #item.extra == 'cat': + bloque = scrapertools.find_single_match(data, '
    (.*?)(.*?)
    (.*?)
    (.*?)
    \s*[^>]+>[^>]+>[^>]+>[^>]+>' patron += r'[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)

    ' - matches = re.compile(patron, re.DOTALL).findall(blocco) + + matches = support.match(item, patron, patron_block, headers)[0] for scrapedurl, scrapedthumbnail, scrapedtitle in matches: - scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle) + scrapedtitle = cleantitle(scrapedtitle) + itemlist.append( Item(channel=item.channel, - action="episodi", - contentType="tv", + action="episodios", + contentType="episode", title=scrapedtitle, fulltitle=scrapedtitle, url=scrapedurl, - extra="tv", show=scrapedtitle, thumbnail=scrapedthumbnail, folder=True)) @@ -126,35 +148,48 @@ def nuoveserie(item): # ---------------------------------------------------------------------------------------------------------------- def serietvaggiornate(item): - logger.info("[GuardaSerieClick.py]==> serietvaggiornate") + support.log(item.channel+" serietvaggiornate") itemlist = [] - data = httptools.downloadpage(item.url, headers=headers).data - blocco = scrapertools.find_single_match(data, - r'(.*?)
    (.*?)
    ]+> ]+>[^>]+>' patron += r'[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)<[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)<[^>]+>' - matches = re.compile(patron, re.DOTALL).findall(blocco) + + matches = support.match(item,patron, patron_block, headers)[0] for scrapedurl, scrapedthumbnail, scrapedep, scrapedtitle in matches: - episode = re.compile(r'^(\d+)x(\d+)', re.DOTALL).findall(scrapedep) # Prendo stagione ed episodio - scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle) - title = "%s %s" % (scrapedtitle, scrapedep) - extra = r']*>' % ( + episode = re.compile(r'^(\d+)x(\d+)', re.DOTALL).findall(scrapedep) # Prendo stagione ed episodioso + scrapedtitle = cleantitle(scrapedtitle) + + contentlanguage = "" + if 'sub-ita' in scrapedep.strip().lower(): + contentlanguage = 'Sub-ITA' + + extra = r']*>' % ( episode[0][0], episode[0][1].lstrip("0")) + + infoLabels = {} + infoLabels['episode'] = episode[0][1].lstrip("0") + infoLabels['season'] = episode[0][0] + + title = str("%s - %sx%s %s" % (scrapedtitle,infoLabels['season'],infoLabels['episode'],contentlanguage)).strip() + itemlist.append( Item(channel=item.channel, action="findepvideos", - contentType="tv", + contentType="episode", title=title, - show=title, + show=scrapedtitle, fulltitle=scrapedtitle, url=scrapedurl, extra=extra, thumbnail=scrapedthumbnail, + contentLanguage=contentlanguage, + infoLabels=infoLabels, folder=True)) + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + return itemlist @@ -162,20 +197,17 @@ def serietvaggiornate(item): # ---------------------------------------------------------------------------------------------------------------- def categorie(item): - logger.info("[GuardaSerieClick.py]==> categorie") + support.log(item.channel+" categorie") itemlist = [] - data = httptools.downloadpage(item.url, headers=headers).data - blocco = scrapertools.find_single_match(data, r'(.*?)') - patron = r'
  • \s*]+>([^<]+)
  • ' - matches = re.compile(patron, re.DOTALL).findall(blocco) + matches = support.match(item, r'
  • \s*]+>([^<]+)
  • ', r'(.*?)', headers)[0] for scrapedurl, scrapedtitle in matches: itemlist.append( Item(channel=item.channel, action="lista_serie", title=scrapedtitle, - contentType="tv", + contentType="tvshow", url="".join([host, scrapedurl]), thumbnail=item.thumbnail, extra="tv", @@ -188,66 +220,93 @@ def categorie(item): # ---------------------------------------------------------------------------------------------------------------- def lista_serie(item): - logger.info("[GuardaSerieClick.py]==> lista_serie") + support.log(item.channel+" lista_serie") itemlist = [] - data = httptools.downloadpage(item.url, headers=headers).data + # data = httptools.downloadpage(item.url, headers=headers).data + # + # patron = r'\s*[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)

    ' + # blocco = scrapertools.find_single_match(data, + # r'(.*?)') + # matches = re.compile(patron, re.DOTALL).findall(blocco) + patron_block = r'(.*?)' patron = r'\s*[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)

    ' - blocco = scrapertools.find_single_match(data, - r'(.*?)') - matches = re.compile(patron, re.DOTALL).findall(blocco) + + matches, data = support.match(item, patron, patron_block, headers) + for scrapedurl, scrapedimg, scrapedtitle in matches: - scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle).strip() - itemlist.append( - Item(channel=item.channel, - action="episodi", - title=scrapedtitle, - fulltitle=scrapedtitle, - url=scrapedurl, - thumbnail=scrapedimg, - extra=item.extra, - show=scrapedtitle, - folder=True)) + scrapedtitle = cleantitle(scrapedtitle) + + if scrapedtitle not in ['DMCA','Contatti','Lista di tutte le serie tv']: + itemlist.append( + Item(channel=item.channel, + action="episodios", + contentType="episode", + title=scrapedtitle, + fulltitle=scrapedtitle, + url=scrapedurl, + thumbnail=scrapedimg, + extra=item.extra, + show=scrapedtitle, + folder=True)) + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + + support.nextPage(itemlist,item,data,r" episodi") +def episodios(item): + support.log(item.channel+" episodios") itemlist = [] - data = httptools.downloadpage(item.url, headers=headers).data + # data = httptools.downloadpage(item.url, headers=headers).data - patron = r'([^<]+)<\/div>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>' - patron += r'[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*' - patron += r']+>' - matches = re.compile(patron, re.DOTALL).findall(data) - for scrapedtitle, scrapedurl, scrapedthumbnail in matches: - scrapedtitle = scrapertools.decodeHtmlentities(scrapedtitle).strip() - itemlist.append( - Item(channel=item.channel, - action="findvideos", - title=scrapedtitle, - fulltitle=scrapedtitle, - url=scrapedurl, - contentType="episode", - thumbnail=scrapedthumbnail, - folder=True)) + patron = r'\s*([^<]+)<\/div>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)?[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>]+>([^<]+)<[^>]+>[^>]+>[^>]+>' + patron += r'[^<]+[^"]+".*?serie="([^"]+)".*?stag="([0-9]*)".*?ep="([0-9]*)"\s*' + patron += r'.*?embed="([^"]+)"\s*.*?embed2="([^"]+)?"\s*.*?embed3="([^"]+)?"?[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>\s*' + patron += r'(?:]+>|]+>)?' + # matches = re.compile(patron, re.DOTALL).findall(data) - if config.get_videolibrary_support() and len(itemlist) != 0: + # logger.debug(matches) + + matches = support.match(item, patron, headers=headers)[0] + + + for scrapedtitle, scrapedepisodetitle, scrapedplot, scrapedserie, scrapedseason, scrapedepisode, scrapedurl, scrapedurl2,scrapedurl3,scrapedthumbnail,scrapedthumbnail2 in matches: + scrapedtitle = cleantitle(scrapedtitle) + scrapedepisode = scrapedepisode.zfill(2) + scrapedepisodetitle = cleantitle(scrapedepisodetitle) + title = str("%sx%s %s" % (scrapedseason, scrapedepisode, scrapedepisodetitle)).strip() + if 'SUB-ITA' in scrapedtitle: + title +=" Sub-ITA" + + infoLabels = {} + infoLabels['season'] = scrapedseason + infoLabels['episode'] = scrapedepisode itemlist.append( - Item(channel=item.channel, - title="[COLOR lightblue]%s[/COLOR]" % config.get_localized_string(30161), - url=item.url, - action="add_serie_to_library", - extra="episodi", - show=item.show)) + Item(channel=item.channel, + action="findvideos", + title=title, + fulltitle=scrapedtitle, + url=scrapedurl+"\r\n"+scrapedurl2+"\r\n"+scrapedurl3, + contentType="episode", + plot=scrapedplot, + contentSerieName=scrapedserie, + contentLanguage='Sub-ITA' if 'Sub-ITA' in title else '', + infoLabels=infoLabels, + thumbnail=scrapedthumbnail2 if scrapedthumbnail2 != '' else scrapedthumbnail, + folder=True)) + + tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + + support.videolibrary(itemlist, item) return itemlist @@ -256,20 +315,12 @@ def episodi(item): # ---------------------------------------------------------------------------------------------------------------- def findepvideos(item): - logger.info("[GuardaSerieClick.py]==> findepvideos") - + support.log(item.channel+" findepvideos") data = httptools.downloadpage(item.url, headers=headers).data - data = scrapertools.find_single_match(data, item.extra) - itemlist = servertools.find_video_items(data=data) - - for videoitem in itemlist: - server = re.sub(r'[-\[\]\s]+', '', videoitem.title).capitalize() - videoitem.title = "".join(["[%s] " % support.color(server.capitalize(), 'orange'), item.title]) - videoitem.fulltitle = item.fulltitle - videoitem.thumbnail = item.thumbnail - videoitem.show = item.show - videoitem.plot = item.plot - videoitem.channel = item.channel + matches = scrapertools.find_multiple_matches(data, item.extra) + data = "\r\n".join(matches[0]) + item.contentType = 'movie' + itemlist = support.server(item, data=data) return itemlist @@ -278,17 +329,8 @@ def findepvideos(item): # ---------------------------------------------------------------------------------------------------------------- def findvideos(item): - logger.info("[GuardaSerieClick.py]==> findvideos") - - itemlist = servertools.find_video_items(data=item.url) - - for videoitem in itemlist: - server = re.sub(r'[-\[\]\s]+', '', videoitem.title).capitalize() - videoitem.title = "".join(["[%s] " % support.color(server.capitalize(), 'orange'), item.title]) - videoitem.fulltitle = item.fulltitle - videoitem.thumbnail = item.thumbnail - videoitem.show = item.show - videoitem.plot = item.plot - videoitem.channel = item.channel + support.log(item.channel+" findvideos") + logger.debug(item.url) + itemlist = support.server(item, data=item.url) return itemlist diff --git a/resources/media/channels/banner/guardaserieclick.png b/resources/media/channels/banner/guardaserieclick.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5e34b31f748b791dac3c644b43d43e2c624874 GIT binary patch literal 30059 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 literal 0 HcmV?d00001 diff --git a/resources/media/channels/thumb/guardaserieclick.png b/resources/media/channels/thumb/guardaserieclick.png new file mode 100644 index 0000000000000000000000000000000000000000..eee22552c124889fd467ce843bc79bab833de7b1 GIT binary patch literal 13552 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 Date: Wed, 29 May 2019 02:30:59 +0200 Subject: [PATCH 61/62] Refactor channel AnimeWorld + fixes --- channels/animeworld.json | 13 +- channels/animeworld.py | 209 +++++++++++++----- channelselector.py | 6 +- .../media/channels/banner/animeworld.png | Bin 0 -> 15365 bytes .../channels/banner/guardaserieclick.png | Bin 30059 -> 21263 bytes resources/media/channels/thumb/animeworld.png | Bin 0 -> 7030 bytes .../media/channels/thumb/guardaserieclick.png | Bin 13552 -> 9928 bytes 7 files changed, 174 insertions(+), 54 deletions(-) create mode 100644 resources/media/channels/banner/animeworld.png create mode 100644 resources/media/channels/thumb/animeworld.png diff --git a/channels/animeworld.json b/channels/animeworld.json index dfcee138..9ebf73f3 100644 --- a/channels/animeworld.json +++ b/channels/animeworld.json @@ -4,9 +4,18 @@ "active": true, "adult": false, "language": ["ita"], - "thumbnail": "https://cdn.animeworld.it/static/images/general/logoaw.png", - "categories": ["anime"], + "thumbnail": "animeworld.png", + "banner": "animeworld.png", + "categories": ["anime"], "settings": [ + { + "id": "channel_host", + "type": "text", + "label": "Host del canale", + "default": "https://www.animeworld.it", + "enabled": true, + "visible": true + }, { "id": "include_in_global_search", "type": "bool", diff --git a/channels/animeworld.py b/channels/animeworld.py index 4a1586be..ee8d71cf 100644 --- a/channels/animeworld.py +++ b/channels/animeworld.py @@ -3,16 +3,20 @@ # Canale per animeworld # ---------------------------------------------------------- import re +import time +import urllib + import urlparse +import channelselector from channelselector import thumb -from core import httptools, scrapertoolsV2, servertools, tmdb, support +from core import httptools, scrapertoolsV2, servertools, tmdb, support, jsontools from core.item import Item from platformcode import logger, config from specials import autoplay, autorenumber -host = "https://www.animeworld.it" - +__channel__ = 'animeworld' +host = config.get_setting("channel_host", __channel__) headers = [['Referer', host]] IDIOMAS = {'Italiano': 'Italiano'} @@ -25,21 +29,51 @@ checklinks_number = config.get_setting('checklinks_number', 'animeworld') def mainlist(item): - logger.info("[animeworld.py] mainlist") + logger.info(__channel__+" mainlist") itemlist =[] - support.menu(itemlist, 'Anime ITA submenu bold', 'build_menu', host+'/filter?language[]=1') - support.menu(itemlist, 'Anime SUB submenu bold', 'build_menu', host+'/filter?language[]=0') - support.menu(itemlist, 'Anime A-Z sub', 'alfabetico', host+'/az-list') - support.menu(itemlist, 'Anime - Ultimi Aggiunti', 'alfabetico', host+'/newest') - support.menu(itemlist, 'Anime - Ultimi Episodi', 'alfabetico', host+'/newest') + support.menu(itemlist, 'Anime bold', 'lista_anime', host+'/az-list') + support.menu(itemlist, 'ITA submenu', 'build_menu', host+'/filter?language[]=1', args=["anime"]) + support.menu(itemlist, 'Sub-ITA submenu', 'build_menu', host+'/filter?language[]=0', args=["anime"]) + support.menu(itemlist, 'Archivio A-Z submenu', 'alfabetico', host+'/az-list', args=["tvshow","a-z"]) + support.menu(itemlist, 'In corso submenu', 'video', host+'/', args=["in sala"]) + support.menu(itemlist, 'Generi submenu', 'generi', host+'/') + support.menu(itemlist, 'Ultimi Aggiunti bold', 'video', host+'/newest', args=["anime"]) + support.menu(itemlist, 'Ultimi Episodi bold', 'video', host+'/updated', args=["novita'"]) support.menu(itemlist, 'Cerca...', 'search') autoplay.init(item.channel, list_servers, list_quality) autoplay.show_option(item.channel, itemlist) + itemlist.append( + Item(channel='setting', + action="channel_config", + title=support.typo("Configurazione Canale color lime"), + config=item.channel, + folder=False, + thumbnail=channelselector.get_thumb('setting_0.png')) + ) + + return itemlist + +# Crea menu dei generi ================================================= + +def generi(item): + support.log(item.channel+" generi") + itemlist = [] + patron_block = r'
    \sGeneri\s*
      (.*?)
    ' + patron = r'' + matches = support.match(item,patron, patron_block, headers)[0] + + for scrapedurl, scrapedtitle in matches: + itemlist.append(Item( + channel=item.channel, + action="video", + title=scrapedtitle, + url="%s%s" % (host,scrapedurl))) + return itemlist @@ -103,7 +137,7 @@ def build_sub_menu(item): # Novità ====================================================== def newest(categoria): - logger.info("[animeworld.py] newest") + logger.info(__channel__+" newest") itemlist = [] item = Item() try: @@ -144,7 +178,7 @@ def search(item, texto): # Lista A-Z ==================================================== def alfabetico(item): - logger.info("[animeworld.py] alfabetico") + logger.info(__channel__+" alfabetico") itemlist = [] data = httptools.downloadpage(item.url).data @@ -170,7 +204,7 @@ def alfabetico(item): return itemlist def lista_anime(item): - logger.info("[animeworld.py] lista_anime") + logger.info(__channel__+" lista_anime") itemlist = [] @@ -202,7 +236,7 @@ def lista_anime(item): itemlist.append( Item(channel=item.channel, extra=item.extra, - contentType="tvshow", + contentType="episode", action="episodios", text_color="azure", title=title, @@ -217,23 +251,24 @@ def lista_anime(item): autorenumber.renumber(itemlist) # Next page - next_page = scrapertoolsV2.find_single_match(data, '