def save_download_movie(item): logger.info("pelisalacarta.channels.descargas save_download_movie") progreso = platformtools.dialog_progress("Descargas", "Obteniendo datos de la pelicula") tmdb.find_and_set_infoLabels_tmdb(item) progreso.update(0, "Añadiendo pelicula...") item.action = "menu" item.channel = "descargas" item.downloadStatus = 0 item.downloadProgress = 0 item.downloadSize = 0 item.downloadCompleted = 0 item.downloadFilename = "%s [%s]" % (item.contentTitle.strip(), item.contentChannel) if item.text_color: del item.text_color if item.text_bold: del item.text_bold if item.text_italic: del item.text_italic item.path = filetools.encode(os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json")) filetools.write(item.path, item.tojson()) progreso.close() if not platformtools.dialog_yesno(config.get_localized_string(30101), "¿Iniciar la descarga ahora?"): platformtools.dialog_ok(config.get_localized_string(30101), item.contentTitle, config.get_localized_string(30109)) else: start_download(item)
def play(item): logger.info() itemlist = [] try: from core import filetools ficherosubtitulo = filetools.join( config.get_data_path(), 'subtitulo_areadocu.srt' ) if filetools.exists(ficherosubtitulo): try: filetools.remove(ficherosubtitulo) except IOError: logger.info("Error al eliminar el archivo "+ficherosubtitulo) raise data = httptools.downloadpage(item.subtitle, headers={'Referer': item.extra}).data filetools.write(ficherosubtitulo, data) subtitle = ficherosubtitulo except: subtitle = "" logger.info("Error al descargar el subtítulo") extension = item.url.rsplit("|", 1)[0][-4:] itemlist.append(['%s %s [directo]' % (extension, item.calidad), item.url, 0, subtitle]) #itemlist.append(item.clone(subtitle=subtitle)) return itemlist
def save_download_tvshow(item): logger.info("pelisalacarta.channels.descargas save_download_tvshow") logger.info("Tipo: %s" % item.contentType) progreso = platformtools.dialog_progress("Descargas", "Obteniendo datos de la serie") tmdb.find_and_set_infoLabels_tmdb(item) item.downloadFilename = item.downloadFilename = "%s [%s]" % (item.contentSerieName, item.contentChannel) episodes = get_episodes(item) progreso.update(0, "Añadiendo capitulos...") for x, i in enumerate(episodes): progreso.update(x * 100 / len(episodes), os.path.basename(i.downloadFilename)) i.path = os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json") filetools.write(i.path, i.tojson()) time.sleep(0.1) progreso.close() if not platformtools.dialog_yesno(config.get_localized_string(30101), "¿Iniciar la descarga ahora?"): platformtools.dialog_ok(config.get_localized_string(30101), str(len(episodes)) + " capitulos de: " + item.contentSerieName, config.get_localized_string(30109)) else: for i in episodes: res = start_download(i) if res == 1: break
def eliminar(item): def eliminar_todo(item): filetools.rmdirtree(item.path) if config.is_xbmc(): import xbmc # esperamos 3 segundos para dar tiempo a borrar los ficheros xbmc.sleep(3000) # TODO mirar por qué no funciona al limpiar en la biblioteca de Kodi al añadirle un path # limpiamos la biblioteca de Kodi library.clean() logger.info("Eliminados todos los enlaces") platformtools.itemlist_refresh() logger.info(item.contentTitle) #logger.debug(item.tostring('\n')) if item.contentType == 'movie': heading = "Eliminar película" else: heading = "Eliminar serie" if item.multicanal: # Obtener listado de canales opciones = ["Eliminar solo los enlaces de %s" % k.capitalize() for k in item.library_urls.keys() if k !="descargas"] opciones.insert(0, heading) index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index == 0: # Seleccionado Eliminar pelicula/serie eliminar_todo(item) elif index > 0: # Seleccionado Eliminar canal X canal = opciones[index].replace("Eliminar solo los enlaces de ", "").lower() num_enlaces= 0 for fd in filetools.listdir(item.path): if fd.endswith(canal + '].json'): if filetools.remove(filetools.join(item.path, fd)): num_enlaces += 1 if num_enlaces > 0: # Actualizar .nfo head_nfo, item_nfo = library.read_nfo(item.nfo) del item_nfo.library_urls[canal] filetools.write(item.nfo, head_nfo + item_nfo.tojson()) msg_txt = "Eliminados %s enlaces del canal %s" % (num_enlaces, canal) logger.info(msg_txt) platformtools.dialog_notification(heading, msg_txt) platformtools.itemlist_refresh() else: if platformtools.dialog_yesno(heading, "¿Realmente desea eliminar '%s' de su biblioteca?" % item.infoLabels['title']): eliminar_todo(item)
def mark_tvshow_as_updatable(item): logger.info() head_nfo, it = library.read_nfo(item.nfo) it.active = item.active filetools.write(item.nfo, head_nfo + it.tojson()) platformtools.itemlist_refresh()
def mark_tvshow_as_updatable(item): logger.info("pelisalacarta.channels.biblioteca mark_tvshow_as_updatable") url_scraper = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) it.active = item.active filetools.write(item.nfo, url_scraper + it.tojson()) platformtools.itemlist_refresh()
def menu(item): logger.info("pelisalacarta.channels.descargas menu") # Opciones disponibles para el menu op = ["Descargar", "Eliminar de la lista", "Reiniciar descarga"] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select("Elige una opción", opciones) # -1 es cancelar if seleccion == -1: return logger.info("pelisalacarta.channels.descargas menu opcion=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: start_download(item) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) JSONItem = Item().fromjson(filetools.read(item.path)) JSONItem.downloadStatus = 0 JSONItem.downloadComplete = 0 JSONItem.downloadProgress = 0 JSONItem.downloadUrl = "" filetools.write(item.path, JSONItem.tojson()) platformtools.itemlist_refresh()
def mark_season_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_season_as_watched") # logger.debug("item:\n" + item.tostring('\n')) # Obtener el diccionario de episodios marcados f = filetools.join(item.path, "tvshow.nfo") url_scraper = filetools.read(f, 0, 1) it = Item().fromjson(filetools.read(f, 1)) if not hasattr(it, "library_playcounts"): it.library_playcounts = {} # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Marcamos cada uno de los episodios encontrados de esta temporada episodios_marcados = 0 for i in ficheros: if i.endswith(".strm"): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason): name_file = os.path.splitext(os.path.basename(i))[0] it.library_playcounts[name_file] = item.playcount episodios_marcados += 1 if episodios_marcados: if int(item.contentSeason) == -1: # Añadimos todas las temporadas al diccionario item.library_playcounts for k in it.library_playcounts.keys(): if k.startswith("season"): it.library_playcounts[k] = item.playcount else: # Añadimos la temporada al diccionario item.library_playcounts it.library_playcounts["season %s" % item.contentSeason] = item.playcount # se comprueba que si todas las temporadas están vistas, se marque la serie como vista it = check_tvshow_playcount(it, item.contentSeason) # Guardamos los cambios en tvshow.nfo filetools.write(f, url_scraper + it.tojson()) item.infoLabels["playcount"] = item.playcount if config.is_xbmc(): # Actualizamos la BBDD de Kodi library.mark_season_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def write_data(channel, show, data): # OBTENEMOS LOS DATOS DEL JSON dict_series = get_tvshows(channel) tvshow = show.strip() list_season_episode = dict_series.get(tvshow, {}).get(TAG_SEASON_EPISODE, []) logger.debug("data {0}".format(list_season_episode)) if data: # cambiamos el orden para que se vea en orden descendente y usarse bien en el _data.json data.sort(key=lambda el: int(el[0]), reverse=True) dict_renumerate = {TAG_SEASON_EPISODE: data} dict_series[tvshow] = dict_renumerate else: # hemos borrado todos los elementos, por lo que se borra la serie del fichero del dict_series[tvshow] fname, json_data = update_json_data(dict_series, channel) result = filetools.write(fname, json_data) if result: if data: message = "FILTRO GUARDADO" else: message = "FILTRO BORRADO" else: message = "Error al guardar en disco" heading = show.strip() platformtools.dialog_notification(heading, message)
def save_favourites(favourites_list): raw = '<favourites>' + chr(10) for name,thumb,data in favourites_list: raw += ' <favourite name="%s" thumb="%s">%s</favourite>' %(name,thumb,data) + chr(10) raw += '</favourites>' + chr(10) return filetools.write(FAVOURITES_PATH, raw)
def check_json_file(data, fname, dict_data): """ Comprueba que si dict_data(conversion del fichero JSON a dict) no es un diccionario, se genere un fichero con data de nombre fname.bk. :param data: contenido del fichero fname :type data: str :param fname: nombre del fichero leido :type fname: str :param dict_data: nombre del diccionario :type dict_data: dict """ logger.info("[filtertools.py] check_json_file") if not dict_data: logger.info("Error al cargar el json del fichero {0}".format(fname)) if data != "": # se crea un nuevo fichero title = filetools.write("{0}.bk".format(fname), data) if title != "": logger.info("Ha habido un error al guardar el fichero: {0}.bk" .format(fname)) else: logger.info("Se ha guardado una copia con el nombre: {0}.bk" .format(fname)) else: logger.info("Está vacío el fichero: {0}".format(fname))
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def borrar_filtro(item): logger.info() if item: # OBTENEMOS LOS DATOS DEL JSON dict_series = get_tvshows(item.from_channel) tvshow = item.show.strip().lower() heading = "¿Está seguro que desea eliminar el filtro?" line1 = "Pulse 'Si' para eliminar el filtro de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana para " \ "no hacer nada.".format(item.show.strip()) if platformtools.dialog_yesno(heading, line1) == 1: lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "") dict_series.pop(tvshow, None) fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO ELIMINADO" else: message = "Error al guardar en disco" heading = "{0} [{1}]".format(item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message)
def mark_content_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_content_as_watched") # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): url_scraper = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == "movie": name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == "episode": name_file = item.contentSeason + "x" + item.contentEpisodeNumber else: name_file = item.contentTitle if not hasattr(it, "library_playcounts"): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != "movie": it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, url_scraper + it.tojson()): item.infoLabels["playcount"] = item.playcount if item.contentType == "tvshow": # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def restart_error(item): logger.info("pelisalacarta.channels.descargas restart_error") for fichero in sorted(filetools.listdir(item.url)): if fichero.endswith(".json"): download_item = Item().fromjson(filetools.read(os.path.join(item.url, fichero))) serie_name = "%s [%s]" % (download_item.contentSerieName, download_item.contentChannel) if not item.serie_name or item.serie_name == serie_name: if download_item.downloadStatus == 3: if filetools.isfile(os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename)): filetools.remove(os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename)) download_item.downloadStatus = 0 download_item.downloadComplete = 0 download_item.downloadProgress = 0 download_item.downloadUrl = "" filetools.write(os.path.join(item.url, fichero), download_item.tojson()) platformtools.itemlist_refresh()
def decrypt_subs(iv, data, id): from Crypto.Cipher import AES data = base64.b64decode(data.encode('utf-8')) iv = base64.b64decode(iv.encode('utf-8')) id = int(id) def obfuscate_key_aux(count, modulo, start): output = list(start) for _ in range(count): output.append(output[-1] + output[-2]) # cut off start values output = output[2:] output = list(map(lambda x: x % modulo + 33, output)) return output def obfuscate_key(key): from math import pow, sqrt, floor num1 = int(floor(pow(2, 25) * sqrt(6.9))) num2 = (num1 ^ key) << 5 num3 = key ^ num1 num4 = num3 ^ (num3 >> 3) ^ num2 prefix = obfuscate_key_aux(20, 97, (1, 2)) prefix = struct.pack('B' * len(prefix), *prefix) shaHash = sha1(prefix + str(num4).encode('ascii')).digest() decshaHash = [] for char in shaHash: decshaHash.append(ord(char)) # Extend 160 Bit hash to 256 Bit return decshaHash + [0] * 12 key = obfuscate_key(id) key = struct.pack('B' * len(key), *key) decryptor = AES.new(key, AES.MODE_CBC, iv) decrypted_data = decryptor.decrypt(data) data = zlib.decompress(decrypted_data) import xml.etree.ElementTree as ET raiz = ET.fromstring(data) ass_sub = convert_to_ass(raiz) file_sub = filetools.join(config.get_data_path(), 'crunchyroll_sub.ass') filetools.write(file_sub, ass_sub) return file_sub
def mark_as_watched_on_strm(item): """ Marca un .strm como "visto" añadiendo el parametro "playcount" a los infoLabels del strm. @param item: item que queremos marcar como visto @type item: item """ logger.info("streamondemand.platformcode.library mark_as_watched_on_strm") if not config.get_setting("mark_as_watched") == "true": return xbmc.sleep(5000) while xbmc.Player().isPlaying(): tiempo_actual = xbmc.Player().getTime() totaltime = xbmc.Player().getTotalTime() condicion = int(config.get_setting("watched_setting")) if condicion == 0: # '5 minutos' mark_time = 300 elif condicion == 1: # '30%' mark_time = totaltime * 0.3 elif condicion == 2: # '50%' mark_time = totaltime * 0.5 elif condicion == 3: # '80%' mark_time = totaltime * 0.8 logger.debug(str(mark_time)) if tiempo_actual > mark_time: strm = Item().fromurl(filetools.read(item.path)) if not type(strm.infoLabels) == dict: strm.infoLabels = {} strm.infoLabels["playcount"] = 1 addon_name = sys.argv[0].strip() if not addon_name: addon_name = "plugin://plugin.video.pelisalacarta/" filetools.write(item.path + ".json", strm.tojson()) filetools.write(item.path, '{addon}?{url}'.format(addon=addon_name, url=strm.tourl())) break xbmc.sleep(30000)
def write_json(item): logger.info("pelisalacarta.channels.descargas write_json") item.action = "menu" item.channel = "descargas" item.downloadStatus = STATUS_CODES.stoped item.downloadProgress = 0 item.downloadSize = 0 item.downloadCompleted = 0 if not item.contentThumbnail: item.contentThumbnail = item.thumbnail for name in ["text_bold", "text_color", "text_italic", "context", "totalItems", "viewmode", "title", "fulltitle", "thumbnail"]: if item.__dict__.has_key(name): item.__dict__.pop(name) path = filetools.encode(os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json")) filetools.write(path, item.tojson()) item.path = path time.sleep(0.1)
def check_bookmark(savepath): from channels import favoritos for fichero in filetools.listdir(savepath): # Ficheros antiguos (".txt") if fichero.endswith(".txt"): # Esperamos 0.1 segundos entre ficheros, para que no se solapen los nombres de archivo time.sleep(0.1) # Obtenemos el item desde el .txt canal, titulo, thumbnail, plot, server, url, fulltitle = favoritos.readbookmark(fichero, savepath) item = Item(channel=canal, action="play", url=url, server=server, title=fulltitle, thumbnail=thumbnail, plot=plot, fanart=thumbnail, extra=os.path.join(savepath, fichero), fulltitle=fulltitle, folder=False) # Eliminamos el .txt os.remove(item.extra) item.extra = "" # Guardamos el archivo filename = os.path.join(savepath, str(time.time()) + ".json") filetools.write(filename, item.tojson())
def create_nfo_file(video_id, path, type_video): """ crea el fichero nfo con la información para scrapear la pelicula o serie @type video_id: str @param video_id: codigo identificativo del video @type path: str @param path: ruta donde se creará el fichero @type type_video: str @param type_video: tipo de video "serie" o "pelicula" """ # TODO meter un parametro más "scraper" para elegir entre una lista: imdb, tvdb, etc... y con el video_id pasado de # esa pagina se genere el nfo especifico logger.info("streamondemand.platformcode.library create_nfo_file") if type_video == "serie": data = "https://www.themoviedb.org/tv/{0}".format(video_id) nfo_file = filetools.join(path, "tvshow.nfo") else: data = "https://www.themoviedb.org/movie/{0}".format(video_id) nfo_file = path + ".nfo" filetools.write(nfo_file, data)
def write_json(item): logger.info("pelisalacarta.channels.descargas write_json") item.action = "menu" item.channel = "descargas" item.downloadStatus = STATUS_CODES.stoped item.downloadProgress = 0 item.downloadSize = 0 item.downloadCompleted = 0 if not item.contentThumbnail: item.contentThumbnail = item.thumbnail for name in [ "text_bold", "text_color", "text_italic", "context", "totalItems", "viewmode", "title", "fulltitle", "thumbnail" ]: if item.__dict__.has_key(name): item.__dict__.pop(name) path = os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json") filetools.write(path, item.tojson()) item.path = path time.sleep(0.1)
def obtener_data(url, referer=''): headers = {} if referer != '': headers['Referer'] = referer data = httptools.downloadpage(url, headers=headers).data if "Javascript is required" in data: ck = decodificar_cookie(data) logger.info("Javascript is required. Cookie necesaria %s" % ck) headers['Cookie'] = ck data = httptools.downloadpage(url, headers=headers).data # Guardar la cookie y eliminar la que pudiera haber anterior cks = ck.split("=") cookie_file = filetools.join(config.get_data_path(), 'cookies.dat') cookie_data = filetools.read(cookie_file) cookie_data = re.sub( r"www\.pelispedia\.tv\tFALSE\t/\tFALSE\t\tsucuri_(.*)\n", "", cookie_data) cookie_data += "www.pelispedia.tv\tFALSE\t/\tFALSE\t\t%s\t%s\n" % ( cks[0], cks[1]) filetools.write(cookie_file, cookie_data) logger.info("Añadida cookie %s con valor %s" % (cks[0], cks[1])) return data
def update_tvshow(item): logger.debug() # logger.debug("item:\n" + item.tostring('\n')) heading = config.get_localized_string(60037) p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading) p_dialog.update(0, heading, item.contentSerieName) import service if service.update(item.path, p_dialog, 0, 100, item, False) and config.is_xbmc() and config.get_setting("videolibrary_kodi"): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(item.path)) p_dialog.close() # check if the TV show is ended or has been canceled and ask the user to remove it from the video library update nfo_path = filetools.join(item.path, "tvshow.nfo") head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path) if item.active and not item_nfo.active: # if not platformtools.dialog_yesno(config.get_localized_string(60037).replace('...',''), config.get_localized_string(70268) % item.contentSerieName): item_nfo.active = 1 filetools.write(nfo_path, head_nfo + item_nfo.tojson()) platformtools.itemlist_refresh()
def get_from_subdivx(sub_url): """ :param sub_url: Url de descarga del subtitulo alojado en suvdivx.com Por Ejemplo: http://www.subdivx.com/bajar.php?id=573942&u=8 :return: La ruta al subtitulo descomprimido """ logger.info() sub = '' sub_dir = os.path.join(config.get_data_path(), 'temp_subs') if os.path.exists(sub_dir): for sub_file in os.listdir(sub_dir): old_sub = os.path.join(sub_dir, sub_file) os.remove(old_sub) else: os.mkdir(sub_dir) sub_url = sub_url.replace("&", "&") sub_data = httptools.downloadpage(sub_url, follow_redirects=False) if 'x-frame-options' not in sub_data.headers: sub_url = '%s' % sub_data.headers['location'] ext = sub_url[-4::] file_id = "subtitle%s" % ext filename = os.path.join(sub_dir, file_id) try: data_dl = httptools.downloadpage(sub_url).data filetools.write(filename, data_dl) sub = extract_file_online(sub_dir, filename) except: logger.info('sub no valido') else: logger.info('sub no valido') return sub
def verify_copy_folders(custom_code_dir, custom_code_json_path): logger.info() #verificamos si es una nueva versión de Alfa instalada o era la existente. Si es la existente, nos vamos sin hacer nada json_data_file = filetools.join(custom_code_json_path, json_data_file_name) json_data = jsontools.load(filetools.read(json_data_file)) current_version = config.get_addon_version(with_fix=False) if current_version == json_data['addon_version']: return #Ahora copiamos los archivos desde el área de Userdata, Custom_code, sobre las carpetas del add-on for root, folders, files in os.walk(custom_code_dir): for file in files: input_file = filetools.join(root, file) output_file = input_file.replace(custom_code_dir, custom_code_json_path) if filetools.copy(input_file, output_file, silent=True) == False: return #Guardamaos el json con la versión actual de Alfa, para no volver a hacer la copia hasta la nueva versión json_data['addon_version'] = current_version filetools.write(json_data_file, jsontools.dump(json_data)) return
def check_blacklist(domain, expiration=0): res = True if not filetools.exists(PATH_BL): return res try: expiration_default = 30 bl_data = jsontools.load(filetools.read(PATH_BL)) bl_data_clean = bl_data.copy() if not expiration: expiration = config.get_setting('cf_assistant_bl_expiration', default=expiration_default) * 60 config.set_setting('cf_assistant_bl_expiration', expiration_default) expiration = expiration_default * 60 else: expiration = expiration * 60 time_today = time.time() if bl_data: for domain_reg, time_rec in list(bl_data_clean.items()): if time_today > time_rec + expiration: del bl_data[domain_reg] filetools.write(PATH_BL, jsontools.dump(bl_data)) for domain_reg, time_rec in list(bl_data.items()): if domain in domain_reg: res = False break else: res = True except: logger.error(traceback.format_exc()) filetools.remove(PATH_BL) res = True return res
def save_download_tvshow(item): logger.info("pelisalacarta.channels.descargas save_download_tvshow") logger.info("Tipo: %s" % item.contentType) progreso = platformtools.dialog_progress("Descargas", "Obteniendo datos de la serie") tmdb.find_and_set_infoLabels_tmdb(item) item.downloadFilename = item.downloadFilename = "%s [%s]" % ( item.contentSerieName, item.contentChannel) episodes = get_episodes(item) progreso.update(0, "Añadiendo capitulos...") for x, i in enumerate(episodes): progreso.update(x * 100 / len(episodes), os.path.basename(i.downloadFilename)) i.path = os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json") filetools.write(i.path, i.tojson()) time.sleep(0.1) progreso.close() if not platformtools.dialog_yesno(config.get_localized_string(30101), "¿Iniciar la descarga ahora?"): platformtools.dialog_ok( config.get_localized_string(30101), str(len(episodes)) + " capitulos de: " + item.contentSerieName, config.get_localized_string(30109)) else: for i in episodes: res = start_download(i) if res == 1: break
def restart_error(item): logger.info("pelisalacarta.channels.descargas restart_error") for fichero in sorted(filetools.listdir(item.url)): if fichero.endswith(".json"): download_item = Item().fromjson( filetools.read(os.path.join(item.url, fichero))) serie_name = "%s [%s]" % (download_item.contentSerieName, download_item.contentChannel) if not item.serie_name or item.serie_name == serie_name: if download_item.downloadStatus == 3: if filetools.isfile( os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename)): filetools.remove( os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename)) download_item.downloadStatus = 0 download_item.downloadComplete = 0 download_item.downloadProgress = 0 download_item.downloadUrl = "" filetools.write(os.path.join(item.url, fichero), download_item.tojson()) platformtools.itemlist_refresh()
def save_filter(item): """ salva el filtro a través del menú contextual :param item: item :type item: item """ logger.info("[filtertools.py] save_filter") dict_series = get_filtered_tvshows(item.from_channel) name = item.show.lower().strip() logger.info("[filtertools.py] config_filter name {0}".format(name)) open_tag_idioma = (0, item.title.find("[")+1)[item.title.find("[") >= 0] close_tag_idioma = (0, item.title.find("]"))[item.title.find("]") >= 0] idioma = item.title[open_tag_idioma: close_tag_idioma] open_tag_calidad = (0, item.title.find("[", item.title.find("[") + 1)+1)[item.title.find("[", item.title.find("[") + 1) >= 0] close_tag_calidad = (0, item.title.find("]", item.title.find("]") + 1))[item.title.find("]", item.title.find("]") + 1) >= 0] calidad_no_permitida = "" # item.title[open_tag_calidad: close_tag_calidad] # filter_idioma = "" # logger.info("idioma {0}".format(idioma)) # if idioma != "": # filter_idioma = [key for key, value in dict_idiomas.iteritems() if value == idioma][0] list_calidad = list() dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: True, TAG_LANGUAGE: idioma, TAG_QUALITY_NOT_ALLOWED: list_calidad} dict_series[name] = dict_filter # filter_list = item.extra.split("##") # dict_series = eval(filter_list[0]) # dict_filter = eval(filter_list[2]) # dict_series[filter_list[1].strip().lower()] = dict_filter # logger.info("categoria {0}".format(item.from_channel)) fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO GUARDADO" else: message = "Error al guardar en disco" heading = "{0} [1]".format(item.show.strip(), idioma) platformtools.dialog_notification(heading, message)
def tojson(self, path=""): from core import filetools """ Create a JSON from the item, to save favorite files, download list, etc.... If a path is specified, it saves it in the specified path, if not, it returns the string json Applications: item.tojson(path="path\archivo\json.json") file.write(item.tojson()) @param path: path @type path: str """ if path: #open(path, "wb").write(json.dump(self.__dict__)) res = filetools.write(path, json.dump(self.__dict__)) else: return json.dump(self.__dict__)
def tojson(self, path=""): from core import filetools """ Crea un JSON a partir del item, para guardar archivos de favoritos, lista de descargas, etc... Si se especifica un path, te lo guarda en la ruta especificada, si no, devuelve la cadena json Usos: item.tojson(path="ruta\archivo\json.json") file.write(item.tojson()) @param path: ruta @type path: str """ if path: #open(path, "wb").write(json.dump(self.__dict__)) res = filetools.write(path, json.dump(self.__dict__)) else: return json.dump(self.__dict__)
def guardar_valores(item, dict_data_saved): """ Guarda los valores configurados en la ventana :param item: item :type item: Item :param dict_data_saved: diccionario con los datos salvados :type dict_data_saved: dict """ logger.info() # Aqui tienes q gestionar los datos obtenidos del cuadro de dialogo if item and dict_data_saved: logger.debug('item: {0}\ndatos: {1}'.format(item.tostring(), dict_data_saved)) # OBTENEMOS LOS DATOS DEL JSON if item.from_channel == "biblioteca": item.from_channel = item.contentChannel dict_series = get_tvshows(item.from_channel) tvshow = item.show.strip().lower() logger.info("Se actualiza los datos") list_quality = [] for _id, value in dict_data_saved.items(): if _id in item.list_calidad and value: list_quality.append(_id.lower()) lang_selected = item.list_idiomas[dict_data_saved[TAG_LANGUAGE]] dict_filter = { TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True), TAG_LANGUAGE: lang_selected, TAG_QUALITY_NOT_ALLOWED: list_quality } dict_series[tvshow] = dict_filter fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO GUARDADO" else: message = "Error al guardar en disco" heading = "{0} [{1}]".format(item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message)
def remove_channel(item): logger.info() import xbmc import xbmcgui path = filetools.join(config.get_data_path(), 'community_channels.json') community_json = open(path, "r") community_json = jsontools.load(community_json.read()) id = item.channel_id to_delete = community_json['channels'][id]['channel_name'] del community_json['channels'][id] res = filetools.write(path, jsontools.dump(community_json), silent=True) platformtools.dialog_notification('Alfa', '%s ha sido eliminado' % to_delete) platformtools.itemlist_refresh() return
def save(item, dict_data_saved): """ Guarda los valores configurados en la ventana @param item: item @type item: Item @param dict_data_saved: diccionario con los datos salvados @type dict_data_saved: dict """ logger.info() if item and dict_data_saved: logger.debug('item: %s\ndatos: %s' % (item.tostring(), dict_data_saved)) if item.from_channel == "biblioteca": item.from_channel = item.contentChannel dict_series = filetools.get_node_from_data_json(item.from_channel, TAG_TVSHOW_FILTER) tvshow = item.show.strip().lower() logger.info("Se actualiza los datos") list_quality = [] for _id, value in dict_data_saved.items(): if _id in item.list_quality and value: list_quality.append(_id.lower()) lang_selected = item.list_language[dict_data_saved[TAG_LANGUAGE]] dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True), TAG_LANGUAGE: lang_selected, TAG_QUALITY_ALLOWED: list_quality} dict_series[tvshow] = dict_filter fname, json_data = filetools.update_json_data(dict_series, item.from_channel, TAG_TVSHOW_FILTER) result = filetools.write(fname, json_data) sound = False if result: message = "FILTRO GUARDADO" else: message = "Error al guardar en disco" sound = True heading = "%s [%s]" % (item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message, sound=sound) if item.from_action in ["findvideos", "play"]: platformtools.itemlist_refresh()
def guardar_valores(item, dict_data_saved): """ Guarda los valores configurados en la ventana :param item: item :type item: Item :param dict_data_saved: diccionario con los datos salvados :type dict_data_saved: dict """ logger.info() # Aqui tienes q gestionar los datos obtenidos del cuadro de dialogo if item and dict_data_saved: logger.debug('item: {0}\ndatos: {1}'.format(item.tostring(), dict_data_saved)) # OBTENEMOS LOS DATOS DEL JSON if item.from_channel == "biblioteca": item.from_channel = item.contentChannel dict_series = get_tvshows(item.from_channel) tvshow = item.show.strip().lower() logger.info("Se actualiza los datos") list_quality = [] for _id, value in dict_data_saved.items(): if _id in item.list_calidad and value: list_quality.append(_id.lower()) lang_selected = item.list_idiomas[dict_data_saved[TAG_LANGUAGE]] dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True), TAG_LANGUAGE: lang_selected, TAG_QUALITY_NOT_ALLOWED: list_quality} dict_series[tvshow] = dict_filter fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO GUARDADO" else: message = "Error al guardar en disco" heading = "{0} [{1}]".format(item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message) if config.get_platform() == "mediaserver": platformtools.itemlist_refresh()
def add_channel(item): logger.info() import xbmc import xbmcgui channel_to_add = {} json_file = '' result = platformtools.dialog_select('Agregar un canal', ['Desde archivo local', 'Desde URL']) if result == -1: return if result==0: file_path = xbmcgui.Dialog().browseSingle(1, 'Alfa - (Comunidad)', 'files') try: channel_to_add['path'] = file_path json_file = jsontools.load(filetools.read(file_path)) channel_to_add['channel_name'] = json_file['channel_name'] if "poster" in json_file: channel_to_add['poster'] = json_file['poster'] except: pass elif result==1: url = platformtools.dialog_input("", 'Ingresa la URL del canal', False) try: channel_to_add['path'] = url json_file = jsontools.load(httptools.downloadpage(url).data) except: pass if len(json_file) == 0: return if "episodes_list" in json_file: platformtools.dialog_ok('Alfa', 'No es posible agregar este tipo de canal') return channel_to_add['channel_name'] = json_file['channel_name'] path = filetools.join(config.get_data_path(), 'community_channels.json') community_json = jsontools.load(filetools.read(path)) id = len(community_json['channels']) + 1 community_json['channels'][id]=(channel_to_add) res = filetools.write(path, jsontools.dump(community_json), silent=True) platformtools.dialog_notification('Alfa', '%s se ha agregado' % json_file['channel_name']) platformtools.itemlist_refresh() return
def search_for_unrar_in_error(download_paths, init=False): logger.info(download_paths) for torrent_client, path in download_paths: list_dir = filetools.listdir(path) for folder_w in list_dir: folder = filetools.join(path, folder_w) if filetools.isdir(folder): if not filetools.exists(filetools.join(folder, '_rar_control.json')): continue else: if not '_rar_control.json' in folder: continue rar_control = jsontools.load(filetools.read(filetools.join(folder, '_rar_control.json'))) rar_control['status'] += ': Recovery' if ('UnRARing' in rar_control['status'] or 'RECOVERY' in rar_control['status']) and not init: continue if 'UnRARing' in rar_control['status'] or 'ERROR' in rar_control['status']: rar_control['status'] = 'RECOVERY: ' + rar_control['status'] rar_control['download_path'] = folder rar_control['torr_client'] = torrent_client if 'ERROR' in rar_control['status'] or 'UnRARing' in rar_control['status'] \ or 'RECOVERY' in rar_control['status']: rar_control['error'] += 1 ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), jsontools.dump(rar_control)) logger.debug('%s, %s, %s, %s, %s, %s' % (rar_control['download_path'], \ rar_control['rar_names'][0], rar_control['password'], \ str(rar_control['error']), rar_control['error_msg'], rar_control['status'])) if ('ERROR' in rar_control['status'] and rar_control['error'] > 2) \ or ('UnRARing' in rar_control['status'] and rar_control['error'] > 3) \ or ('RECOVERY' in rar_control['status'] and rar_control['error'] > 3) \ or 'DONE' in rar_control['status']: continue if ret: try: threading.Thread(target=call_unrar, args=(rar_control,)).start() # Creamos un Thread independiente por UnRAR time.sleep(1) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, pasamos al siguiente logger.error(traceback.format_exc()) if not init: sys.exit(0)
def borrar(channel, show): logger.info() heading = "¿Está seguro que desea eliminar renumeración?" line1 = "Pulse 'Si' para eliminar la renumeración de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana " \ "para no hacer nada.".format(show.strip()) if platformtools.dialog_yesno(heading, line1) == 1: dict_series = get_tvshows(channel) dict_series.pop(show, None) fname, json_data = update_json_data(dict_series, channel) result = filetools.write(fname, json_data) if result: message = "FILTRO ELIMINADO" else: message = "Error al guardar en disco" heading = show.strip() platformtools.dialog_notification(heading, message)
def del_filter(item): """ elimina el filtro a través del menú contextual :param item: item :type item: item """ logger.info("[filtertools.py] del_filter") dict_series = get_filtered_tvshows(item.from_channel) dict_series.pop(item.show.lower().strip(), None) fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO ELIMINADO" else: message = "Error al guardar en disco" heading = "{0}".format(item.show.strip()) platformtools.dialog_notification(heading, message)
def save_from_context(item): """ Salva el filtro a través del menú contextual @param item: item @type item: item """ logger.info() dict_series = filetools.get_node_from_data_json(item.from_channel, TAG_TVSHOW_FILTER) tvshow = item.show.strip().lower() dict_filter = { TAG_NAME: item.show, TAG_ACTIVE: True, TAG_LANGUAGE: item.language, TAG_QUALITY_ALLOWED: [] } dict_series[tvshow] = dict_filter fname, json_data = filetools.update_json_data(dict_series, item.from_channel, TAG_TVSHOW_FILTER) result = filetools.write(fname, json_data) sound = False if result: message = "FILTRO GUARDADO" else: message = "Error al guardar en disco" sound = True heading = "%s [%s]" % (item.show.strip(), item.language) platformtools.dialog_notification(heading, message, sound=sound) if item.from_action in ["findvideos", "play"]: platformtools.itemlist_refresh()
def delete_from_context(item): """ Elimina el filtro a través del menú contextual @param item: item @type item: item """ logger.info() # venimos desde get_links y no se ha obtenido ningún resultado, en menu contextual y damos a borrar if item.to_channel != "": item.from_channel = item.to_channel dict_series = filetools.get_node_from_data_json(item.from_channel, TAG_TVSHOW_FILTER) tvshow = item.show.strip().lower() lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "") dict_series.pop(tvshow, None) fname, json_data = filetools.update_json_data(dict_series, item.from_channel, TAG_TVSHOW_FILTER) result = filetools.write(fname, json_data) sound = False if result: message = "FILTRO ELIMINADO" else: message = "Error al guardar en disco" sound = True heading = "%s [%s]" % (item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message, sound=sound) if item.from_action in ["findvideos", "play", "no_filter" ]: # 'no_filter' es el mismo caso que L#601 platformtools.itemlist_refresh()
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc() and item.contentType == 'episode': from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi( item, item.playcount) platformtools.itemlist_refresh()
def borrar_filtro(item): logger.info("[filtertools.py] borrar_filtro") if item: # OBTENEMOS LOS DATOS DEL JSON dict_series = get_filtered_tvshows(item.from_channel) tvshow = item.show.strip().lower() heading = "¿Está seguro que desea eliminar el filtro?" line1 = "Pulse 'Si' para eliminar el filtro de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana para " \ "no hacer nada.".format(item.show.strip()) if platformtools.dialog_yesno(heading, line1) == 1: lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "") dict_series.pop(tvshow, None) fname, json_data = update_json_data(dict_series, item.from_channel) result = filetools.write(fname, json_data) if result: message = "FILTRO ELIMINADO" else: message = "Error al guardar en disco" heading = "{0} [{1}]".format(item.show.strip(), lang_selected) platformtools.dialog_notification(heading, message)
def mark_content_as_watched(item): logger.info() #logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) if item.contentType == 'movie': name_file = os.path.splitext(filetools.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # it is verified that if all the episodes of a season are marked, tb the season is marked if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # We save the changes to item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow' and item.type != 'episode' : # Update entire series new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def mark_content_as_watched2(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.isfile(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) name_file = "" if item.contentType == 'movie' or item.contentType == 'tvshow': name_file = os.path.splitext(filetools.basename(item.nfo))[0] if name_file != 'tvshow' : it.library_playcounts.update({name_file: item.playcount}) if item.contentType == 'episode' or item.contentType == 'tvshow' or item.contentType == 'list' or name_file == 'tvshow': name_file = os.path.splitext(filetools.basename(item.strm_path))[0] num_season = name_file [0] item.__setattr__('contentType', 'episode') item.__setattr__('contentSeason', num_season) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # it is verified that if all the episodes of a season are marked, tb the season is marked if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # We save the changes to item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi(item , item.playcount)
def save_episodes(path, episodelist, serie, silent=False, overwrite=True): """ guarda en la ruta indicada todos los capitulos incluidos en la lista episodelist @type path: str @param path: ruta donde guardar los episodios @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @type serie: item @param serie: serie de la que se van a guardar los episodios @type silent: bool @param silent: establece si se muestra la notificación @param overwrite: permite sobreescribir los ficheros existentes @type overwrite: bool @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos """ logger.info() # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = next(filetools.walk(path)) ficheros = [filetools.join(path, f) for f in ficheros] nostrm_episodelist = [] for root, folders, files in filetools.walk(path): for file in files: season_episode = scrapertools.get_season_and_episode(file) if season_episode == "" or filetools.exists(filetools.join(path, "%s.strm" % season_episode)): continue nostrm_episodelist.append(season_episode) nostrm_episodelist = sorted(set(nostrm_episodelist)) # Silent es para no mostrar progreso (para videolibrary_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60064)) p_dialog.update(0, config.get_localized_string(60065)) channel_alt = generictools.verify_channel(serie.channel) #Preparamos para añadir las urls de emergencia emergency_urls_stat = config.get_setting("emergency_urls", channel_alt) #El canal quiere urls de emergencia? emergency_urls_succ = False channel = __import__('channels.%s' % channel_alt, fromlist=["channels.%s" % channel_alt]) if serie.torrent_caching_fail: #Si el proceso de conversión ha fallado, no se cachean emergency_urls_stat = 0 del serie.torrent_caching_fail new_episodelist = [] # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean tags = [] if config.get_setting("enable_filter", "videolibrary"): tags = [x.strip() for x in config.get_setting("filters", "videolibrary").lower().split(",")] for e in episodelist: headers = {} if e.headers: headers = e.headers if tags != [] and tags != None and any(tag in e.title.lower() for tag in tags): continue try: season_episode = scrapertools.get_season_and_episode(e.title) if not season_episode: continue # Si se ha marcado la opción de url de emergencia, se añade ésta a cada episodio después de haber ejecutado Findvideos del canal if e.emergency_urls and isinstance(e.emergency_urls, dict): del e.emergency_urls #Borramos trazas anteriores json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) #Path del .json del episodio if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode': #Guardamos urls de emergencia? if not silent: p_dialog.update(0, 'Cacheando enlaces y archivos .torrent...', e.title) #progress dialog if json_path in ficheros: #Si existe el .json sacamos de ahí las urls if overwrite: #pero solo si se se sobrescriben los .json json_epi = Item().fromjson(filetools.read(json_path)) #Leemos el .json if json_epi.emergency_urls: #si existen las urls de emergencia... e.emergency_urls = json_epi.emergency_urls #... las copiamos else: #y si no... e = emergency_urls(e, channel, json_path, headers=headers) #... las generamos else: e = emergency_urls(e, channel, json_path, headers=headers) #Si el episodio no existe, generamos las urls if e.emergency_urls: #Si ya tenemos urls... emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo elif emergency_urls_stat == 2 and e.contentType == 'episode': #Borramos urls de emergencia? if e.emergency_urls: del e.emergency_urls emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo elif emergency_urls_stat == 3 and e.contentType == 'episode': #Actualizamos urls de emergencia? if not silent: p_dialog.update(0, 'Cacheando enlaces y archivos .torrent...', e.title) #progress dialog e = emergency_urls(e, channel, json_path, headers=headers) #generamos las urls if e.emergency_urls: #Si ya tenemos urls... emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo if not e.infoLabels["tmdb_id"] or (serie.infoLabels["tmdb_id"] and e.infoLabels["tmdb_id"] != serie.infoLabels["tmdb_id"]): #en series multicanal, prevalece el infolabels... e.infoLabels = serie.infoLabels #... del canal actual y no el del original e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") if e.videolibray_emergency_urls: del e.videolibray_emergency_urls if e.channel_redir: del e.channel_redir #... y se borran las marcas de redirecciones new_episodelist.append(e) except: if e.contentType == 'episode': logger.error("No se ha podido guardar las urls de emergencia de %s en la videoteca" % e.contentTitle) logger.error(traceback.format_exc()) continue # No hay lista de episodios, no hay nada que guardar if not len(new_episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 # fix float porque la division se hace mal en python 2.x try: t = float(100) / len(new_episodelist) except: t = 0 last_season_episode = '' for i, e in enumerate(scraper.sort_episode_list(new_episodelist)): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), config.get_localized_string(60064), e.title) high_sea = e.contentSeason high_epi = e.contentEpisodeNumber if scrapertools.find_single_match(e.title, '[a|A][l|L]\s*(\d+)'): high_epi = int(scrapertools.find_single_match(e.title, 'al\s*(\d+)')) max_sea = e.infoLabels["number_of_seasons"] max_epi = 0 if e.infoLabels["number_of_seasons"] and (e.infoLabels["temporada_num_episodios"] or e.infoLabels["number_of_seasons"] == 1): if e.infoLabels["number_of_seasons"] == 1 and e.infoLabels["number_of_episodes"]: max_epi = e.infoLabels["number_of_episodes"] else: max_epi = e.infoLabels["temporada_num_episodios"] season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2)) strm_path = filetools.join(path, "%s.strm" % season_episode) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) if season_episode in nostrm_episodelist: logger.error('Error en la estructura de la Videoteca: Serie ' + serie.contentSerieName + ' ' + season_episode) continue strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros if not strm_exists: # Si no existe season_episode.strm añadirlo item_strm = Item(action='play_from_library', channel='videolibrary', strm_path=strm_path.replace(TVSHOWS_PATH, ""), infoLabels={}) item_strm.contentSeason = e.contentSeason item_strm.contentEpisodeNumber = e.contentEpisodeNumber item_strm.contentType = e.contentType item_strm.contentTitle = season_episode # FILTERTOOLS if item_strm.list_language: # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show if item_strm.library_filter_show == "": logger.error("Se ha producido un error al obtener el nombre de la serie a filtrar") # logger.debug("item_strm" + item_strm.tostring('\n')) # logger.debug("serie " + serie.tostring('\n')) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo = None if not nfo_exists and e.infoLabels["code"]: # Si no existe season_episode.nfo añadirlo scraper.find_and_set_infoLabels(e) head_nfo = scraper.get_nfo(e) item_nfo = e.clone(channel="videolibrary", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) if item_nfo.emergency_urls: del item_nfo.emergency_urls #Solo se mantiene en el .json del episodio nfo_exists = filetools.write(nfo_path, head_nfo + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos if nfo_exists and strm_exists: if not json_exists or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: head_nfo, item_nfo = read_nfo(nfo_path) # En series multicanal, prevalece el infolabels del canal actual y no el del original if not e.infoLabels["tmdb_id"] or (item_nfo.infoLabels["tmdb_id"] \ and e.infoLabels["tmdb_id"] != item_nfo.infoLabels["tmdb_id"]): e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists: logger.info("Insertado: %s" % json_path) insertados += 1 # Marcamos episodio como no visto news_in_playcounts[season_episode] = 0 # Marcamos la temporada como no vista news_in_playcounts["season %s" % e.contentSeason] = 0 # Marcamos la serie como no vista # logger.debug("serie " + serie.tostring('\n')) news_in_playcounts[serie.contentSerieName] = 0 else: logger.info("Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("Fallido: %s" % json_path) fallidos += 1 else: logger.info("Fallido: %s" % json_path) fallidos += 1 if not silent and p_dialog.iscanceled(): break #logger.debug('high_sea x high_epi: %sx%s' % (str(high_sea), str(high_epi))) #logger.debug('max_sea x max_epi: %sx%s' % (str(max_sea), str(max_epi))) if not silent: p_dialog.close() if news_in_playcounts or emergency_urls_succ or serie.infoLabels["status"] == "Ended" or serie.infoLabels["status"] == "Canceled": # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ... tvshow_path = filetools.join(path, "tvshow.nfo") try: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) #Si la operación de insertar/borrar urls de emergencia en los .jsons de los episodios ha tenido éxito, se marca el .nfo if emergency_urls_succ: if tvshow_item.emergency_urls and not isinstance(tvshow_item.emergency_urls, dict): del tvshow_item.emergency_urls if emergency_urls_stat in [1, 3]: #Operación de guardar/actualizar enlaces if not tvshow_item.emergency_urls: tvshow_item.emergency_urls = dict() if tvshow_item.library_urls.get(serie.channel, False): tvshow_item.emergency_urls.update({serie.channel: True}) elif emergency_urls_stat == 2: #Operación de Borrar enlaces if tvshow_item.emergency_urls and tvshow_item.emergency_urls.get(serie.channel, False): tvshow_item.emergency_urls.pop(serie.channel, None) #borramos la entrada del .nfo if tvshow_item.active == 30: tvshow_item.active = 1 if tvshow_item.infoLabels["tmdb_id"] == serie.infoLabels["tmdb_id"]: tvshow_item.infoLabels = serie.infoLabels tvshow_item.infoLabels["title"] = tvshow_item.infoLabels["tvshowtitle"] if max_sea == high_sea and max_epi == high_epi and (tvshow_item.infoLabels["status"] == "Ended" or tvshow_item.infoLabels["status"] == "Canceled") and insertados == 0 and fallidos == 0: tvshow_item.active = 0 # ... no la actualizaremos más logger.debug("%s [%s]: serie 'Terminada' o 'Cancelada'. Se desactiva la actualización periódica" % \ (serie.contentSerieName, serie.channel)) update_last = datetime.date.today() tvshow_item.update_last = update_last.strftime('%Y-%m-%d') update_next = datetime.date.today() + datetime.timedelta(days=int(tvshow_item.active)) tvshow_item.update_next = update_next.strftime('%Y-%m-%d') filetools.write(tvshow_path, head_nfo + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") logger.error("No se ha podido guardar las urls de emergencia de %s en la videoteca" % tvshow_item.contentSerieName) logger.error(traceback.format_exc()) fallidos = -1 else: # ... si ha sido correcto actualizamos la videoteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_videolibrary xbmc_videolibrary.update(FOLDER_TVSHOWS, filetools.basename(path)) if fallidos == len(episodelist): fallidos = -1 logger.debug("%s [%s]: insertados= %s, sobreescritos= %s, fallidos= %s" % (serie.contentSerieName, serie.channel, insertados, sobreescritos, fallidos)) return insertados, sobreescritos, fallidos
def save_tvshow(item, episodelist): """ guarda en la libreria de series la serie con todos los capitulos incluidos en la lista episodelist @type item: item @param item: item que representa la serie a guardar @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos o -1 si ha fallado toda la serie @rtype path: str @return: directorio serie """ logger.info() # logger.debug(item.tostring('\n')) path = "" # Si llegados a este punto no tenemos titulo o code, salimos if not (item.contentSerieName or item.infoLabels['code']) or not item.channel: logger.error("NO ENCONTRADO contentSerieName NI code: " + item.url) return 0, 0, -1, path # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la serie # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.error("NO ENCONTRADO EN SCRAPER O NO TIENE code: " + item.url) return 0, 0, -1, path _id = item.infoLabels['code'][0] if not item.infoLabels['code'][0] or item.infoLabels['code'][0] == 'None': if item.infoLabels['code'][1] and item.infoLabels['code'][1] != 'None': _id = item.infoLabels['code'][1] elif item.infoLabels['code'][2] and item.infoLabels['code'][2] != 'None': _id = item.infoLabels['code'][2] else: logger.error("NO ENCONTRADO EN SCRAPER O NO TIENE code: " + item.url + ' / ' + item.infoLabels['code']) return 0, 0, -1, path if config.get_setting("original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] elif item.infoLabels['tvshowtitle']: base_name = item.infoLabels['tvshowtitle'] elif item.infoLabels['title']: base_name = item.infoLabels['title'] else: base_name = item.contentSerieName if not PY3: base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8") else: base_name = filetools.validate_path(base_name.replace('/', '-')) if config.get_setting("lowerize_title", "videolibrary") == 0: base_name = base_name.lower() for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code != 'None' and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: path = filetools.join(TVSHOWS_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio serie: " + path) try: filetools.mkdir(path) except OSError as exception: if exception.errno != errno.EEXIST: raise tvshow_path = filetools.join(path, "tvshow.nfo") if not filetools.exists(tvshow_path): # Creamos tvshow.nfo, si no existe, con la head_nfo, info de la serie y marcas de episodios vistos logger.info("Creando tvshow.nfo: " + tvshow_path) head_nfo = scraper.get_nfo(item) item.infoLabels['mediatype'] = "tvshow" item.infoLabels['title'] = item.contentSerieName item_tvshow = Item(title=item.contentSerieName, channel="videolibrary", action="get_seasons", fanart=item.infoLabels['fanart'], thumbnail=item.infoLabels['thumbnail'], infoLabels=item.infoLabels, path=path.replace(TVSHOWS_PATH, "")) item_tvshow.library_playcounts = {} item_tvshow.library_urls = {item.channel: item.url} else: # Si existe tvshow.nfo, pero estamos añadiendo un nuevo canal actualizamos el listado de urls head_nfo, item_tvshow = read_nfo(tvshow_path) item_tvshow.channel = "videolibrary" item_tvshow.action = "get_seasons" item_tvshow.library_urls[item.channel] = item.url # FILTERTOOLS # si el canal tiene filtro de idiomas, añadimos el canal y el show if episodelist and "list_language" in episodelist[0]: # si ya hemos añadido un canal previamente con filtro, añadimos o actualizamos el canal y show if "library_filter_show" in item_tvshow: if item.title_from_channel: item_tvshow.library_filter_show[item.channel] = item.title_from_channel else: item_tvshow.library_filter_show[item.channel] = item.show # no habia ningún canal con filtro y lo generamos por primera vez else: if item.title_from_channel: item_tvshow.library_filter_show = {item.channel: item.title_from_channel} else: item_tvshow.library_filter_show = {item.channel: item.show} if item.channel != "downloads": item_tvshow.active = 1 # para que se actualice a diario cuando se llame a videolibrary_service filetools.write(tvshow_path, head_nfo + item_tvshow.tojson()) if not episodelist: # La lista de episodios esta vacia return 0, 0, 0, path # Guardar los episodios '''import time start_time = time.time()''' insertados, sobreescritos, fallidos = save_episodes(path, episodelist, item) '''msg = "Insertados: %d | Sobreescritos: %d | Fallidos: %d | Tiempo: %2.2f segundos" % \ (insertados, sobreescritos, fallidos, time.time() - start_time) logger.debug(msg)''' return insertados, sobreescritos, fallidos, path
def get_video_url(page_url, premium=False, user="", password="", video_password=""): logger.info("url=" + page_url) # Lo pide una vez data = httptools.downloadpage(page_url, cookies=False).data # Si salta aviso, se carga la pagina de comprobacion y luego la inicial if "You try to access this video with Kodi" in data: url_reload = scrapertools.find_single_match(data, 'try to reload the page.*?href="([^"]+)"') url_reload = "http://www.flashx.tv" + url_reload[1:] try: data = httptools.downloadpage(url_reload, cookies=False).data data = httptools.downloadpage(page_url, cookies=False).data except: pass matches = scrapertools.find_multiple_matches(data, "<script type='text/javascript'>(.*?)</script>") for n, m in enumerate(matches): if m.startswith("eval"): try: m = jsunpack.unpack(m) fake = (scrapertools.find_single_match(m, "(\w{40,})") == "") if fake: m = "" else: break except: m = "" match = m if "sources:[{file:" not in match: page_url = page_url.replace("playvid-", "") headers = {'Host': 'www.flashx.tv', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'Cookie': ''} data = httptools.downloadpage(page_url, headers=headers, replace_headers=True).data flashx_id = scrapertools.find_single_match(data, 'name="id" value="([^"]+)"') fname = scrapertools.find_single_match(data, 'name="fname" value="([^"]+)"') hash_f = scrapertools.find_single_match(data, 'name="hash" value="([^"]+)"') post = 'op=download1&usr_login=&id=%s&fname=%s&referer=&hash=%s&imhuman=Proceed+to+video' % ( flashx_id, urllib.quote(fname), hash_f) wait_time = scrapertools.find_single_match(data, "<span id='xxc2'>(\d+)") file_id = scrapertools.find_single_match(data, "'file_id', '([^']+)'") #coding_url = 'https://files.fx.fastcontentdelivery.com/jquery2.js?fx=%s' % base64.encodestring(file_id) #headers['Host'] = "files.fx.fastcontentdelivery.com" headers['Referer'] = "https://www.flashx.tv/" headers['Accept'] = "*/*" #coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data coding_url = 'https://www.flashx.tv/counter.cgi?fx=%s' % base64.encodestring(file_id) headers['Host'] = "www.flashx.tv" #coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data coding_url = 'https://www.flashx.tv/flashx.php?fxfx=3' headers['X-Requested-With'] = 'XMLHttpRequest' coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data try: time.sleep(int(wait_time) + 1) except: time.sleep(6) headers.pop('X-Requested-With') headers['Content-Type'] = 'application/x-www-form-urlencoded' data = httptools.downloadpage('https://www.flashx.tv/dl?playthis', post, headers, replace_headers=True).data matches = scrapertools.find_multiple_matches(data, "(eval\(function\(p,a,c,k.*?)\s+</script>") for match in matches: if match.startswith("eval"): try: match = jsunpack.unpack(match) fake = (scrapertools.find_single_match(match, "(\w{40,})") == "") if fake: match = "" else: break except: match = "" if not match: match = data # Extrae la URL # {file:"http://f11-play.flashx.tv/luq4gfc7gxixexzw6v4lhz4xqslgqmqku7gxjf4bk43u4qvwzsadrjsozxoa/video1.mp4"} video_urls = [] match = match.replace("\\","").replace('\"',"\'") media_urls = scrapertools.find_multiple_matches(match, "{src:'([^']+)'.*?,label:'([^']+)'") subtitle = "" for media_url, label in media_urls: if media_url.endswith(".srt") and label == "Spanish": try: from core import filetools data = scrapertools.downloadpage(media_url) subtitle = os.path.join(config.get_data_path(), 'sub_flashx.srt') filetools.write(subtitle, data) except: import traceback logger.info("Error al descargar el subtítulo: " + traceback.format_exc()) for media_url, label in media_urls: if not media_url.endswith("png") and not media_url.endswith(".srt"): video_urls.append(["." + media_url.rsplit('.', 1)[1] + " [flashx]", media_url, 0, subtitle]) for video_url in video_urls: logger.info("%s - %s" % (video_url[0], video_url[1])) return video_urls
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() try: if config.get_setting("updatelibrary", "biblioteca") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "biblioteca") heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i+1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar continue # obtenemos las fecha de actualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "biblioteca") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta(days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "biblioteca" serie.action = "get_temporadas" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "biblioteca") == 0: # Actualizamos la biblioteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(folder=filetools.basename(path)) else: update_when_finished = True if config.get_setting("search_new_content", "biblioteca") == 1 and update_when_finished: # Actualizamos la biblioteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update() p_dialog.close() else: logger.info("No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta") except Exception as ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
def save_library_episodes(path, episodelist, serie, silent=False, overwrite=True): """ guarda en la ruta indicada todos los capitulos incluidos en la lista episodelist @type path: str @param path: ruta donde guardar los episodios @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @type serie: item @param serie: serie de la que se van a guardar los episodios @type silent: bool @param silent: establece si se muestra la notificación @param overwrite: permite sobreescribir los ficheros existentes @type overwrite: bool @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos """ logger.info("pelisalacarta.platformcode.library save_library_episodes") # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("pelisalacarta.platformcode.library save_library_episodes No hay lista de episodios, " "salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo episodios...') p_dialog.update(0, 'Añadiendo episodio...') # fix float porque la division se hace mal en python 2.x t = float(100) / len(episodelist) for i, e in enumerate(episodelist): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Añadiendo episodio...', e.title) # Añade todos menos el que dice "Añadir esta serie..." o "Descargar esta serie..." if e.action == "add_serie_to_library" or e.action == "download_all_episodes": continue try: if e.channel == "descargas": season_episode = scrapertools.get_season_and_episode(e.contentTitle.lower()) else: season_episode = scrapertools.get_season_and_episode(e.title.lower()) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2)) except: continue strm_path = filetools.join(path, "%s.strm" % season_episode) if not filetools.exists(strm_path): # Si no existe season_episode.strm añadirlo item_strm = e.clone(action='play_from_library', channel='biblioteca', strm_path=strm_path.replace(TVSHOWS_PATH, ""), infoLabels={}) item_strm.contentSeason = e.contentSeason item_strm.contentEpisodeNumber = e.contentEpisodeNumber item_strm.contentType = e.contentType item_strm.contentTitle = season_episode # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente, if item_strm.list_idiomas: # si viene de library_service se obtiene del fichero tvshow.nfo, propiedad "library_filter_show" if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show.get(serie.channel, "") # si se ha agregado la serie lo obtenemos del titulo. else: item_strm.library_filter_show = serie.title if item_strm.library_filter_show == "": logger.error("Se ha producido un error al obtener el nombre de la serie a filtrar") # logger.debug("item_strm" + item_strm.tostring('\n')) # logger.debug("serie " + serie.tostring('\n')) filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) nfo_path = filetools.join(path, "%s.nfo" % season_episode) item_nfo = None if not filetools.exists(nfo_path) and e.infoLabels.get("tmdb_id"): # Si no existe season_episode.nfo añadirlo tmdb.find_and_set_infoLabels_tmdb(e) item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) url_scraper = "https://www.themoviedb.org/tv/%s/season/%s/episode/%s\n" % (item_nfo.infoLabels['tmdb_id'], item_nfo.contentSeason, item_nfo.contentEpisodeNumber) filetools.write(nfo_path, url_scraper + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) if filetools.exists(nfo_path) and filetools.exists(strm_path): nuevo = not filetools.exists(json_path) if nuevo or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: item_nfo = Item().fromjson(filetools.read(nfo_path, 1)) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if nuevo: logger.info("pelisalacarta.platformcode.library savelibrary Insertado: %s" % json_path) insertados += 1 # Marcamos episodio como no visto news_in_playcounts[season_episode] = 0 # Marcamos la temporada como no vista news_in_playcounts["season %s" % e.contentSeason] = 0 # Marcamos la serie como no vista # logger.debug("serie " + serie.tostring('\n')) news_in_playcounts[serie.contentTitle] = 0 else: logger.info("pelisalacarta.platformcode.library savelibrary Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("pelisalacarta.platformcode.library savelibrary Fallido: %s" % json_path) fallidos += 1 else: logger.info("pelisalacarta.platformcode.library savelibrary Fallido: %s" % json_path) fallidos += 1 if not silent and p_dialog.iscanceled(): break if not silent: p_dialog.close() if news_in_playcounts: # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ... tvshow_path = filetools.join(path, "tvshow.nfo") try: url_scraper = filetools.read(tvshow_path, 0, 1) tvshow_item = Item().fromjson(filetools.read(tvshow_path, 1)) tvshow_item.library_playcounts.update(news_in_playcounts) filetools.write(tvshow_path, url_scraper + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") fallidos = -1 # ... y actualizamos la biblioteca de Kodi if config.is_xbmc(): update(FOLDER_TVSHOWS, filetools.basename(path) + "/") if fallidos == len(episodelist): fallidos = -1 logger.debug("%s [%s]: insertados= %s, sobreescritos= %s, fallidos= %s" % (serie.contentSerieName, serie.channel, insertados, sobreescritos, fallidos)) return insertados, sobreescritos, fallidos
def sync_trakt_addon(path_folder): """ Actualiza los valores de episodios vistos si """ logger.info() # si existe el addon hacemos la busqueda if xbmc.getCondVisibility('System.HasAddon("script.trakt")'): # importamos dependencias paths = ["special://home/addons/script.module.dateutil/lib/", "special://home/addons/script.module.six/lib/", "special://home/addons/script.module.arrow/lib/", "special://home/addons/script.module.trakt/lib/", "special://home/addons/script.trakt/"] for path in paths: sys.path.append(xbmc.translatePath(path)) # se obtiene las series vistas try: from resources.lib.traktapi import traktAPI traktapi = traktAPI() except: return shows = traktapi.getShowsWatched({}) shows = list(shows.items()) # obtenemos el id de la serie para comparar _id = re.findall("\[(.*?)\]", path_folder, flags=re.DOTALL)[0] logger.debug("el id es %s" % _id) if "tt" in _id: type_id = "imdb" elif "tvdb_" in _id: _id = _id.strip("tvdb_") type_id = "tvdb" elif "tmdb_" in _id: type_id = "tmdb" _id = _id.strip("tmdb_") else: logger.error("No hay _id de la serie") return # obtenemos los valores de la serie from core import videolibrarytools tvshow_file = filetools.join(path_folder, "tvshow.nfo") head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) # buscamos en las series de trakt for show in shows: show_aux = show[1].to_dict() try: _id_trakt = show_aux['ids'].get(type_id, None) # logger.debug("ID ES %s" % _id_trakt) if _id_trakt: if _id == _id_trakt: logger.debug("ENCONTRADO!! %s" % show_aux) # creamos el diccionario de trakt para la serie encontrada con el valor que tiene "visto" dict_trakt_show = {} for idx_season, season in enumerate(show_aux['seasons']): for idx_episode, episode in enumerate(show_aux['seasons'][idx_season]['episodes']): sea_epi = "%sx%s" % (show_aux['seasons'][idx_season]['number'], str(show_aux['seasons'][idx_season]['episodes'][idx_episode][ 'number']).zfill(2)) dict_trakt_show[sea_epi] = show_aux['seasons'][idx_season]['episodes'][idx_episode][ 'watched'] logger.debug("dict_trakt_show %s " % dict_trakt_show) # obtenemos las keys que son episodios regex_epi = re.compile('\d+x\d+') keys_episodes = [key for key in serie.library_playcounts if regex_epi.match(key)] # obtenemos las keys que son temporadas keys_seasons = [key for key in serie.library_playcounts if 'season ' in key] # obtenemos los numeros de las keys temporadas seasons = [key.strip('season ') for key in keys_seasons] # marcamos los episodios vistos for k in keys_episodes: serie.library_playcounts[k] = dict_trakt_show.get(k, 0) for season in seasons: episodios_temporada = 0 episodios_vistos_temporada = 0 # obtenemos las keys de los episodios de una determinada temporada keys_season_episodes = [key for key in keys_episodes if key.startswith("%sx" % season)] for k in keys_season_episodes: episodios_temporada += 1 if serie.library_playcounts[k] > 0: episodios_vistos_temporada += 1 # se comprueba que si todos los episodios están vistos, se marque la temporada como vista if episodios_temporada == episodios_vistos_temporada: serie.library_playcounts.update({"season %s" % season: 1}) temporada = 0 temporada_vista = 0 for k in keys_seasons: temporada += 1 if serie.library_playcounts[k] > 0: temporada_vista += 1 # se comprueba que si todas las temporadas están vistas, se marque la serie como vista if temporada == temporada_vista: serie.library_playcounts.update({serie.title: 1}) logger.debug("los valores nuevos %s " % serie.library_playcounts) filetools.write(tvshow_file, head_nfo + serie.tojson()) break else: continue else: logger.error("no se ha podido obtener el id, trakt tiene: %s" % show_aux['ids']) except: import traceback logger.error(traceback.format_exc())
def save_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info() # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la videoteca..." # 2. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la peli # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code") return 0, 0, -1 _id = item.infoLabels['code'][0] # progress dialog p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60062)) if config.get_setting("original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] else: base_name = item.contentTitle if not PY3: base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8") else: base_name = filetools.validate_path(base_name.replace('/', '-')) if config.get_setting("lowerize_title", "videolibrary") == 0: base_name = base_name.lower() for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio pelicula:" + path) if not filetools.mkdir(path): logger.debug("No se ha podido crear el directorio") return 0, 0, -1 nfo_path = filetools.join(path, "%s [%s].nfo" % (base_name, _id)) strm_path = filetools.join(path, "%s.strm" % base_name) json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel.lower()))) nfo_exists = filetools.exists(nfo_path) strm_exists = filetools.exists(strm_path) json_exists = filetools.exists(json_path) if not nfo_exists: # Creamos .nfo si no existe logger.info("Creando .nfo: " + nfo_path) head_nfo = scraper.get_nfo(item) item_nfo = Item(title=item.contentTitle, channel="videolibrary", action='findvideos', library_playcounts={"%s [%s]" % (base_name, _id): 0}, infoLabels=item.infoLabels, library_urls={}) else: # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # Crear base_name.strm si no existe item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie', contentTitle=item.contentTitle) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "") # Solo si existen item_nfo y .strm continuamos if item_nfo and strm_exists: if json_exists: logger.info("El fichero existe. Se sobreescribe") sobreescritos += 1 else: insertados += 1 # Si se ha marcado la opción de url de emergencia, se añade ésta a la película después de haber ejecutado Findvideos del canal try: headers = {} if item.headers: headers = item.headers channel = generictools.verify_channel(item.channel) if config.get_setting("emergency_urls", channel) in [1, 3]: item = emergency_urls(item, None, json_path, headers=headers) if item_nfo.emergency_urls and not isinstance(item_nfo.emergency_urls, dict): del item_nfo.emergency_urls if not item_nfo.emergency_urls: item_nfo.emergency_urls = dict() item_nfo.emergency_urls.update({item.channel: True}) except: logger.error("No se ha podido guardar las urls de emergencia de %s en la videoteca" % item.contentTitle) logger.error(traceback.format_exc()) if filetools.write(json_path, item.tojson()): p_dialog.update(100, 'Añadiendo película...', item.contentTitle) item_nfo.library_urls[item.channel] = item.url if filetools.write(nfo_path, head_nfo + item_nfo.tojson()): # actualizamos la videoteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(FOLDER_MOVIES, filetools.basename(path) + "/") p_dialog.close() return insertados, sobreescritos, fallidos # Si llegamos a este punto es por q algo ha fallado logger.error("No se ha podido guardar %s en la videoteca" % item.contentTitle) p_dialog.update(100, config.get_localized_string(60063), item.contentTitle) p_dialog.close() return 0, 0, -1
def set_content(content_type, silent=False): """ Procedimiento para auto-configurar la biblioteca de kodi con los valores por defecto @type content_type: str ('CINE' o 'SERIES') @param content_type: tipo de contenido para configurar, series o peliculas """ if config.is_xbmc(): continuar = True msg_text = "" librarypath = config.get_setting("librarypath") if content_type == 'CINE': if not xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)'): if not silent: # Preguntar si queremos instalar metadata.themoviedb.org install = platformtools.dialog_yesno("The Movie Database", "TheMovieDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.themoviedb.org xbmc.executebuiltin('xbmc.installaddon(metadata.themoviedb.org)', True) logger.info("Instalado el Scraper de películas de TheMovieDB") except: pass continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)')) if not continuar: msg_text = "The Movie Database no instalado." else: # SERIES # Instalar The TVDB if not xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'): if not silent: # Preguntar si queremos instalar metadata.tvdb.com install = platformtools.dialog_yesno("The TVDB", "The TVDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.tvdb.com xbmc.executebuiltin('xbmc.installaddon(metadata.tvdb.com)', True) logger.info("Instalado el Scraper de series de The TVDB") except: pass continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)')) if not continuar: msg_text = "The TVDB no instalado." # Instalar TheMovieDB if continuar and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): continuar = False if not silent: # Preguntar si queremos instalar metadata.tvshows.themoviedb.org install = platformtools.dialog_yesno("The Movie Database", "TheMovieDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.tvshows.themoviedb.org # 1º Probar desde el repositorio ... xbmc.executebuiltin('xbmc.installaddon(metadata.tvshows.themoviedb.org)', True) if not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): # ...si no funciona descargar e instalar desde la web url = "http://mirrors.kodi.tv/addons/jarvis/metadata.tvshows.themoviedb.org/metadata.tvshows.themoviedb.org-1.3.1.zip" path_down = xbmc.translatePath( "special://home/addons/packages/metadata.tvshows.themoviedb.org-1.3.1.zip") path_unzip = xbmc.translatePath("special://home/addons/") header = ("User-Agent", "Kodi/15.2 (Windows NT 10.0; WOW64) App_Bitness/32 Version/15.2-Git:20151019-02e7013") from core import downloadtools from core import ziptools downloadtools.downloadfile(url, path_down, continuar=True, headers=[header]) unzipper = ziptools.ziptools() unzipper.extract(path_down, path_unzip) xbmc.executebuiltin('UpdateLocalAddons') strSettings = '<settings>\n' \ ' <setting id="fanart" value="true" />\n' \ ' <setting id="keeporiginaltitle" value="false" />\n' \ ' <setting id="language" value="it" />\n' \ '</settings>' path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml") tv_themoviedb_addon_path = filetools.dirname(path_settings) if not filetools.exists(tv_themoviedb_addon_path): filetools.mkdir(tv_themoviedb_addon_path) if filetools.write(path_settings,strSettings): continuar = True except: pass continuar = (install and continuar) if not continuar: msg_text = "The Movie Database non installato." idPath = 0 idParentPath = 0 strPath = "" if continuar: continuar = False # Buscamos el idPath sql = 'SELECT MAX(idPath) FROM path' nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idPath = records[0][0] + 1 sql_librarypath = librarypath if sql_librarypath.startswith("special://"): sql_librarypath = sql_librarypath.replace('/profile/', '/%/').replace('/home/userdata/', '/%/') sep = '/' elif sql_librarypath.startswith("smb://"): sep = '/' else: sep = os.sep if not sql_librarypath.endswith(sep): sql_librarypath += sep # Buscamos el idParentPath sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_librarypath nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idParentPath = records[0][0] librarypath = records[0][1][:-1] continuar = True else: # No existe librarypath en la BD: la insertamos sql_librarypath = librarypath if not sql_librarypath.endswith(sep): sql_librarypath += sep sql = 'INSERT INTO path (idPath, strPath, scanRecursive, useFolderNames, noUpdate, exclude) VALUES ' \ '(%s, "%s", 0, 0, 0, 0)' % (idPath, sql_librarypath) nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True idParentPath = idPath idPath += 1 else: msg_text = "Omesso di impostare LibraryPath in BD" if continuar: continuar = False # Fijamos strContent, strScraper, scanRecursive y strSettings if content_type == 'CINE': strContent = 'movies' strScraper = 'metadata.themoviedb.org' scanRecursive = 2147483647 strSettings = "<settings><setting id='RatingS' value='TMDb' /><setting id='certprefix' value='Rated ' />" \ "<setting id='fanart' value='true' /><setting id='keeporiginaltitle' value='false' />" \ "<setting id='language' value='it' /><setting id='tmdbcertcountry' value='us' />" \ "<setting id='trailer' value='true' /></settings>" strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per i film ?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting("folder_movies") + sep else: strContent = 'tvshows' strScraper = 'metadata.tvdb.com' scanRecursive = 0 strSettings = "<settings><setting id='RatingS' value='TheTVDB' />" \ "<setting id='absolutenumber' value='false' />" \ "<setting id='dvdorder' value='false' />" \ "<setting id='fallback' value='true' />" \ "<setting id='fanart' value='true' />" \ "<setting id='language' value='it' /></settings>" strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per le serie ?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting("folder_tvshows") + sep logger.info("%s: %s" % (content_type, strPath)) # Comprobamos si ya existe strPath en la BD para evitar duplicados sql = 'SELECT idPath FROM path where strPath="%s"' % strPath nun_records, records = execute_sql_kodi(sql) sql = "" if nun_records == 0: # Insertamos el scraper sql = 'INSERT INTO path (idPath, strPath, strContent, strScraper, scanRecursive, useFolderNames, ' \ 'strSettings, noUpdate, exclude, idParentPath) VALUES (%s, "%s", "%s", "%s", %s, 0, ' \ '"%s", 0, 0, %s)' % ( idPath, strPath, strContent, strScraper, scanRecursive, strSettings, idParentPath) else: if not silent: # Preguntar si queremos configurar themoviedb.org como opcion por defecto actualizar = platformtools.dialog_yesno("The TVDB", strActualizar) else: actualizar = True if actualizar: # Actualizamos el scraper idPath = records[0][0] sql = 'UPDATE path SET strContent="%s", strScraper="%s", scanRecursive=%s, strSettings="%s" ' \ 'WHERE idPath=%s' % (strContent, strScraper, scanRecursive, strSettings, idPath) if sql: nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True if not continuar: msg_text = "Omesso impostare LibraryPath in BD" if not continuar: heading = "Biblioteca %s no configurada" % content_type elif content_type == 'SERIES' and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): heading = "Biblioteca %s configurata" % content_type msg_text = "Riavviare Kodi per attuare le modifiche." else: heading = "Biblioteca %s configurata" % content_type msg_text = "Libreria di Kodi configurata correttamente." platformtools.dialog_notification(heading, msg_text, icon=1, time=10000) logger.info("%s: %s" % (heading,msg_text))
def get_video_url(page_url, premium=False, user="", password="", video_password=""): logger.info("url=" + page_url) # Lo pide una vez data = httptools.downloadpage(page_url, cookies=False).data # Si salta aviso, se carga la pagina de comprobacion y luego la inicial if "You try to access this video with Kodi" in data: url_reload = scrapertools.find_single_match(data, 'try to reload the page.*?href="([^"]+)"') url_reload = "http://www.flashx.tv" + url_reload[1:] try: data = httptools.downloadpage(url_reload, cookies=False).data data = httptools.downloadpage(page_url, cookies=False).data except: pass matches = scrapertools.find_multiple_matches(data, "<script type='text/javascript'>(.*?)</script>") for n, m in enumerate(matches): if m.startswith("eval"): try: m = jsunpack.unpack(m) fake = (scrapertools.find_single_match(m, "(\w{40,})") == "") if fake: m = "" else: break except: m = "" match = m if "sources:[{file:" not in match: page_url = page_url.replace("playvid-", "") headers = {'Host': 'www.flashx.tv', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'Cookie': ''} data = httptools.downloadpage(page_url, headers=headers, replace_headers=True).data flashx_id = scrapertools.find_single_match(data, 'name="id" value="([^"]+)"') fname = scrapertools.find_single_match(data, 'name="fname" value="([^"]+)"') hash_f = scrapertools.find_single_match(data, 'name="hash" value="([^"]+)"') post = 'op=download1&usr_login=&id=%s&fname=%s&referer=&hash=%s&imhuman=Proceed+to+video' % (flashx_id, urllib.quote(fname), hash_f) wait_time = scrapertools.find_single_match(data, "<span id='xxc2'>(\d+)") file_id = scrapertools.find_single_match(data, "'file_id', '([^']+)'") coding_url = 'https://files.fx.fastcontentdelivery.com/jquery2.js?fx=%s' % base64.encodestring(file_id) headers['Host'] = "files.fx.fastcontentdelivery.com" headers['Referer'] = "https://www.flashx.tv/" headers['Accept'] = "*/*" coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data coding_url = 'https://www.flashx.tv/counter.cgi?fx=%s' % base64.encodestring(file_id) headers['Host'] = "www.flashx.tv" coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data coding_url = 'https://www.flashx.tv/flashx.php?fxfx=3' headers['X-Requested-With'] = 'XMLHttpRequest' coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data try: time.sleep(int(wait_time) + 1) except: time.sleep(6) headers.pop('X-Requested-With') headers['Content-Type'] = 'application/x-www-form-urlencoded' data = httptools.downloadpage('https://www.flashx.tv/dl?playthis', post, headers, replace_headers=True).data matches = scrapertools.find_multiple_matches(data, "(eval\(function\(p,a,c,k.*?)\s+</script>") for match in matches: if match.startswith("eval"): try: match = jsunpack.unpack(match) fake = (scrapertools.find_single_match(match, "(\w{40,})") == "") if fake: match = "" else: break except: match = "" if not match: match = data # Extrae la URL # {file:"http://f11-play.flashx.tv/luq4gfc7gxixexzw6v4lhz4xqslgqmqku7gxjf4bk43u4qvwzsadrjsozxoa/video1.mp4"} video_urls = [] media_urls = scrapertools.find_multiple_matches(match, '\{file\:"([^"]+)",label:"([^"]+)"') subtitle = "" for media_url, label in media_urls: if media_url.endswith(".srt") and label == "Italian": try: from core import filetools data = scrapertools.downloadpage(media_url) subtitle = os.path.join(config.get_data_path(), 'sub_flashx.srt') filetools.write(subtitle, data) except: import traceback logger.info("streamondemand.servers.flashx Error al descargar el subtítulo: "+traceback.format_exc()) for media_url, label in media_urls: if not media_url.endswith("png") and not media_url.endswith(".srt"): video_urls.append(["." + media_url.rsplit('.', 1)[1] + " [flashx]", media_url, 0, subtitle]) for video_url in video_urls: logger.info("%s - %s" % (video_url[0], video_url[1])) return video_urls
def mark_content_as_watched_on_alfa(path): from channels import videolibrary from core import videolibrarytools """ marca toda la serie o película como vista o no vista en la Videoteca de Alfa basado en su estado en la Videoteca de Kodi @type str: path @param path: carpeta de contenido a marcar """ logger.info() #logger.debug("path: " + path) FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") VIDEOLIBRARY_PATH = config.get_videolibrary_config_path() if not VIDEOLIBRARY_PATH: return # Solo podemos marcar el contenido como vista en la BBDD de Kodi si la BBDD es local, # en caso de compartir BBDD esta funcionalidad no funcionara #if config.get_setting("db_mode", "videolibrary"): # return path2 = '' if "special://" in VIDEOLIBRARY_PATH: if FOLDER_TVSHOWS in path: path2 = re. sub(r'.*?%s' % FOLDER_TVSHOWS, VIDEOLIBRARY_PATH + "/" + FOLDER_TVSHOWS, path).replace("\\", "/") if FOLDER_MOVIES in path: path2 = re. sub(r'.*?%s' % FOLDER_MOVIES, VIDEOLIBRARY_PATH + "/" + FOLDER_MOVIES, path).replace("\\", "/") if "\\" in path: path = path.replace("/", "\\") head_nfo, item = videolibrarytools.read_nfo(path) #Leo el .nfo del contenido if not item: logger.error('.NFO no encontrado: ' + path) return if FOLDER_TVSHOWS in path: #Compruebo si es CINE o SERIE contentType = "episode_view" #Marco la tabla de BBDD de Kodi Video nfo_name = "tvshow.nfo" #Construyo el nombre del .nfo path1 = path.replace("\\\\", "\\").replace(nfo_name, '') #para la SQL solo necesito la carpeta if not path2: path2 = path1.replace("\\", "/") #Formato no Windows else: path2 = path2.replace(nfo_name, '') else: contentType = "movie_view" #Marco la tabla de BBDD de Kodi Video path1 = path.replace("\\\\", "\\") #Formato Windows if not path2: path2 = path1.replace("\\", "/") #Formato no Windows nfo_name = scrapertools.find_single_match(path2, '\]\/(.*?)$') #Construyo el nombre del .nfo path1 = path1.replace(nfo_name, '') #para la SQL solo necesito la carpeta path2 = path2.replace(nfo_name, '') #para la SQL solo necesito la carpeta path2 = filetools.remove_smb_credential(path2) #Si el archivo está en un servidor SMB, quitamos las credenciales #Ejecutmos la sentencia SQL sql = 'select strFileName, playCount from %s where (strPath like "%s" or strPath like "%s")' % (contentType, path1, path2) nun_records = 0 records = None nun_records, records = execute_sql_kodi(sql) #ejecución de la SQL if nun_records == 0: #hay error? logger.error("Error en la SQL: " + sql + ": 0 registros") return #salimos: o no está catalogado en Kodi, o hay un error en la SQL for title, playCount in records: #Ahora recorremos todos los registros obtenidos if contentType == "episode_view": title_plain = title.replace('.strm', '') #Si es Serie, quitamos el sufijo .strm else: title_plain = scrapertools.find_single_match(item.strm_path, '.(.*?\s\[.*?\])') #si es peli, quitamos el título if playCount is None or playCount == 0: #todavía no se ha visto, lo ponemos a 0 playCount_final = 0 elif playCount >= 1: playCount_final = 1 elif not PY3 and isinstance(title_plain, (str, unicode)): title_plain = title_plain.decode("utf-8").encode("utf-8") #Hacemos esto porque si no genera esto: u'title_plain' elif PY3 and isinstance(var, bytes): title_plain = title_plain.decode('utf-8') item.library_playcounts.update({title_plain: playCount_final}) #actualizamos el playCount del .nfo if item.infoLabels['mediatype'] == "tvshow": #Actualizamos los playCounts de temporadas y Serie for season in item.library_playcounts: if "season" in season: #buscamos las etiquetas "season" dentro de playCounts season_num = int(scrapertools.find_single_match(season, 'season (\d+)')) #salvamos el núm, de Temporada item = videolibrary.check_season_playcount(item, season_num) #llamamos al método que actualiza Temps. y Series filetools.write(path, head_nfo + item.tojson())
def update_json(path, params): item = Item().fromjson(filetools.read(path)) item.__dict__.update(params) filetools.write(path, item.tojson())
def add_sources(path): logger.info() from xml.dom import minidom SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml") if os.path.exists(SOURCES_PATH): xmldoc = minidom.parse(SOURCES_PATH) else: # Crear documento xmldoc = minidom.Document() nodo_sources = xmldoc.createElement("sources") for type in ['programs', 'video', 'music', 'picture', 'files']: nodo_type = xmldoc.createElement(type) element_default = xmldoc.createElement("default") element_default.setAttribute("pathversion", "1") nodo_type.appendChild(element_default) nodo_sources.appendChild(nodo_type) xmldoc.appendChild(nodo_sources) # Buscamos el nodo video nodo_video = xmldoc.childNodes[0].getElementsByTagName("video")[0] # Buscamos el path dentro de los nodos_path incluidos en el nodo_video nodos_paths = nodo_video.getElementsByTagName("path") list_path = [p.firstChild.data for p in nodos_paths] logger.debug(list_path) if path in list_path: logger.debug("La ruta %s ya esta en sources.xml" % path) return logger.debug("La ruta %s NO esta en sources.xml" % path) # Si llegamos aqui es por q el path no esta en sources.xml, asi q lo incluimos nodo_source = xmldoc.createElement("source") # Nodo <name> nodo_name = xmldoc.createElement("name") sep = os.sep if path.startswith("special://") or scrapertools.find_single_match(path, '(^\w+:\/\/)'): sep = "/" name = path if path.endswith(sep): name = path[:-1] nodo_name.appendChild(xmldoc.createTextNode(name.rsplit(sep)[-1])) nodo_source.appendChild(nodo_name) # Nodo <path> nodo_path = xmldoc.createElement("path") nodo_path.setAttribute("pathversion", "1") nodo_path.appendChild(xmldoc.createTextNode(path)) nodo_source.appendChild(nodo_path) # Nodo <allowsharing> nodo_allowsharing = xmldoc.createElement("allowsharing") nodo_allowsharing.appendChild(xmldoc.createTextNode('true')) nodo_source.appendChild(nodo_allowsharing) # Añadimos <source> a <video> nodo_video.appendChild(nodo_source) # Guardamos los cambios filetools.write(SOURCES_PATH, '\n'.join([x for x in xmldoc.toprettyxml().encode("utf-8").splitlines() if x.strip()]))
item_nfo = Item(title=item.contentTitle, channel="biblioteca", action='findvideos', library_playcounts={"%s [%s]" % (base_name, _id): 0}, infoLabels=item.infoLabels, library_urls={}) else: # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos url_scraper = filetools.read(nfo_path, 0, 1) item_nfo = Item().fromjson(filetools.read(nfo_path, 1)) strm_path = filetools.join(path, "%s.strm" % base_name) if not filetools.exists(strm_path): # Crear base_name.strm si no existe item_strm = item.clone(channel='biblioteca', action='play_from_library', strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie', infoLabels={'title': item.contentTitle}) filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "") # Solo si existen item_nfo y .strm continuamos if item_nfo and filetools.exists(strm_path): json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel)).lower()) if filetools.exists(json_path): logger.info("pelisalacarta.platformcode.library savelibrary el fichero existe. Se sobreescribe") sobreescritos += 1 else: insertados += 1 if filetools.write(json_path, item.tojson()): p_dialog.update(100, 'Añadiendo película...', item.contentTitle) item_nfo.library_urls[item.channel] = item.url