Merge remote-tracking branch 'alfa-addon/master' into fixes

This commit is contained in:
Unknown
2018-06-11 09:41:55 -03:00
37 changed files with 3167 additions and 777 deletions

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.alfa" name="Alfa" version="2.5.16" provider-name="Alfa Addon">
<addon id="plugin.video.alfa" name="Alfa" version="2.5.18" provider-name="Alfa Addon">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.libtorrent" optional="true"/>
@@ -19,15 +19,15 @@
</assets>
<news>[B]Estos son los cambios para esta versión:[/B]
[COLOR green][B]Canales agregados y arreglos[/B][/COLOR]
» clipwatching » vidup
» allcalidad » descargacineclasico
» mastorrent » tiotorrent
» animeshd » filebebo
» cuevana2 » Cuevana2español
» seriesverde » flashx
» grantorrent » descargas2020
» torrentlocura » torrentrapid
» tumejortorrent » tvsinpagar
» mispelisyseries » vidoza
» streamplay » powvideo
» streamcloud
¤ arreglos internos
¤ Agradecimientos a @angedam, @alaquepasa, @mrgaturus, @axlt2002 por colaborar con ésta versión.
¤ Agradecimientos al equipo iSOD, @alaquepasa por colaborar con ésta versión.
</news>
<description lang="es">Navega con Kodi por páginas web para ver sus videos de manera fácil.</description>

View File

@@ -33,13 +33,12 @@ def mainlist(item):
itemlist = list()
itemlist.append(Item(channel=item.channel, action="lista", title="Series", url=host+"/lista-de-anime.php",
thumbnail=thumb_series))
#itemlist.append(Item(channel=item.channel, action="lista", title="Series Animadas", url=host,
# thumbnail=thumb_series))
#itemlist.append(Item(channel=item.channel, action="lista", title="Novedades", url=host,
# thumbnail=thumb_series))
#itemlist.append(Item(channel=item.channel, action="lista", title="Pokemon", url=host,
# thumbnail=thumb_series))
thumbnail=thumb_series, range=[0,19]))
itemlist.append(Item(channel=item.channel, action="lista", title="Películas", url=host+"/catalogo.php?g=&t=peliculas&o=0",
thumbnail=thumb_series, range=[0,19] ))
itemlist.append(Item(channel=item.channel, action="lista", title="Especiales", url=host+"/catalogo.php?g=&t=especiales&o=0",
thumbnail=thumb_series, range=[0,19]))
itemlist = renumbertools.show_option(item.channel, itemlist)
autoplay.show_option(item.channel, itemlist)
return itemlist
@@ -60,8 +59,9 @@ def lista(item):
patron +=".+?<span .+?>(.+?)<\/span>" #scrapedplot
matches = scrapertools.find_multiple_matches(data, patron)
for scrapedurl, scrapedthumbnail,scrapedtitle,scrapedplot in matches:
if ":" in scrapedtitle:
next_page = [item.range[0]+19, item.range[1]+20]
for scrapedurl, scrapedthumbnail,scrapedtitle,scrapedplot in matches[item.range[0] : item.range[1]]:
if ":" in scrapedtitle:
cad = scrapedtitle.split(":")
show = cad[0]
else:
@@ -81,9 +81,15 @@ def lista(item):
context2 = autoplay.context
context.extend(context2)
scrapedurl=host+scrapedurl
itemlist.append(item.clone(title=scrapedtitle, url=scrapedurl, plot=scrapedplot,
thumbnail=scrapedthumbnail, action="episodios", show=show, context=context))
#tmdb.set_infoLabels(itemlist)
if item.title!="Series":
itemlist.append(item.clone(title=scrapedtitle, contentTitle=show,url=scrapedurl,
thumbnail=scrapedthumbnail, action="findvideos", context=context))
else:
itemlist.append(item.clone(title=scrapedtitle, contentSerieName=show,url=scrapedurl, plot=scrapedplot,
thumbnail=scrapedthumbnail, action="episodios", context=context))
tmdb.set_infoLabels(itemlist, seekTmdb=True)
itemlist.append(Item(channel=item.channel, url=item.url, range=next_page, title='Pagina Siguente >>>', action='lista'))
return itemlist
@@ -92,16 +98,16 @@ def episodios(item):
itemlist = []
data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data)
patron = '<div class="pagina">(.+?)<\/div><div id="fade".+?>'
data = scrapertools.find_single_match(data, patron)
patron_caps = "<li><a href='(.+?)'>Cap(?:i|í)tulo: (.+?) - (.+?)<\/a>"
matches = scrapertools.find_multiple_matches(data, patron_caps)
show = scrapertools.find_single_match(data, '<span>Titulo.+?<\/span>(.+?)<br><span>')
#show = scrapertools.find_single_match(data, '<span>Titulo.+?<\/span>(.+?)<br><span>')
scrapedthumbnail = scrapertools.find_single_match(data, "<img src='(.+?)'.+?>")
scrapedplot = scrapertools.find_single_match(data, '<span>Descripcion.+?<\/span>(.+?)<br>')
i = 0
temp = 0
infoLabels = item.infoLabels
for link, cap, name in matches:
if int(cap) == 1:
temp = temp + 1
@@ -109,19 +115,25 @@ def episodios(item):
cap = "0" + cap
season = temp
episode = int(cap)
season, episode = renumbertools.numbered_for_tratk(
item.channel, item.show, season, episode)
infoLabels['season'] = season
infoLabels['episode'] = episode
date = name
title = "%sx%s %s (%s)" % (season, str(episode).zfill(2), "Episodio %s" % episode, date)
# title = str(temp)+"x"+cap+" "+name
url = host + "/" + link
if "NO DISPONIBLE" not in name:
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, thumbnail=scrapedthumbnail,
plot=scrapedplot, url=url, show=show))
plot=scrapedplot, url=url, contentSeasonNumber=season, contentEpisodeNumber=episode,
contentSerieName=item.contentSerieName, infoLabels=infoLabels))
if config.get_videolibrary_support() and len(itemlist) > 0:
itemlist.append(Item(channel=item.channel, title="[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]", url=item.url,
action="add_serie_to_library", extra="episodios", show=item.title))
action="add_serie_to_library", extra="episodios", contentSerieName=item.contentSerieName))
return itemlist
@@ -149,15 +161,15 @@ def findvideos(item):
scrapedthumbnail = scrapertools.find_single_match(data, '<div class="caracteristicas"><img src="([^<]+)">')
itemla = scrapertools.find_multiple_matches(data_vid, '"(.+?)"')
for url in itemla:
url=url.replace('\/', '/')
server1=url.split('/')
server=server1[2]
if "." in server:
server1=server.split('.')
if len(server1)==3:
server=server1[1]
else:
server=server1[0]
url=url.replace('\/', '/')
server1=url.split('/')
server=server1[2]
if "." in server:
server1=server.split('.')
if len(server1)==3:
server=server1[1]
else:
server=server1[0]
if "goo" in url:
url = googl(url)
server='netutv'
@@ -168,6 +180,9 @@ def findvideos(item):
itemlist.append(item.clone(url=url, action="play",
thumbnail=scrapedthumbnail, server=server, plot=scrapedplot,
title="Enlace encontrado en: %s [%s]" % (server.capitalize(), quality)))
if item.contentTitle!="" and config.get_videolibrary_support() and len(itemlist) > 0:
itemlist.append(Item(channel=item.channel, title="[COLOR yellow]Añadir esta película a la videoteca[/COLOR]", url=item.url,
action="add_pelicula_to_library", extra="episodios", show=item.contentTitle))
autoplay.start(itemlist, item)
return itemlist

