def mark_content_as_watched2(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) #logger.debug(it) 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 == 'list' or name_file == 'tvshow': # elif item.contentType == 'episode': 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) #logger.debug(name_file) else: name_file = item.contentTitle # logger.debug(name_file) 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) #logger.debug(it) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount #logger.debug(item.playcount) # if item.contentType == 'episodesss': # Actualizar toda la serie #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) # logger.debug(item) platformtools.itemlist_refresh()
def marshal_check(): try: marshal_modules = ['lib/alfaresolver_py3', 'core/proxytools_py3'] for module in marshal_modules: path = filetools.join(ADDON_PATH, filetools.dirname(module)) path_list = filetools.listdir(path) library = filetools.dirname(module).rstrip('/') module_name = filetools.basename(module) for alt_module in path_list: if module_name not in alt_module: continue if alt_module == module_name + '.py': continue try: alt_module_path = '%s.%s' % (library, alt_module.rstrip('.py')) spec = __import__(alt_module_path, None, None, [alt_module_path]) if not spec: raise except Exception as e: logger.info('marshal_check ERROR in %s: %s' % (alt_module, str(e)), force=True) continue filetools.copy(filetools.join(path, alt_module), filetools.join(path, module_name + '.py'), silent=True) logger.info('marshal_check FOUND: %s' % alt_module, force=True) break else: logger.info('marshal_check NOT FOUND: %s.py' % module_name, force=True) except: logger.error(traceback.format_exc(1))
def move_to_libray(item): # Copiamos el archivo a la biblioteca filetools.move( filetools.join(config.get_setting("downloadpath"), item.downloadFilename), filetools.join(config.get_library_path(), filetools.basename(item.downloadFilename)))
def mainlist_listas(item): logger.info() itemlist = [] item.category = 'Listas' current_dbname = trackingtools.get_current_dbname() tracking_path = trackingtools.get_tracking_path() import glob path = filetools.join(tracking_path, '*.sqlite') for fichero in glob.glob(path): lista = filetools.basename(fichero) nombre = lista.replace('.sqlite', '') titulo = nombre if nombre != current_dbname else '[COLOR gold]%s[/COLOR] [lista activa]' % nombre context = [ {'title': 'Gestionar lista', 'channel': item.channel, 'action': 'acciones_lista', 'lista': lista} ] # ídem que intro pero por si se accede al menú contextual itemlist.append(item.clone(action='acciones_lista', lista=lista, title=titulo, folder=False, context=context)) plot = 'Puedes crear varias listas para guardar películas y series. Por ejemplo una infantil, otras temáticas, otras para cada usuario, etc.' plot += ' Desde el menú contextual de cada película o serie tienes la opción de mover o copiar a otras listas.' itemlist.append(item.clone(action='crear_lista', title='Crear nueva lista ...', folder=False, plot=plot, thumbnail=config.get_thumb('booklet'))) plot = 'Si tienes alguna lista en otros dispositivos de tu red puedes copiarla a este.' plot += ' Para poder hacerlo necesitas haber añadido tu dispositivo remoto como fuente desde Kodi y tener acceso a la carpeta dónde tengas las listas.' itemlist.append(item.clone(action='copiar_lista', title='Copiar de otro dispositivo ...', folder=False, plot=plot, thumbnail=config.get_thumb('computer'))) return itemlist
def extract(self, file, dir, folder_to_extract="", overwrite_question=False, backup=False): logger.info("file= %s" % file) logger.info("dir= %s" % dir) if not dir.endswith(':') and not filetools.exists(dir): filetools.mkdir(dir) zf = zipfile.ZipFile(filetools.file_open(file, vfs=False)) if not folder_to_extract: self._createstructure(file, dir) num_files = len(zf.namelist()) for nameo in zf.namelist(): name = nameo.replace(':', '_').replace('<', '_').replace('>', '_').replace('|', '_').replace('"', '_').replace('?', '_').replace('*', '_') logger.info("name=%s" % nameo) if not name.endswith('/'): logger.info("it's not a directory") try: (path, filename) = filetools.split(filetools.join(dir, name)) logger.info("path=%s" % path) logger.info("name=%s" % name) if folder_to_extract: if path != filetools.join(dir, folder_to_extract): break else: filetools.mkdir(path) except: pass if folder_to_extract: outfilename = filetools.join(dir, filename) else: outfilename = filetools.join(dir, name) logger.info("outfilename=%s" % outfilename) try: if filetools.exists(outfilename) and overwrite_question: from platformcode import platformtools dyesno = platformtools.dialog_yesno("File already exists "," File %s to unzip already exists, do you want to overwrite it?" % filetools.basename(outfilename)) if not dyesno: break if backup: import time hora_folder = "Backup [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), 'backups', hora_folder, folder_to_extract) if not filetools.exists(backup): filetools.mkdir(backup) filetools.copy(outfilename, filetools.join(backup, filetools.basename(outfilename))) if not filetools.write(outfilename, zf.read(nameo), silent=True, vfs=VFS): #TRUNCA en FINAL en Kodi 19 con VFS logger.error("File error " + nameo) except: import traceback logger.error(traceback.format_exc()) logger.error("File error " + nameo) try: zf.close() except: logger.info("Error closing .zip " + file)
def peliculas(item): logger.info() itemlist = [] for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): for f in ficheros: if f.endswith(".nfo"): nfo_path = filetools.join(raiz, f) head_nfo, new_item = library.read_nfo(nfo_path) new_item.nfo = nfo_path new_item.path = raiz new_item.thumbnail = new_item.contentThumbnail new_item.text_color = "blue" if not filetools.exists(filetools.join(new_item.path, filetools.basename(new_item.strm_path))): # Si se ha eliminado el strm desde la bilbioteca de kodi, no mostrarlo continue # Menu contextual: Marcar como visto/no visto visto = new_item.library_playcounts.get(os.path.splitext(f)[0], 0) new_item.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Segna film come non visto" contador = 0 else: texto_visto = "Segna film come visto" contador = 1 # Menu contextual: Eliminar serie/canal num_canales = len(new_item.library_urls) if "descargas" in new_item.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Elimina film/canale" multicanal = True else: texto_eliminar = "Elimina questo film" multicanal = False new_item.context = [{"title": texto_visto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": contador}, {"title": texto_eliminar, "action": "eliminar", "channel": "biblioteca", "multicanal": multicanal}] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "biblioteca"}] #logger.debug("new_item: " + new_item.tostring('\n')) itemlist.append(new_item) return sorted(itemlist, key=lambda it: it.title.lower())
def __get_download_filename__(self): # Obtenemos nombre de archivo y extension if "filename" in self.response_headers.get( "content-disposition", "") and "attachment" in self.response_headers.get( "content-disposition", ""): cd_filename, cd_ext = os.path.splitext( urllib.unquote_plus( re.compile( "attachment; filename ?= ?[\"|']?([^\"']+)[\"|']?"). match(self.response_headers.get( "content-disposition")).group(1))) elif "filename" in self.response_headers.get( "content-disposition", "") and "inline" in self.response_headers.get( "content-disposition", ""): cd_filename, cd_ext = os.path.splitext( urllib.unquote_plus( re.compile( "inline; filename ?= ?[\"|']?([^\"']+)[\"|']?").match( self.response_headers.get( "content-disposition")).group(1))) else: cd_filename, cd_ext = "", "" url_filename, url_ext = os.path.splitext( urllib.unquote_plus( filetools.basename(urlparse.urlparse(self.url)[2]))) if self.response_headers.get( "content-type", "application/octet-stream") <> "application/octet-stream": mime_ext = mimetypes.guess_extension( self.response_headers.get("content-type")) else: mime_ext = "" # Seleccionamos el nombre mas adecuado if cd_filename: self.remote_filename = cd_filename if not self._filename: self._filename = cd_filename elif url_filename: self.remote_filename = url_filename if not self._filename: self._filename = url_filename # Seleccionamos la extension mas adecuada if cd_ext: if not cd_ext in self._filename: self._filename += cd_ext if self.remote_filename: self.remote_filename += cd_ext elif mime_ext: if not mime_ext in self._filename: self._filename += mime_ext if self.remote_filename: self.remote_filename += mime_ext elif url_ext: if not url_ext in self._filename: self._filename += url_ext if self.remote_filename: self.remote_filename += url_ext
def __get_download_filename__(self): # We get file name and extension if "filename" in self.response_headers.get( "content-disposition", "") and "attachment" in self.response_headers.get( "content-disposition", ""): cd_filename, cd_ext = os.path.splitext( urllib.parse.unquote_plus( re.compile( "attachment; filename ?= ?[\"|']?([^\"']+)[\"|']?"). match(self.response_headers.get( "content-disposition")).group(1))) elif "filename" in self.response_headers.get( "content-disposition", "") and "inline" in self.response_headers.get( "content-disposition", ""): cd_filename, cd_ext = os.path.splitext( urllib.parse.unquote_plus( re.compile( "inline; filename ?= ?[\"|']?([^\"']+)[\"|']?").match( self.response_headers.get( "content-disposition")).group(1))) else: cd_filename, cd_ext = "", "" url_filename, url_ext = os.path.splitext( urllib.parse.unquote_plus( filetools.basename(urllib.parse.urlparse(self.url)[2]))) if self.response_headers.get( "content-type", "application/octet-stream") != "application/octet-stream": mime_ext = mimetypes.guess_extension( self.response_headers.get("content-type")) else: mime_ext = "" # We select the most suitable name if cd_filename: self.remote_filename = cd_filename if not self._filename: self._filename = cd_filename elif url_filename: self.remote_filename = url_filename if not self._filename: self._filename = url_filename # We select the most suitable extension if cd_ext: if not cd_ext in self._filename: self._filename += cd_ext if self.remote_filename: self.remote_filename += cd_ext elif mime_ext: if not mime_ext in self._filename: self._filename += mime_ext if self.remote_filename: self.remote_filename += mime_ext elif url_ext: if not url_ext in self._filename: self._filename += url_ext if self.remote_filename: self.remote_filename += url_ext
def peliculas(item): logger.info() itemlist = [] for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): for f in ficheros: if f.endswith(".nfo"): nfo_path = filetools.join(raiz, f) head_nfo, new_item = library.read_nfo(nfo_path) new_item.nfo = nfo_path new_item.path = raiz new_item.thumbnail = new_item.contentThumbnail new_item.text_color = "blue" if not filetools.exists(filetools.join(new_item.path, filetools.basename(new_item.strm_path))): # Si se ha eliminado el strm desde la bilbioteca de kodi, no mostrarlo continue # Menu contextual: Marcar como visto/no visto visto = new_item.library_playcounts.get(os.path.splitext(f)[0], 0) new_item.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Segna film come non visto" contador = 0 else: texto_visto = "Segna film come visto" contador = 1 # Menu contextual: Eliminar serie/canal num_canales = len(new_item.library_urls) if "descargas" in new_item.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Elimina film/canale" multicanal = True else: texto_eliminar = "Elimina questo film" multicanal = False new_item.context = [{"title": texto_visto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": contador}, {"title": texto_eliminar, "action": "eliminar", "channel": "biblioteca", "multicanal": multicanal}] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "biblioteca"}] # logger.debug("new_item: " + new_item.tostring('\n')) itemlist.append(new_item) return sorted(itemlist, key=lambda it: it.title.lower())
def mark_season_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) # Obtener el diccionario de episodios marcados f = filetools.join(item.path, 'tvshow.nfo') head_nfo, it = videolibrarytools.read_nfo(f) 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(filetools.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, head_nfo + it.tojson()) item.infoLabels['playcount'] = item.playcount if config.is_xbmc(): # Actualizamos la BBDD de Kodi from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_season_as_watched_on_kodi( item, item.playcount) platformtools.itemlist_refresh()
def download_from_url(url, item): logger.info("Intentando descargar: %s" % (url)) if url.lower().endswith(".m3u8") or url.lower().startswith("rtmp"): save_server_statistics(item.server, 0, False) return {"downloadStatus": STATUS_CODES.error} # Obtenemos la ruta de descarga y el nombre del archivo item.downloadFilename = item.downloadFilename.replace('/','-') download_path = filetools.dirname(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) file_name = filetools.basename(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) # Creamos la carpeta si no existe if not filetools.exists(download_path): filetools.mkdir(download_path) # Lanzamos la descarga d = Downloader(url, download_path, file_name, max_connections=1 + int(config.get_setting("max_connections", "downloads")), block_size=2 ** (17 + int(config.get_setting("block_size", "downloads"))), part_size=2 ** (20 + int(config.get_setting("part_size", "downloads"))), max_buffer=2 * int(config.get_setting("max_buffer", "downloads"))) d.start_dialog(config.get_localized_string(60332)) # Descarga detenida. Obtenemos el estado: # Se ha producido un error en la descarga if d.state == d.states.error: logger.info("Error al intentar descargar %s" % (url)) status = STATUS_CODES.error # La descarga se ha detenifdo elif d.state == d.states.stopped: logger.info("Descarga detenida") status = STATUS_CODES.canceled # La descarga ha finalizado elif d.state == d.states.completed: logger.info("Descargado correctamente") status = STATUS_CODES.completed if item.downloadSize and item.downloadSize != d.size[0]: status = STATUS_CODES.error save_server_statistics(item.server, d.speed[0], d.state != d.states.error) dir = os.path.dirname(item.downloadFilename) file = filetools.join(dir, d.filename) if status == STATUS_CODES.completed: move_to_libray(item.clone(downloadFilename=file)) return {"downloadUrl": d.download_url, "downloadStatus": status, "downloadSize": d.size[0], "downloadProgress": d.progress, "downloadCompleted": d.downloaded[0], "downloadFilename": file}
def update_serie(item): logger.info() #logger.debug("item:\n" + item.tostring('\n')) heading = 'Actualizando serie....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, heading, item.contentSerieName) import library_service if library_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): library.update(folder=filetools.basename(item.path)) p_dialog.close()
def mark_season_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) # Get dictionary of marked episodes f = filetools.join(item.path, 'tvshow.nfo') head_nfo, it = videolibrarytools.read_nfo(f) if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} # We get the archives of the episodes raiz, carpetas_series, ficheros = next(filetools.walk(item.path)) # We mark each of the episodes found this season episodios_marcados = 0 for i in ficheros: if i.endswith(".strm"): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # The file does not include the season and episode number continue season, episode = season_episode.split("x") if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason): name_file = os.path.splitext(filetools.basename(i))[0] it.library_playcounts[name_file] = item.playcount episodios_marcados += 1 if episodios_marcados: if int(item.contentSeason) == -1: # We add all seasons to the dictionary item.library_playcounts for k in list(it.library_playcounts.keys()): if k.startswith("season"): it.library_playcounts[k] = item.playcount else: # Add season to dictionary item.library_playcounts it.library_playcounts["season %s" % item.contentSeason] = item.playcount # it is verified that if all the seasons are seen, the series is marked as view it = check_tvshow_playcount(it, item.contentSeason) # We save the changes to tvshow.nfo filetools.write(f, head_nfo + it.tojson()) item.infoLabels['playcount'] = item.playcount if config.is_xbmc(): # We update the Kodi database from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_season_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def update_serie(item): logger.info() #logger.debug("item:\n" + item.tostring('\n')) heading = 'Aggiornamento serie....' p_dialog = platformtools.dialog_progress_bg('streamondemand', heading) p_dialog.update(0, heading, item.contentSerieName) import library_service if library_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(folder=filetools.basename(item.path)) p_dialog.close()
def update_serie(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) heading = 'Aggiornamento serie....' p_dialog = platformtools.dialog_progress_bg('streamondemand', heading) p_dialog.update(0, heading, item.contentSerieName) import library_service if library_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(folder=filetools.basename(item.path)) p_dialog.close()
def update_tvshow(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) heading = 'Actualizando serie....' p_dialog = platformtools.dialog_progress_bg('alfa', heading) p_dialog.update(0, heading, item.contentSerieName) import videolibrary_service if videolibrary_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(item.path)) p_dialog.close()
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 copiar_lista(item): logger.info() import xbmcgui origen = xbmcgui.Dialog().browseSingle(1, 'Selecciona el fichero .sqlite a copiar', 'files', '.sqlite', False, False, '') # 1:ShowAndGetFile if origen is None or origen == '': return False lista_origen = filetools.basename(origen) destino = filetools.join(trackingtools.get_tracking_path(), lista_origen) if filetools.exists(destino): lista_origen = lista_origen.replace('.sqlite', '') + '-' + datetime.now().strftime('%Y%m%d-%H%M%S') + '.sqlite' destino = filetools.join(trackingtools.get_tracking_path(), lista_origen) platformtools.dialog_ok(config.__addon_name, 'Ya existe una lista con este nombre, se le añade un sufijo para diferenciarla.', lista_origen) if not filetools.copy(origen, destino, silent=False): platformtools.dialog_ok(config.__addon_name, 'Error, no se ha podido copiar la lista!', origen, destino) return False platformtools.itemlist_refresh() return True
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}) # 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' and item.type != 'episode': # 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 update_tvshow(item): logger.info() # 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 videolibrary_service if videolibrary_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(item.path)) p_dialog.close() for channel, url in list(item.library_urls.items()): channel_f = generictools.verify_channel(channel) if config.get_setting('auto_download_new', channel_f): from channels import downloads downloads.download_auto(item) break
def __get_download_filename__(self): #Obtenemos nombre de archivo y extension if "filename" in self.response_headers.get("content-disposition","") and "attachment" in self.response_headers.get("content-disposition",""): cd_filename, cd_ext = os.path.splitext(urllib.unquote_plus(re.compile("attachment; filename ?= ?[\"|']?([^\"']+)[\"|']?").match(self.response_headers.get("content-disposition")).group(1))) if "filename" in self.response_headers.get("content-disposition","") and "inline" in self.response_headers.get("content-disposition",""): cd_filename, cd_ext = os.path.splitext(urllib.unquote_plus(re.compile("inline; filename ?= ?[\"|']?([^\"']+)[\"|']?").match(self.response_headers.get("content-disposition")).group(1))) else: cd_filename, cd_ext = "","" url_filename, url_ext = os.path.splitext(urllib.unquote_plus(filetools.basename(urlparse.urlparse(self.url)[2]))) if self.response_headers.get("content-type","application/octet-stream") <> "application/octet-stream": mime_ext = mimetypes.guess_extension(self.response_headers.get("content-type")) else: mime_ext = "" #Seleccionamos el nombre mas adecuado if cd_filename: self.remote_filename = cd_filename if not self._filename: self._filename = cd_filename elif url_filename: self.remote_filename = url_filename if not self._filename: self._filename = url_filename #Seleccionamos la extension mas adecuada if cd_ext: if not cd_ext in self._filename: self._filename += cd_ext if self.remote_filename: self.remote_filename += cd_ext elif mime_ext: if not mime_ext in self._filename: self._filename += mime_ext if self.remote_filename: self.remote_filename += mime_ext elif url_ext: if not url_ext in self._filename: self._filename += url_ext if self.remote_filename: self.remote_filename += url_ext
def update_tvshow(item): logger.info() # 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 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 get_results(nfo_path, root, Type, local=False): dead_list = [] zombie_list = [] value = 0 if Type == 'movie': folder = "folder_movies" else: folder = "folder_tvshows" if filetools.exists(nfo_path): # We synchronize the episodes seen from the Kodi video library with that of KoD from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kod(nfo_path) head_nfo, item = videolibrarytools.read_nfo(nfo_path) # If you have not read the .nfo well, we will proceed to the next if not item: logger.error('.nfo erroneous in ' + str(nfo_path)) return Item(), 0 if len(item.library_urls) > 1: multichannel = True else: multichannel = False # Verify the existence of the channels. If the channel does not exist, ask yourself if you want to remove the links from that channel. for canal in item.library_urls: try: if canal in ['community', 'downloads']: channel_verify = __import__('specials.%s' % canal, fromlist=["channels.%s" % canal]) else: channel_verify = __import__('channels.%s' % canal, fromlist=["channels.%s" % canal]) logger.debug('Channel %s seems correct' % channel_verify) except: dead_item = Item(multichannel=multichannel, contentType='tvshow', dead=canal, path=filetools.split(nfo_path)[0], nfo=nfo_path, library_urls=item.library_urls, infoLabels={'title': item.contentTitle}) if canal not in dead_list and canal not in zombie_list: confirm = platformtools.dialog_yesno(config.get_localized_string(30131), config.get_localized_string(30132) % canal.upper() + '\n' + config.get_localized_string(30133)) elif canal in zombie_list: confirm = False else: confirm = True if confirm: delete(dead_item) if canal not in dead_list: dead_list.append(canal) continue else: if canal not in zombie_list: zombie_list.append(canal) if len(dead_list) > 0: for canal in dead_list: if canal in item.library_urls: del item.library_urls[canal] # continue loading the elements of the video library if Type == 'movie': item.path = filetools.split(nfo_path)[0] item.nfo = nfo_path sep = '/' if '/' in nfo_path else '\\' item.extra = filetools.join(config.get_setting("videolibrarypath"), config.get_setting(folder), item.path.split(sep)[-1]) strm_path = item.strm_path.replace("\\", "/").rstrip("/") if not item.thumbnail: item.thumbnail = item.infoLabels['thumbnail'] if '/' in item.path: item.strm_path = strm_path # If strm has been removed from kodi library, don't show it if not filetools.exists(filetools.join(item.path, filetools.basename(strm_path))) and not local: return Item(), 0 # Contextual menu: Mark as seen / not seen visto = item.library_playcounts.get(item.path.split(sep)[0], 0) item.infoLabels["playcount"] = visto if visto > 0: seen_text = config.get_localized_string(60016) counter = 0 else: seen_text = config.get_localized_string(60017) counter = 1 # Context menu: Delete series / channel channels_num = len(item.library_urls) if "downloads" in item.library_urls: channels_num -= 1 if channels_num > 1: delete_text = config.get_localized_string(60018) else: delete_text = config.get_localized_string(60019) item.context = [{"title": seen_text, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": counter}, {"title": delete_text, "action": "delete", "channel": "videolibrary", "multichannel": multichannel}] else: # Sometimes it gives random errors, for not finding the .nfo. Probably timing issues try: item.title = item.contentTitle item.path = filetools.split(nfo_path)[0] item.nfo = nfo_path sep = '/' if '/' in nfo_path else '\\' item.extra = filetools.join(config.get_setting("videolibrarypath"), config.get_setting(folder), item.path.split(sep)[-1]) # Contextual menu: Mark as seen / not seen visto = item.library_playcounts.get(item.contentTitle, 0) item.infoLabels["playcount"] = visto logger.info('item\n' + str(item)) if visto > 0: seen_text = config.get_localized_string(60020) counter = 0 else: seen_text = config.get_localized_string(60021) counter = 1 except: logger.error('Not find: ' + str(nfo_path)) logger.error(traceback.format_exc()) return Item(), 0 # Context menu: Automatically search for new episodes or not if item.active and int(item.active) > 0: update_text = config.get_localized_string(60022) value = 0 else: update_text = config.get_localized_string(60023) value = 1 item.title += " [B]" + u"\u2022" + "[/B]" # Context menu: Delete series / channel channels_num = len(item.library_urls) if "downloads" in item.library_urls: channels_num -= 1 if channels_num > 1: delete_text = config.get_localized_string(60024) else: delete_text = config.get_localized_string(60025) item.context = [{"title": seen_text, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": counter}, {"title": update_text, "action": "mark_tvshow_as_updatable", "channel": "videolibrary", "active": value}, {"title": delete_text, "action": "delete", "channel": "videolibrary", "multichannel": multichannel}, {"title": config.get_localized_string(70269), "action": "update_tvshow", "channel": "videolibrary"}] if item.local_episodes_path == "": item.context.append({"title": config.get_localized_string(80048), "action": "add_local_episodes", "channel": "videolibrary"}) else: item.context.append({"title": config.get_localized_string(80049), "action": "remove_local_episodes", "channel": "videolibrary"}) else: item = Item() return item, value
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 if filetools.write(nfo_path, url_scraper + item_nfo.tojson()): # actualizamos la biblioteca de Kodi con la pelicula if config.is_xbmc(): 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 biblioteca" % item.contentTitle) p_dialog.update(100, 'Fallo al añadir...', item.contentTitle) p_dialog.close() # TODO habria q poner otra advertencia? return 0, 0, -1 def save_library_tvshow(item, episodelist): """ guarda en la libreria de series la serie con todos los capitulos incluidos en la lista episodelist
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 move_to_libray(item): # Copiamos el archivo a la biblioteca filetools.move(filetools.join(config.get_setting("downloadpath"), item.downloadFilename), filetools.join(config.get_library_path(), filetools.basename(item.downloadFilename)))
def save_library_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 biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: 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 # TODO configurar para segun el scraper se llamara a uno u otro 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 IMDB_ID") return 0, 0, -1 _id = item.infoLabels['code'] # progress dialog p_dialog = platformtools.dialog_progress('streamondemand', 'Aggiunta film...') base_name = filetools.validate_path(item.contentTitle).lower() for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: if c.endswith("[%s]" % _id): path = filetools.join(raiz, c) 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) if item.infoLabels['tmdb_id']: head_nfo = "https://www.themoviedb.org/movie/%s\n" % item.infoLabels[ 'tmdb_id'] else: head_nfo = "Aqui ira el xml" # TODO 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 head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # 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}) 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 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 biblioteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.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 biblioteca" % item.contentTitle) p_dialog.update(100, 'Fallo al añadir...', item.contentTitle) p_dialog.close() # TODO habria q poner otra advertencia? return 0, 0, -1
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 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 downloadfileGzipped(url, pathfichero): logger.info("url= " + url) nombrefichero = pathfichero logger.info("filename= " + nombrefichero) import xbmc nombrefichero = xbmc.makeLegalFilename(nombrefichero) logger.info("filename= " + nombrefichero) patron = "(http://[^/]+)/.+" matches = re.compile(patron, re.DOTALL).findall(url) if len(matches): logger.info("Main URL: " + matches[0]) url1 = matches[0] else: url1 = url txheaders = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; ' 'Media Center PC 5.0; .NET CLR 3.0.04506)', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'es-es,es;q=0.8,en-us;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip,deflate', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Keep-Alive': '115', 'Connection': 'keep-alive', 'Referer': url1, } txdata = "" # Create the progress dialog from platformcode import platformtools progreso = platformtools.dialog_progress("addon", config.get_localized_string(60200) + '\n' + url.split("|")[0] + '\n' + nombrefichero) # Socket timeout at 60 seconds socket.setdefaulttimeout(10) h = urllib.request.HTTPHandler(debuglevel=0) request = urllib.request.Request(url, txdata, txheaders) # if existSize > 0: # request.add_header('Range', 'bytes=%d-' % (existSize, )) opener = urllib.request.build_opener(h) urllib.request.install_opener(opener) try: connexion = opener.open(request) except urllib.error.HTTPError as e: logger.error("error %d (%s) when opening the url %s" % (e.code, e.msg, url)) progreso.close() # Error 416 is that the requested range is greater than the file => is that it is already complete if e.code == 416: return 0 else: return -2 nombre_fichero_base = filetools.basename(nombrefichero) if len(nombre_fichero_base) == 0: logger.info("Searching for name in the answer Headers") nombre_base = connexion.headers["Content-Disposition"] logger.info(nombre_base) patron = 'filename="([^"]+)"' matches = re.compile(patron, re.DOTALL).findall(nombre_base) if len(matches) > 0: titulo = matches[0] titulo = GetTitleFromFile(titulo) nombrefichero = filetools.join(pathfichero, titulo) else: logger.info("Name of the file not found, Placing temporary name: no_name.txt") titulo = "no_name.txt" nombrefichero = filetools.join(pathfichero, titulo) totalfichero = int(connexion.headers["Content-Length"]) # then f = filetools.file_open(nombrefichero, 'w', vfs=VFS) logger.info("new file open") grabado = 0 logger.info("Content-Length= %s" % totalfichero) blocksize = 100 * 1024 bloqueleido = connexion.read(blocksize) try: import io compressedstream = io.StringIO(bloqueleido) import gzip gzipper = gzip.GzipFile(fileobj=compressedstream) bloquedata = gzipper.read() gzipper.close() logger.info("Starting downloading the file, blocked= %s" % len(bloqueleido)) except: logger.error("ERROR: The file to be downloaded is not compressed with Gzip") f.close() progreso.close() return -2 maxreintentos = 10 while len(bloqueleido) > 0: try: # Write the block read f.write(bloquedata) grabado += len(bloqueleido) percent = int(float(grabado) * 100 / float(totalfichero)) totalmb = float(float(totalfichero) / (1024 * 1024)) descargadosmb = float(float(grabado) / (1024 * 1024)) # Read the next block, retrying not to stop everything at the first timeout reintentos = 0 while reintentos <= maxreintentos: try: before = time.time() bloqueleido = connexion.read(blocksize) import gzip import io compressedstream = io.StringIO(bloqueleido) gzipper = gzip.GzipFile(fileobj=compressedstream) bloquedata = gzipper.read() gzipper.close() after = time.time() if (after - before) > 0: velocidad = old_div(len(bloqueleido), (after - before)) falta = totalfichero - grabado if velocidad > 0: tiempofalta = old_div(falta, velocidad) else: tiempofalta = 0 logger.info(sec_to_hms(tiempofalta)) progreso.update(percent, "%.2fMB/%.2fMB (%d%%) %.2f Kb/s %s left " % (descargadosmb, totalmb, percent, old_div(velocidad, 1024), sec_to_hms(tiempofalta))) break except: reintentos += 1 logger.info("ERROR in block download, retry %d" % reintentos) for line in sys.exc_info(): logger.error("%s" % line) # The user cancels the download if progreso.iscanceled(): logger.info("Download of file canceled") f.close() progreso.close() return -1 # There was an error in the download if reintentos > maxreintentos: logger.info("ERROR in the file download") f.close() progreso.close() return -2 except: logger.info("ERROR in the file download") for line in sys.exc_info(): logger.error("%s" % line) f.close() progreso.close() return -2 f.close() # print data progreso.close() logger.info("End download of the file") return nombrefichero
def mark_content_as_watched_on_kodi(item, value=1): """ marca el contenido como visto o no visto en la libreria de Kodi @type item: item @param item: elemento a marcar @type value: int @param value: >0 para visto, 0 para no visto """ logger.info() # logger.debug("item:\n" + item.tostring('\n')) payload_f = '' if item.contentType == "movie": movieid = 0 payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "originaltitle", "file"]}, "id": 1} data = get_data(payload) if 'result' in data and "movies" in data['result']: filename = filetools.basename(item.strm_path) head, tail = filetools.split(filetools.split(item.strm_path)[0]) path = filetools.join(tail, filename) for d in data['result']['movies']: if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")): # logger.debug("marco la pelicula como vista") movieid = d['movieid'] break if movieid != 0: payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": { "movieid": movieid, "playcount": value}, "id": 1} else: # item.contentType != 'movie' episodeid = 0 payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"properties": ["title", "playcount", "showtitle", "file", "tvshowid"]}, "id": 1} data = get_data(payload) if 'result' in data and "episodes" in data['result']: filename = filetools.basename(item.strm_path) head, tail = filetools.split(filetools.split(item.strm_path)[0]) path = filetools.join(tail, filename) for d in data['result']['episodes']: if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")): # logger.debug("marco el episodio como visto") episodeid = d['episodeid'] break if episodeid != 0: payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": { "episodeid": episodeid, "playcount": value}, "id": 1} if payload_f: # Marcar como visto data = get_data(payload_f) # logger.debug(str(data)) if data['result'] != 'OK': logger.error("ERROR al poner el contenido como visto")
def mark_content_as_watched_on_kodi(item, value=1): """ marca el contenido como visto o no visto en la libreria de Kodi @type item: item @param item: elemento a marcar @type value: int @param value: >0 para visto, 0 para no visto """ logger.info() # logger.debug("item:\n" + item.tostring('\n')) payload_f = '' if item.contentType == "movie": movieid = 0 payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "originaltitle", "file"]}, "id": 1} data = get_data(payload) if 'result' in data and "movies" in data['result']: if item.strm_path: #Si Item es de un episodio filename = filetools.basename(item.strm_path) head, tail = filetools.split(filetools.split(item.strm_path)[0]) else: #Si Item es de la Serie filename = filetools.basename(item.path) head, tail = filetools.split(filetools.split(item.path)[0]) path = filetools.join(tail, filename) for d in data['result']['movies']: if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")): # logger.debug("marco la pelicula como vista") movieid = d['movieid'] break if movieid != 0: payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": { "movieid": movieid, "playcount": value}, "id": 1} else: # item.contentType != 'movie' episodeid = 0 payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"properties": ["title", "playcount", "showtitle", "file", "tvshowid"]}, "id": 1} data = get_data(payload) if 'result' in data and "episodes" in data['result']: if item.strm_path: #Si Item es de un episodio filename = filetools.basename(item.strm_path) head, tail = filetools.split(filetools.split(item.strm_path)[0]) else: #Si Item es de la Serie filename = filetools.basename(item.path) head, tail = filetools.split(filetools.split(item.path)[0]) path = filetools.join(tail, filename) for d in data['result']['episodes']: if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")): # logger.debug("marco el episodio como visto") episodeid = d['episodeid'] break if episodeid != 0: payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": { "episodeid": episodeid, "playcount": value}, "id": 1} if payload_f: # Marcar como visto data = get_data(payload_f) # logger.debug(str(data)) if data['result'] != 'OK': logger.error("ERROR al poner el contenido como visto")
def save_library_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 biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: 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('streamondemand', 'Aggiunta film...') if config.get_setting("original_title_folder", "biblioteca") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] else: base_name = item.contentTitle base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").lower().encode("utf8") 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="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 head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # Crear base_name.strm si no existe item_strm = Item(channel='biblioteca', 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 if filetools.write(json_path, item.tojson()): p_dialog.update(100, 'Aggiunta film...', item.contentTitle) item_nfo.library_urls[item.channel] = item.url if filetools.write(nfo_path, head_nfo + item_nfo.tojson()): # actualizamos la biblioteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.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 biblioteca" % item.contentTitle) p_dialog.update(100, 'Aggiunta fallita...', item.contentTitle) p_dialog.close() return 0, 0, -1
def delete_all(_item): for file in filetools.listdir(_item.path): if file.endswith(".strm") or file.endswith(".nfo") or file.endswith(".json")or file.endswith(".torrent"): filetools.remove(filetools.join(_item.path, file)) if _item.contentType == 'movie': heading = config.get_localized_string(70084) else: heading = config.get_localized_string(70085) if config.is_xbmc() and config.get_setting("videolibrary_kodi"): from platformcode import xbmc_videolibrary if _item.local_episodes_path: platformtools.dialog_ok(heading, config.get_localized_string(80047) % _item.infoLabels['title']) path_list = [_item.extra] xbmc_videolibrary.clean(path_list) raiz, carpeta_serie, ficheros = next(filetools.walk(_item.path)) if ficheros == []: filetools.rmdir(_item.path) elif platformtools.dialog_yesno(heading, config.get_localized_string(70081) % filetools.basename(_item.path)): filetools.rmdirtree(_item.path) logger.info("All links removed") xbmc.sleep(1000) platformtools.itemlist_refresh()
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() # 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 = {} if overwrite == "everything": overwrite = True overwrite_everything = True else: overwrite_everything = False # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('streamondemand', 'Aggiunta episodi...') p_dialog.update(0, 'Aggiunta 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)), 'Aggiunta episodio...', e.title) try: 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) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros strm_exists_before = True nfo_exists_before = True json_exists_before = True if not strm_exists or overwrite_everything: if not overwrite_everything: strm_exists_before = False # Si no existe season_episode.strm añadirlo item_strm = Item(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 # FILTERTOOLS if item_strm.list_idiomas: # 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 or overwrite_everything) and e.infoLabels.get("imdb_id"): if not overwrite_everything: nfo_exists_before = False # Si no existe season_episode.nfo añadirlo if e.infoLabels["tmdb_id"]: scraper.find_and_set_infoLabels(e) head_nfo = "https://www.themoviedb.org/tv/%s/season/%s/episode/%s\n" % ( e.infoLabels['tmdb_id'], e.contentSeason, e.contentEpisodeNumber) elif e.infoLabels["tvdb_id"]: head_nfo = e.url_scraper else: head_nfo = "Aqui ira el xml" # TODO item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) 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) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists or overwrite_everything: if not overwrite_everything: json_exists_before = False logger.info("Insertado: %s" % json_path) else: logger.info("Sobreescritos todos los archivos!") # 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 if (not overwrite_everything and not json_exists): json_exists = True 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 strm_exists_before or not nfo_exists_before or not json_exists_before): if (strm_exists and nfo_exists and json_exists): insertados += 1 else: logger.error("El archivo strm, nfo o json no existe") 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: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) if tvshow_item.active == 30: tvshow_item.active = 1 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") fallidos = -1 # ... y actualizamos la biblioteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_library xbmc_library.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 check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() estado_verify_playcount_series = False try: if config.get_setting("update", "videolibrary") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary") heading = config.get_localized_string(60389) p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk( videolibrarytools.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 = videolibrarytools.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) #Verificamos el estado del serie.library_playcounts de la Serie por si está incompleto try: estado = False #Si no hemos hecho la verificación o no tiene playcount, entramos estado = config.get_setting("verify_playcount", "videolibrary") if not estado or estado == False or not serie.library_playcounts: #Si no se ha pasado antes, lo hacemos ahora serie, estado = videolibrary.verify_playcount_series( serie, path ) #También se pasa si falta un PlayCount por completo except: logger.error(traceback.format_exc()) else: if estado: #Si ha tenido éxito la actualización... estado_verify_playcount_series = True #... se marca para cambiar la opción de la Videoteca interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar if not overwrite: #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa, aunque la serie esté desactivada try: if config.is_xbmc(): #Si es Kodi, lo hacemos from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_alfa( path + '/tvshow.nfo') except: logger.error(traceback.format_exc()) 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", "videolibrary") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next = hoy + datetime.timedelta(days=interval) 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 serie_actualizada: update_last = hoy update_next = hoy + datetime.timedelta(days=interval) head_nfo, serie = videolibrarytools.read_nfo( tvshow_file) #Vuelve a leer el.nfo, que ha sido modificado if interval != int(serie.active) or update_next.strftime( '%Y-%m-%d' ) != serie.update_next or update_last.strftime( '%Y-%m-%d') != serie.update_last: serie.update_last = update_last.strftime('%Y-%m-%d') if update_next > hoy: serie.update_next = update_next.strftime('%Y-%m-%d') serie.active = interval serie.channel = "videolibrary" serie.action = "get_seasons" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "videolibrary") == 0: # Actualizamos la videoteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update( folder=filetools.basename(path)) else: update_when_finished = True if estado_verify_playcount_series: #Si se ha cambiado algún playcount, ... estado = config.set_setting( "verify_playcount", True, "videolibrary" ) #... actualizamos la opción de Videolibrary if config.get_setting( "search_new_content", "videolibrary") == 1 and update_when_finished: # Actualizamos la videoteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update() p_dialog.close() else: logger.info( "No actualiza la videoteca, está desactivado en la configuración de alfa" ) except Exception, 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 findvideos(item): from core import autoplay logger.info() # logger.debug("item:\n" + item.tostring('\n')) videolibrarytools.check_renumber_options(item) itemlist = [] list_canales = {} item_local = None # Disable autoplay # autoplay.set_status(False) if not item.contentTitle or not item.strm_path: logger.debug("Unable to search for videos due to lack of parameters") return [] content_title = str(item.contentSeason) + 'x' + (str(item.contentEpisodeNumber) if item.contentEpisodeNumber > 9 else '0' + str(item.contentEpisodeNumber)) if item.contentType == 'movie': item.strm_path = filetools.join(videolibrarytools.MOVIES_PATH, item.strm_path) path_dir = filetools.dirname(item.strm_path) item.nfo = filetools.join(path_dir, filetools.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(videolibrarytools.TVSHOWS_PATH, item.strm_path) path_dir = filetools.dirname(item.strm_path) item.nfo = filetools.join(path_dir, 'tvshow.nfo') for fd in filetools.listdir(path_dir): if fd.endswith('.json'): contenido, nom_canal = fd[:-6].split('[') if (contenido.startswith(content_title) or item.contentType == 'movie') and nom_canal not in list(list_canales.keys()): list_canales[nom_canal] = filetools.join(path_dir, fd) num_canales = len(list_canales) if 'downloads' in list_canales: json_path = list_canales['downloads'] item_json = Item().fromjson(filetools.read(json_path)) item_json.contentChannel = "local" # Support for relative paths in downloads if filetools.is_relative(item_json.url): item_json.url = filetools.join(videolibrarytools.VIDEOLIBRARY_PATH, item_json.url) del list_canales['downloads'] # Check that the video has not been deleted if filetools.exists(item_json.url): item_local = item_json.clone(action='play') itemlist.append(item_local) else: num_canales -= 1 filtro_canal = '' if num_canales > 1 and config.get_setting("ask_channel", "videolibrary"): opciones = [config.get_localized_string(70089) % k.capitalize() for k in list(list_canales.keys())] opciones.insert(0, config.get_localized_string(70083)) if item_local: opciones.append(item_local.title) from platformcode import platformtools index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index < 0: return [] elif item_local and index == len(opciones) - 1: filtro_canal = 'downloads' platformtools.play_video(item_local) elif index > 0: filtro_canal = opciones[index].replace(config.get_localized_string(70078), "").strip() itemlist = [] for nom_canal, json_path in list(list_canales.items()): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue item_canal = Item() # We import the channel of the selected part try: if nom_canal == 'community': channel = __import__('specials.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) else: channel = __import__('channels.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) except ImportError: exec("import channels." + nom_canal + " as channel") item_json = Item().fromjson(filetools.read(json_path)) list_servers = [] # from core.support import dbg;dbg() try: # FILTERTOOLS # if the channel has a filter, the name it has saved is passed to it so that it filters correctly. if "list_language" in item_json: # if it comes from the addon video library if "library_filter_show" in item: item_json.show = item.library_filter_show.get(nom_canal, "") # We run find_videos, from the channel or common item_json.contentChannel = 'videolibrary' item_json.play_from = item.play_from item_json.nfo = item.nfo item_json.strm_path = item.strm_path if hasattr(channel, 'findvideos'): from core import servertools if item_json.videolibray_emergency_urls: del item_json.videolibray_emergency_urls list_servers = getattr(channel, 'findvideos')(item_json) elif item_json.action == 'play': from platformcode import platformtools # autoplay.set_status(True) item_json.contentChannel = item_json.channel item_json.channel = "videolibrary" platformtools.play_video(item_json) return '' else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception as ex: logger.error("The findvideos function for the channel %s failed" % nom_canal) template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) logger.error(traceback.format_exc()) # Change the title to the servers adding the name of the channel in front and the infoLabels and the images of the item if the server does not have for server in list_servers: server.contentChannel = server.channel server.channel = "videolibrary" server.nfo = item.nfo server.strm_path = item.strm_path server.play_from = item.play_from # Kodi 18 Compatibility - Prevents wheel from spinning around in Direct Links if server.action == 'play': server.folder = False # Channel name is added if desired if config.get_setting("quit_channel_name", "videolibrary") == 0: server.title = "%s: %s" % (nom_canal.capitalize(), server.title) if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server) if autoplay.play_multi_channel(item, itemlist): # hideserver return [] add_download_items(item, itemlist) return itemlist
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 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() # 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 = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('streamondemand', 'Aggiunta episodi...') p_dialog.update(0, 'Aggiunta episodio...') new_episodelist =[] # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean for e in episodelist: try: season_episode = scrapertools.get_season_and_episode(e.title) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") new_episodelist.append(e) except: 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 t = float(100) / len(new_episodelist) for i, e in enumerate(scraper.sort_episode_list(new_episodelist)): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Aggiunta episodio...', e.title) 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()) 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='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 # FILTERTOOLS if item_strm.list_idiomas: # 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="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) 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) 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.contentTitle] = 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 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: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) if tvshow_item.active == 30: tvshow_item.active = 1 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") fallidos = -1 else: # ... si ha sido correcto actualizamos la biblioteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_library xbmc_library.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 list_storage(item): logger.info() from core import filetools from lib import generictools itemlist = [] torrent_params = { 'url': item.url, 'torrents_path': '', 'local_torr': item.torrents_path, 'lookup': False, 'force': True, 'data_torrent': True, 'subtitles': True, 'file_list': True } #logger.debug(item) browse_type = 0 path_out = item.url if not filetools.exists(path_out): path_out = '' if not path_out: msg = 'Seleccione carpeta de destino:' path_out = platformtools.dialog_browse(browse_type, msg, shares='') path_list = filetools.listdir(path_out) VIDEOLIBRARY_PATH = config.get_videolibrary_path() FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") FOLDER = '' if VIDEOLIBRARY_PATH in path_out: if FOLDER_MOVIES in path_out: FOLDER = FOLDER_MOVIES elif FOLDER_TVSHOWS in path_out: FOLDER = FOLDER_TVSHOWS MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES) TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS) VIDEO_FOLDER = filetools.join(VIDEOLIBRARY_PATH, FOLDER) TEMP_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'cached_torrents_Alfa') MIS_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'Mis_Torrents') for file in path_list: if FOLDER and file.endswith('.json') and file.split( '.')[0] + '_01.torrent' in str(path_list): json_video = Item().fromjson( filetools.read(filetools.join(path_out, file))) json_video.channel = 'url' json_video.action = 'findvideos' json_video.torrents_path = json_video.url itemlist.append(json_video) elif FOLDER and filetools.isdir(filetools.join(path_out, file)): if '.torrent' in str(filetools.listdir(filetools.join(path_out, file))) \ or '.magnet' in str(filetools.listdir(filetools.join(path_out, file))): itemlist.append( Item(channel=item.channel, action="list_storage", url=filetools.join(path_out, file), title=file.title(), contentTitle=file.title(), contentType="list", unify=False, context=context)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos elif not FOLDER and filetools.isdir(filetools.join(path_out, file)): if MIS_TORRENT_FOLDER in path_out: title = file.title() if 'BTDigg' in file: title = title.replace( 'Btdigg', '[B][COLOR limegreen]BT[/COLOR][COLOR red]Digg[/COLOR][/B]' ) itemlist.append( Item(channel=item.channel, action="list_storage", url=filetools.join(path_out, file), title=title, contentTitle=title, contentType="list", unify=False, btdigg=True if 'BTDigg' in file else False, url_org=filetools.join(path_out, file), context=context)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos elif not FOLDER and ('.torrent' in file or '.magnet' in file): btdigg = False if '.torrent' in file: url = filetools.join(TEMP_TORRENT_FOLDER, file) filetools.copy(filetools.join(path_out, file), url, silent=True) if not filetools.exists(url): continue else: url = filetools.read(filetools.join(path_out, file), silent=True) if btdigg_magnet in url: btdigg = True size = 'MAGNET' if not url: continue torrent_params['url'] = url torrent_params['torrents_path'] = '' torrent_params['local_torr'] = filetools.join( TEMP_TORRENT_FOLDER, file) torrent_params = generictools.get_torrent_size( url, torrent_params=torrent_params) if '.magnet' in file and 'ERROR' in torrent_params['size']: torrent_params['size'] = 'MAGNET' size = torrent_params['size'] itemlist.append( Item(channel=item.channel, action="play", url=url, url_org=filetools.join(path_out, file), server='torrent', title=filetools.join( filetools.basename(path_out.rstrip('/').rstrip('\\')), file).title() + " [%s]" % size, contentTitle=filetools.join( filetools.basename(path_out.rstrip('/').rstrip('\\')), file).title(), contentType="movie", unify=False, torrents_path=torrent_params['torrents_path'], infoLabels={"tmdb_id": "111"}, context=context, btdigg=btdigg)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos return itemlist
def download_from_url(url, item): logger.info("pelisalacarta.channels.descargas download_from_url - Intentando descargar: %s" % (url)) if url.lower().endswith(".m3u8") or url.lower().startswith("rtmp"): save_server_statistics(item.server, 0, False) return {"downloadStatus": STATUS_CODES.error} # Obtenemos la ruta de descarga y el nombre del archivo download_path = filetools.dirname(filetools.join(config.get_setting("downloadpath"), item.downloadFilename)) file_name = filetools.basename(filetools.join(config.get_setting("downloadpath"), item.downloadFilename)) # Creamos la carpeta si no existe if not filetools.exists(download_path): filetools.mkdir(download_path) # Mostramos el progreso progreso = platformtools.dialog_progress("Descargas", "Iniciando descarga...") # Lanzamos la descarga d = Downloader(url, filetools.encode(download_path), filetools.encode(file_name)) d.start() # Monitorizamos la descarga hasta que se termine o se cancele while d.state == d.states.downloading and not progreso.iscanceled(): time.sleep(0.1) line1 = "%s" % (filetools.decode(d.filename)) line2 = "%.2f%% - %.2f %s de %.2f %s a %.2f %s/s (%d/%d)" % ( d.progress, d.downloaded[1], d.downloaded[2], d.size[1], d.size[2], d.speed[1], d.speed[2], d.connections[0], d.connections[1]) line3 = "Tiempo restante: %s" % (d.remaining_time) progreso.update(int(d.progress), line1, line2, line3) # Descarga detenida. Obtenemos el estado: # Se ha producido un error en la descarga if d.state == d.states.error: logger.info("pelisalacarta.channels.descargas download_video - Error al intentar descargar %s" % (url)) d.stop() progreso.close() status = STATUS_CODES.error # Aun está descargando (se ha hecho click en cancelar) elif d.state == d.states.downloading: logger.info("pelisalacarta.channels.descargas download_video - Descarga detenida") d.stop() progreso.close() status = STATUS_CODES.canceled # La descarga ha finalizado elif d.state == d.states.completed: logger.info("pelisalacarta.channels.descargas download_video - Descargado correctamente") progreso.close() status = STATUS_CODES.completed if item.downloadSize and item.downloadSize != d.size[0]: status = STATUS_CODES.error save_server_statistics(item.server, d.speed[0], d.state != d.states.error) if progreso.iscanceled(): status = STATUS_CODES.canceled dir = os.path.dirname(item.downloadFilename) file = filetools.join(dir, filetools.decode(d.filename)) if status == STATUS_CODES.completed: move_to_libray(item.clone(downloadFilename = file)) return {"downloadUrl": d.download_url, "downloadStatus": status, "downloadSize": d.size[0], "downloadProgress": d.progress, "downloadCompleted": d.downloaded[0], "downloadFilename": file}