item.infoLabels["number_of_episodes"]: #Si tenemos en .nfo más episodios, 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"
+
+ 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" [^>]+>(.*?)') #Seleccionamos la zona de links
+
+ patron = '\/icono_.*?png" title="(?P.*?)?" [^>]+><\/td>(?P.*?)?\/td>.*?(?P.*?)?<\/td>| 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, __modo_grafico__)
+
+ # 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":
+ 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 []
| | |