View File

@@ -21,18 +21,9 @@ def mainlist(item):
logger.info()
autoplay.init(item.channel, list_servers, list_quality)
itemlist = []
itemlist.append(Item(channel = item.channel, title = "Peliculas", action = "movies_menu",
url = host + "pelicula", thumbnail = get_thumb("movies", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Series", action = "shows_menu",
url = host + "pelicula", thumbnail = get_thumb("tvshows", auto = True) ))
itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search",
url = host + "search/", thumbnail = get_thumb("search", auto = True)))
autoplay.show_option(item.channel, itemlist)
return itemlist
def movies_menu(item):
itemlist = []
# PELICULAS
itemlist.append(Item(channel = item.channel, title = "Peliculas", folder=False,
thumbnail = get_thumb("movies", auto = True), text_bold=True))
itemlist.append(Item(channel = item.channel, title = "Novedades", action = "movies",
url = host + "pelicula", thumbnail = get_thumb("newest", auto = True)))
@@ -42,18 +33,20 @@ def movies_menu(item):
url = host + "pelicula", thumbnail = get_thumb("year", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Favoritas", action = "movies",
url = host + "peliculas-destacadas", thumbnail = get_thumb("favorites", auto = True) ))
itemlist.append(Item(channel = item.channel, title = ""))
itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search",
url = host + "search/", thumbnail = get_thumb("search", auto = True)))
return itemlist
# SERIES
itemlist.append(Item(channel = item.channel, title = "Series", folder=False,
thumbnail = get_thumb("tvshows", auto = True), text_bold=True))
def shows_menu(item):
itemlist = []
itemlist.append(Item(channel = item.channel, title = "Todas las Series", action = "shows",
url = host + "listar-series", thumbnail = get_thumb("tvshows", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search", extra='1',
url = host + "listar-series", thumbnail = get_thumb("search", auto = True)))
autoplay.show_option(item.channel, itemlist)
return itemlist
### FIN MENUS ###
@@ -98,7 +91,8 @@ def episodes(item):
matches = scrapertools.find_multiple_matches(data, seasonsPattern)
for season, title in matches:
itemlist.append(Item(channel = item.channel, title="[COLOR blue]%s[/COLOR]" % title))
itemlist.append(Item(channel = item.channel, title="[COLOR blue]%s[/COLOR]" % title,
folder=False, text_bold=True))
episodeMatches = scrapertools.find_single_match(data, episodesPattern % season)
put_episodes(itemlist, item, episodeMatches)
@@ -166,7 +160,7 @@ def searchMovies(itemlist, item, texto):
#coloca las peliculas encontradas en la lista, improvisando do while
next_page = True
while next_page:
put_movies(itemlist, data, pattern)
put_movies(itemlist, item, data, pattern)
next_page = scrapertools.find_single_match(data, '<a class="nextpostslink" rel="next" href="([^"]+)">')
if next_page:

View File

@@ -33,7 +33,10 @@ def mainlist(item):
url = host + "tendencias", thumbnail = get_thumb("hot", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Ranking IMDB", action = "moviesIMDB",
url = host + "raking-imdb", thumbnail = get_thumb("hot", auto = True) ))
itemlist.append(Item(channel = item.channel, title = ""))
itemlist.append(Item(channel = item.channel, title = "Busqueda", folder=False, text_bold=True,
thumbnail = get_thumb("search", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Por Letra", action = "letters",
url = host, thumbnail = get_thumb("alphabet", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search",
url = host + "?s=", thumbnail = get_thumb("search", auto = True)))
@@ -82,6 +85,38 @@ def moviesIMDB(item):
return itemlist
def byLetter(item):
itemlist = []
letter = item.extra
pageForNonce = load_data(item.url)
nonce = scrapertools.find_single_match(pageForNonce, '"nonce":"([^"]+)"')
raw = httptools.downloadpage('http://cuevana2espanol.com/wp-json/dooplay/glossary/?term=%s&nonce=%s&type=all' % (letter, nonce)).data
json = jsontools.load(raw)
logger.info(nonce)
if 'error' not in json:
for movie in json.items():
data = movie[1]
itemTitle = data['title']
if 'year' in data:
itemTitle += " [COLOR blue](%s)[/COLOR]" % data['year']
if data['imdb']:
itemTitle += " [COLOR yellow](%s)[/COLOR]" % data['imdb']
itemlist.append(Item(channel = item.channel, title=itemTitle, fulltitle=data['title'], url=data['url'],
thumbnail=data['img'].replace('-90x135', ''), action="findvideos"))
return itemlist
def letters(item):
itemlist = []
letter = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for let in letter:
itemlist.append(item.clone(title=let, extra=let.lower(), action="byLetter"))
return itemlist
def searchMovies(item):
itemlist = []
@@ -94,8 +129,8 @@ def searchMovies(item):
matches = scrapertools.find_multiple_matches(data, pattern)
for link, img, title, year, plot in matches:
itemTitle = "%s [COLOR blue](%s)[/COLOR]" % (title, year)
itemlist.append(Item(channel = item.channel, title=itemTitle, fulltitle=title, thumbnail=img,
fullimg = img.replace('-150x150', '')
itemlist.append(Item(channel = item.channel, title=itemTitle, fulltitle=title, thumbnail=fullimg,
url=link, plot=plot, action="findvideos"))
next_page = scrapertools.find_single_match(data, 'href="([^"]+)" ><span class="icon-chevron-right">')

View File

@@ -11,7 +11,9 @@
"tvshow",
"anime",
"torrent",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -22,6 +24,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://descargas2020.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

View File

@@ -0,0 +1,53 @@
{
"id": "grantorrent",
"name": "GranTorrent",
"active": true,
"adult": false,
"language": ["*"],
"thumbnail": "grantorrent.jpg",
"banner": "grantorrent.png",
"fanart": "grantorrent.png",
"categories": [
"torrent",
"movie",
"tvshow"
],
"settings": [
{
"id": "include_in_global_search",
"type": "bool",
"label": "Incluir en busqueda global",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_serie_temporada",
"type": "list",
"label": "Seleccionar agrupar por Serie o Temporada",
"default": 0,
"enabled": true,
"visible": true,
"lvalues": [
"Temporada",
"Serie"
]
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -349,11 +349,16 @@ def fichas(item):
bus = host[-4:]
tag_type = scrapertools.find_single_match(url, '%s/([^/]+)/' %bus)
title += " - [COLOR blue]" + tag_type.capitalize() + "[/COLOR]"
itemlist.append(
Item(channel=item.channel, action=action, title=title, url=url, fulltitle=title, thumbnail=thumbnail,
show=show, folder=True, contentType=contentType, contentTitle=contentTitle,
language =language, infoLabels=infoLabels))
if "/serie" in url or "/tags-tv" in url:
itemlist.append(
Item(channel=item.channel, action=action, title=title, url=url, thumbnail=thumbnail,
contentSerieName=show, folder=True, contentType=contentType,
language =language, infoLabels=infoLabels))
else:
itemlist.append(
Item(channel=item.channel, action=action, title=title, url=url, fulltitle=title, thumbnail=thumbnail,
folder=True, contentType=contentType, contentTitle=contentTitle,
language =language, infoLabels=infoLabels))
## Paginación
next_page_url = scrapertools.find_single_match(data, '<a href="([^"]+)">.raquo;</a>')
if next_page_url != "":
@@ -389,50 +394,41 @@ def episodios(item):
str = get_status(status, "shows", id)
if str != "" and account and item.category != "Series" and "XBMC" not in item.title:
if config.get_videolibrary_support():
title = " ( [COLOR gray][B]" + item.show + "[/B][/COLOR] )"
title = " ( [COLOR gray][B]" + item.contentSerieName + "[/B][/COLOR] )"
itemlist.append(
Item(channel=item.channel, action="episodios", title=title, fulltitle=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=False))
Item(channel=item.channel, action="episodios", title=title, url=url_targets,
thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=False))
title = str.replace('green', 'red').replace('Siguiendo', 'Abandonar')
itemlist.append(Item(channel=item.channel, action="set_status", title=title, fulltitle=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=True))
itemlist.append(Item(channel=item.channel, action="set_status", title=title, url=url_targets,
thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=True))
elif account and item.category != "Series" and "XBMC" not in item.title:
if config.get_videolibrary_support():
title = " ( [COLOR gray][B]" + item.show + "[/B][/COLOR] )"
itemlist.append(
Item(channel=item.channel, action="episodios", title=title, fulltitle=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=False))
Item(channel=item.channel, action="episodios", title=title, url=url_targets,
thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=False))
title = " ( [COLOR orange][B]Seguir[/B][/COLOR] )"
itemlist.append(Item(channel=item.channel, action="set_status", title=title, fulltitle=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=True))
itemlist.append(Item(channel=item.channel, action="set_status", title=title, url=url_targets,
thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=True))
patron = "<li><a href='([^']+)'>[^<]+</a></li>"
matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedurl in matches:
if "temporada-0" in scrapedurl:
continue
## Episodios
data = agrupa_datos(httptools.downloadpage(scrapedurl).data)
sid = scrapertools.get_match(data, "<script>var sid = '(\d+)'")
ssid = scrapertools.get_match(scrapedurl, "temporada-(\d+)")
post = "action=season&start=0&limit=0&show=%s&season=%s" % (sid, ssid)
url = host + "/a/episodes"
data = httptools.downloadpage(url, post=post).data
episodes = jsontools.load(data)
for episode in episodes:
thumbnail = host + "/thumbs/" + episode['thumbnail']
language = episode['languages']
temporada = episode['season']
episodio = episode['episode']
if len(episodio) == 1: episodio = '0' + episodio
if episode['languages'] != "[]":
idiomas = "( [COLOR teal][B]"
for idioma in episode['languages']: idiomas += idioma + " "
@@ -440,15 +436,12 @@ def episodios(item):
idiomas = idiomas
else:
idiomas = ""
if episode['title']:
try:
title = episode['title']['es'].strip()
except:
title = episode['title']['en'].strip()
if len(title) == 0: title = "Temporada " + temporada + " Episodio " + episodio
try:
title = temporada + "x" + episodio + " - " + title.decode('utf-8') + ' ' + idiomas
except:
@@ -456,38 +449,30 @@ def episodios(item):
# try: title = temporada + "x" + episodio + " - " + title + ' ' + idiomas
# except: pass
# except: title = temporada + "x" + episodio + " - " + title.decode('iso-8859-1') + ' ' + idiomas
str = get_status(status, 'episodes', episode['id'])
if str != "": title += str
try:
title = title.encode('utf-8')
except:
title = title.encode('iso-8859-1')
url = urlparse.urljoin(scrapedurl, 'temporada-' + temporada + '/episodio-' + episodio) + "###" + episode[
'id'] + ";3"
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, fulltitle=title, url=url,
thumbnail=thumbnail, show=item.show, folder=True, contentType="episode",
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, url=url,
thumbnail=thumbnail, contentSerieName=item.contentSerieName, folder=True, contentType="episode",
language=language))
if config.get_videolibrary_support() and len(itemlist) > 0:
itemlist.append(Item(channel=item.channel, title="Añadir esta serie a la videoteca", url=url_targets,
action="add_serie_to_library", extra="episodios", show=item.show))
action="add_serie_to_library", extra="episodios", contentSerieName=item.contentSerieName))
itemlist.append(Item(channel=item.channel, title="Descargar todos los episodios de la serie", url=url_targets,
action="download_all_episodes", extra="episodios", show=item.show))
action="download_all_episodes", extra="episodios"))
return itemlist
def novedades_episodios(item):
logger.info()
itemlist = []
## Carga estados
status = jsontools.load(httptools.downloadpage(host + '/a/status/all').data)
## Episodios
url = item.url.split("?")[0]
post = item.url.split("?")[1]

