Merge branch 'master' into explora

This commit is contained in:
unknown
2018-06-09 10:35:17 -03:00
29 changed files with 2675 additions and 571 deletions
+11 -9
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?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.17" provider-name="Alfa Addon">
<requires> <requires>
<import addon="xbmc.python" version="2.1.0"/> <import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.libtorrent" optional="true"/> <import addon="script.module.libtorrent" optional="true"/>
@@ -19,15 +19,17 @@
</assets> </assets>
<news>[B]Estos son los cambios para esta versión:[/B] <news>[B]Estos son los cambios para esta versión:[/B]
[COLOR green][B]Canales agregados y arreglos[/B][/COLOR] [COLOR green][B]Canales agregados y arreglos[/B][/COLOR]
» clipwatching » vidup » grantorrent » descargas2020
» allcalidad » descargacineclasico » mejortorrent » mispelisyseries
» mastorrent » tiotorrent » torrentlocura » torrentrapid
» animeshd » filebebo » tumejortorrent » tvsinpagar
» cuevana2 » Cuevana2español » hdfull » clipwatching
» seriesverde » flashx » filebebo » anitoons
» netutv » seriesverde
» peliculasdk » cuevana2
» cuevana2español
¤ arreglos internos ¤ arreglos internos
¤ Agradecimientos a @mrgaturus por colaborar con ésta versión.
¤ Agradecimientos a @angedam, @alaquepasa, @mrgaturus, @axlt2002 por colaborar con ésta versión.
</news> </news>
<description lang="es">Navega con Kodi por páginas web para ver sus videos de manera fácil.</description> <description lang="es">Navega con Kodi por páginas web para ver sus videos de manera fácil.</description>
+40 -25
View File
@@ -33,13 +33,12 @@ def mainlist(item):
itemlist = list() itemlist = list()
itemlist.append(Item(channel=item.channel, action="lista", title="Series", url=host+"/lista-de-anime.php", itemlist.append(Item(channel=item.channel, action="lista", title="Series", url=host+"/lista-de-anime.php",
thumbnail=thumb_series)) thumbnail=thumb_series, range=[0,19]))
#itemlist.append(Item(channel=item.channel, action="lista", title="Series Animadas", url=host, itemlist.append(Item(channel=item.channel, action="lista", title="Películas", url=host+"/catalogo.php?g=&t=peliculas&o=0",
# thumbnail=thumb_series)) thumbnail=thumb_series, range=[0,19] ))
#itemlist.append(Item(channel=item.channel, action="lista", title="Novedades", url=host, itemlist.append(Item(channel=item.channel, action="lista", title="Especiales", url=host+"/catalogo.php?g=&t=especiales&o=0",
# thumbnail=thumb_series)) thumbnail=thumb_series, range=[0,19]))
#itemlist.append(Item(channel=item.channel, action="lista", title="Pokemon", url=host,
# thumbnail=thumb_series))
itemlist = renumbertools.show_option(item.channel, itemlist) itemlist = renumbertools.show_option(item.channel, itemlist)
autoplay.show_option(item.channel, itemlist) autoplay.show_option(item.channel, itemlist)
return itemlist return itemlist
@@ -60,8 +59,9 @@ def lista(item):
patron +=".+?<span .+?>(.+?)<\/span>" #scrapedplot patron +=".+?<span .+?>(.+?)<\/span>" #scrapedplot
matches = scrapertools.find_multiple_matches(data, patron) matches = scrapertools.find_multiple_matches(data, patron)
for scrapedurl, scrapedthumbnail,scrapedtitle,scrapedplot in matches: next_page = [item.range[0]+19, item.range[1]+20]
if ":" in scrapedtitle: for scrapedurl, scrapedthumbnail,scrapedtitle,scrapedplot in matches[item.range[0] : item.range[1]]:
if ":" in scrapedtitle:
cad = scrapedtitle.split(":") cad = scrapedtitle.split(":")
show = cad[0] show = cad[0]
else: else:
@@ -81,9 +81,15 @@ def lista(item):
context2 = autoplay.context context2 = autoplay.context
context.extend(context2) context.extend(context2)
scrapedurl=host+scrapedurl scrapedurl=host+scrapedurl
itemlist.append(item.clone(title=scrapedtitle, url=scrapedurl, plot=scrapedplot, if item.title!="Series":
thumbnail=scrapedthumbnail, action="episodios", show=show, context=context)) itemlist.append(item.clone(title=scrapedtitle, contentTitle=show,url=scrapedurl,
#tmdb.set_infoLabels(itemlist) 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 return itemlist
@@ -92,16 +98,16 @@ def episodios(item):
itemlist = [] itemlist = []
data = httptools.downloadpage(item.url).data data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data) data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data)
patron = '<div class="pagina">(.+?)<\/div><div id="fade".+?>' patron = '<div class="pagina">(.+?)<\/div><div id="fade".+?>'
data = scrapertools.find_single_match(data, patron) data = scrapertools.find_single_match(data, patron)
patron_caps = "<li><a href='(.+?)'>Cap(?:i|í)tulo: (.+?) - (.+?)<\/a>" patron_caps = "<li><a href='(.+?)'>Cap(?:i|í)tulo: (.+?) - (.+?)<\/a>"
matches = scrapertools.find_multiple_matches(data, patron_caps) 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='(.+?)'.+?>") scrapedthumbnail = scrapertools.find_single_match(data, "<img src='(.+?)'.+?>")
scrapedplot = scrapertools.find_single_match(data, '<span>Descripcion.+?<\/span>(.+?)<br>') scrapedplot = scrapertools.find_single_match(data, '<span>Descripcion.+?<\/span>(.+?)<br>')
i = 0 i = 0
temp = 0 temp = 0
infoLabels = item.infoLabels
for link, cap, name in matches: for link, cap, name in matches:
if int(cap) == 1: if int(cap) == 1:
temp = temp + 1 temp = temp + 1
@@ -109,19 +115,25 @@ def episodios(item):
cap = "0" + cap cap = "0" + cap
season = temp season = temp
episode = int(cap) episode = int(cap)
season, episode = renumbertools.numbered_for_tratk( season, episode = renumbertools.numbered_for_tratk(
item.channel, item.show, season, episode) item.channel, item.show, season, episode)
infoLabels['season'] = season
infoLabels['episode'] = episode
date = name date = name
title = "%sx%s %s (%s)" % (season, str(episode).zfill(2), "Episodio %s" % episode, date) title = "%sx%s %s (%s)" % (season, str(episode).zfill(2), "Episodio %s" % episode, date)
# title = str(temp)+"x"+cap+" "+name # title = str(temp)+"x"+cap+" "+name
url = host + "/" + link url = host + "/" + link
if "NO DISPONIBLE" not in name: if "NO DISPONIBLE" not in name:
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, thumbnail=scrapedthumbnail, 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: 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, 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 return itemlist
@@ -149,15 +161,15 @@ def findvideos(item):
scrapedthumbnail = scrapertools.find_single_match(data, '<div class="caracteristicas"><img src="([^<]+)">') scrapedthumbnail = scrapertools.find_single_match(data, '<div class="caracteristicas"><img src="([^<]+)">')
itemla = scrapertools.find_multiple_matches(data_vid, '"(.+?)"') itemla = scrapertools.find_multiple_matches(data_vid, '"(.+?)"')
for url in itemla: for url in itemla:
url=url.replace('\/', '/') url=url.replace('\/', '/')
server1=url.split('/') server1=url.split('/')
server=server1[2] server=server1[2]
if "." in server: if "." in server:
server1=server.split('.') server1=server.split('.')
if len(server1)==3: if len(server1)==3:
server=server1[1] server=server1[1]
else: else:
server=server1[0] server=server1[0]
if "goo" in url: if "goo" in url:
url = googl(url) url = googl(url)
server='netutv' server='netutv'
@@ -168,6 +180,9 @@ def findvideos(item):
itemlist.append(item.clone(url=url, action="play", itemlist.append(item.clone(url=url, action="play",
thumbnail=scrapedthumbnail, server=server, plot=scrapedplot, thumbnail=scrapedthumbnail, server=server, plot=scrapedplot,
title="Enlace encontrado en: %s [%s]" % (server.capitalize(), quality))) 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) autoplay.start(itemlist, item)
return itemlist return itemlist
+12 -18
View File
@@ -21,18 +21,9 @@ def mainlist(item):
logger.info() logger.info()
autoplay.init(item.channel, list_servers, list_quality) autoplay.init(item.channel, list_servers, list_quality)
itemlist = [] itemlist = []
itemlist.append(Item(channel = item.channel, title = "Peliculas", action = "movies_menu", # PELICULAS
url = host + "pelicula", thumbnail = get_thumb("movies", auto = True))) itemlist.append(Item(channel = item.channel, title = "Peliculas", folder=False,
itemlist.append(Item(channel = item.channel, title = "Series", action = "shows_menu", thumbnail = get_thumb("movies", auto = True), text_bold=True))
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 = []
itemlist.append(Item(channel = item.channel, title = "Novedades", action = "movies", itemlist.append(Item(channel = item.channel, title = "Novedades", action = "movies",
url = host + "pelicula", thumbnail = get_thumb("newest", auto = True))) 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))) url = host + "pelicula", thumbnail = get_thumb("year", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Favoritas", action = "movies", itemlist.append(Item(channel = item.channel, title = "Favoritas", action = "movies",
url = host + "peliculas-destacadas", thumbnail = get_thumb("favorites", auto = True) )) 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", itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search",
url = host + "search/", thumbnail = get_thumb("search", auto = True))) 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", itemlist.append(Item(channel = item.channel, title = "Todas las Series", action = "shows",
url = host + "listar-series", thumbnail = get_thumb("tvshows", auto = True))) url = host + "listar-series", thumbnail = get_thumb("tvshows", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search", extra='1', itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search", extra='1',
url = host + "listar-series", thumbnail = get_thumb("search", auto = True))) url = host + "listar-series", thumbnail = get_thumb("search", auto = True)))
autoplay.show_option(item.channel, itemlist)
return itemlist return itemlist
### FIN MENUS ### ### FIN MENUS ###
@@ -98,7 +91,8 @@ def episodes(item):
matches = scrapertools.find_multiple_matches(data, seasonsPattern) matches = scrapertools.find_multiple_matches(data, seasonsPattern)
for season, title in matches: 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) episodeMatches = scrapertools.find_single_match(data, episodesPattern % season)
put_episodes(itemlist, item, episodeMatches) put_episodes(itemlist, item, episodeMatches)
@@ -166,7 +160,7 @@ def searchMovies(itemlist, item, texto):
#coloca las peliculas encontradas en la lista, improvisando do while #coloca las peliculas encontradas en la lista, improvisando do while
next_page = True next_page = True
while next_page: 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="([^"]+)">') next_page = scrapertools.find_single_match(data, '<a class="nextpostslink" rel="next" href="([^"]+)">')
if next_page: if next_page:
+38 -3
View File
@@ -33,7 +33,10 @@ def mainlist(item):
url = host + "tendencias", thumbnail = get_thumb("hot", auto = True))) url = host + "tendencias", thumbnail = get_thumb("hot", auto = True)))
itemlist.append(Item(channel = item.channel, title = "Ranking IMDB", action = "moviesIMDB", itemlist.append(Item(channel = item.channel, title = "Ranking IMDB", action = "moviesIMDB",
url = host + "raking-imdb", thumbnail = get_thumb("hot", auto = True) )) 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", itemlist.append(Item(channel = item.channel, title = "Buscar...", action = "search",
url = host + "?s=", thumbnail = get_thumb("search", auto = True))) url = host + "?s=", thumbnail = get_thumb("search", auto = True)))
@@ -82,6 +85,38 @@ def moviesIMDB(item):
return itemlist 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): def searchMovies(item):
itemlist = [] itemlist = []
@@ -94,8 +129,8 @@ def searchMovies(item):
matches = scrapertools.find_multiple_matches(data, pattern) matches = scrapertools.find_multiple_matches(data, pattern)
for link, img, title, year, plot in matches: for link, img, title, year, plot in matches:
itemTitle = "%s [COLOR blue](%s)[/COLOR]" % (title, year) itemTitle = "%s [COLOR blue](%s)[/COLOR]" % (title, year)
fullimg = img.replace('-150x150', '')
itemlist.append(Item(channel = item.channel, title=itemTitle, fulltitle=title, thumbnail=img, itemlist.append(Item(channel = item.channel, title=itemTitle, fulltitle=title, thumbnail=fullimg,
url=link, plot=plot, action="findvideos")) url=link, plot=plot, action="findvideos"))
next_page = scrapertools.find_single_match(data, 'href="([^"]+)" ><span class="icon-chevron-right">') next_page = scrapertools.find_single_match(data, 'href="([^"]+)" ><span class="icon-chevron-right">')
+19 -1
View File
@@ -11,7 +11,9 @@
"tvshow", "tvshow",
"anime", "anime",
"torrent", "torrent",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -22,6 +24,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://descargas2020.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
@@ -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
}
]
}
+994
View File
@@ -0,0 +1,994 @@
# -*- coding: utf-8 -*-
import re
import sys
import urllib
import urlparse
from channelselector import get_thumb
from core import httptools
from core import scrapertools
from core import servertools
from core.item import Item
from platformcode import config, logger
from core import tmdb
host = "https://grantorrent.net/"
dict_url_seasons = dict()
__modo_grafico__ = config.get_setting('modo_grafico', 'grantorrent')
modo_serie_temp = config.get_setting('seleccionar_serie_temporada', 'grantorrent')
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', 'grantorrent')
def mainlist(item):
logger.info()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
thumb_pelis_hd = get_thumb("channels_movie_hd.png")
thumb_series = get_thumb("channels_tvshow.png")
thumb_series_hd = get_thumb("channels_tvshow_hd.png")
thumb_buscar = get_thumb("search.png")
thumb_settings = get_thumb("setting_0.png")
itemlist.append(Item(channel=item.channel, action="submenu", title="Películas", url=host, extra="peliculas", thumbnail=thumb_pelis))
#Buscar películas
itemlist.append(Item(channel=item.channel, action="search", title="Buscar en Películas >>", url=host, extra="peliculas", thumbnail=thumb_buscar))
itemlist.append(Item(channel=item.channel, action="submenu", title="Series", url=host, extra="series", thumbnail=thumb_series))
#Buscar series
itemlist.append(Item(channel=item.channel, action="search", title="Buscar en Series >>", url=host + "series/", extra="series", thumbnail=thumb_buscar))
itemlist.append(
Item(channel=item.channel, action="", title="[COLOR yellow]Configuración del Canal:[/COLOR]", url="", thumbnail=thumb_settings))
itemlist.append(
Item(channel=item.channel, action="settingCanal", title="Opciones de Videoteca y TMDB", url="", thumbnail=thumb_settings))
return itemlist
def settingCanal(item):
from platformcode import platformtools
return platformtools.show_channel_settings()
def submenu(item):
logger.info()
itemlist = []
thumb_buscar = get_thumb("search.png")
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")
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
if item.extra == "peliculas":
patron = '<li class="navigation-top">.*?<a href="(.*?)".*?class="nav"> (.*?)\s?<\/a><\/li>'
matches = re.compile(patron, re.DOTALL).findall(data)
itemlist.append(item.clone(action="listado", title="Novedades", url=host)) #Menú principal películas
for scrapedurl, scrapedtitle in matches:
scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('utf8').encode('utf8').strip()
if not "películas" in scrapedtitle.lower(): #Evita la entrada de ayudas y demás
continue
itemlist.append(item.clone(action="listado", title=scrapedtitle, url=scrapedurl)) #Menú películas
else: #Tratamos Series
patron = '<li class="navigation-top-dcha">.*?<a href="(.*?)".*?class="series"> (.*?)\s?<\/a><\/li>'
matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedurl, scrapedtitle in matches:
scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('utf8').encode('utf8').strip()
itemlist.append(item.clone(action="listado", title=scrapedtitle, url=scrapedurl)) #Menú series
return itemlist
def listado(item):
logger.info()
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página
cnt_title = 0 # Contador de líneas insertadas en Itemlist
result_mode = config.get_setting("result_mode", channel="search") # Búsquedas globales: listado completo o no
#Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
title_lista = [] # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
if item.title_lista: # Si viene de una pasada anterior, la lista ya estará guardada
title_lista = item.title_lista # Se usa la lista de páginas anteriores en Item
title_lista_alt = [] # Creamos otra lista para esta pasada
for url in title_lista:
title_lista_alt += [url] #hacemos una copia no vinculada de title_lista
matches = []
cnt_next = 0 #num de página próxima
cnt_top = 10 #max. num de páginas web a leer antes de pintar
total_pag = 1
post_num = 1 #num pagina actual
#Máximo num. de líneas permitidas por TMDB (40). Máx de 5 páginas por Itemlist para no degradar el rendimiento.
#Si itemlist sigue vacío después de leer 5 páginas, se pueden llegar a leer hasta 10 páginas para encontrar algo
while cnt_title <= cnt_tot and cnt_next < cnt_top:
# Descarga la página
try:
if not item.post:
item.post = item.url
video_section = ''
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.post).data)
video_section = scrapertools.find_single_match(data, '<div class="contenedor-home">(.*?</div>)</div></div>')
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL " + " / DATA: " + video_section)
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
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL " + " / DATA: " + video_section)
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
#Obtiene la dirección de la próxima página, si la hay
try:
patron = '<div class="nav-links">.*?<a class="next page.*?href="(.*?)"'
next_page = scrapertools.find_single_match(data, patron) #url próxima página
post = scrapertools.find_single_match(next_page, '\/page\/(\d+)\/') #número próxima página
if next_page: #Hay próxima página?
patron = '<div class="nav-links">.*?'
patron += "href='.*?\/page\/\d+\/.*?'>(\d+)<\/a>\s?"
patron += '<a class="next page-numbers"'
total_pag = scrapertools.find_single_match(data, patron) #guarda el núm total de páginas
except:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
if post: #puntero a la siguiente página. Cada página de la web tiene 30 entradas
if "page/" in item.post:
item.post = re.sub(r"page\/\d+\/", "page/%s/" % post, item.post)
else:
if "/series" in item.post:
item.post = re.sub(r"\/series\/", "/series/page/%s/" % post, item.post)
elif "/categoria" in item.post:
item.post = re.sub(r"\/$", "/page/%s/" % post, item.post)
else:
item.post = re.sub(r"\.net\/", ".net/page/%s/" % post, item.post)
post_num = int(post) - 1 #Guardo página actual
else:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
# Preparamos un patron que pretende recoger todos los datos significativos del video
patron = '<a href="(?P<url>[^"]+)"><img.*?src="(?P<thumb>[^"]+)".*?'
if "categoria" in item.url or item.media == "search": #Patron distinto para páginas de Categorías o Búsquedas
patron += 'class="attachment-(?P<quality>.*?)-(?P<lang>[^\s]+)\s.*?'
else:
patron += 'class="bloque-superior">\s*(?P<quality>.*?)\s*<div class="imagen-idioma">\s*<img src=".*?icono_(?P<lang>[^\.]+).*?'
patron += '<div class="bloque-inferior">\s*(?P<title>.*?)\s*<\/div>\s?<div class="bloque-date">\s*(?P<date>.*?)\s*<\/div>'
matches_alt = re.compile(patron, re.DOTALL).findall(video_section)
if not matches_alt and not '<div class="titulo-load-core">0 resultados' 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
#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, scrapedthumb, quality, lang, scrapedtitle, date 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 o pelicula 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 modo_serie_temp == 1: #si está en modo Serie agrupamos todos los episodios en una línea
scrapedurl_alt = re.sub(r'-temporada.*?-\d+.*', '/', scrapedurl_alt)
scrapedurl_alt = re.sub(r'-?\d+x\d+.*', '/', scrapedurl_alt) #quita los datos de Temporada/episodio
else: #si es modo Temporada, se agrupan a una línea por Temporada
num_temp = scrapertools.find_single_match(scrapedurl_alt, '-?(\d+)x') #captura num de Temporada
scrapedurl_alt = re.sub(r'-?\d+x\d+.*', '-temporada-%s-completa' % num_temp, scrapedurl_alt) #epis. a Temporada
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
title_lista_alt_for += [scrapedurl_alt]
cnt_title += 1 # Sería una línea real más para Itemlist
#Control de página
if cnt_title > cnt_tot*0.65: #si se acerca al máximo num. de lineas por pagina, tratamos lo que tenemos
cnt_next = 99 #Casi completo, no sobrepasar con la siguiente página
if cnt_title > cnt_tot:
cnt_title = 99 #Sobrepasado el máximo. Ignoro página actual
#Restauro puntero "next" a la página actual, para releearla en otra pasada, y salgo
item.post = re.sub(r"page\/\d+\/", "page/%s/" % post_num, item.post)
break
if cnt_title > 0: #Si se ha llegado a las 5 páginas tratadas, pintamos. Si no continuamos un poco
if cnt_next >= cnt_top*0.5:
cnt_next = 99
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("BUCLE: " + item.post + " / post: " + str(post) + " / post_num: " + str(post_num) + " / cnt_next: " + str(cnt_next) + " / " + str(title_lista_alt))
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
#logger.debug(video_section)
cnt_title = 0
for scrapedurl, scrapedthumb, quality, lang, scrapedtitle, date in matches:
#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
#El control de página ya se ha realizado más arriba
scrapedurl_alt = scrapedurl
if modo_serie_temp == 1: #si está en modo Serie agrupamos todos los episodios en una línea
scrapedurl_alt = re.sub(r'-temporada.*?-\d+.*', '/', scrapedurl_alt)
scrapedurl_alt = re.sub(r'-?\d+x\d+.*', '/', scrapedurl_alt) #quita los datos de Temporada/episodio
else: #si es modo Temporada, se agrupan a una línea por Temporada
num_temp = scrapertools.find_single_match(scrapedurl_alt, '-?(\d+)x') #captura num de Temporada
scrapedurl_alt = re.sub(r'-?\d+x\d+.*', '-temporada-%s-completa' % num_temp, scrapedurl_alt) #epis. a Temporada
if scrapedurl_alt in title_lista: # si ya se ha tratado, pasamos al siguiente item
continue # solo guardamos la url para series y docus
title_lista += [scrapedurl_alt]
cnt_title += 1 # Sería una línea real más para Itemlist
item_local = item.clone() #Creamos copia de Item para trabajar y limpiamos campos innecesarios
if item_local.media: #Viene de Búsquedas
del item_local.media
if item_local.title_lista:
del item_local.title_lista
item_local.post = True
del item_local.post
if item_local.category:
del item_local.category
item_local.context = "['buscar_trailer']"
title = re.sub('\r\n', '', scrapedtitle).decode('utf8').encode('utf8').strip() #Decode-encode utf8
title = re.sub(r"\s{2}", " ", title)
title = title.replace("&#8217;", "'").replace("\xc3\x97", "x")
item_local.url = urlparse.urljoin(host, scrapedurl)
if "categoria" in item.url: #En páginas de Categorias no viene ni la calidad ni el idioma
item_local.quality = scrapertools.find_single_match(item.url, r'\/categoria\/(.*?)\/')
if "4k" in item_local.quality.lower():
item_local.quality = "4K HDR" #Maquillamos un poco la calidad
lang = '' #Ignoramos el idioma
elif not "post" in quality:
item_local.quality = quality #Salvamos la calidad en el resto de páginas
item_local.language = [] #Verificamos el idioma por si encontramos algo
if "latino" in lang.lower() or "latino" in item.url or "latino" in title.lower():
item_local.language += ["LAT"]
if "ingles" in lang.lower() or "ingles" in item.url or "vose" in scrapedurl or "vose" in item.url:
if "VOSE" in lang.lower() or "sub" in title.lower() or "vose" in scrapedurl or "vose" in item.url:
item_local.language += ["VOS"]
else:
item_local.language += ["VO"]
if "dual" in lang.lower() or "dual" in title.lower():
item_local.language[0:0] = ["DUAL"]
#Limpiamos el título de la basuna innecesaria
title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("Sub", "").replace("sub", "").replace("(Reparado)", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("(Latino)", "").replace("Latino", "")
title = title.replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("(HDRip)", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "")
if item_local.extra == "peliculas": #preparamos Item para películas
if "/serie" in scrapedurl or "/serie" in item.url:
continue
item_local.contentType = "movie"
item_local.action = "findvideos"
title = scrapertools.htmlclean(title) #Quitamos html restante
item_local.contentTitle = title.strip()
else: #preparamos Item para series
if not "/serie" in scrapedurl and not "/serie" in item.url:
continue
if modo_serie_temp == 1: #si está en modo Serie
item_local.contentType = "tvshow"
item_local.extra = "tvshow"
else: #si no, en modo temporada
item_local.contentType = "season"
item_local.extra = "season"
item_local.action = "episodios"
title = re.sub(r'[t|T]emp.*?\d+.*', '', title) #Limpiamos temporadas completas, solo queremos la serie entera
title = re.sub(r'\d?\d?&#.*', '', title) #Limpiamos temporada y episodio
title = re.sub(r'\d+[x|×]\d+.*', '', title) #Limpiamos temporada y episodio
title = scrapertools.htmlclean(title) #Quitamos html restante
item_local.contentSerieName = title.strip()
item_local.title = title.strip() #Salvamos el título
item_local.infoLabels['year'] = "-" #Reseteamos el año para que TMDB nos lo de
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
if not item.category and result_mode == 0: #Si este campo no existe, viene de la primera pasada de una búsqueda global
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorrar tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
title = item_local.title
# Si TMDB no ha encontrado el vídeo limpiamos el año
if item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = ''
item_local.infoLabels['aired'] = ''
# Preparamos el título para series, con los núm. de temporadas, si las hay
if item_local.contentType == "season":
item_local.contentTitle= ''
if scrapertools.find_single_match(item_local.url, '-(\d+)x'):
title = '%s -Temporada %s' % (title, scrapertools.find_single_match(item_local.url, '-(\d+)x'))
if scrapertools.find_single_match(item_local.url, '-temporadas?-(\d+)'):
title = '%s -Temporada %s' % (title, scrapertools.find_single_match(item_local.url, '-temporadas?-(\d+)'))
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Ahora maquillamos un poco los titulos dependiendo de si se han seleccionado títulos inteligentes o no
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
if item_local.contentType == "season" or item_local.contentType == "tvshow":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
elif item_local.contentType == "movie":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, str(item_local.infoLabels['year']), rating, item_local.quality, str(item_local.language))
if config.get_setting("unify"): #Si Titulos Inteligentes SÍ seleccionados:
title = title.replace("[", "-").replace("]", "-")
title = title.replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title).strip()
title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title).strip()
item_local.title = title
#logger.debug("url: " + item_local.url + " / title: " + item_local.title + " / content title: " + item_local.contentTitle + "/" + item_local.contentSerieName + " / calidad: " + item_local.quality + "[" + str(item_local.language) + "]" + " / year: " + str(item_local.infoLabels['year']))
#logger.debug(item_local)
#Gestionamos el paginador
patron = '<div class="nav-links">.*?<a class="next page.*?href="(.*?)"'
next_page = scrapertools.find_single_match(data, patron) #url próxima página
#next_page_num = scrapertools.find_single_match(next_page, '\/page\/(\d+)\/') #número próxima página
if next_page: #Hay próxima página?
patron = '<div class="nav-links">.*?'
patron += "href='.*?\/page\/\d+\/.*?'>(\d+)<\/a>\s?"
patron += '<a class="next page-numbers"'
last_page = scrapertools.find_single_match(data, patron) #cargamos la última página
if last_page: #Sabemos la ultima página?
title = '[COLOR gold]Página siguiente >>[/COLOR] %s de %s' % (post_num, last_page)
else:
title = '[COLOR gold]Página siguiente >>[/COLOR] %s' % post_num
itemlist.append(item.clone(action="listado", title=title, url=next_page, thumbnail=get_thumb("next.png"), title_lista=title_lista))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
# Saber si estamos en una ventana emergente lanzada desde una viñeta del menú principal,
# con la función "play_from_library"
unify_status = False
try:
import xbmc
if xbmc.getCondVisibility('Window.IsMedia') == 1:
unify_status = config.get_setting("unify")
except:
unify_status = config.get_setting("unify")
#Salvamos la información de max num. de episodios por temporada para despues de TMDB
if item.infoLabels['temporada_num_episodios']:
num_episodios = item.infoLabels['temporada_num_episodios']
else:
num_episodios = 1
# 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, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
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
#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'])
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(' - ' + item.contentSerieName, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Bajamos los datos de la página
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 " + " / 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, "utf-8", errors="replace").encode("utf-8")
data = scrapertools.find_single_match(data, 'div id="Tokyo" [^>]+>(.*?)</div>') #Seleccionamos la zona de links
patron = '\/icono_.*?png" title="(?P<lang>.*?)?" [^>]+><\/td><td>(?P<quality>.*?)?<?\/td>.*?<td>(?P<size>.*?)?<\/td><td><a class="link" href="(?P<url>.*?)?"'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches: #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
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
#logger.debug(data)
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
#Pintamos el pseudo-título con toda la información disponible del vídeo
item_local.action = ""
item_local.server = "torrent"
rating = '' #Ponemos el rating
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Pintamos el pseudo-título con toda la información disponible del vídeo
item_local.action = ""
item_local.server = "torrent"
if item_local.contentType == "episode":
title = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
if item_local.infoLabels['temporada_num_episodios']:
title = '%s (de %s)' % (title, str(item_local.infoLabels['temporada_num_episodios']))
title = '%s %s' % (title, item_local.infoLabels['episodio_titulo'])
title_gen = '%s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR red]%s[/COLOR]' % (title, item_local.contentSerieName, item_local.infoLabels['year'], rating, str(item_local.language))
else:
title = item_local.contentTitle
title_gen = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR red]%s[/COLOR]' % (title, item_local.infoLabels['year'], rating, str(item_local.language))
title_gen = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title_gen).strip() #Quitamos etiquetas vacías
title_gen = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title_gen).strip() #Quitamos colores vacíos
title_gen = title_gen.replace(" []", "").strip() #Quitamos etiquetas vacías
if not unify_status: #Si Titulos Inteligentes NO seleccionados:
title_gen = '**- [COLOR gold]Enlaces Ver: [/COLOR]%s[COLOR gold] -**[/COLOR]' % (title_gen)
else:
title_gen = '[COLOR gold]Enlaces Ver: [/COLOR]%s' % (title_gen)
if config.get_setting("quit_channel_name", "videolibrary") == 1 and item_local.contentChannel == "videolibrary":
title_gen = '%s: %s' % (item_local.channel.capitalize(), title_gen)
itemlist.append(item_local.clone(title=title_gen)) #Título con todos los datos del vídeo
#Ahora recorremos todos los links por calidades
for lang, quality, size, scrapedurl in matches:
temp_epi = ''
if item.contentType == "episode": #En Series los campos están en otro orden. No hay size, en su lugar sxe
temp_epi = quality
quality = size
contentSeason = ''
contentEpisodeNumber = ''
try: #obtenemos la temporada y episodio de la página y la comparamos con Item
if "temporada" in temp_epi.lower():
contentSeason = scrapertools.find_single_match(temp_epi, r'[t|T]emporada.*?(\d+)')
contentSeason = int(contentSeason)
contentEpisodeNumber = 1
else:
if scrapertools.find_single_match(temp_epi, r'(\d+)&#.*?;(\d+)'):
contentSeason, contentEpisodeNumber = scrapertools.find_single_match(temp_epi, r'(\d+)&#.*?;(\d+)')
if not contentEpisodeNumber:
contentSeason = scrapertools.find_single_match(item.url, r'temporadas?-(\d+)') #num de temporada
if not contentEpisodeNumber:
contentSeason = 1
contentEpisodeNumber = scrapertools.find_single_match(temp_epi, r'(\d+)-')
if not contentEpisodeNumber:
contentEpisodeNumber = 1
contentSeason = int(contentSeason)
contentEpisodeNumber = int(contentEpisodeNumber)
except:
logger.error("ERROR 03: FINDVIDEOS: Error en número de Episodio: " + temp_epi + " / " + str(contentSeason) + " / " + str(contentEpisodeNumber))
continue
if (contentSeason != item.contentSeason or contentEpisodeNumber != item.contentEpisodeNumber) and item.contentEpisodeNumber != 0:
continue #si no son iguales, lo ignoramos
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
#Verificamos el idioma por si encontramos algo
if not item_local.language:
if "latino" in lang.lower() or "latino" in scrapedurl:
item_local.language += ["LAT"]
if "ingles" in lang.lower() or "ingles" in scrapedurl or "vose" in scrapedurl or "vose" in scrapedurl:
if "VOSE" in lang.lower() or "sub" in lang.lower() or "vose" in scrapedurl or "vose" in scrapedurl:
item_local.language += ["VOS"]
else:
item_local.language += ["VO"]
if "dual" in lang.lower() or "dual" in scrapedurl:
item_local.language[0:0] = ["DUAL"]
#Tratamos la calidad y tamaño de cada link
if quality:
item_local.quality = quality
if "temporada" in temp_epi.lower():
item_local.quality = '%s [Temporada]' % item_local.quality
if size and item_local.contentType != "episode":
size = size.replace(".", ",").replace("B,", " B").replace("b,", " b")
item_local.quality = '%s [%s]' % (item_local.quality, size)
#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'])
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})')
#Salvamos la url del .torrent
if scrapedurl:
item_local.url = scrapedurl
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Seridor Torrent
itemlist.append(item_local.clone()) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + title_gen + " / " + title + " / calidad: " + item_local.quality)
#logger.debug(item_local)
return itemlist
def episodios(item):
logger.info()
itemlist = []
temp_actual_num = 0
temp_actual = ''
temp_previous = ''
temp_next = ''
item.extra = "episodios"
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data) #Cargamos los datos de la página
patron_actual = '<link rel="canonical" href="(.*?)"' #Patrón de url temporada actual
patron_actual_num = 'temporadas?-(\d+)' #Patrón de núm. de temporada actual
patron_previous = '<a class="temp-anterior" href="(.*?)">' #Patrón de url temporada anterior
patron_next = '<a class="temp-siguiente" href="(.*?)">' #Patrón de url temporada próxima
temp_actual = scrapertools.find_single_match(data, patron_actual) #url actual de la temporada
item.url = temp_actual #Salvamos la temporada actual como primera para la Videoteca
temp_next = scrapertools.find_single_match(data, patron_next) #url de temporada siguiente
temp_previous = scrapertools.find_single_match(data, patron_previous) #url de temporada anterior
temp_advance = 'back' #por defecto procesamos temporadas hacia atrás
temp_actual_num = scrapertools.find_single_match(temp_actual, patron_actual_num) #num de la temporada actual
if not temp_actual_num: #Si el formato es extraño...
temp_actual_num = 1 #... ponemos 1 como valor
temp_actual_num = int(temp_actual_num)
contentSeason = temp_actual_num #Salvamos el núm de temporada actual
temp_previous_num = scrapertools.find_single_match(temp_previous, patron_actual_num) #num de la temporada previa
temp_previous_num = int(temp_actual_num)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / DATA: " + data)
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
max_temp = 1
if item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
max_temp = int(max(matches))
if not item.library_playcounts: #no viene de Videoteca, se ponen valores de configuración o de la pasada anterior
if not item.contentType:
if modo_serie_temp == 0:
item.contentType = "season"
else:
item.contentType = "tvshow"
if item.contentSeason:
item.contentSeason = 0
elif max_temp < item.infoLabels["number_of_seasons"]: #Si tenemos en .nfo menos temporadas, Temp.
item.contentType = "season"
elif max_temp >= item.infoLabels["number_of_seasons"]: #Si tenemos en .nfo igaual o más temporadas, investigar
cnt_s = 0
for s in item.library_playcounts: #Ver cuántas Temporadas hay en Videoteca
if "season" in s:
cnt_s += 1
if cnt_s > 1: #hay más de 1 temporada en Videoteca, es Serie?
if temp_actual_num > 1: #Temp. actual > 1, parece Temporada
s = 1
while s <= item.infoLabels["number_of_seasons"]: #Buscamos la primera Temporada de Videoteca
if item.library_playcounts.has_key('season %d' % s): #Buscamos si la Temporada 1 existe
if item.library_playcounts["season %d" % s] < temp_actual_num: #Si menor que actual, es Temp.
item.contentType = "season"
else:
item.contentType = "tvshow" #No es Temporada 1, pero es más baja que la actual. Es Serie
break
s += 1
else: #Sí, es Serie
item.contentType = "tvshow"
else: #Solo hay una temporada en la Videoteca
if temp_actual_num > 1: #es Temporada la actual?
if item.contentSeason:
item.contentType = "season" #Si está informado el num de Temp. se creó como Temporada
else:
item.contentType = "tvshow" #Si no, es Serie que no tiene Temp. 1
else: #Si es Temp. 1, se procesa según el valor de configuración
if modo_serie_temp == 0: #Es Temporada
item.contentType = "season"
else: #Es Serie
item.contentType = "tvshow"
else:
item.contentType = "list"
temp_lista = []
temp_bucle = 0
temp_next_alt = ''
while temp_actual != '': #revisamos las temporadas hasta el final
if not data: #si no hay datos, descargamos. Si los hay de loop anterior, los usamos
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(temp_actual).data)
#Controla que no haya un bucle en la cadena de links entre temporadas
if scrapertools.find_single_match(temp_actual, patron_actual_num) in temp_lista:
temp_bucle += 1
if temp_bucle > 5: #Si ha pasado por aquí más de 5 veces es que algo anda mal
logger.error("ERROR 05: EPISODIOS: Los links entre temporadas están rotos y se está metiendo en un loop: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista temps: " + str(temp_lista) + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel + ': ERROR 05: EPISODIOS. Los links entre temporadas están rotos y se está metiendo en un loop. Reportar error con log'))
data = ''
return itemlist #Algo no funciona con los links, pintamos lo que tenemos
if temp_advance == "back": #Se salta una temporada hacia atrás
logger.error("ERROR 05: EPISODIOS: Temporada duplicada. Link BACK erroneo: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista temps: " + str(temp_lista) + " / Bucle: " + str(temp_bucle) + " / DATA: " + data)
temp_actual = scrapertools.find_single_match(data, patron_previous) #url de temporada anterior
data = ''
continue #volvemos a leer página con la url de la anterior
if temp_advance == "forw": #Se salta una temporada hacia adelante
logger.error("ERROR 05: EPISODIOS: Temporada duplicada. Link FORW erroneo: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista temps: " + str(temp_lista) + " / Bucle: " + str(temp_bucle) + " / DATA: " + data)
temp_actual = scrapertools.find_single_match(data, patron_next) #url de temporada siguiente
data = ''
continue #volvemos a leer página con la url de la siguiente
#Comprobamos si se ha saltado una Temporada
if temp_advance == "back": #Avanza marcha atrás?
temp_num_alt = int(scrapertools.find_single_match(temp_actual, patron_actual_num)) #nuevo num. Temp.
if temp_num_alt < temp_actual_num - 1: #Hay un salto a la Temp. anterior, o más?
temp_next_alt = scrapertools.find_single_match(data, patron_next) #url de temporada siguiente
temp_num_alt = int(scrapertools.find_single_match(temp_next_alt, patron_actual_num))
#Localizamos la Temp. siguiente y nos aseguramos que no está procesada
if temp_num_alt <= temp_actual_num - 1 and temp_num_alt not in temp_lista:
temp_actual_alt = temp_next_alt #url actual de la temporada = url de la siguiente
temp_previous_alt = temp_actual #url temporada anterior = url de la actual anterior
logger.error("ERROR 06: EPISODIOS: Se ha saltado una Temporda: Actual: " + temp_actual + " / Actual ALT: " + temp_actual_alt + " / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Bucle: " + str(temp_bucle))
temp_actual = temp_actual_alt #url actual de la temporada = url de la siguiente
temp_bucle += 1
if temp_bucle > 5: #Evitamos loops infinitos
logger.error("ERROR 05: EPISODIOS: Los links entre temporadas están rotos y se está metiendo en un loop: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista temps: " + str(temp_lista) + " / DATA: " + data)
data = ''
itemlist.append(item.clone(action='', title=item.channel + ': ERROR 05: EPISODIOS. Los links entre temporadas están rotos y se está metiendo en un loop. Reportar error con log'))
return itemlist #Algo no funciona con los links, pintamos lo que tenemos
data = ''
continue #volvemos a leer página con la url de la siguiente
#Comprobamos si se ha saltado una Temporada
if temp_advance == "forw": #Avanza marcha adelante?
temp_num_alt = int(scrapertools.find_single_match(temp_actual, patron_actual_num)) #nuevo num. Temp.
if temp_num_alt > temp_actual_num + 1: #Hay un salto a la Temp. siguiente, o más?
temp_previous_alt = scrapertools.find_single_match(data, patron_previous) #url de temporada anterior
temp_num_alt = int(scrapertools.find_single_match(temp_previous_alt, patron_actual_num))
#Localizamos la Temp. anterior y nos aseguramos que no está procesada
if temp_num_alt >= temp_actual_num + 1 and temp_num_alt not in temp_lista:
temp_actual_alt = temp_previous_alt #url actual de la temporada = url de la anterior
temp_next_alt = temp_actual #url temporada siguiente = url de la actual anterior
logger.error("ERROR 06: EPISODIOS: Se ha saltado una Temporda: Actual: " + temp_actual + " / Actual ALT: " + temp_actual_alt + " / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Bucle: " + str(temp_bucle))
temp_actual = temp_actual_alt #url actual de la temporada = url de la siguiente
temp_bucle += 1
if temp_bucle > 5: #Evitamos loops infinitos
logger.error("ERROR 05: EPISODIOS: Los links entre temporadas están rotos y se está metiendo en un loop: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista temps: " + str(temp_lista) + " / DATA: " + data)
data = ''
itemlist.append(item.clone(action='', title=item.channel + ': ERROR 05: EPISODIOS. Los links entre temporadas están rotos y se está metiendo en un loop. Reportar error con log'))
return itemlist #Algo no funciona con los links, pintamos lo que tenemos
data = ''
continue #volvemos a leer página con la url de la siguiente
temp_actual_num = scrapertools.find_single_match(temp_actual, patron_actual_num) #num de la temporada actual
temp_actual_num = int(temp_actual_num)
temp_previous = scrapertools.find_single_match(data, patron_previous) #url de temporada anterior
if temp_advance == 'forw': #si estamos con temporadas previas, dejamos la url de la siguiente temporada inicial
temp_next = scrapertools.find_single_match(data, patron_next) #url de temporada siguiente
temp_previous = '' #ya están procesadas las temporadas previas, no volvemos a hacerlo
except: #Error al leer o procesar la página actual? Salimos
logger.error("ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea: " + temp_actual + " (" + str (temp_actual_num) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / DATA: " + data)
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 #si no hay más datos, algo no funciona, pintamos lo que tenemos
if item.contentType == "season":
temp_advance = '' #Es la única temporada
if temp_next and item.library_playcounts: #Permitimos en actualización de Videoteca añadir nuevas temporadas
temp_advance = 'forw' #Si hay nueva temporada, pasamos a esa como actual
temp_previous = '' #lo limpiamos, por control
item.url = temp_actual #Salvamos la temporada actual como primera para la Videoteca
contentSeason = temp_actual_num #Salvamos el núm de temporada
elif temp_previous: #Para Series, vamos retrocediendo y procesando temporadas
if temp_advance == 'back':
if not modo_ultima_temp: #Actualiza la Serie entera en la Videoteca?
item.url = temp_previous #Salvamos la temporada previa como primera para la Videoteca
contentSeason = temp_previous_num #Salvamos en núm de temporada
temp_advance = 'back' #hay temporadas anteriores, iremos marcha atrás procesándolas
elif temp_next:
if temp_advance == 'back': #Esta es la primera temporada disponible
if not modo_ultima_temp: #Actualiza la Serie entera en la Videoteca?
item.url = temp_actual #Salvamos la temporada actual como primera para la Videoteca
contentSeason = temp_actual_num #Salvamos en núm de temporada
else:
if modo_ultima_temp and not item.library_playcounts: #Actualiza la última Temporada en la Videoteca?
item.url = temp_next #Salvamos la temporada siguiente como primera para la Videoteca
temp_advance = 'forw' #No hay temporadas anteriores, pero sí posteriores. Las procesamos
else:
temp_advance = '' #lo limpiamos, por control
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
data = scrapertools.find_single_match(data, 'div id="Tokyo" [^>]+>(.*?)</div>') #Seleccionamos la zona de links
patron = '\/icono_.*?png" title="(?P<lang>.*?)?" [^>]+><\/td><td>(?P<temp_epi>.*?)?<?\/td>.*?<td>(?P<quality>.*?)?<\/td><td><a class="link" href="(?P<url>.*?)?"'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / 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: " + patron)
#logger.debug(matches)
#logger.debug(data)
#Ahora recorremos todos los links por calidades
for lang, temp_epi, quality, scrapedurl in matches: #la URL apunta ya al .torrent. nos quedamos con la URL de temporada
#Generamos una copia de Item para trabajar sobre ella y la rellenamos. Borramos etiquetas innecesarias
item_local = item.clone()
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.url = temp_actual #salvamos la URL de la temporada
item_local.action = "findvideos"
item_local.contentType = "episode"
#item_local.contentSeason = temp_actual_num #salvamos num de temporada
item_local.title = re.sub(r'\[COLOR limegreen\]\[.*?\]\[\/COLOR\]', '', item_local.title)
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
#Verificamos el idioma por si encontramos algo
if not item_local.language:
if "latino" in lang.lower() or "latino" in scrapedurl:
item_local.language += ["LAT"]
if "ingles" in lang.lower() or "ingles" in scrapedurl or "vose" in scrapedurl or "vose" in scrapedurl:
if "VOSE" in lang.lower() or "sub" in lang.lower() or "vose" in scrapedurl or "vose" in scrapedurl:
item_local.language += ["VOS"]
else:
item_local.language += ["VO"]
if "dual" in lang.lower() or "dual" in scrapedurl:
item_local.language[0:0] = ["DUAL"]
try:
if "temporada" in temp_epi.lower(): #si es una temporada en vez de un episodio, lo aceptamos como episodio 1
item_local.contentSeason = scrapertools.find_single_match(temp_epi, r'[t|T]emporada.*?(\d+)')
if not item_local.contentSeason:
item_local.contentSeason = temp_actual_num
item_local.contentSeason = int(item_local.contentSeason)
item_local.contentEpisodeNumber = 1
else: #si es un episodio lo guardamos
if scrapertools.find_single_match(temp_epi, r'(\d+)&#.*?;(\d+)'):
item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(temp_epi, r'(\d+)&#.*?;(\d+)')
if not item_local.contentSeason:
item_local.contentSeason = temp_actual_num
item_local.contentSeason = int(item_local.contentSeason)
#item_local.contentEpisodeNumber = scrapertools.find_single_match(temp_epi, r'\d+&#.*?;(\d+)')
if not item_local.contentEpisodeNumber:
item_local.contentEpisodeNumber = scrapertools.find_single_match(temp_epi, r'(\d+)-')
if not item_local.contentEpisodeNumber:
item_local.contentEpisodeNumber = 0
item_local.contentEpisodeNumber = int(item_local.contentEpisodeNumber)
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Episodio: " + temp_epi)
continue #si da un error pasamos del episodio
if item_local.contentSeason != temp_actual_num: #A veces es diferente el num de Temp. de la URL y de
temp_actual_num = item_local.contentSeason #los episodios. Anatomia de Grey Temp. 14
if "-" in temp_epi: #episodios múltiples
episode2 = scrapertools.find_single_match(temp_epi, r'-(\d+)')
item_local.title = "%sx%s al %s -" % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2), str(episode2).zfill(2)) #Creamos un título con el rango de episodios
elif "temporada" in temp_epi.lower(): #Temporada completa
item_local.title = '%sx%s - Temporada %s Completa -' % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2), item_local.contentSeason)
elif item_local.contentEpisodeNumber == 0: #episodio extraño
item_local.title = '%sx%s - %s' % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2), temp_epi)
else: #episodio normal
item_local.title = '%sx%s -' % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2))
if len(itemlist) > 0 and item_local.contentSeason == itemlist[-1].contentSeason and item_local.contentEpisodeNumber == itemlist[-1].contentEpisodeNumber and not "Temporada" in itemlist[-1].title and itemlist[-1].contentEpisodeNumber != 0: #solo guardamos un episodio ...
if itemlist[-1].quality:
itemlist[-1].quality += ", " + quality #... pero acumulamos las calidades
else:
itemlist[-1].quality = quality
continue #ignoramos el episodio duplicado
else:
item_local.quality = quality
itemlist.append(item_local.clone()) #guardamos el episodio
#logger.debug("EPISODIOS: " + temp_actual + " (" + str (item_local.contentSeason) + "x" + str (item_local.contentEpisodeNumber) + ") / Previa: " + temp_previous + " / o Siguiente: " + temp_next + " / Avance: " + temp_advance + " / Lista Temps: " + str(temp_lista))
#logger.debug(item_local)
temp_lista += [temp_actual_num]
if temp_advance == 'back':
temp_actual = temp_previous #hay temporadas anteriores, iremos marcha atrás procesándolas
elif temp_advance == 'forw':
temp_actual = temp_next #hay temporadas posteriores. Las procesamos
else:
temp_actual = '' #No hay más temporadas, salimos
data = '' #Limpiamos data para forzar la lectura en la próxima pasada
if len(itemlist) > 1:
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 maquillaje 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
if item_local.infoLabels['aired']:
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
if item_local.infoLabels['temporada_num_episodios']:
num_episodios = item_local.infoLabels['temporada_num_episodios']
#Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if item_local.infoLabels['episodio_titulo'] and not "Temporada" in item_local.title:
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)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
item_local.infoLabels['episodio_titulo'] = '%s [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.infoLabels['year'])
if rating:
item_local.infoLabels['episodio_titulo'] = '%s [%s]' % (item_local.infoLabels['episodio_titulo'], rating)
else:
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
if "Temporada" in item_local.title:
item_local.infoLabels['episodio_titulo'] = '%s - %s [%s] [%s]' % (scrapertools.find_single_match(item_local.title, r'(Temporada \d+ Completa)'), item_local.contentSerieName, item_local.infoLabels['year'], rating)
else:
item_local.infoLabels['episodio_titulo'] = '%s [%s] [%s]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating)
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.title = '%s [%s] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.title, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
#Quitamos campos vacíos
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace(" []", "").strip()
item_local.title = item_local.title.replace(" []", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip()
#logger.debug(str(num_episodios) + " / " + str(item_local.contentEpisodeNumber) + " / " + str(item_local.infoLabels['temporada_num_episodios']) + str(num_episodios_lista))
if num_episodios < item_local.contentEpisodeNumber:
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 + " / 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)
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']:
title = ' [Temp. de %s ep.]' % item_local.infoLabels['temporada_num_episodios']
if item_local.quality: #La Videoteca no toma la calidad del episodio, sino de la serie. Pongo del episodio
item.quality = item_local.quality
if item.action == 'get_seasons': #si es actualización de videoteca, título estándar
#Si hay una nueva Temporada, se activa como la actual
if item.library_urls[item.channel] != item.url and (item.contentType == "season" or modo_ultima_temp):
item.library_urls[item.channel] = item.url #Se actualiza la url apuntando a la última Temporada
try:
from core import videolibrarytools #Se fuerza la actualización de la url en el .nfo
itemlist_fake = [] #Se crea un Itemlist vacio para actualizar solo el .nfo
videolibrarytools.save_tvshow(item, itemlist_fake) #Se actualiza el .nfo
except:
logger.error("ERROR 08: EPISODIOS: No se ha podido actualizar la URL a la nueva Temporada")
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a la Videoteca[/COLOR]" + title, action="add_serie_to_library"))
elif modo_serie_temp == 1: #si es Serie damos la opción de guardar la última temporada o la serie completa
itemlist.append(item.clone(title="[COLOR yellow]Añadir última Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason, url=item_local.url))
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow"))
else: #si no, damos la opción de guardar la temporada actual o la serie completa
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow"))
item.contentSeason = contentSeason
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason))
return itemlist
def search(item, texto):
logger.info("texto:" + texto)
texto = texto.replace(" ", "+")
itemlist = []
item.url = "%s?s=%s" % (item.url, texto)
item.media = "search" #Marcar para "Listado": igual comportamiento que "Categorías"
try:
if "series/" in item.url:
item.extra = "series"
item.title = "Series"
else:
item.extra = "peliculas"
item.title = "Películas"
itemlist = listado(item)
return itemlist
# Se captura la excepción, para no interrumpir al buscador global si un canal falla
except:
import sys
for line in sys.exc_info():
logger.error("ERROR: %s: SEARCH" % line)
return []
+25 -40
View File
@@ -349,11 +349,16 @@ def fichas(item):
bus = host[-4:] bus = host[-4:]
tag_type = scrapertools.find_single_match(url, '%s/([^/]+)/' %bus) tag_type = scrapertools.find_single_match(url, '%s/([^/]+)/' %bus)
title += " - [COLOR blue]" + tag_type.capitalize() + "[/COLOR]" title += " - [COLOR blue]" + tag_type.capitalize() + "[/COLOR]"
if "/serie" in url or "/tags-tv" in url:
itemlist.append( itemlist.append(
Item(channel=item.channel, action=action, title=title, url=url, fulltitle=title, thumbnail=thumbnail, Item(channel=item.channel, action=action, title=title, url=url, thumbnail=thumbnail,
show=show, folder=True, contentType=contentType, contentTitle=contentTitle, contentSerieName=show, folder=True, contentType=contentType,
language =language, infoLabels=infoLabels)) 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 ## Paginación
next_page_url = scrapertools.find_single_match(data, '<a href="([^"]+)">.raquo;</a>') next_page_url = scrapertools.find_single_match(data, '<a href="([^"]+)">.raquo;</a>')
if next_page_url != "": if next_page_url != "":
@@ -389,50 +394,41 @@ def episodios(item):
str = get_status(status, "shows", id) str = get_status(status, "shows", id)
if str != "" and account and item.category != "Series" and "XBMC" not in item.title: if str != "" and account and item.category != "Series" and "XBMC" not in item.title:
if config.get_videolibrary_support(): if config.get_videolibrary_support():
title = " ( [COLOR gray][B]" + item.show + "[/B][/COLOR] )" title = " ( [COLOR gray][B]" + item.contentSerieName + "[/B][/COLOR] )"
itemlist.append( itemlist.append(
Item(channel=item.channel, action="episodios", title=title, fulltitle=title, url=url_targets, Item(channel=item.channel, action="episodios", title=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=False)) thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=False))
title = str.replace('green', 'red').replace('Siguiendo', 'Abandonar') title = str.replace('green', 'red').replace('Siguiendo', 'Abandonar')
itemlist.append(Item(channel=item.channel, action="set_status", title=title, fulltitle=title, url=url_targets, itemlist.append(Item(channel=item.channel, action="set_status", title=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=True)) thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=True))
elif account and item.category != "Series" and "XBMC" not in item.title: elif account and item.category != "Series" and "XBMC" not in item.title:
if config.get_videolibrary_support(): if config.get_videolibrary_support():
title = " ( [COLOR gray][B]" + item.show + "[/B][/COLOR] )" title = " ( [COLOR gray][B]" + item.show + "[/B][/COLOR] )"
itemlist.append( itemlist.append(
Item(channel=item.channel, action="episodios", title=title, fulltitle=title, url=url_targets, Item(channel=item.channel, action="episodios", title=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=False)) thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=False))
title = " ( [COLOR orange][B]Seguir[/B][/COLOR] )" title = " ( [COLOR orange][B]Seguir[/B][/COLOR] )"
itemlist.append(Item(channel=item.channel, action="set_status", title=title, fulltitle=title, url=url_targets, itemlist.append(Item(channel=item.channel, action="set_status", title=title, url=url_targets,
thumbnail=item.thumbnail, show=item.show, folder=True)) thumbnail=item.thumbnail, contentSerieName=item.contentSerieName, folder=True))
patron = "<li><a href='([^']+)'>[^<]+</a></li>" patron = "<li><a href='([^']+)'>[^<]+</a></li>"
matches = re.compile(patron, re.DOTALL).findall(data) matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedurl in matches: for scrapedurl in matches:
if "temporada-0" in scrapedurl:
continue
## Episodios ## Episodios
data = agrupa_datos(httptools.downloadpage(scrapedurl).data) data = agrupa_datos(httptools.downloadpage(scrapedurl).data)
sid = scrapertools.get_match(data, "<script>var sid = '(\d+)'") sid = scrapertools.get_match(data, "<script>var sid = '(\d+)'")
ssid = scrapertools.get_match(scrapedurl, "temporada-(\d+)") ssid = scrapertools.get_match(scrapedurl, "temporada-(\d+)")
post = "action=season&start=0&limit=0&show=%s&season=%s" % (sid, ssid) post = "action=season&start=0&limit=0&show=%s&season=%s" % (sid, ssid)
url = host + "/a/episodes" url = host + "/a/episodes"
data = httptools.downloadpage(url, post=post).data data = httptools.downloadpage(url, post=post).data
episodes = jsontools.load(data) episodes = jsontools.load(data)
for episode in episodes: for episode in episodes:
thumbnail = host + "/thumbs/" + episode['thumbnail'] thumbnail = host + "/thumbs/" + episode['thumbnail']
language = episode['languages'] language = episode['languages']
temporada = episode['season'] temporada = episode['season']
episodio = episode['episode'] episodio = episode['episode']
if len(episodio) == 1: episodio = '0' + episodio if len(episodio) == 1: episodio = '0' + episodio
if episode['languages'] != "[]": if episode['languages'] != "[]":
idiomas = "( [COLOR teal][B]" idiomas = "( [COLOR teal][B]"
for idioma in episode['languages']: idiomas += idioma + " " for idioma in episode['languages']: idiomas += idioma + " "
@@ -440,15 +436,12 @@ def episodios(item):
idiomas = idiomas idiomas = idiomas
else: else:
idiomas = "" idiomas = ""
if episode['title']: if episode['title']:
try: try:
title = episode['title']['es'].strip() title = episode['title']['es'].strip()
except: except:
title = episode['title']['en'].strip() title = episode['title']['en'].strip()
if len(title) == 0: title = "Temporada " + temporada + " Episodio " + episodio if len(title) == 0: title = "Temporada " + temporada + " Episodio " + episodio
try: try:
title = temporada + "x" + episodio + " - " + title.decode('utf-8') + ' ' + idiomas title = temporada + "x" + episodio + " - " + title.decode('utf-8') + ' ' + idiomas
except: except:
@@ -456,38 +449,30 @@ def episodios(item):
# try: title = temporada + "x" + episodio + " - " + title + ' ' + idiomas # try: title = temporada + "x" + episodio + " - " + title + ' ' + idiomas
# except: pass # except: pass
# except: title = temporada + "x" + episodio + " - " + title.decode('iso-8859-1') + ' ' + idiomas # except: title = temporada + "x" + episodio + " - " + title.decode('iso-8859-1') + ' ' + idiomas
str = get_status(status, 'episodes', episode['id']) str = get_status(status, 'episodes', episode['id'])
if str != "": title += str if str != "": title += str
try: try:
title = title.encode('utf-8') title = title.encode('utf-8')
except: except:
title = title.encode('iso-8859-1') title = title.encode('iso-8859-1')
url = urlparse.urljoin(scrapedurl, 'temporada-' + temporada + '/episodio-' + episodio) + "###" + episode[ url = urlparse.urljoin(scrapedurl, 'temporada-' + temporada + '/episodio-' + episodio) + "###" + episode[
'id'] + ";3" 'id'] + ";3"
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, url=url,
itemlist.append(Item(channel=item.channel, action="findvideos", title=title, fulltitle=title, url=url, thumbnail=thumbnail, contentSerieName=item.contentSerieName, folder=True, contentType="episode",
thumbnail=thumbnail, show=item.show, folder=True, contentType="episode",
language=language)) language=language))
if config.get_videolibrary_support() and len(itemlist) > 0: 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, 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, 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 return itemlist
def novedades_episodios(item): def novedades_episodios(item):
logger.info() logger.info()
itemlist = [] itemlist = []
## Carga estados ## Carga estados
status = jsontools.load(httptools.downloadpage(host + '/a/status/all').data) status = jsontools.load(httptools.downloadpage(host + '/a/status/all').data)
## Episodios ## Episodios
url = item.url.split("?")[0] url = item.url.split("?")[0]
post = item.url.split("?")[1] post = item.url.split("?")[1]
@@ -21,6 +21,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "include_in_newest_peliculas",
"type": "bool", "type": "bool",
+21 -8
View File
@@ -15,6 +15,8 @@ from core import tmdb
host = "http://www.mejortorrent.com" host = "http://www.mejortorrent.com"
__modo_grafico__ = config.get_setting('modo_grafico', 'mejortorrent')
def mainlist(item): def mainlist(item):
logger.info() logger.info()
@@ -386,7 +388,7 @@ def listado(item):
break break
#Llamamos a TMDB para que complete InfoLabels #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 # Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist: 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 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 #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 # Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -773,9 +775,9 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = 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 #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']: if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(' - ' + item.contentSerieName, '')
item_local.infoLabels['episodio_titulo'] = ''
if item_local.infoLabels['aired'] and item_local.contentType == "episode": 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})') item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
@@ -882,6 +883,10 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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 # Carga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data) 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()) itemlist.append(item_local.clone())
# Llamamos a TMDB para que complete el episodio en InfoLabels # 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: 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)))
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # 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 #Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) 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 num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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 + "], 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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
if item_local.infoLabels['temporada_num_episodios']: if item_local.infoLabels['temporada_num_episodios']:
@@ -10,7 +10,9 @@
"torrent", "torrent",
"movie", "movie",
"tvshow", "tvshow",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -21,6 +23,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://mispelisyseries.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
+3 -2
View File
@@ -7,8 +7,9 @@
"thumbnail": "http://s29.postimg.cc/wzw749oon/pldklog.jpg", "thumbnail": "http://s29.postimg.cc/wzw749oon/pldklog.jpg",
"banner": "peliculasdk.png", "banner": "peliculasdk.png",
"categories": [ "categories": [
"torrent", "movie",
"movie" "vos",
"adult"
], ],
"settings": [ "settings": [
{ {
+191 -121
View File
@@ -10,35 +10,76 @@ from core.scrapertools import decodeHtmlentities as dhe
from platformcode import logger from platformcode import logger
from platformcode import config from platformcode import config
from core import tmdb 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__ = config.get_setting('comprueba_enlaces', 'peliculasdk')
__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', 'peliculasdk') __comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', 'peliculasdk')
__adult_mode__ = config.get_setting("adult_mode")
host = "http://www.peliculasdk.com" 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): def mainlist(item):
logger.info() logger.info()
autoplay.init(item.channel, list_servers, list_quality)
itemlist = [] itemlist = []
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Estrenos[/COLOR]", action="peliculas", url= host + "/ver/estrenos", itemlist.append(Item(channel=item.channel, title='Estrenos', action='peliculas', url= host + "/ver/estrenos/",
fanart="http://s24.postimg.cc/z6ulldcph/pdkesfan.jpg", thumbnail=get_thumb('newest', auto=True), type='movies'))
thumbnail="http://s16.postimg.cc/st4x601d1/pdkesth.jpg"))
itemlist.append( itemlist.append(Item(channel=item.channel, title='Por géneros', action='section',
Item(channel=item.channel, title="[COLOR orange]PelisHd[/COLOR]", action="peliculas", url= host + "/calidad/HD-720/", thumbnail=get_thumb('genres', auto=True), type='movies'))
fanart="http://s18.postimg.cc/wzqonq3w9/pdkhdfan.jpg",
thumbnail="http://s8.postimg.cc/nn5669ln9/pdkhdthu.jpg")) itemlist.append(Item(channel=item.channel, title='Por calidades', action='section',
itemlist.append( thumbnail=get_thumb('quality', auto=True), type='movies'))
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", itemlist.append(Item(channel=item.channel, title='Por idiomas', action='section',
thumbnail="http://s12.postimg.cc/r7re8fie5/pdkhdripthub.jpg")) thumbnail=get_thumb('language', auto=True), type='movies'))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Pelis Audio español[/COLOR]", action="peliculas", url= host + "/idioma/Espanol/", if __adult_mode__ != 0:
fanart="http://s11.postimg.cc/65t7bxlzn/pdkespfan.jpg", itemlist.append(Item(channel=item.channel, title='Adultos +18', action='peliculas', url= host + "/genero/adultos/",
thumbnail="http://s13.postimg.cc/sh1034ign/pdkhsphtub.jpg")) thumbnail=get_thumb('adults', auto=True), type='movies'))
itemlist.append(
Item(channel=item.channel, title="[COLOR orange]Buscar...[/COLOR]", action="search", url= host + "/calidad/HD-720/", itemlist.append(Item(channel=item.channel, title='Buscar...', action='search',
fanart="http://s14.postimg.cc/ceqajaw2p/pdkbusfan.jpg", thumbnail=get_thumb('search', auto=True), type='movies'))
thumbnail="http://s13.postimg.cc/o85gsftyv/pdkbusthub.jpg"))
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 return itemlist
@@ -62,132 +103,161 @@ def search(item, texto):
def buscador(item): def buscador(item):
logger.info() logger.info()
itemlist = [] itemlist = []
data = httptools.downloadpage(item.url).data data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data) data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;|&#.*?;", "", data)
patron = '<div class="karatula".*?'
patron += 'src="([^"]+)".*?' patron = 'style="position:relative"> '
patron += '<div class="tisearch"><a href="([^"]+)">' patron += '<a href="([^"]+)">'
patron += '([^<]+)<.*?' patron += '<img src="([^"]+)" alt="([^"]+)"></a><br>'
patron += 'Audio:(.*?)</a>.*?' patron += '<div class="titulope">([^<]+)</div>.*?'
patron += 'Género:(.*?)</a>.*?' patron += 'Audio: (.+?)</div>.*?'
patron += 'Calidad:(.*?),' patron += 'Calidad: (.+?)</div>.*?'
matches = re.compile(patron, re.DOTALL).findall(data) matches = scrapertools.find_multiple_matches(data, patron)
for scrapedthumbnail, scrapedurl, scrapedtitle, scrapedlenguaje, scrapedgenero, scrapedcalidad in matches: for scrapedurl, scrapedthumbnail, scrapedtitle, scrapedtitleorig, scrapedlenguaje, scrapedcalidad in matches:
year = scrapertools.find_single_match(scrapedtitle, '\((\d+)\)') year = scrapertools.find_single_match(scrapedtitle, '\((\d+)\)')
scrapedcalidad = re.sub(r"<a href.*?>|</a>|</span>", "", scrapedcalidad).strip() scrapedtitle = re.sub(r"\(\d+\)", "", scrapedtitle).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: audios = scrapertools.find_multiple_matches(scrapedlenguaje, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
scrapedcalidad = "[COLOR orange]" + scrapedcalidad + "[/COLOR]" calidad = scrapertools.find_single_match(scrapedcalidad, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
scrapedlenguaje = "[COLOR orange]" + scrapedlenguaje + "[/COLOR]"
title = scrapedtitle + "-(Idioma: " + scrapedlenguaje + ")" + "-(Calidad: " + scrapedcalidad + ")" titulo = '%s [%s][%s]' % (scrapedtitle, ','.join([a[:3] for a in audios]), calidad)
title = "[COLOR white]" + title + "[/COLOR]"
scrapedtitle = scrapedtitle.split("(")[0].strip() # Parece que las pelis de adultos se mezclan en la búsqueda y lo único que las diferencia es que no tienen Calidad
itemlist.append(Item(channel=item.channel, title=title, url=scrapedurl, action="findvideos", if calidades or __adult_mode__ != 0:
thumbnail=scrapedthumbnail, contentTitle = scrapedtitle, infoLabels={'year':year}, itemlist.append(Item(channel=item.channel,
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", library=True, folder=True)) action="findvideos", url=scrapedurl,
tmdb.set_infoLabels(itemlist, True) title=titulo, contentTitle=scrapedtitle,
try: thumbnail=scrapedthumbnail,
next_page = scrapertools.get_match(data, language=audios,
'<span class="current">.*?<a href="(.*?)".*?>Siguiente &raquo;</a></div>') quality=calidad,
itemlist.append(Item(channel=item.channel, action="buscador", title="[COLOR red]siguiente>>[/COLOR]", url=next_page, infoLabels={'year':year}
thumbnail="http://s6.postimg.cc/uej03x4r5/bricoflecha.png", ))
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", folder=True))
except: tmdb.set_infoLabels(itemlist)
pass
# 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 return itemlist
def peliculas(item): def peliculas(item):
logger.info() logger.info()
itemlist = [] itemlist = []
# Descarga la página
data = httptools.downloadpage(item.url).data data = httptools.downloadpage(item.url).data
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;|&#.*?;", "", data) data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;|&#.*?;", "", data)
patron = 'style="position:relative;"> '
patron += '<a href="([^"]+)" ' patron = 'style="position:relative"> '
patron += 'title="([^<]+)">' patron += '<a href="([^"]+)">'
patron += '<img src="([^"]+)".*?' patron += '<img src="([^"]+)" alt="([^"]+)"></a><br>'
patron += 'Audio:(.*?)</br>.*?' patron += '<div class="titulope">([^<]+)</div>.*?'
patron += 'Calidad:(.*?)</br>.*?' patron += 'Audio: (.+?)</div>.*?'
patron += 'Género:.*?tag">(.*?)</a>' patron += 'Calidad: (.+?)</div>.*?'
patron += 'Género: (.+?)</div>'
matches = scrapertools.find_multiple_matches(data, patron) 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+)\)') year = scrapertools.find_single_match(scrapedtitle, '\((\d+)\)')
scrapedtitle = re.sub(r"\(\d+\)", "", scrapedtitle).strip() 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() audios = scrapertools.find_multiple_matches(scrapedlenguaje, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
scrapedlenguaje = scrapedlenguaje.split(',') calidad = scrapertools.find_single_match(scrapedcalidad, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
if not "Adultos" in scrapedgenero and not "Adultos" in scrapedlenguaje and not "Adultos" in scrapedcalidad: generos = scrapertools.find_multiple_matches(scrapedgenero, '<a href="[^"]*" rel="[^"]*">([^<]*)</a>')
scrapedtitle = scrapedtitle
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, itemlist.append(Item(channel=item.channel,
title=scrapedtitle, action="findvideos", url=scrapedurl,
url=scrapedurl, title=titulo, contentTitle=scrapedtitle,
action="findvideos",
thumbnail=scrapedthumbnail, thumbnail=scrapedthumbnail,
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", library=True, folder=True, language=audios,
language=scrapedlenguaje, quality=calidad,
quality=scrapedcalidad,
contentTitle = scrapedtitle,
infoLabels={'year':year} infoLabels={'year':year}
)) ))
tmdb.set_infoLabels(itemlist) tmdb.set_infoLabels(itemlist)
## Paginación
next_page = scrapertools.get_match(data, '<span class="current">.*?<a href="(.*?)".*?>Siguiente &raquo;</a></div>') # Paginación
itemlist.append(Item(channel=item.channel, action="peliculas", title="[COLOR red]siguiente>>[/COLOR]", url=next_page, url_next_page = scrapertools.find_single_match(data,'<a href="([^"]*)">Siguiente &raquo;</a>')
thumbnail="http://s6.postimg.cc/uej03x4r5/bricoflecha.png", if url_next_page:
fanart="http://s18.postimg.cc/h9kb22mnt/pdkfanart.jpg", folder=True)) itemlist.append(item.clone(title="Siguiente >>", url=url_next_page))
return itemlist return itemlist
def findvideos(item): def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
data = httptools.downloadpage(item.url).data data = httptools.downloadpage(item.url).data
data = re.sub(r"<!--.*?-->", "", data)
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data) patron = '<li><a href="#(tab\d+)"><span class="re">\d<\/span><span class="([^"]+)"><\/span><span class=.*?>([^<]+)<\/span>'
bloque_tab = scrapertools.find_single_match(data, '<div id="verpelicula">(.*?)<div class="tab_container">') check = re.compile(patron, re.DOTALL).findall(data)
patron = '<li><a href="#([^<]+)"><span class="re">\d<\/span><span class="([^<]+)"><\/span><span class=.*?>([^<]+)<\/span>' if not check:
check = re.compile(patron, re.DOTALL).findall(bloque_tab) patron = '<li><a href="#(tab\d+)">'
servers_data_list = [] check = re.compile(patron, re.DOTALL).findall(data)
patron = '<div id="(tab\d+)" class="tab_content"><script type="text/rocketscript">(\w+)\("([^"]+)"\)</script></div>' 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) matches = re.compile(patron, re.DOTALL).findall(data)
if len(matches) == 0:
patron = '<div id="(tab\d+)" class="tab_content"><script>(\w+)\("([^"]+)"\)</script></div>' servers_data_list = []
matches = re.compile(patron, re.DOTALL).findall(data) for i, match in enumerate(matches):
for check_tab, server, id in matches: if match[0] == check[i][0]:
if check_tab in str(check): if '<iframe' in match[1]:
idioma, calidad = scrapertools.find_single_match(str(check), "" + check_tab + "', '(.*?)', '(.*?)'") src = scrapertools.find_single_match(match[1], ' src="([^"]*)"')
servers_data_list.append([server, id, idioma, calidad]) servers_data_list.append([check[i][1], check[i][2], 'iframe', src]) # idioma, calidad, 'iframe', src
url = host + "/Js/videod.js"
data = httptools.downloadpage(url).data elif '<script' in match[1]:
data = re.sub(r"\n|\r|\t|\s{2}|&nbsp;", "", data) src = scrapertools.find_single_match(match[1], '<script>(.*?)<\/script>')
data = data.replace('<iframe width="100%" height="400" scrolling="no" frameborder="0"', '') if src:
patron = 'function (\w+)\(id\).*?' func, parm = scrapertools.find_single_match(src, '(.*?)\("([^"]*)"\)')
patron += 'data-src="([^"]+)"' servers_data_list.append([check[i][1], check[i][2], func, parm ]) # idioma, calidad, func, parm
matches = scrapertools.find_multiple_matches(data, patron)
for server, url in matches: data = httptools.downloadpage(host + '/Js/videod.js').data
for enlace, id, idioma, calidad in servers_data_list: patron = 'function (\w+)\(id\){(.*?)}'
if server == enlace: matches = re.compile(patron, re.DOTALL).findall(data)
video_url = re.sub(r"embed\-|\-.*?x.*?\.html|u\'|\'\(", "", str(url))
video_url = re.sub(r"'\+codigo\+'", "", video_url) for idioma, calidad, func, parm in servers_data_list:
video_url = video_url.replace('embed//', 'embed/') if func == 'iframe':
video_url = video_url + id title = "Ver en: %s [" + idioma + "][" + calidad + "]"
if "goo.gl" in video_url: itemlist.append(
try: item.clone(title=title, url=parm, action="play",
from unshortenit import unshorten thumbnail=item.category,
url = unshorten(video_url) language=idioma, quality=calidad))
video_url = scrapertools.get_match(str(url), "u'([^']+)'")
except: else:
continue for funcion, contenido in matches:
title = "Ver en: %s [" + idioma + "][" + calidad + "]" if funcion == func:
itemlist.append( if '<script' in contenido: continue
item.clone(title=title, url=video_url, action="play", if '<iframe' in contenido:
thumbnail=item.category, src = scrapertools.find_single_match(contenido, 'src="([^"]*)"')
language=idioma, quality=calidad)) 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) tmdb.set_infoLabels(itemlist)
itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % i.server.capitalize()) itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % i.server.capitalize())
if __comprueba_enlaces__: if __comprueba_enlaces__:
itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__) itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__)
if item.library and config.get_videolibrary_support() and len(itemlist) > 0: if item.library and config.get_videolibrary_support() and len(itemlist) > 0:
infoLabels = {'tmdb_id': item.infoLabels['tmdb_id'], infoLabels = {'tmdb_id': item.infoLabels['tmdb_id'],
'title': item.fulltitle} 'title': item.fulltitle}
@@ -195,14 +265,14 @@ def findvideos(item):
action="add_pelicula_to_library", url=item.url, infoLabels=infoLabels, action="add_pelicula_to_library", url=item.url, infoLabels=infoLabels,
text_color="0xFFff6666", text_color="0xFFff6666",
thumbnail='http://imgur.com/0gyYvuC.png')) thumbnail='http://imgur.com/0gyYvuC.png'))
itemlist = filtertools.get_links(itemlist, item, list_language)
autoplay.start(itemlist, item)
return itemlist return itemlist
def play(item):
item.thumbnail = item.contentThumbnail
return [item]
def newest(categoria): def newest(categoria):
logger.info() logger.info()
itemlist = [] itemlist = []
+1 -1
View File
@@ -499,7 +499,7 @@ def do_search(item, categories=None):
result_mode = 1 result_mode = 1
if result_mode == 0: if result_mode == 0:
if len(search_results[channel]) > 1: if len(search_results[channel]) > 1:
title += " [%s]" % element["item"].title.strip() title += " -%s" % element["item"].title.strip()
title += " (%s)" % len(element["itemlist"]) title += " (%s)" % len(element["itemlist"])
title = re.sub("\[COLOR [^\]]+\]", "", title) title = re.sub("\[COLOR [^\]]+\]", "", title)
+14 -7
View File
@@ -169,7 +169,7 @@ def seasons(item):
return itemlist return itemlist
def all_episodes(item): def epidodios(item):
logger.info() logger.info()
itemlist = [] itemlist = []
templist = seasons(item) templist = seasons(item)
@@ -183,8 +183,9 @@ def episodesxseason(item):
itemlist = [] itemlist = []
data = get_source(item.url) data = get_source(item.url)
season = item.contentSeasonNumber 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 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 infoLabels = item.infoLabels
for scrapedurl, scraped_episode, scrapedtitle, lang_data in matches: for scrapedurl, scraped_episode, scrapedtitle, lang_data in matches:
url = host + scrapedurl url = host + scrapedurl
@@ -207,15 +208,22 @@ def episodesxseason(item):
def add_language(title, string): def add_language(title, string):
logger.info() logger.info()
language = []
languages = scrapertools.find_multiple_matches(string, '/banderas/(.*?).png') languages = scrapertools.find_multiple_matches(string, '/banderas/(.*?).png')
language = []
for lang in languages: for lang in languages:
if 'jap' in lang or lang not in IDIOMAS: if 'jap' in lang or lang not in IDIOMAS:
lang = 'vos' lang = 'vos'
language.append(IDIOMAS[lang]) if len(languages) == 1:
title = '%s [%s]' % (title, IDIOMAS[lang]) language = IDIOMAS[languages[0]]
title = '%s [%s]' % (title, language)
else:
language.append(IDIOMAS[lang])
title = '%s [%s]' % (title, IDIOMAS[lang])
return title, language return title, language
@@ -226,9 +234,8 @@ def findvideos(item):
itemlist = [] itemlist = []
data = get_source(item.url) data = get_source(item.url)
patron = "<a href=([^ ]+) target=_blank><img src='/servidores/(.*?).(?:png|jpg)'.*?sno.*?" 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) matches = re.compile(patron, re.DOTALL).findall(data)
+18 -1
View File
@@ -12,7 +12,9 @@
"tvshow", "tvshow",
"anime", "anime",
"torrent", "torrent",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -23,6 +25,21 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://torrentlocura.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
+19 -1
View File
@@ -12,7 +12,9 @@
"anime", "anime",
"torrent", "torrent",
"latino", "latino",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -23,6 +25,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://torrentrapid.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
+19 -1
View File
@@ -11,7 +11,9 @@
"tvshow", "tvshow",
"anime", "anime",
"torrent", "torrent",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -22,6 +24,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://tumejortorrent.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
+19 -1
View File
@@ -11,7 +11,9 @@
"tvshow", "tvshow",
"anime", "anime",
"torrent", "torrent",
"documentary" "documentary",
"vos",
"direct"
], ],
"settings": [ "settings": [
{ {
@@ -22,6 +24,22 @@
"enabled": true, "enabled": true,
"visible": 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", "id": "clonenewpct1_ver_enlaces_veronline",
"type": "list", "type": "list",
+188 -53
View File
@@ -15,6 +15,12 @@ from core import tmdb
host = 'http://www.tvsinpagar.com/' 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): def mainlist(item):
logger.info() logger.info()
@@ -57,7 +63,12 @@ def submenu(item):
logger.info() logger.info()
itemlist = [] 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")
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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
@@ -68,11 +79,19 @@ def submenu(item):
else: else:
if data: if data:
data = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<.*?href="([^"]+)".*?>([^>]+)</a>' patron = '<.*?href="([^"]+)".*?>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.strip() title = scrapedtitle.strip()
@@ -106,6 +125,10 @@ def alfabeto(item):
patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>' patron = '<a href="([^"]+)"[^>]+>([^>]+)</a>'
matches = re.compile(patron, re.DOTALL).findall(data) 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: for scrapedurl, scrapedtitle in matches:
title = scrapedtitle.upper() title = scrapedtitle.upper()
@@ -130,7 +153,12 @@ def listado(item):
if item.totalItems: if item.totalItems:
del 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 " + " / 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 #Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas": if item.extra == "peliculas":
@@ -150,6 +178,12 @@ def listado(item):
patron = '<ul class="' + clase + '">(.*?)</ul>' patron = '<ul class="' + clase + '">(.*?)</ul>'
if data: if data:
fichas = scrapertools.get_match(data, patron) 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: else:
return itemlist return itemlist
page_extra = clase 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 #Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = '<a href="([^"]+).*?' # la url patron = '<a href="([^"]+).*?' # la url
patron += 'title="([^"]+).*?' # el titulo 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 += '<h2.*?>(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '<span>([^<].*?)?<' # la calidad patron += '<span>([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas) 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: " + str(len(matches)))
#logger.debug(matches) #logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas) #logger.debug("patron: " + patron + " / fichas: " + fichas)
@@ -361,7 +400,7 @@ def listado(item):
itemlist.append(item_local.clone()) itemlist.append(item_local.clone())
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -466,10 +505,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 #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: 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 " + " / 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 cnt_next += 1
if not data: #Si la web está caída salimos sin dar error 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 " + " / 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 #Obtiene la dirección de la próxima página, si la hay
try: try:
@@ -487,26 +533,33 @@ def listado_busqueda(item):
post_num = int(post)-1 #Guardo página actual post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video # 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) 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<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2.*?>(?P<title>.*?)?<\/h2>'
pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url pattern = '<li[^>]*><a href="(?P<scrapedurl>[^"]+).*?' #url
pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título pattern += 'title="(?P<scrapedtitle>[^"]+).*?' #título
pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb pattern += '<img.*?src="(?P<scrapedthumbnail>[^"]+)?".*?' #thumb
pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad pattern += '<h2.*?(?P<calidad>\[.*?)?<\/h2.*?' #calidad
pattern += '<span.*?>\d+-\d+-(?P<year>\d{4})?<\/span>*.?' #año 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 += '<span.*?>(?P<size>\d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas)
matches_alt = re.compile(pattern, re.DOTALL).findall(data) 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. #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 #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: 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 #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 #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 #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. 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+-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.*?-\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 scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie
@@ -514,14 +567,12 @@ def listado_busqueda(item):
if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente 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 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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
if "pelisyseries.com" in host: title_lista_alt_for += [scrapedurl_alt]
title_lista_alt += [scrapedurl_alt]
else:
title_lista_alt += [scrapedurl]
if "juego/" in scrapedurl: # no mostramos lo que no sean videos if "juego/" in scrapedurl: # no mostramos lo que no sean videos
continue continue
cnt_title += 1 # Sería una línea real más para Itemlist cnt_title += 1 # Sería una línea real más para Itemlist
@@ -537,6 +588,7 @@ def listado_busqueda(item):
if cnt_title <= cnt_tot: if cnt_title <= cnt_tot:
matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página 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("PATRON: " + pattern)
#logger.debug(matches) #logger.debug(matches)
@@ -811,7 +863,7 @@ def listado_busqueda(item):
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist #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 # Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist: for item_local in itemlist:
@@ -884,6 +936,8 @@ def findvideos(item):
logger.info() logger.info()
itemlist = [] itemlist = []
logger.debug(item)
# Cualquiera de las tres opciones son válidas # Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/") # item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/") # item.url = item.url.replace(".com/",".com/descarga-directa/")
@@ -970,14 +1024,14 @@ def findvideos(item):
except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables 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) logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex)
#Mostrar los errores #Mostrar los errores
logger.debug(ver_enlaces_veronline) logger.error(ver_enlaces_veronline)
logger.debug(verificar_enlaces_veronline) logger.error(verificar_enlaces_veronline)
logger.debug(verificar_enlaces_veronline_validos) logger.error(verificar_enlaces_veronline_validos)
logger.debug(excluir_enlaces_veronline) logger.error(excluir_enlaces_veronline)
logger.debug(ver_enlaces_descargas) logger.error(ver_enlaces_descargas)
logger.debug(verificar_enlaces_descargas) logger.error(verificar_enlaces_descargas)
logger.debug(verificar_enlaces_descargas_validos) logger.error(verificar_enlaces_descargas_validos)
logger.debug(excluir_enlaces_descargas) logger.error(excluir_enlaces_descargas)
#Resetear las variables a sus valores por defecto #Resetear las variables a sus valores por defecto
ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online
verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online
@@ -1006,15 +1060,20 @@ def findvideos(item):
# Obtener la información actualizada del Episodio, si no la hay # 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'): 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": 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 #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']: if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios item.infoLabels['temporada_num_episodios'] = num_episodios
# Descarga la página # 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 " + " / 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -1029,10 +1088,9 @@ def findvideos(item):
#Limpiamos de año y rating de episodios #Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']: if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', 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'].replace(item.wanted, '')
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode": 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 #Generamos una copia de Item para trabajar sobre ella
item_local = item.clone() item_local = item.clone()
@@ -1040,6 +1098,10 @@ def findvideos(item):
# obtenemos la url torrent # obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron) 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 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("Patron: " + patron + " url: " + item_local.url)
#logger.debug(data) #logger.debug(data)
@@ -1136,6 +1198,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1225,6 +1288,7 @@ def findvideos(item):
item_local.alive = "??" #Se asume poe defecto que es link es dudoso 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 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? 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 ? 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 verificar_enlaces_descargas_validos: #Los links tienen que ser válidos para contarlos?
if item_local.alive == "Ok": #Sí if item_local.alive == "Ok": #Sí
@@ -1268,17 +1332,41 @@ def episodios(item):
logger.info() logger.info()
itemlist = [] 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")
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 #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 pattern = '<ul class="%s">(.*?)</ul>' % "pagination" # item.pattern
pagination = scrapertools.find_single_match(data, pattern) pagination = scrapertools.find_single_match(data, pattern)
if pagination: 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) full_url = scrapertools.find_single_match(pagination, pattern)
url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)')
last_page = int(last_page)
list_pages = [item.url] 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 #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)) #response = httptools.downloadpage('%s%s'% (url,x))
#if response.sucess: #if response.sucess:
@@ -1287,28 +1375,39 @@ def episodios(item):
else: else:
list_pages = [item.url] list_pages = [item.url]
for index, page in enumerate(list_pages): #Recorre la lista de páginas for page in list_pages: #Recorre la lista de páginas
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page).data) if not list_pages:
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") break
data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com try:
pattern = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern if not data:
if scrapertools.find_single_match(data, pattern): 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) data = scrapertools.get_match(data, pattern)
else: if not data:
logger.debug(item) raise
logger.debug("patron: " + pattern + " / data: " + data) except:
return itemlist 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: if "pelisyseries.com" in host:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>' pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else: else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>' pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
matches = re.compile(pattern, re.DOTALL).findall(data) 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
data = ''
#logger.debug("patron: " + pattern) #logger.debug("patron: " + pattern)
#logger.debug(matches) #logger.debug(matches)
#Empezamos a generar cada episodio #Empezamos a generar cada episodio
season = "1" season = max_temp
for url, thumb, info in matches: for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden if "pelisyseries.com" in host: #En esta web están en diferente orden
interm = url interm = url
@@ -1359,6 +1458,10 @@ def episodios(item):
r = re.compile(pattern) r = re.compile(pattern)
match = [m.groupdict() for m in r.finditer(info)][0] 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['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico
if match['episode'] is None: match['episode'] = "0" if match['episode'] is None: match['episode'] = "0"
@@ -1379,13 +1482,37 @@ def episodios(item):
item_local.contentEpisodeNumber = match['episode'] item_local.contentEpisodeNumber = match['episode']
item_local.contentSeason = match['season'] 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.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios" 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()) 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 # Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, seekTmdb = True) tmdb.set_infoLabels(itemlist, seekTmdb = True)
if len(itemlist) > 1: if len(itemlist) > 1:
@@ -1393,7 +1520,9 @@ def episodios(item):
# Pasada para maqullaje de los títulos obtenidos desde TMDB # Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1 num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1 num_temporada = 1
num_episodios_flag = True
for item_local in itemlist: for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco # Si no hay datos de TMDB, pongo los datos locales que conozco
@@ -1416,7 +1545,7 @@ def episodios(item):
if item_local.infoLabels['episodio_titulo']: if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie 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) item_local.infoLabels['episodio_titulo'] = '%s - %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else: else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo']) item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']: if item_local.infoLabels['year']:
@@ -1439,8 +1568,14 @@ def episodios(item):
num_episodios = item_local.contentEpisodeNumber num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']: if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = 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))
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: if config.get_videolibrary_support() and len(itemlist) > 0:
title = '' title = ''
+4 -2
View File
@@ -492,7 +492,9 @@ def thumbnail_type(item):
thumb_type = config.get_setting('video_thumbnail_type') thumb_type = config.get_setting('video_thumbnail_type')
info = item.infoLabels info = item.infoLabels
item.contentThumbnail = item.thumbnail if not item.contentThumbnail:
item.contentThumbnail = item.thumbnail
if info: if info:
if info['thumbnail'] !='': if info['thumbnail'] !='':
item.contentThumbnail = info['thumbnail'] item.contentThumbnail = info['thumbnail']
@@ -505,7 +507,7 @@ def thumbnail_type(item):
from core.servertools import get_server_parameters from core.servertools import get_server_parameters
#logger.debug('item.server: %s'%item.server) #logger.debug('item.server: %s'%item.server)
server_parameters = get_server_parameters(item.server.lower()) 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 return item.thumbnail
+1 -1
View File
@@ -8,7 +8,7 @@ from platformcode import logger
def test_video_exists(page_url): def test_video_exists(page_url):
logger.info("(page_url='%s')" % page_url) logger.info("(page_url='%s')" % page_url)
data = httptools.downloadpage(page_url).data 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 False, "[clipwatching] El video ha sido borrado"
return True, "" return True, ""
+1 -1
View File
@@ -19,7 +19,7 @@ def test_video_exists(page_url):
logger.info("(page_url='%s')" % page_url) logger.info("(page_url='%s')" % page_url)
data = get_source(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 False, "[Filebebo] El video ha sido borrado"
return True, "" return True, ""
+2 -2
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, js_wise = scrapertools.find_single_match(data_page_url_hqq,
"<script type=[\"']text/javascript[\"']>\s*;?(eval.*?)</script>") "<script type=[\"']text/javascript[\"']>\s*;?(eval.*?)</script>")
data_unwise = jswise(js_wise).replace("\\", "") data_unwise = jswise(js_wise).replace("\\", "")
at = scrapertools.find_single_match(data_unwise, 'var at\s*=\s*"([^"]+)"') at = scrapertools.find_single_match(data_unwise, 'at=(\w+)')
http_referer = scrapertools.find_single_match(data_unwise, 'var http_referer\s*=\s*"([^"]+)"') 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" \ 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) "&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 data_player = httptools.downloadpage(url, add_referer=True).data