def renumber(itemlist, item='', typography=''): log() if item: try: dict_series = jsontools.get_node_from_file(item.channel, TAG_TVSHOW_RENUMERATE) SERIES = dict_series[item.show.rstrip()]['season_episode'] S = SERIES[0] E = SERIES[1] SP = SERIES[2] ID = SERIES[3] page = 1 epList = [] exist = True item.infoLabels['tvdb_id'] = ID tvdb.set_infoLabels_item(item) while exist: data = tvdb.otvdb_global.get_list_episodes(ID, page) if data: for episodes in data['data']: if episodes['airedSeason'] >= S: if E == 0: epList.append([0, SP]) E = 1 if episodes['airedEpisodeNumber'] >= E: epList.append([ episodes['airedSeason'], episodes['airedEpisodeNumber'] ]) page = page + 1 else: exist = False epList.sort() ep = 0 for item in itemlist: s = str(epList[ep][0]) e = str(epList[ep][1]) item.title = typo(s + 'x' + e + ' - ', typography) + item.title ep = ep + 1 except: return itemlist else: for item in itemlist: if item.contentType != 'movie': if item.context: context2 = item.context item.context = context() + context2 else: item.context = context() return itemlist
def update_infolabels_show(tmdb_id, with_tvdb=False): logger.info() if with_tvdb: from core import tvdb as scrapper else: from core import tmdb as scrapper tit = 'Actualizando datos desde ' + ('TVDB' if with_tvdb else 'TMDB') progreso = platformtools.dialog_progress(tit, 'Serie y temporadas ...') db = TrackingData() cambios = [] # Serie # ----- infolabels = db.get_show(tmdb_id) it = Item(infoLabels = infolabels) # ~ logger.debug(it) scrapper.set_infoLabels_item(it) # ~ logger.debug(it) if base64.b64encode(jsontools.dump(infolabels)) != base64.b64encode(jsontools.dump(it.infoLabels)): db.save_show(tmdb_id, it.infoLabels) cambios.append('Serie') # Temporadas # ---------- rows = db.get_seasons(tmdb_id) num_rows = len(rows) n = 0 for season, infolabels in rows: it = Item(infoLabels = infolabels) # ~ logger.debug(it) scrapper.set_infoLabels_item(it) # ~ logger.debug(it) if base64.b64encode(jsontools.dump(infolabels)) != base64.b64encode(jsontools.dump(it.infoLabels)): db.save_season(tmdb_id, season, it.infoLabels) cambios.append('T%d' % season) n += 1 perc = int(n / num_rows * 100) progreso.update(perc, tit, 'Procesada temporada %d' % season) if progreso.iscanceled(): break # Para episodios podrían ser demasiadas llamadas a tmdb, mejor hacerlo por una temporada concreta progreso.close() commit = True if len(cambios) > 0 else False db.close(commit=commit) msg = 'Sin cambios en la serie ni en las temporadas.' if not commit else 'Actualizados cambios en %s.' % ', '.join(cambios) logger.info(msg) return commit, msg
def update_infolabels_episodes(tmdb_id, season=-1, episode=-1, with_tvdb=False): logger.info() if with_tvdb: from core import tvdb as scrapper else: from core import tmdb as scrapper tit = 'Actualizando episodios desde ' + ('TVDB' if with_tvdb else 'TMDB') if season == -1: subtit = 'Todas las temporadas ...' elif episode == -1: subtit = 'Temporada %d ...' % season else: subtit = 'Temporada %d Episodio %d ...' % (season, episode) progreso = platformtools.dialog_progress(tit, subtit) db = TrackingData() cambios = [] if season > 0 and episode > 0: rows = [ [season, episode, db.get_episode(tmdb_id, season, episode)] ] else: rows = db.get_episodes(tmdb_id, season) num_rows = len(rows) n = 0 for season, episode, infolabels in rows: it = Item(infoLabels = infolabels) scrapper.set_infoLabels_item(it) if base64.b64encode(jsontools.dump(infolabels)) != base64.b64encode(jsontools.dump(it.infoLabels)): db.save_episode(tmdb_id, season, episode, it.infoLabels) cambios.append('%dx%d' % (season, episode)) n += 1 perc = int(n / num_rows * 100) progreso.update(perc, tit, 'Procesado episodio %dx%d' % (season, episode)) if progreso.iscanceled(): break progreso.close() commit = True if len(cambios) > 0 else False db.close(commit=commit) msg = 'Sin cambios en los episodios.' if not commit else 'Episodios actualizados: %s.' % ', '.join(cambios) logger.info(msg) return commit, msg
def make_list(itemlist, item, typography, dict_series, ID, SEASON, EPISODE, MODE, TITLE): from core import support log() page = 1 EpList = [] EpisodeDict = {} exist = True item.infoLabels['tvdb_id'] = ID tvdb.set_infoLabels_item(item) FirstOfSeason = 0 try: SPECIAL = dict_series[TITLE][TAG_SPECIAL] except: SPECIAL = [] # Ricava Informazioni da TVDB while exist: data = tvdb.otvdb_global.get_list_episodes(ID, page) if data: page = page + 1 else: exist = False if data: for episodes in data['data']: EpList.append([ episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber'] ]) EpList.sort() log(EpList) # Crea Dizionari per la numerazione if EpList: specials = [] regular = {} complete = {} allep = 1 ep = 1 specialep = 0 for episode in EpList: complete[allep] = [ str(episode[1]) + 'x' + str(episode[2]), episode[0] ] if episode[1] == 0: specials.append(allep) specialep = specialep + 1 else: regular[ep] = [ str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1 ] ep = ep + 1 allep = allep + 1 # seleziona l'Episodio di partenza if int(SEASON) > 1: for numbers, data in regular.items(): if data[0] == SEASON + 'x1': FirstOfSeason = numbers - 1 if MODE == True: SPECIAL = specials log(SPECIAL) log(complete) log(regular) addiction = 0 for item in itemlist: # Otiene Numerazione Episodi episode = int(scrapertoolsV2.find_single_match(item.title, r'\d+')) log('EPISODE= ', episode) number = episode + FirstOfSeason - addiction count = number + addiction # find = episode + FirstOfSeason # log('FIND= ',find, ' ',str(episode) + ' ' + str(FirstOfSeason)) # Crea Dizionario Episodi # log(episode, ' ', number, ' ', count) if episode == 0: EpisodeDict[str(episode)] = str( complete[regular[FirstOfSeason + 1][2]][0]) elif addiction < len(SPECIAL): if episode in SPECIAL: season = complete[regular[count][2]][0] EpisodeDict[str(episode)] = str( complete[regular[count][2]][0]) if season.startswith( '0') else '0x' + platformtools.dialog_numeric( 0, item.title + '?', '') addiction = addiction + 1 else: EpisodeDict[str(episode)] = str(regular[number][0]) elif number <= len(regular): EpisodeDict[str(episode)] = str(regular[number][0]) else: try: EpisodeDict[str(episode)] = str(complete[regular[number + 2][2]][0]) except: EpisodeDict[str(episode)] = '0x0' # Aggiunge numerazione agli Episodi item.title = typo(EpisodeDict[str(episode)] + ' - ', typography) + item.title # Scrive Dizionario Episodi sul json EpisodeDict = base64.b64encode(json.dumps(EpisodeDict)) dict_series[TITLE][TAG_EPISODE] = EpisodeDict jsontools.update_node(dict_series, item.channel, TAG_TVSHOW_RENUMERATE)[0] else: heading = config.get_localized_string(70704) ID = platformtools.dialog_numeric(0, heading) dict_series[TITLE][TAG_ID] = ID jsontools.update_node(dict_series, item.channel, TAG_TVSHOW_RENUMERATE)[0] if ID == '0': return itemlist else: return make_list(itemlist, item, typography, dict_series, ID, SEASON, EPISODE, MODE, TITLE)
def scrap_and_save_tvshow(item, op='add', tvdbinfo=False): # Al añadir una serie se guardan los infolabels de serie + temporadas + episodios, y los enlaces al canal desde dónde se añade. # El item recibido tiene que tener tmdb_id informado y ser 'tvshow', 'season' o 'episode'. # También se requiere el channel+action y los parámetros necesarios para hacer la llamada al canal. # Con tvdbinfo=True, para cada episodio añadido se llama a tvdb para recuperar la info de allí. # # 'tvshow' : Se llama al canal para recuperar todas las temporadas, y para cada una de ellas todos sus capítulos. # 'season' : Se llama al canal para una temporada concreta y se obtienen todos sus capítulos. # 'episode' : Se llama al canal para un episodio concreto. # # Los datos recogidos al llamar a esta rutina dependerán de lo que devuelva el canal y de si se pasa una serie, una temporada o un episodio. # Ej: Si un canal solamente devuelve una temporada para una serie, se añade esa temporada. Si otro canal (o el mismo desde otro enlace) # devuelve dos temporadas para la misma serie, se completan los datos nuevos. # Ej: Si se llama para un episodio suelto desde algún listado de últimos capítulos, y la serie no está trackeada todavía, se añade el # enlace del canal al episodio, pero como no se dispone de la "url" para listar todas las temporadas o una temporada concreta, no # se puede añadir más. En cambio si se llama para la serie entera, se disponen de los enlaces a cada temporada y se pueden guardar. # # Devuelve True si se completa ok y False en caso contrario, más un texto con la información del error o proceso ok # logger.info() tmdb_id = item.infoLabels['tmdb_id'] if not tmdb_id: return False, 'Se requiere id de TMDB' if item.contentType not in ['tvshow', 'season', 'episode']: return False, 'contentType no contemplado!' # Tipo de scrap a realizar # ------------------------ if op == 'add': # Al añadir una serie/temp/epi desde el menú contextual, actualizar siempre urls, infolabels solamente si no existen. update_infolabels = False update_urls = True elif op == 'new_episodes': # Al buscar nuevos episodios, actualizar urls e infolabels solamente si no existen (episodios nuevos). update_infolabels = False update_urls = False else: return False, 'Invalid op!' # Conexión bd # ----------- db = TrackingData() cambios = [] # Para apuntar los cambios hechos en caso de refresco para buscar nuevos episodios # Datos a nivel de la serie # ------------------------- if not db.show_exists(tmdb_id): # Si no existe dar de alta if item.contentType == 'tvshow': # Si proviene de una serie ya se tienen los infolabels db.save_show(tmdb_id, item.infoLabels) else: # Sino buscar en tmdb it = Item( title='', contentType='tvshow', contentSerieName=item.contentSerieName, infoLabels={'tmdb_id': tmdb_id} ) from core import tmdb tmdb.set_infoLabels_item(it) db.save_show(tmdb_id, it.infoLabels) # Datos a nivel de serie+canal # ---------------------------- if item.contentType == 'tvshow': # Si proviene de serie, guardar su url if update_urls or not db.show_channel_exists(tmdb_id, item.channel): db.save_show_channel(tmdb_id, item.channel, item.clone(infoLabels={}).tourl()) # Cargar itemlist a tratar # ------------------------ if item.contentType in ['season', 'episode']: itemlist = [item] elif item.contentType == 'tvshow': try: canal = __import__('channels.' + item.channel, fromlist=['']) except: return False, 'El canal %s ya no existe' % item.channel # Si el canal tiene tracking_all_episodes usarlo para ir más rápido. # Excepción con newpct1, usar sólo tracking_all al añadir para que recorra todos los episodios, pero para actualizar mirar solamente en la primera página de episodios. if item.channel == 'newpct1' and op == 'new_episodes': buscar_tracking_all = False else: buscar_tracking_all = True if buscar_tracking_all and hasattr(canal, 'tracking_all_episodes'): itemlist = getattr(canal, 'tracking_all_episodes')(item) else: if hasattr(canal, item.action): itemlist = getattr(canal, item.action)(item) else: return False, 'En el canal %s ya no existe %s' % (item.channel, item.action) if itemlist is None or len(itemlist) == 0: db.close() return False, 'El canal no devuelve resultados' # Si es una actualización y el canal devuelve temporadas en lugar de episodios, solamente buscar episodios nuevos en la última temporada if op == 'new_episodes' and itemlist[0].contentType == 'season' and len(itemlist) > 1: itemlist = itemlist[-1:] # Datos a nivel de temporadas/episodios # ------------------------------------- # Si el canal devuelve una lista de temporadas if itemlist[0].contentType == 'season': try: canal = __import__('channels.' + item.channel, fromlist=['']) except: return False, 'El canal %s ya no existe' % item.channel for it in itemlist: # ~ logger.debug(it) if it.contentType != 'season': continue if it.infoLabels['tmdb_id'] != tmdb_id: continue # Guardar datos de la temporada if update_infolabels or not db.season_exists(tmdb_id, it.contentSeason): db.save_season(tmdb_id, it.contentSeason, it.infoLabels) # Guardar url para temporada+canal if update_urls or not db.season_channel_exists(tmdb_id, it.contentSeason, it.channel): db.save_season_channel(tmdb_id, it.contentSeason, it.channel, it.clone(infoLabels={}).tourl()) cambios.append('T%d' % it.contentSeason) # Llamar al canal para obtener episodios de la temporada if hasattr(canal, it.action): itemlist_epi = getattr(canal, it.action)(it) else: itemlist_epi = [] for it_epi in itemlist_epi: if it_epi.contentType != 'episode': continue if it_epi.contentSeason != it.contentSeason: continue if it_epi.infoLabels['tmdb_id'] != tmdb_id: continue # Guardar datos del episodio if update_infolabels or not db.episode_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber): if tvdbinfo and it_epi.infoLabels['tvdb_id']: from core import tvdb tvdb.set_infoLabels_item(it_epi) db.save_episode(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.infoLabels) # Guardar url para episodio+canal if update_urls or not db.episode_channel_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel): db.save_episode_channel(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel, it_epi.clone(infoLabels={}).tourl()) cambios.append('%dx%d' % (it_epi.contentSeason, it_epi.contentEpisodeNumber)) # Si el canal devuelve una lista de episodios elif itemlist[0].contentType == 'episode': ant_season = -1 # para no repetir llamadas mientras sea la misma temporada for it_epi in itemlist: # ~ logger.debug(it_epi) if it_epi.contentType != 'episode': continue if not it_epi.contentSeason: continue if it_epi.infoLabels['tmdb_id'] != tmdb_id: continue # Si no hay datos guardados de la temporada, buscarlos en tmdb y darlos de alta if ant_season != it_epi.contentSeason: if not db.season_exists(tmdb_id, it_epi.contentSeason): it = Item( title='', contentType='season', contentSerieName=it_epi.contentSerieName, contentSeason=it_epi.contentSeason, infoLabels={'tmdb_id': tmdb_id} ) from core import tmdb tmdb.set_infoLabels_item(it) db.save_season(tmdb_id, it.contentSeason, it.infoLabels) cambios.append('T%d' % it_epi.contentSeason) ant_season = it_epi.contentSeason # Guardar datos del episodio if update_infolabels or not db.episode_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber): if tvdbinfo and it_epi.infoLabels['tvdb_id']: from core import tvdb tvdb.set_infoLabels_item(it_epi) db.save_episode(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.infoLabels) # Guardar url para episodio+canal if update_urls or not db.episode_channel_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel): db.save_episode_channel(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel, it_epi.clone(infoLabels={}).tourl()) cambios.append('%dx%d' % (it_epi.contentSeason, it_epi.contentEpisodeNumber)) else: db.close() return False, 'El canal no devuelve temporadas ni episodios válidos' # Si es una actualización y ha habido cambios, actualizar updated de la tabla shows para que conste como actualizada if op == 'new_episodes' and len(cambios) > 0: db.cur.execute('UPDATE shows SET updated=? WHERE tmdb_id=?', (datetime.now(), tmdb_id)) # Cerrar conexión bd # ------------------ db.close(commit=True) # Si es una actualización informar de los cambios if op == 'new_episodes': return True, cambios # ~ if len(cambios) == 0: # ~ return False, 'No se detectan temporadas ni episodios nuevos.' # ~ else: # ~ return True, 'Añadidos enlaces para: [COLOR limegreen]%s[/COLOR]' % ', '.join(cambios) return True, 'Seguimiento serie con tmdb_id: %s' % tmdb_id
def make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title): log() exist = True item.infoLabels['tvdb_id'] = ID tvdb.set_infoLabels_item(item) FirstOfSeason = 0 EpisodeDict = json.loads(base64.b64decode(Episode)) if Episode else {} Special = dict_series[title][TAG_SPECIAL] if TAG_SPECIAL in dict_series[ title] else [] EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST]) ) if TAG_EPLIST in dict_series[title] else [] Pages = dict_series[title][TAG_CHECK] if TAG_CHECK in dict_series[ title] else [1] # Ricava Informazioni da TVDB checkpages = [] check = True Page = Pages[-1] while exist: if check: for page in Pages: data = tvdb.otvdb_global.get_list_episodes(ID, page) for episodes in data['data']: if episodes['firstAired'] and [ episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber'] ] not in EpList: EpList.append([ episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber'] ]) else: if page not in checkpages: checkpages.append(page) check = False data = tvdb.otvdb_global.get_list_episodes(ID, Page) if data: Page = Page + 1 for episodes in data['data']: if episodes['firstAired'] and [ episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber'] ] not in EpList: EpList.append([ episodes['firstAired'], episodes['airedSeason'], episodes['airedEpisodeNumber'] ]) else: if page not in checkpages: checkpages.append(Page - 1) exist = False EpList.sort() dict_series[title][TAG_CHECK] = checkpages EpList = base64.b64encode(json.dumps(EpList).encode()) dict_series[title][TAG_EPLIST] = EpList.decode() write(item, dict_series) # Crea Dizionari per la numerazione if EpList: EpList = json.loads(base64.b64decode(dict_series[title][TAG_EPLIST])) specials = [] regular = {} complete = {} allep = 1 ep = 1 specialep = 0 for episode in EpList: complete[allep] = [ str(episode[1]) + 'x' + str(episode[2]), episode[0] ] if episode[1] == 0: specials.append(allep) specialep = specialep + 1 else: regular[ep] = [ str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1 ] ep = ep + 1 allep = allep + 1 # seleziona l'Episodio di partenza if int(Season) > 1: for numbers, data in regular.items(): if data[0] == Season + 'x1': FirstOfSeason = numbers - 1 if Mode == True: Special = specials addiction = 0 for item in itemlist: # Otiene Numerazione Episodi if config.get_localized_string(30992) not in item.title: episode = int( scrapertools.find_single_match(item.title, r'\d+')) number = episode + FirstOfSeason - addiction count = number + addiction # Crea Dizionario Episodi if episode == 0: EpisodeDict[str(episode)] = str( complete[regular[FirstOfSeason + 1][2]][0]) elif addiction < len(Special): if episode in Special: try: season = complete[regular[count][2]][0] EpisodeDict[str(episode)] = str( complete[regular[count][2]][0] ) if season.startswith( '0') else '0x' + platformtools.dialog_numeric( 0, item.title + '?', '') except: EpisodeDict[ str(episode )] = '0x' + platformtools.dialog_numeric( 0, item.title + '?', '') addiction = addiction + 1 elif number <= len(regular): EpisodeDict[str(episode)] = str(regular[number][0]) else: try: EpisodeDict[str(episode)] = str( complete[regular[number + 2][2]][0]) except: EpisodeDict[str(episode)] = '0x0' elif number <= len(regular) and number in regular: EpisodeDict[str(episode)] = str(regular[number][0]) else: try: EpisodeDict[str(episode)] = str( complete[regular[number + 2][2]][0]) except: EpisodeDict[str(episode)] = '0x0' # Aggiunge numerazione agli Episodi item.title = typo(EpisodeDict[str(episode)] + ' - ', typography) + item.title # Scrive Dizionario Episodi sul json EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode()) dict_series[title][TAG_EPISODE] = EpisodeDict.decode() write(item, dict_series) else: heading = config.get_localized_string(70704) ID = platformtools.dialog_numeric(0, heading) dict_series[title][TAG_ID] = ID write(item, dict_series) if ID == '0': return itemlist else: return make_list(itemlist, item, typography, dict_series, ID, Season, Episode, Mode, title)
def renumber(itemlist, item='', typography=''): log() if item: try: dict_series = jsontools.get_node_from_file(item.channel, TAG_TVSHOW_RENUMERATE) ID = dict_series[item.show.rstrip()]['ID'] SEASON = dict_series[item.show.rstrip()]['Season'] page = 1 epDict = {} epList = [] exist = True item.infoLabels['tvdb_id'] = ID tvdb.set_infoLabels_item(item) ep = 1 while exist: data = tvdb.otvdb_global.get_list_episodes(ID, page) log(data) if data: for episodes in data['data']: log(episodes) if hasattr(episodes, 'absoluteNumber'): ABS = episodes['absoluteNumber'] else: ABS = str(ep) epDict[str(ABS)] = [ str(episodes['airedSeason']) + 'x' + str(episodes['airedEpisodeNumber']), episodes['firstAired'] ] epList.append(episodes['firstAired']) ep = ep + 1 page = page + 1 else: exist = False log(epDict) epList.sort() log(epList) if SEASON: for name, episode in epDict.items(): if episode[0] == SEASON + 'x1': ep = int(name) - 1 else: ep = 0 if SEASON != '0': for item in itemlist: number = int( scrapertoolsV2.find_single_match(item.title, r'\d+')) episode = str(ep + number) if number == 0: episode = previous(epList, epDict, str(ep + 1)) item.title = typo(epDict[episode][0] + ' - ', typography) + item.title else: for item in itemlist: number = scrapertoolsV2.find_single_match( item.title, r'\d+') item.title = typo('0x' + number + ' - ', typography) + item.title except: return itemlist else: for item in itemlist: if item.contentType != 'movie': if item.context: context2 = item.context item.context = context() + context2 else: item.context = context() return itemlist