View File

@@ -21,6 +21,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "include_in_newest_peliculas",
"type": "bool",

View File

@@ -15,6 +15,8 @@ from core import tmdb
host = "http://www.mejortorrent.com"
__modo_grafico__ = config.get_setting('modo_grafico', 'mejortorrent')
def mainlist(item):
logger.info()
@@ -386,7 +388,7 @@ def listado(item):
break
#Llamamos a TMDB para que complete InfoLabels
tmdb.set_infoLabels(itemlist, seekTmdb = True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -682,7 +684,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Llamamos a TMDB para que complete InfoLabels desde itemlist. Mejor desde itemlist porque envía las queries en paralelo
tmdb.set_infoLabels(itemlist, seekTmdb = True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -773,9 +775,9 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
@@ -815,8 +817,7 @@ def findvideos(item):
#Limpiamos de año y rating de episodios, usamos el año del episodio en vez del de la serie
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['episodio_titulo'] == item_local.contentSerieName:
item_local.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(' - ' + item.contentSerieName, '')
if item_local.infoLabels['aired'] and item_local.contentType == "episode":
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
@@ -881,6 +882,10 @@ def findvideos(item):
def episodios(item):
logger.info()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
# Carga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
@@ -954,13 +959,15 @@ def episodios(item):
itemlist.append(item_local.clone())
# Llamamos a TMDB para que complete el episodio en InfoLabels
tmdb.set_infoLabels(itemlist, seekTmdb = True)
tmdb.set_infoLabels(itemlist, True)
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -989,7 +996,7 @@ def episodios(item):
#Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.title = '%s - %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
@@ -1013,9 +1020,15 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason:] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''
if item_local.infoLabels['temporada_num_episodios']:

View File

@@ -10,7 +10,9 @@
"torrent",
"movie",
"tvshow",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -21,6 +23,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://mispelisyseries.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

5
plugin.video.alfa/channels/peliculasdk.json Executable file → Normal file
View File

@@ -7,8 +7,9 @@
"thumbnail": "http://s29.postimg.cc/wzw749oon/pldklog.jpg",
"banner": "peliculasdk.png",
"categories": [
"torrent",
"movie"
"movie",
"vos",
"adult"
],
"settings": [
{

View File

@@ -10,35 +10,76 @@ from core.scrapertools import decodeHtmlentities as dhe
from platformcode import logger
from platformcode import config
from core import tmdb
from channelselector import get_thumb
from channels import filtertools
from channels import autoplay
__comprueba_enlaces__ = config.get_setting('comprueba_enlaces', 'peliculasdk')
__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', 'peliculasdk')
__adult_mode__ = config.get_setting("adult_mode")
host = "http://www.peliculasdk.com"
IDIOMAS = {'es': 'Español', 'la': 'Latino', 'su': 'Subtitulado', 'in': 'Inglés'}
list_language = IDIOMAS.values()
list_quality = ['HD-1080', 'HD-720', 'HD-320', 'BR-R', 'BR-S', 'DVD-R', 'DVD-S', 'TS-HQ', 'TS', 'CAM'] # -R:Rip, -S:Screener
list_servers = ['directo', 'streamango', 'powvideo', 'datoporn', 'gamovideo', 'streamplay', 'okru', 'rapidvideo', 'openload']
def mainlist(item):
logger.info()
autoplay.init(item.channel, list_servers, list_quality)
itemlist = []
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Estrenos[/COLOR]", action="peliculas", url= host + "/ver/estrenos",
fanart="http://s24.postimg.cc/z6ulldcph/pdkesfan.jpg",
thumbnail="http://s16.postimg.cc/st4x601d1/pdkesth.jpg"))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]PelisHd[/COLOR]", action="peliculas", url= host + "/calidad/HD-720/",
fanart="http://s18.postimg.cc/wzqonq3w9/pdkhdfan.jpg",
thumbnail="http://s8.postimg.cc/nn5669ln9/pdkhdthu.jpg"))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Pelis HD-Rip[/COLOR]", action="peliculas", url= host + "/calidad/HD-320",
fanart="http://s7.postimg.cc/3pmnrnu7f/pdkripfan.jpg",
thumbnail="http://s12.postimg.cc/r7re8fie5/pdkhdripthub.jpg"))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Pelis Audio español[/COLOR]", action="peliculas", url= host + "/idioma/Espanol/",
fanart="http://s11.postimg.cc/65t7bxlzn/pdkespfan.jpg",
thumbnail="http://s13.postimg.cc/sh1034ign/pdkhsphtub.jpg"))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Buscar...[/COLOR]", action="search", url= host + "/calidad/HD-720/",
fanart="http://s14.postimg.cc/ceqajaw2p/pdkbusfan.jpg",
thumbnail="http://s13.postimg.cc/o85gsftyv/pdkbusthub.jpg"))
itemlist.append(Item(channel=item.channel, title='Estrenos', action='peliculas', url= host + "/ver/estrenos/",
thumbnail=get_thumb('newest', auto=True), type='movies'))
itemlist.append(Item(channel=item.channel, title='Por géneros', action='section',
thumbnail=get_thumb('genres', auto=True), type='movies'))
itemlist.append(Item(channel=item.channel, title='Por calidades', action='section',
thumbnail=get_thumb('quality', auto=True), type='movies'))
itemlist.append(Item(channel=item.channel, title='Por idiomas', action='section',
thumbnail=get_thumb('language', auto=True), type='movies'))
if __adult_mode__ != 0:
itemlist.append(Item(channel=item.channel, title='Adultos +18', action='peliculas', url= host + "/genero/adultos/",
thumbnail=get_thumb('adults', auto=True), type='movies'))
itemlist.append(Item(channel=item.channel, title='Buscar...', action='search',
thumbnail=get_thumb('search', auto=True), type='movies'))
autoplay.show_option(item.channel, itemlist)
return itemlist
def section(item):
logger.info()
itemlist=[]
duplicados=[]
data = httptools.downloadpage(host).data
if 'Por géneros' in item.title:
patron = '<li><a href="(\/genero\/[^"]*)">([^<]*)<\/a><\/li>' #<li><a href="/genero/accion">Acción</a></li>
elif 'Por calidades' in item.title:
patron = "<li><a href='(\/calidad\/[^']*)'>([^<]*)<\/a><\/li>" #<li><a href='/calidad/HD-1080/'>HD 1080</a></li>
elif 'Por idiomas' in item.title:
patron = "<li><a href='(\/idioma\/[^']*)'>([^<]*)<\/a><\/li>" #<li><a href='/idioma/Espanol/'>Español</a></li>
matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedurl, scrapedtitle in matches:
if scrapedtitle not in duplicados:
itemlist.append(Item(channel=item.channel, url=host + scrapedurl, title=scrapedtitle, action='peliculas',
type=item.type))
duplicados.append(scrapedtitle)
return itemlist
@@ -62,132 +103,161 @@ def search(item, texto):
def buscador(item):
logger.info()
itemlist = []
data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data)
patron = '<div class="karatula".*?'
patron += 'src="([^"]+)".*?'
patron += '<div class="tisearch"><a href="([^"]+)">'
patron += '([^<]+)<.*?'
patron += 'Audio:(.*?)</a>.*?'
patron += 'Género:(.*?)</a>.*?'
patron += 'Calidad:(.*?),'
matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedthumbnail, scrapedurl, scrapedtitle, scrapedlenguaje, scrapedgenero, scrapedcalidad in matches:
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;|&#.*?;", "", data)
patron = 'style="position:relative"> '
patron += '<a href="([^"]+)">'
patron += '<img src="([^"]+)" alt="([^"]+)"></a><br>'
patron += '<div class="titulope">([^<]+)</div>.*?'
patron += 'Audio: (.+?)</div>.*?'
patron += 'Calidad: (.+?)</div>.*?'
matches = scrapertools.find_multiple_matches(data, patron)
for scrapedurl, scrapedthumbnail, scrapedtitle, scrapedtitleorig, scrapedlenguaje, scrapedcalidad in matches:
year = scrapertools.find_single_match(scrapedtitle, '\((\d+)\)')
scrapedcalidad = re.sub(r"<a href.*?>|</a>|</span>", "", scrapedcalidad).strip()
scrapedlenguaje = re.sub(r"<a href.*?>|</a>|</span>", "", scrapedlenguaje).strip()
if not "Adultos" in scrapedgenero and not "Adultos" in scrapedlenguaje and not "Adultos" in scrapedcalidad:
scrapedcalidad = "[COLOR orange]" + scrapedcalidad + "[/COLOR]"
scrapedlenguaje = "[COLOR orange]" + scrapedlenguaje + "[/COLOR]"
title = scrapedtitle + "-(Idioma: " + scrapedlenguaje + ")" + "-(Calidad: " + scrapedcalidad + ")"
title = "[COLOR white]" + title + "[/COLOR]"
scrapedtitle = scrapedtitle.split("(")[0].strip()
itemlist.append(Item(channel=item.channel, title=title, url=scrapedurl, action="findvideos",
thumbnail=scrapedthumbnail, contentTitle = scrapedtitle, infoLabels={'year':year},
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", library=True, folder=True))
tmdb.set_infoLabels(itemlist, True)
try:
next_page = scrapertools.get_match(data,
'<span class="current">.*?<a href="(.*?)".*?>Siguiente &raquo;</a></div>')
itemlist.append(Item(channel=item.channel, action="buscador", title="[COLOR red]siguiente>>[/COLOR]", url=next_page,
thumbnail="http://s6.postimg.cc/uej03x4r5/bricoflecha.png",
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", folder=True))
except:
pass
scrapedtitle = re.sub(r"\(\d+\)", "", scrapedtitle).strip()
audios = scrapertools.find_multiple_matches(scrapedlenguaje, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
calidad = scrapertools.find_single_match(scrapedcalidad, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
titulo = '%s [%s][%s]' % (scrapedtitle, ','.join([a[:3] for a in audios]), calidad)
# Parece que las pelis de adultos se mezclan en la búsqueda y lo único que las diferencia es que no tienen Calidad
if calidades or __adult_mode__ != 0:
itemlist.append(Item(channel=item.channel,
action="findvideos", url=scrapedurl,
title=titulo, contentTitle=scrapedtitle,
thumbnail=scrapedthumbnail,
language=audios,
quality=calidad,
infoLabels={'year':year}
))
tmdb.set_infoLabels(itemlist)
# Paginación
url_next_page = scrapertools.find_single_match(data,'<a href="([^"]*)">Siguiente &raquo;</a>')
if url_next_page:
itemlist.append(item.clone(title="Siguiente >>", url=url_next_page))
return itemlist
def peliculas(item):
logger.info()
itemlist = []
# Descarga la página
data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;|&#.*?;", "", data)
patron = 'style="position:relative;"> '
patron += '<a href="([^"]+)" '
patron += 'title="([^<]+)">'
patron += '<img src="([^"]+)".*?'
patron += 'Audio:(.*?)</br>.*?'
patron += 'Calidad:(.*?)</br>.*?'
patron += 'Género:.*?tag">(.*?)</a>'
patron = 'style="position:relative"> '
patron += '<a href="([^"]+)">'
patron += '<img src="([^"]+)" alt="([^"]+)"></a><br>'
patron += '<div class="titulope">([^<]+)</div>.*?'
patron += 'Audio: (.+?)</div>.*?'
patron += 'Calidad: (.+?)</div>.*?'
patron += 'Género: (.+?)</div>'
matches = scrapertools.find_multiple_matches(data, patron)
for scrapedurl, scrapedtitle, scrapedthumbnail, scrapedlenguaje, scrapedcalidad, scrapedgenero in matches:
for scrapedurl, scrapedthumbnail, scrapedtitle, scrapedtitleorig, scrapedlenguaje, scrapedcalidad, scrapedgenero in matches:
year = scrapertools.find_single_match(scrapedtitle, '\((\d+)\)')
scrapedtitle = re.sub(r"\(\d+\)", "", scrapedtitle).strip()
scrapedcalidad = re.sub(r"<a href.*?>|</a>", "", scrapedcalidad).strip()
scrapedlenguaje = re.sub(r"<a href.*?>|</a>", "", scrapedlenguaje).strip()
scrapedlenguaje = scrapedlenguaje.split(',')
if not "Adultos" in scrapedgenero and not "Adultos" in scrapedlenguaje and not "Adultos" in scrapedcalidad:
scrapedtitle = scrapedtitle
audios = scrapertools.find_multiple_matches(scrapedlenguaje, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
calidad = scrapertools.find_single_match(scrapedcalidad, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
generos = scrapertools.find_multiple_matches(scrapedgenero, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
titulo = '%s [%s][%s]' % (scrapedtitle, ','.join([a[:3] for a in audios]), calidad)
if 'Adultos' not in generos or __adult_mode__ != 0:
itemlist.append(Item(channel=item.channel,
title=scrapedtitle,
url=scrapedurl,
action="findvideos",
action="findvideos", url=scrapedurl,
title=titulo, contentTitle=scrapedtitle,
thumbnail=scrapedthumbnail,
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", library=True, folder=True,
language=scrapedlenguaje,
quality=scrapedcalidad,
contentTitle = scrapedtitle,
language=audios,
quality=calidad,
infoLabels={'year':year}
))
tmdb.set_infoLabels(itemlist)
## Paginación
next_page = scrapertools.get_match(data, '<span class="current">.*?<a href="(.*?)".*?>Siguiente &raquo;</a></div>')
itemlist.append(Item(channel=item.channel, action="peliculas", title="[COLOR red]siguiente>>[/COLOR]", url=next_page,
thumbnail="http://s6.postimg.cc/uej03x4r5/bricoflecha.png",
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", folder=True))
# Paginación
url_next_page = scrapertools.find_single_match(data,'<a href="([^"]*)">Siguiente &raquo;</a>')
if url_next_page:
itemlist.append(item.clone(title="Siguiente >>", url=url_next_page))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
data = httptools.downloadpage(item.url).data
data = re.sub(r"<!--.*?-->", "", data)
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data)
bloque_tab = scrapertools.find_single_match(data, '<div id="verpelicula">(.*?)<div class="tab_container">')
patron = '<li><a href="#([^<]+)"><span class="re">\d<\/span><span class="([^<]+)"><\/span><span class=.*?>([^<]+)<\/span>'
check = re.compile(patron, re.DOTALL).findall(bloque_tab)
servers_data_list = []
patron = '<div id="(tab\d+)" class="tab_content"><script type="text/rocketscript">(\w+)\("([^"]+)"\)</script></div>'
patron = '<li><a href="#(tab\d+)"><span class="re">\d<\/span><span class="([^"]+)"><\/span><span class=.*?>([^<]+)<\/span>'
check = re.compile(patron, re.DOTALL).findall(data)
if not check:
patron = '<li><a href="#(tab\d+)">'
check = re.compile(patron, re.DOTALL).findall(data)
for i, valor in enumerate(check):
check[i] = [valor, '', '']
patron = '<div id="(tab\d+)" class="tab_content">(.*?)</div>'
matches = re.compile(patron, re.DOTALL).findall(data)
if len(matches) == 0:
patron = '<div id="(tab\d+)" class="tab_content"><script>(\w+)\("([^"]+)"\)</script></div>'
matches = re.compile(patron, re.DOTALL).findall(data)
for check_tab, server, id in matches:
if check_tab in str(check):
idioma, calidad = scrapertools.find_single_match(str(check), "" + check_tab + "', '(.*?)', '(.*?)'")
servers_data_list.append([server, id, idioma, calidad])
url = host + "/Js/videod.js"
data = httptools.downloadpage(url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data)
data = data.replace('<iframe width="100%" height="400" scrolling="no" frameborder="0"', '')
patron = 'function (\w+)\(id\).*?'
patron += 'data-src="([^"]+)"'
matches = scrapertools.find_multiple_matches(data, patron)
for server, url in matches:
for enlace, id, idioma, calidad in servers_data_list:
if server == enlace:
video_url = re.sub(r"embed\-|\-.*?x.*?\.html|u\'|\'\(", "", str(url))
video_url = re.sub(r"'\+codigo\+'", "", video_url)
video_url = video_url.replace('embed//', 'embed/')
video_url = video_url + id
if "goo.gl" in video_url:
try:
from unshortenit import unshorten
url = unshorten(video_url)
video_url = scrapertools.get_match(str(url), "u'([^']+)'")
except:
continue
title = "Ver en: %s [" + idioma + "][" + calidad + "]"
itemlist.append(
item.clone(title=title, url=video_url, action="play",
thumbnail=item.category,
language=idioma, quality=calidad))
servers_data_list = []
for i, match in enumerate(matches):
if match[0] == check[i][0]:
if '<iframe' in match[1]:
src = scrapertools.find_single_match(match[1], ' src="([^"]*)"')
servers_data_list.append([check[i][1], check[i][2], 'iframe', src]) # idioma, calidad, 'iframe', src
elif '<script' in match[1]:
src = scrapertools.find_single_match(match[1], '<script>(.*?)<\/script>')
if src:
func, parm = scrapertools.find_single_match(src, '(.*?)\("([^"]*)"\)')
servers_data_list.append([check[i][1], check[i][2], func, parm ]) # idioma, calidad, func, parm
data = httptools.downloadpage(host + '/Js/videod.js').data
patron = 'function (\w+)\(id\){(.*?)}'
matches = re.compile(patron, re.DOTALL).findall(data)
for idioma, calidad, func, parm in servers_data_list:
if func == 'iframe':
title = "Ver en: %s [" + idioma + "][" + calidad + "]"
itemlist.append(
item.clone(title=title, url=parm, action="play",
thumbnail=item.category,
language=idioma, quality=calidad))
else:
for funcion, contenido in matches:
if funcion == func:
if '<script' in contenido: continue
if '<iframe' in contenido:
src = scrapertools.find_single_match(contenido, 'src="([^"]*)"')
else:
src = scrapertools.find_single_match(contenido, 'href="([^"]*)"')
if "'+codigo+'" not in src: continue
src = src.replace("'+codigo+'", parm)
title = "Ver en: %s [" + idioma + "][" + calidad + "]"
itemlist.append(
item.clone(title=title, url=src, action="play",
thumbnail=item.category,
language=idioma, quality=calidad))
break
tmdb.set_infoLabels(itemlist)
itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % i.server.capitalize())
if __comprueba_enlaces__:
itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__)
if item.library and config.get_videolibrary_support() and len(itemlist) > 0:
infoLabels = {'tmdb_id': item.infoLabels['tmdb_id'],
'title': item.fulltitle}
@@ -195,14 +265,14 @@ def findvideos(item):
action="add_pelicula_to_library", url=item.url, infoLabels=infoLabels,
text_color="0xFFff6666",
thumbnail='http://imgur.com/0gyYvuC.png'))
itemlist = filtertools.get_links(itemlist, item, list_language)
autoplay.start(itemlist, item)
return itemlist
def play(item):
item.thumbnail = item.contentThumbnail
return [item]
def newest(categoria):
logger.info()
itemlist = []

View File

@@ -38,6 +38,9 @@ def mainlist(item):
itemlist.append(Item(channel=item.channel, action="opciones", title="Opciones",
thumbnail=get_thumb("search.png")))
itemlist.append(Item(channel="tvmoviedb", action="mainlist", title="Busquèda alternativa",
thumbnail=get_thumb("search.png")))
saved_searches_list = get_saved_searches()
context2 = context[:]
context2.append({"title": "Borrar búsquedas guardadas",
@@ -437,7 +440,7 @@ def do_search(item, categories=None):
result_mode = 1
if result_mode == 0:
if len(search_results[channel]) > 1:
title += " [%s]" % element["item"].title.strip()
title += " -%s" % element["item"].title.strip()
title += " (%s)" % len(element["itemlist"])
title = re.sub("\[COLOR [^\]]+\]", "", title)

View File

@@ -169,7 +169,7 @@ def seasons(item):
return itemlist
def all_episodes(item):
def epidodios(item):
logger.info()
itemlist = []
templist = seasons(item)
@@ -183,8 +183,9 @@ def episodesxseason(item):
itemlist = []
data = get_source(item.url)
season = item.contentSeasonNumber
season_data = scrapertools.find_single_match(data, '<div id=collapse%s.*?panel-success' % season)
patron = "<td><a href='([^ ]+)'.*?itemprop='episodeNumber'>%s+x(\d+)</span> - (.*?) </a>.*?(/banderas.*?)</td>" % season
matches = re.compile(patron, re.DOTALL).findall(data)
matches = re.compile(patron, re.DOTALL).findall(season_data)
infoLabels = item.infoLabels
for scrapedurl, scraped_episode, scrapedtitle, lang_data in matches:
url = host + scrapedurl
@@ -207,15 +208,22 @@ def episodesxseason(item):
def add_language(title, string):
logger.info()
language = []
languages = scrapertools.find_multiple_matches(string, '/banderas/(.*?).png')
language = []
for lang in languages:
if 'jap' in lang or lang not in IDIOMAS:
lang = 'vos'
language.append(IDIOMAS[lang])
title = '%s [%s]' % (title, IDIOMAS[lang])
if len(languages) == 1:
language = IDIOMAS[languages[0]]
title = '%s [%s]' % (title, language)
else:
language.append(IDIOMAS[lang])
title = '%s [%s]' % (title, IDIOMAS[lang])
return title, language
@@ -226,9 +234,8 @@ def findvideos(item):
itemlist = []
data = get_source(item.url)
patron = "<a href=([^ ]+) target=_blank><img src='/servidores/(.*?).(?:png|jpg)'.*?sno.*?"
patron += "sno><span>(.*?)<.*?(/banderas.*?)td"
patron += "<span>(.*?)<.*?(/banderas.*?)td"
matches = re.compile(patron, re.DOTALL).findall(data)

View File

@@ -12,7 +12,9 @@
"tvshow",
"anime",
"torrent",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -23,6 +25,21 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://torrentlocura.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

View File

@@ -12,7 +12,9 @@
"anime",
"torrent",
"latino",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -23,6 +25,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://torrentrapid.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

View File

@@ -11,7 +11,9 @@
"tvshow",
"anime",
"torrent",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -22,6 +24,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://tumejortorrent.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

View File

@@ -1,178 +1,178 @@
{
"id": "tvmoviedb",
"name": "TvMovieDB",
"active": true,
"adult": false,
"language": ["*"],
"thumbnail": "http://i.imgur.com/HA7fvgD.png",
"categories": [
"movie",
"tvshow",
"anime"
],
"settings": [
{
"id": "tmdb",
"type": "list",
"label": "Idioma de búsqueda en TMDB",
"default": 7,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "tmdb_alternativo",
"type": "list",
"label": "Idioma alternativo para TMDB (No sinopsis idioma principal)",
"default": 6,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "imdb",
"type": "list",
"label": "Idioma de los títulos en IMDB",
"color": "0xFFE0F04B",
"default": 7,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "label1",
"type": "label",
"label": "",
"enabled": false,
"visible": true
},
{
"id": "filmaff",
"type": "list",
"label": "Sitio Web Filmaffinity",
"color": "0xFF25AA48",
"default": 5,
"enabled": true,
"visible": true,
"lvalues": [
"Colombia",
"Chile",
"Argentina",
"México",
"US/UK",
"España"
]
},
{
"id": "usuariofa",
"type": "text",
"label": "Usuario Filmaffinity (Opcional)",
"color": "0xFFd50b0b",
"default": "",
"enabled": true,
"visible": true
},
{
"id": "passfa",
"type": "text",
"label": "Contraseña Filmaffinity",
"color": "0xFFd50b0b",
"default": "",
"enabled": "!eq(-1,'')",
"hidden": true,
"visible": true
},
{
"id": "orderfa",
"type": "list",
"label": "Ordenar listas personales de Filmaffinity por:",
"color": "0xFF25AA48",
"default": 0,
"enabled": "!eq(-1,'')",
"visible": true,
"lvalues": [
"Posición",
"Título",
"Año",
"Voto",
"Nota media"
]
},
{
"id": "label2",
"type": "label",
"label": "",
"enabled": false,
"visible": true
},
{
"id": "usuariomal",
"type": "text",
"label": "Usuario MyAnimeList (Opcional)",
"color": "0xFF25AA48",
"default": "",
"enabled": true,
"visible": true
},
{
"id": "passmal",
"type": "text",
"label": "Contraseña MyAnimeList",
"color": "0xFF25AA48",
"default": "",
"enabled": "!eq(-1,'')",
"hidden": true,
"visible": true
},
{
"id": "adult_mal",
"type": "bool",
"label": "Mostrar Hentais en MyAnimeList",
"color": "0xFFd50b0b",
"default": false,
"enabled": true,
"visible": true
},
{
"id": "perfil",
"type": "list",
"label": "Perfil de color",
"default": 2,
"enabled": true,
"visible": true,
"lvalues": [
"Perfil 3",
"Perfil 2",
"Perfil 1",
"Ninguno"
]
}
]
{
"id": "tvmoviedb",
"name": "TvMovieDB",
"active": false,
"adult": false,
"language": ["*"],
"thumbnail": "http://i.imgur.com/HA7fvgD.png",
"categories": [
"movie",
"tvshow",
"anime"
],
"settings": [
{
"id": "tmdb",
"type": "list",
"label": "Idioma de búsqueda en TMDB",
"default": 7,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "tmdb_alternativo",
"type": "list",
"label": "Idioma alternativo para TMDB (No sinopsis idioma principal)",
"default": 6,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "imdb",
"type": "list",
"label": "Idioma de los títulos en IMDB",
"color": "0xFFE0F04B",
"default": 7,
"enabled": true,
"visible": true,
"lvalues": [
"Alemán",
"Francés",
"Portugués",
"Italiano",
"Español Latino",
"Catalán",
"Inglés",
"Castellano"
]
},
{
"id": "label1",
"type": "label",
"label": "",
"enabled": false,
"visible": true
},
{
"id": "filmaff",
"type": "list",
"label": "Sitio Web Filmaffinity",
"color": "0xFF25AA48",
"default": 5,
"enabled": true,
"visible": true,
"lvalues": [
"Colombia",
"Chile",
"Argentina",
"México",
"US/UK",
"España"
]
},
{
"id": "usuariofa",
"type": "text",
"label": "Usuario Filmaffinity (Opcional)",
"color": "0xFFd50b0b",
"default": "",
"enabled": true,
"visible": true
},
{
"id": "passfa",
"type": "text",
"label": "Contraseña Filmaffinity",
"color": "0xFFd50b0b",
"default": "",
"enabled": "!eq(-1,'')",
"hidden": true,
"visible": true
},
{
"id": "orderfa",
"type": "list",
"label": "Ordenar listas personales de Filmaffinity por:",
"color": "0xFF25AA48",
"default": 0,
"enabled": "!eq(-1,'')",
"visible": true,
"lvalues": [
"Posición",
"Título",
"Año",
"Voto",
"Nota media"
]
},
{
"id": "label2",
"type": "label",
"label": "",
"enabled": false,
"visible": true
},
{
"id": "usuariomal",
"type": "text",
"label": "Usuario MyAnimeList (Opcional)",
"color": "0xFF25AA48",
"default": "",
"enabled": true,
"visible": true
},
{
"id": "passmal",
"type": "text",
"label": "Contraseña MyAnimeList",
"color": "0xFF25AA48",
"default": "",
"enabled": "!eq(-1,'')",
"hidden": true,
"visible": true
},
{
"id": "adult_mal",
"type": "bool",
"label": "Mostrar Hentais en MyAnimeList",
"color": "0xFFd50b0b",
"default": false,
"enabled": true,
"visible": true
},
{
"id": "perfil",
"type": "list",
"label": "Perfil de color",
"default": 2,
"enabled": true,
"visible": true,
"lvalues": [
"Perfil 3",
"Perfil 2",
"Perfil 1",
"Ninguno"
]
}
]
}

View File

@@ -730,11 +730,11 @@ def indices_tmdb(item):
from datetime import datetime
if "Géneros" in item.title:
thumbnail = {}
url = ('http://api.themoviedb.org/3/genre/%s/list?api_key=f7f51775877e0bb6703520952b3c7840&language=%s'
url = ('http://api.themoviedb.org/3/genre/%s/list?api_key=a1ab8b8669da03637a4b98fa39c39228&language=%s'
% (item.extra, langt))
lista_generos = {}
try:
lista = jsontools.load(httptools.downloadpage(url, cookies=False).data)["genres"]
lista_generos = {}
for l in lista:
lista_generos[str(l["id"])] = l["name"]
if "es" in langt:
@@ -754,12 +754,10 @@ def indices_tmdb(item):
sort_by = 'first_air_date.desc'
param_year = 'air_date.lte'
for key, value in lista_generos.items():
new_item = item.clone()
new_item.title = value
new_item.thumbnail = thumbnail[key]
new_item.search = {'url': 'discover/%s' % item.extra, 'with_genres': key, 'sort_by': sort_by,
param_year: fecha,
'language': langt, 'page': 1}
search = {'url': 'discover/%s' % item.extra, 'with_genres': key, 'sort_by': sort_by,
param_year: fecha,
'language': langt, 'page': 1}
new_item = item.clone(title=value, thumbnail=thumbnail[key], action="listado_tmdb", search=search)
itemlist.append(new_item)
itemlist.sort(key=lambda item: item.title)

View File

@@ -11,7 +11,9 @@
"tvshow",
"anime",
"torrent",
"documentary"
"documentary",
"vos",
"direct"
],
"settings": [
{
@@ -22,6 +24,22 @@
"enabled": true,
"visible": true
},
{
"id": "modo_grafico",
"type": "bool",
"label": "Buscar información extra (TMDB)",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_ver_enlaces_veronline",
"type": "list",

View File

@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://www.tvsinpagar.com/'
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else:
if data:
data = scrapertools.get_match(data, patron)
if not data:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
else:
return itemlist
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems:
del item.totalItems
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif '<h3><strong>( 0 ) Resultados encontrados </strong>' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
@@ -157,10 +191,15 @@ def listado(item):
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<img.*?src="([^"]+)"[^>]+>.*?' # el thumbnail
patron += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -263,6 +302,7 @@ def listado(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -361,7 +401,7 @@ def listado(item):
itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -466,10 +506,17 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
return itemlist
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -487,26 +534,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos en bloque que nos interesa
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
#pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año
pattern += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data)
if not matches_alt and not '<h3><strong>( 0 ) Resultados encontrados </strong>' in data_alt: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist.
#Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse
title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt:
#Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas
#Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora
#Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series
scrapedurl_alt = scrapedurl
if "pelisyseries.com" in host: #Excepción para mispelisyseries.com.
scrapedurl_alt = scrapedurl
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +568,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if scrapedurl in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item
if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host:
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
title_lista_alt_for += [scrapedurl_alt]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue
cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,9 +589,11 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
@@ -639,6 +693,7 @@ def listado_busqueda(item):
#Extraemos info adicional del título y la guardamos para después de TMDB
if ("temp" in title.lower() or "cap" in title.lower()) and item_local.contentType != "movie":
#Eliminamos Temporada de Series, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+[x|X]\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
@@ -811,7 +866,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
@@ -970,14 +1025,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables
logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores
logger.debug(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas)
logger.error(ver_enlaces_veronline)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
logger.error(verificar_enlaces_descargas_validos)
logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1061,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1089,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -1040,6 +1099,10 @@ def findvideos(item):
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
item_local.url = item_local.url.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.debug("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data)
@@ -1136,6 +1199,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para cada link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1225,6 +1289,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor) #activo el link ?
if verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí
@@ -1268,17 +1333,41 @@ def episodios(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
max_temp = 1
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada página
pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern)
if pagination:
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
if "/pg/" in item.url:
act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual
else:
act_page = 1
pattern = '<li><a href="([^"]+)">Last<\/a>' #Busca última página
full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url]
for x in range(2, int(last_page) + 1): #carga cada página para obtener la url de la siguiente
for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente
#LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa
#response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess:
@@ -1287,28 +1376,42 @@ def episodios(item):
else:
list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
if scrapertools.find_single_match(data, pattern):
season = max_temp
if item.library_playcounts: #Comprobamos si realmente sabemos el num. máximo de temporadas
num_temporadas_flag = True
else:
num_temporadas_flag = False
for page in list_pages: #Recorre la lista de páginas
if not list_pages:
break
try:
if not data:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data = scrapertools.get_match(data, pattern)
else:
logger.debug(item)
logger.debug("patron: " + pattern + " / data: " + data)
return itemlist
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("patron: " + pattern)
#logger.debug(matches)
#Empezamos a generar cada episodio
season = "1"
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url
@@ -1359,9 +1462,30 @@ def episodios(item):
r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0]
if not match: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0"
try:
match['season'] = int(match['season'])
match['episode'] = int(match['episode'])
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
item_local.contentSeason = match['season']
season = match['season']
num_temporadas_flag = True
if season > max_temp:
max_temp = season
if match['quality'] and not item_local.quality and estado == True:
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
@@ -1378,22 +1502,52 @@ def episodios(item):
item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2))
item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season']
if modo_ultima_temp and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
list_pages = [] #Sale del bucle de leer páginas
break #Sale del bucle actual del FOR de episodios por página
#if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts:
# continue
if item_local.active:
del item_local.active
if item_local.category:
del item_local.category
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
item_local.context = "['buscar_trailer']"
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
itemlist.append(item_local.clone())
logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber))
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True)
data = ''
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = []
for i in range(0, 50): num_episodios_lista += [0]
num_temporada = 1
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1406,6 +1560,19 @@ def episodios(item):
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if item_local.infoLabels['number_of_seasons']:
#Si el num de temporada está fuera de control, se pone 0, y se reclasifica itemlist
if item_local.contentSeason > item_local.infoLabels['number_of_seasons'] + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(item_local.infoLabels['number_of_seasons']) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
else:
num_temporada_max = item_local.infoLabels['number_of_seasons']
else:
if item_local.contentSeason > num_temporada_max + 1:
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
item_local.contentSeason = 0
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
@@ -1416,7 +1583,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
@@ -1439,8 +1606,18 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
try:
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''

View File

@@ -267,6 +267,16 @@
"Título original"
]
},
{
"id": "lowerize_title",
"type": "list",
"label": "Crear directorios con letras en miúsculas",
"default": 0,
"lvalues": [
"Si",
"No"
]
},
{
"id": "lab_1",
"type": "label",

View File

@@ -125,6 +125,9 @@ def save_movie(item):
base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8")
if config.get_setting("lowerize_title", "videolibrary") == 0:
base_name = base_name.lower()
for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH):
for c in subcarpetas:
code = scrapertools.find_single_match(c, '\[(.*?)\]')
@@ -246,6 +249,9 @@ def save_tvshow(item, episodelist):
base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8")
if config.get_setting("lowerize_title", "videolibrary") == 0:
base_name = base_name.lower()
for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH):
for c in subcarpetas:
code = scrapertools.find_single_match(c, '\[(.*?)\]')

View File

@@ -475,7 +475,9 @@ def thumbnail_type(item):
thumb_type = config.get_setting('video_thumbnail_type')
info = item.infoLabels
item.contentThumbnail = item.thumbnail
if not item.contentThumbnail:
item.contentThumbnail = item.thumbnail
if info:
if info['thumbnail'] !='':
item.contentThumbnail = info['thumbnail']
@@ -488,7 +490,7 @@ def thumbnail_type(item):
from core.servertools import get_server_parameters
#logger.debug('item.server: %s'%item.server)
server_parameters = get_server_parameters(item.server.lower())
item.thumbnail = server_parameters.get("thumbnail", "")
item.thumbnail = server_parameters.get("thumbnail", item.contentThumbnail)
return item.thumbnail

View File

@@ -8,7 +8,7 @@ from platformcode import logger
def test_video_exists(page_url):
logger.info("(page_url='%s')" % page_url)
data = httptools.downloadpage(page_url).data
if "File Not Found" in data:
if "File Not Found" in data or "File was deleted" in data:
return False, "[clipwatching] El video ha sido borrado"
return True, ""

View File

@@ -19,7 +19,7 @@ def test_video_exists(page_url):
logger.info("(page_url='%s')" % page_url)
data = get_source(page_url)
if "File was deleted" in data:
if "File was deleted" in data or "File Not Found" in data:
return False, "[Filebebo] El video ha sido borrado"
return True, ""

View File

@@ -31,8 +31,8 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
js_wise = scrapertools.find_single_match(data_page_url_hqq,
"<script type=[\"']text/javascript[\"']>\s*;?(eval.*?)</script>")
data_unwise = jswise(js_wise).replace("\\", "")
at = scrapertools.find_single_match(data_unwise, 'var at\s*=\s*"([^"]+)"')
http_referer = scrapertools.find_single_match(data_unwise, 'var http_referer\s*=\s*"([^"]+)"')
at = scrapertools.find_single_match(data_unwise, 'at=(\w+)')
http_referer = scrapertools.find_single_match(data_unwise, 'http_referer=(.*?)&')
url = "http://hqq.watch/sec/player/embed_player.php?iss=&vid=%s&at=%s&autoplayed=yes&referer=on" \
"&http_referer=%s&pass=&embed_from=&need_captcha=0&hash_from=" % (id_video, at, http_referer)
data_player = httptools.downloadpage(url, add_referer=True).data

View File

@@ -44,5 +44,5 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
def decode_powvideo_url(url):
tria = re.compile('[0-9a-z]{40,}', re.IGNORECASE).findall(url)[0]
gira = tria[::-1]
x = gira[:2] + gira[3:]
x = gira[1:]
return re.sub(tria, x, url)

View File

@@ -45,7 +45,8 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
media_url = scrapertools.get_match(data, 'file\: "([^"]+)"')
video_urls = []
video_urls.append([scrapertools.get_filename_from_url(media_url)[-4:] + " [streamcloud]", media_url])
video_urls.append([scrapertools.get_filename_from_url(media_url)[-4:] + " [streamcloud]", media_url+"|Referer="+page_url])
for video_url in video_urls:
logger.info("%s - %s" % (video_url[0], video_url[1]))

View File

@@ -46,5 +46,5 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
def decode_video_url(url):
tria = re.compile('[0-9a-z]{40,}', re.IGNORECASE).findall(url)[0]
gira = tria[::-1]
x = gira[:2] + gira[3:]
x = gira[:3] + gira[4:]
return re.sub(tria, x, url)

View File

@@ -20,7 +20,7 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
logger.info("(page_url='%s')" % page_url)
data = httptools.downloadpage(page_url).data
video_urls = []
matches = scrapertools.find_multiple_matches(data, 'file\s*:\s*"([^"]+)"\s*,\s*label:"([^"]+)"')
matches = scrapertools.find_multiple_matches(data, 'src\s*:\s*"([^"]+)".*?label:\'([^\']+)\'')
for media_url, calidad in matches:
ext = media_url[-4:]
video_urls.append(["%s %s [vidoza]" % (ext, calidad), media_url])