def start(self, list_controls=None, dict_values=None, title="Opciones", callback=None, item=None, custom_button=None, channelpath=None): logger.info("[xbmc_config_menu] start") # Ruta para las imagenes de la ventana self.mediapath = os.path.join(config.get_runtime_path(), 'resources', 'skins', 'Default', 'media') # Capturamos los parametros self.list_controls = list_controls self.values = dict_values self.title = title self.callback = callback self.item = item if type(custom_button) == dict: self.custom_button = {} self.custom_button["label"] = custom_button.get("label", "") self.custom_button["function"] = custom_button.get("function", "") self.custom_button["visible"] = bool(custom_button.get("visible", True)) self.custom_button["close"] = bool(custom_button.get("close", False)) else: self.custom_button = None # Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal if not channelpath: channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename self.channel = os.path.basename(channelpath).replace(".py", "") # Si no tenemos list_controls, hay que sacarlos del xml del canal if not self.list_controls: # Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools if os.path.join(config.get_runtime_path(), "channels") in channelpath: # La llamada se hace desde un canal self.list_controls, default_values = channeltools.get_channel_controls_settings(self.channel) # En caso contrario salimos else: return None # Si no se pasan dict_values, creamos un dict en blanco if self.values is None: self.values = {} # Ponemos el titulo if self.title == "": self.title = str(config.get_localized_string(30100)) + " -- " + self.channel.capitalize() elif self.title.startswith('@') and unicode(self.title[1:]).isnumeric(): self.title = config.get_localized_string(int(self.title[1:])) # Muestra la ventana self.return_value = None self.doModal() return self.return_value
def PlayStream(self, url): logger.info("CustomPlayer.PlayStream url="+url) self.play(url) self.actualtime=0 self.url=url while self.isPlaying(): self.actualtime = self.getTime() self.totaltime = self.getTotalTime() logger.info("CustomPlayer.PlayStream actualtime="+str(self.actualtime)+" totaltime="+str(self.totaltime)) xbmc.sleep(3000)
def get_servers_list(): logger.info("from resources.lib.httpkir.servertools get_servers_list") ServersPath = os.path.join(config.get_runtime_path(),"servers") ServerList={} for server in os.listdir(ServersPath): if server.endswith(".xml"): if is_server_enabled(server): server_parameters = get_server_parameters(server) ServerList[server_parameters["id"]] = server_parameters return ServerList
def get_server_parameters(server): server=scrapertools.find_single_match(server,'([^\.]+)') try: JSONFile = xml2dict(os.path.join(config.get_runtime_path(),"servers", server + ".xml"))["server"] if type(JSONFile["premium"]) == dict: JSONFile["premium"]=JSONFile["premium"]["value"] if JSONFile["premium"] == "": JSONFile["premium"]=[] if type(JSONFile["premium"]) == str and not JSONFile["premium"] == "": JSONFile["premium"]=[JSONFile["premium"]] return JSONFile except: logger.info("Error al cargar el servidor: " + server) import traceback logger.info(traceback.format_exc()) return {}
def findvideos(data, skip=False): logger.info("pelisalacarta.core.servertools findvideos") # en #"+data+"#") encontrados = set() devuelve = [] # Ejecuta el findvideos en cada servidor server_list = get_servers_list() for serverid in server_list: try: # Sustituye el código por otro "Plex compatible" #exec "from servers import "+serverid #exec "devuelve.extend("+serverid+".find_videos(data))" servers_module = __import__("servers."+serverid) server_module = getattr(servers_module,serverid) result = server_module.find_videos(data) if result and skip: return result devuelve.extend(result) except ImportError: logger.info("No existe conector para #"+serverid+"#") #import traceback #logger.info(traceback.format_exc()) except: logger.info("Error en el conector #"+serverid+"#") import traceback logger.info(traceback.format_exc()) return devuelve
def __init__(self, url, file_name, download_path): logger.info("DownloadThread.__init__ "+repr(file)) self.url = url self.download_path = download_path self.file_name = os.path.join( download_path , file_name ) self.progress = 0 self.force_stop_file_name = os.path.join( self.download_path , "force_stop.tmp" ) self.velocidad=0 self.tiempofalta=0 self.actual_size=0 self.total_size=0 if os.path.exists(self.force_stop_file_name): os.remove(self.force_stop_file_name) threading.Thread.__init__(self)
def is_server_enabled(server): try: server_parameters = get_server_parameters(server) if server_parameters["active"] == "true": if not config.get_setting("hidepremium")=="true": return True else: if server_parameters["free"] == "true": return True if [premium for premium in server_parameters["premium"] if config.get_setting(premium+"premium")=="true"]: return True else: return False else: return False except: import traceback logger.info(traceback.format_exc()) return False
def handle_wait(time_to_wait, title, text): logger.info("handle_wait(time_to_wait=%d)" % time_to_wait) espera = dialog_progress(' ' + title, "") secs = 0 increment = int(100 / time_to_wait) cancelled = False while secs < time_to_wait: secs += 1 percent = increment * secs secs_left = str((time_to_wait - secs)) remaining_display = ' Espera ' + secs_left + ' segundos para que comience el vídeo...' espera.update(percent, ' ' + text, remaining_display) xbmc.sleep(1000) if espera.iscanceled(): cancelled = True break if cancelled: logger.info('Espera cancelada') return False else: logger.info('Espera finalizada') return True
def get_video_seleccionado(item, seleccion, video_urls): logger.info("platformtools get_video_seleccionado") mediaurl = "" view = False wait_time = 0 mpd = False # Ha elegido uno de los vídeos if seleccion < len(video_urls): mediaurl = video_urls[seleccion][1] if len(video_urls[seleccion]) > 4: wait_time = video_urls[seleccion][2] item.subtitle = video_urls[seleccion][3] mpd = True if len(video_urls[seleccion]) > 3: wait_time = video_urls[seleccion][2] item.subtitle = video_urls[seleccion][3] elif len(video_urls[seleccion]) > 2: wait_time = video_urls[seleccion][2] view = True # Si no hay mediaurl es porque el vídeo no está :) logger.info("deportesalacarta.platformcode.platformstools mediaurl=" + mediaurl) if mediaurl == "": if item.server == "unknown": alert_unsopported_server() else: alert_no_disponible_server(item.server) # Si hay un tiempo de espera (como en megaupload), lo impone ahora if wait_time > 0: continuar = handle_wait(wait_time, item.server, "Cargando vídeo...") if not continuar: mediaurl = "" return mediaurl, view, mpd
def findvideosbyserver(data, serverid): logger.info("deportesalacarta.core.servertools findvideosbyserver") encontrados = set() devuelve = [] try: exec "from servers import "+serverid exec "devuelve.extend("+serverid+".find_videos(data))" except ImportError: logger.info("No existe conector para #"+serverid+"#") #import traceback #logger.info(traceback.format_exc()) except: logger.info("Error en el conector #"+serverid+"#") import traceback logger.info(traceback.format_exc()) return devuelve
def get_video_url(page_url, premium=False, user="", password="", video_password=""): logger.info("(page_url='%s')" % page_url) if not page_url.startswith("http"): page_url = "http://www.youtube.com/watch?v=%s" % page_url logger.info(" page_url->'%s'" % page_url) if "shared?ci=" in page_url: response = httptools.downloadpage(page_url, follow_redirects=False) if "watch?v=" in response.headers.get("location", ""): page_url = response.headers["location"] video_id = scrapertools.find_single_match(page_url, 'v=([A-z0-9_-]{11})') video_urls = extract_videos(video_id) video_urls.reverse() for video_url in video_urls: logger.info(str(video_url)) return video_urls
def set_player(item, xlistitem, mediaurl, view, strm, info): logger.info("platformtools set_player") logger.debug("item:\n" + item.tostring('\n')) # Movido del conector "torrent" aqui if item.server == "torrent": play_torrent(item, xlistitem, mediaurl) return # Si es un fichero strm no hace falta el play elif strm: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem) if item.subtitle != "": xbmc.sleep(2000) xbmc.Player().setSubtitles(item.subtitle) else: logger.info("player_mode=" + config.get_setting("player_mode")) logger.info("mediaurl=" + mediaurl) if item.server == "p2p" and info: from platformcode import windowinfo return windowinfo.start(item, xlistitem, mediaurl) elif config.get_setting( "player_mode") == "3" or "megacrypter.com" in mediaurl: import download_and_play download_and_play.download_and_play( mediaurl, "download_and_play.tmp", config.get_setting("downloadpath")) return elif config.get_setting("player_mode") == "0" or \ (config.get_setting("player_mode") == "3" and mediaurl.startswith("rtmp")): # Añadimos el listitem a una lista de reproducción (playlist) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(mediaurl, xlistitem) # Reproduce playersettings = config.get_setting('player_type') logger.info( "deportesalacarta.platformcode.platformstools playersettings=" + playersettings) if config.get_system_platform() == "xbox": player_type = xbmc.PLAYER_CORE_AUTO if playersettings == "0": player_type = xbmc.PLAYER_CORE_AUTO logger.info( "deportesalacarta.platformcode.platformstools PLAYER_CORE_AUTO" ) elif playersettings == "1": player_type = xbmc.PLAYER_CORE_MPLAYER logger.info( "deportesalacarta.platformcode.platformstools PLAYER_CORE_MPLAYER" ) elif playersettings == "2": player_type = xbmc.PLAYER_CORE_DVDPLAYER logger.info( "deportesalacarta.platformcode.platformstools PLAYER_CORE_DVDPLAYER" ) xbmc_player = xbmc.Player(player_type) else: xbmc_player = xbmc.Player() xbmc_player.play(playlist, xlistitem) elif config.get_setting("player_mode") == "1": logger.info("mediaurl :" + mediaurl) logger.info("Tras setResolvedUrl") xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=mediaurl)) elif config.get_setting("player_mode") == "2": xbmc.executebuiltin("PlayMedia(" + mediaurl + ")") # TODO MIRAR DE QUITAR VIEW if item.subtitle != "" and view: logger.info("Subtítulos externos: " + item.subtitle) xbmc.sleep(2000) xbmc.Player().setSubtitles(item.subtitle)
def download_file_megacrypter(self): logger.info("DownloadThread.download_file Megacrypter downloader") comando = "./megacrypter.sh" logger.info("DownloadThread.download_file comando="+comando) oldcwd = os.getcwd() logger.info("DownloadThread.download_file oldcwd="+oldcwd) cwd = os.path.join( config.get_runtime_path() , "tools") logger.info("DownloadThread.download_file cwd="+cwd) os.chdir(cwd) logger.info("DownloadThread.download_file directory changed to="+os.getcwd()) logger.info("DownloadThread.download_file destino="+self.download_path) os.system( comando+" '"+self.url+ "' \"" + self.download_path+"\"" ) #p = subprocess.Popen([comando , self.url , self.download_path], cwd=cwd, stdout=subprocess.PIPE , stderr=subprocess.PIPE ) #out, err = p.communicate() #logger.info("DownloadThread.download_file out="+out) os.chdir(oldcwd)
def guess_server_thumbnail(title): logger.info("deportesalacarta.core.servertools guess_server_thumbnail title="+title) lowcase_title = title.lower() if "netu" in lowcase_title: logger.info("deportesalacarta.core.servertools guess_server_thumbnail caso especial netutv") return "http://media.tvalacarta.info/servers/server_netutv.png" if "ul.to" in lowcase_title: logger.info("deportesalacarta.core.servertools guess_server_thumbnail caso especial ul.to") return "http://media.tvalacarta.info/servers/server_uploadedto.png" if "waaw" in lowcase_title: logger.info("deportesalacarta.core.servertools guess_server_thumbnail caso especial waaw") return "http://media.tvalacarta.info/servers/server_waaw.png" if "streamin" in lowcase_title: logger.info("deportesalacarta.core.servertools guess_server_thumbnail caso especial streamin") return "http://media.tvalacarta.info/servers/server_streaminto.png" servers = get_servers_list() for serverid in servers: if serverid in lowcase_title: logger.info("deportesalacarta.core.servertools guess_server_thumbnail encontrado "+serverid) return "http://media.tvalacarta.info/servers/server_"+serverid+".png" return ""
def play_torrent(item, xlistitem, mediaurl): logger.info("platformtools play_torrent") # Opciones disponibles para Reproducir torrents torrent_options = list() torrent_options.append(["Cliente interno (necesario libtorrent)"]) torrent_options.append(["Cliente interno MCT (necesario libtorrent)"]) # Plugins externos se pueden añadir otros if xbmc.getCondVisibility('System.HasAddon("plugin.video.xbmctorrent")'): torrent_options.append([ "Plugin externo: xbmctorrent", "plugin://plugin.video.xbmctorrent/play/%s" ]) if xbmc.getCondVisibility('System.HasAddon("plugin.video.pulsar")'): torrent_options.append([ "Plugin externo: pulsar", "plugin://plugin.video.pulsar/play?uri=%s" ]) if xbmc.getCondVisibility('System.HasAddon("plugin.video.quasar")'): torrent_options.append([ "Plugin externo: quasar", "plugin://plugin.video.quasar/play?uri=%s" ]) if xbmc.getCondVisibility('System.HasAddon("plugin.video.stream")'): torrent_options.append( ["Plugin externo: stream", "plugin://plugin.video.stream/play/%s"]) if xbmc.getCondVisibility('System.HasAddon("plugin.video.torrenter")'): torrent_options.append([ "Plugin externo: torrenter", "plugin://plugin.video.torrenter/?action=playSTRM&url=%s" ]) if xbmc.getCondVisibility('System.HasAddon("plugin.video.torrentin")'): torrent_options.append([ "Plugin externo: torrentin", "plugin://plugin.video.torrentin/?uri=%s&image=" ]) if len(torrent_options) > 1: seleccion = dialog_select("Abrir torrent con...", [opcion[0] for opcion in torrent_options]) else: seleccion = 0 # Plugins externos if seleccion > 1: mediaurl = urllib.quote_plus(item.url) xbmc.executebuiltin("PlayMedia(" + torrent_options[seleccion][1] % mediaurl + ")") if seleccion == 1: from platformcode import mct mct.play(mediaurl, xlistitem, subtitle=item.subtitle) # Reproductor propio (libtorrent) if seleccion == 0: import time played = False debug = (config.get_setting("debug") == "true") # Importamos el cliente from btserver import Client # Iniciamos el cliente: c = Client(url=mediaurl, is_playing_fnc=xbmc.Player().isPlaying, wait_time=None, timeout=10, temp_path=os.path.join(config.get_data_path(), "torrent"), print_status=debug) # Mostramos el progreso progreso = dialog_progress("Pelisalacarta - Torrent", "Iniciando...") # Mientras el progreso no sea cancelado ni el cliente cerrado while not c.closed: try: # Obtenemos el estado del torrent s = c.status if debug: # Montamos las tres lineas con la info del torrent txt = '%.2f%% de %.1fMB %s | %.1f kB/s' % \ (s.progress_file, s.file_size, s.str_state, s._download_rate) txt2 = 'S: %d(%d) P: %d(%d) | DHT:%s (%d) | Trakers: %d' % \ (s.num_seeds, s.num_complete, s.num_peers, s.num_incomplete, s.dht_state, s.dht_nodes, s.trackers) txt3 = 'Origen Peers TRK: %d DHT: %d PEX: %d LSD %d ' % \ (s.trk_peers, s.dht_peers, s.pex_peers, s.lsd_peers) else: txt = '%.2f%% de %.1fMB %s | %.1f kB/s' % \ (s.progress_file, s.file_size, s.str_state, s._download_rate) txt2 = 'S: %d(%d) P: %d(%d)' % ( s.num_seeds, s.num_complete, s.num_peers, s.num_incomplete) try: txt3 = 'Deteniendo automaticamente en: %ss' % (int( s.timeout)) except: txt3 = '' progreso.update(s.buffer, txt, txt2, txt3) time.sleep(0.5) if progreso.iscanceled(): progreso.close() if s.buffer == 100: if dialog_yesno("Pelisalacarta - Torrent", "¿Deseas iniciar la reproduccion?"): played = False progreso = dialog_progress( "Pelisalacarta - Torrent", "") progreso.update(s.buffer, txt, txt2, txt3) else: progreso = dialog_progress( "Pelisalacarta - Torrent", "") break else: if dialog_yesno("Pelisalacarta - Torrent", "¿Deseas cancelar el proceso?"): progreso = dialog_progress( "Pelisalacarta - Torrent", "") break else: progreso = dialog_progress( "Pelisalacarta - Torrent", "") progreso.update(s.buffer, txt, txt2, txt3) # Si el buffer se ha llenado y la reproduccion no ha sido iniciada, se inicia if s.buffer == 100 and not played: # Cerramos el progreso progreso.close() # Obtenemos el playlist del torrent videourl = c.get_play_list() # Iniciamos el reproductor playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(videourl, xlistitem) xbmc_player = xbmc.Player() xbmc_player.play(playlist) # Marcamos como reproducido para que no se vuelva a iniciar played = True # Y esperamos a que el reproductor se cierre while xbmc.Player().isPlaying(): time.sleep(1) # Cuando este cerrado, Volvemos a mostrar el dialogo progreso = dialog_progress("Pelisalacarta - Torrent", "") progreso.update(s.buffer, txt, txt2, txt3) except: import traceback logger.info(traceback.format_exc()) break progreso.update(100, "Terminando y eliminando datos", " ", " ") # Detenemos el cliente if not c.closed: c.stop() # Y cerramos el progreso progreso.close()
def force_stop_download_thread(self): logger.info("CustomPlayer.force_stop_download_thread") if self.download_thread.isAlive(): logger.info("CustomPlayer.force_stop_download_thread Killing download thread") self.download_thread.force_stop()
def set_download_thread(self,download_thread): logger.info("CustomPlayer.set_download_thread") self.download_thread = download_thread
def resolve_video_urls_for_playing(server,url,video_password="",muestra_dialogo=False,encode=False): if not encode: logger.info("deportesalacarta.core.servertools resolve_video_urls_for_playing, server="+server+", url="+url) video_urls = [] torrent = False server = server.lower() # Si el vídeo es "directo", no hay que buscar más if server=="directo" or server=="local": logger.info("deportesalacarta.core.servertools server=directo, la url es la buena") try: import urlparse parsed_url = urlparse.urlparse(url) logger.info("parsed_url="+str(parsed_url)) extension = parsed_url.path[-4:] except: extension = url[-4:] video_urls = [[ "%s [%s]" % (extension,server) , url ]] return video_urls,True,"" # Averigua las URL de los vídeos else: # Carga el conector try: if encode: return [base64.b64decode(url)], True, "" # Muestra un diágo de progreso if muestra_dialogo: from platformcode import platformtools progreso = platformtools.dialog_progress( "pelisalacarta" , "Conectando con "+server) server_parameters = get_server_parameters(server) #Cuenta las opciones disponibles, para calcular el porcentaje opciones = [] if server_parameters["free"] == "true": opciones.append("free") opciones.extend([premium for premium in server_parameters["premium"] if config.get_setting(premium+"premium")=="true"]) logger.info("deportesalacarta.core.servertools opciones disponibles para " + server + ": " + str(len(opciones)) + " "+str(opciones)) # Sustituye el código por otro "Plex compatible" #exec "from servers import "+server+" as server_connector" servers_module = __import__("servers."+server) server_connector = getattr(servers_module,server) if not encode: logger.info("deportesalacarta.core.servertools servidor de "+server+" importado") # Si tiene una función para ver si el vídeo existe, lo comprueba ahora if hasattr(server_connector, 'test_video_exists'): logger.info("deportesalacarta.core.servertools invocando a "+server+".test_video_exists") puedes,motivo = server_connector.test_video_exists( page_url=url ) # Si la funcion dice que no existe, fin if not puedes: logger.info("deportesalacarta.core.servertools test_video_exists dice que el video no existe") if muestra_dialogo: progreso.close() return video_urls,puedes,motivo else: logger.info("deportesalacarta.core.servertools test_video_exists dice que el video SI existe") # Obtiene enlaces free if server_parameters["free"]=="true": if muestra_dialogo: progreso.update((100 / len(opciones)) * opciones.index("free") , "Conectando con "+server) logger.info("deportesalacarta.core.servertools invocando a "+server+".get_video_url") video_urls = server_connector.get_video_url( page_url=url , video_password=video_password ) # Si no se encuentran vídeos en modo free, es porque el vídeo no existe if len(video_urls)==0: if muestra_dialogo: progreso.close() return video_urls,False,"No se puede encontrar el vídeo en "+server # Obtiene enlaces para las diferentes opciones premium error_message = [] for premium in server_parameters["premium"]: if config.get_setting(premium+"premium")=="true": if muestra_dialogo: progreso.update((100 / len(opciones)) * opciones.index(premium) , "Conectando con "+premium) exec "from servers import "+premium+" as premium_conector" if premium == "realdebrid": debrid_urls = premium_conector.get_video_url( page_url=url , premium=True , video_password=video_password ) if not "REAL-DEBRID:" in debrid_urls[0][0]: video_urls.extend(debrid_urls) else: error_message.append(debrid_urls[0][0]) elif premium == "alldebrid": alldebrid_urls = premium_conector.get_video_url( page_url=url , premium=True , user=config.get_setting(premium+"user") , password=config.get_setting(premium+"password"), video_password=video_password ) if not "Alldebrid:" in alldebrid_urls[0][0]: video_urls.extend(alldebrid_urls) else: error_message.append(alldebrid_urls[0][0]) else: video_urls.extend(premium_conector.get_video_url( page_url=url , premium=True , user=config.get_setting(premium+"user") , password=config.get_setting(premium+"password"), video_password=video_password )) if not video_urls and error_message: return video_urls, False, " || ".join(error_message) if muestra_dialogo: progreso.update( 100 , "Proceso finalizado") # Cierra el diálogo de progreso if muestra_dialogo: progreso.close() # Llegas hasta aquí y no tienes ningún enlace para ver, así que no vas a poder ver el vídeo if len(video_urls)==0: # ¿Cual es el motivo? # 1) No existe -> Ya está controlado # 2) No tienes alguna de las cuentas premium compatibles # Lista de las cuentas que soportan este servidor listapremium = [] for premium in server_parameters["premium"]: listapremium.append(get_server_parameters(premium)["name"]) return video_urls,False,"Para ver un vídeo en "+server+" necesitas<br/>una cuenta en "+" o ".join(listapremium) except: if muestra_dialogo: progreso.close() import traceback logger.info(traceback.format_exc()) return video_urls,False,"Se ha producido un error en<br/>el conector con "+server return video_urls,True,""
def onPlayBackStarted(self): logger.info("CustomPlayer.onPlayBackStarted PLAYBACK STARTED")
def __init__( self, *args, **kwargs ): logger.info("CustomPlayer.__init__") self.actualtime=0 self.totaltime=0 self.stopped=False xbmc.Player.__init__( self )
def onPlayBackEnded(self): logger.info("CustomPlayer.onPlayBackEnded PLAYBACK ENDED")
def set_opcion(item, seleccion, opciones, video_urls): logger.info("platformtools set_opcion") # logger.debug(item.tostring('\n')) salir = False # No ha elegido nada, lo más probable porque haya dado al ESC # TODO revisar if seleccion == -1: # Para evitar el error "Uno o más elementos fallaron" al cancelar la selección desde fichero strm listitem = xbmcgui.ListItem(item.title, iconImage="DefaultVideo.png", thumbnailImage=item.thumbnail) xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) # "Enviar a JDownloader" if opciones[seleccion] == config.get_localized_string(30158): from core import scrapertools # TODO comprobar que devuelve 'data' if item.subtitle != "": data = scrapertools.cachePage( config.get_setting("jdownloader") + "/action/add/links/grabber0/start1/web=" + item.url + " " + item.thumbnail + " " + item.subtitle) else: data = scrapertools.cachePage( config.get_setting("jdownloader") + "/action/add/links/grabber0/start1/web=" + item.url + " " + item.thumbnail) salir = True elif opciones[seleccion] == config.get_localized_string( 30164): # Borrar archivo en descargas # En "extra" está el nombre del fichero en favoritos os.remove(item.url) xbmc.executebuiltin("Container.Refresh") salir = True # Descargar elif opciones[seleccion] == config.get_localized_string( 30153): # "Descargar" download_title = item.fulltitle if item.hasContentDetails == "true": download_title = item.contentTitle # El vídeo de más calidad es el último mediaurl = video_urls[len(video_urls) - 1][1] from core import downloadtools keyboard = xbmc.Keyboard(download_title) keyboard.doModal() if (keyboard.isConfirmed()): download_title = keyboard.getText() devuelve = downloadtools.downloadbest(video_urls, download_title) if devuelve == 0: advertencia = xbmcgui.Dialog() resultado = advertencia.ok("plugin", "Descargado con éxito") elif devuelve == -1: advertencia = xbmcgui.Dialog() resultado = advertencia.ok("plugin", "Descarga abortada") else: advertencia = xbmcgui.Dialog() resultado = advertencia.ok("plugin", "Error en la descarga") salir = True elif opciones[seleccion] == config.get_localized_string( 30159): #"Borrar descarga definitivamente" from channels import descargas descargas.delete_error_bookmark(urllib.unquote_plus(item.extra)) advertencia = xbmcgui.Dialog() resultado = advertencia.ok( config.get_localized_string(30101), item.title, config.get_localized_string(30106)) # 'Se ha quitado de la lista' xbmc.executebuiltin("Container.Refresh") salir = True elif opciones[seleccion] == config.get_localized_string( 30160): #"Pasar de nuevo a lista de descargas": from channels import descargas descargas.mover_descarga_error_a_pendiente( urllib.unquote_plus(item.extra)) advertencia = xbmcgui.Dialog() resultado = advertencia.ok( config.get_localized_string(30101), item.title, config.get_localized_string( 30107)) # 'Ha pasado de nuevo a la lista de descargas' salir = True # "Quitar de favoritos" elif opciones[seleccion] == config.get_localized_string(30154): from channels import favoritos favoritos.delFavourite(item) salir = True # "Añadir a favoritos": elif opciones[seleccion] == config.get_localized_string(30155): from channels import favoritos item.from_channel = "favoritos" favoritos.addFavourite(item) salir = True elif opciones[seleccion] == config.get_localized_string( 30156): #"Quitar de lista de descargas": # La categoría es el nombre del fichero en la lista de descargas from channels import descargas descargas.deletebookmark((urllib.unquote_plus(item.extra))) advertencia = xbmcgui.Dialog() resultado = advertencia.ok( config.get_localized_string(30101), item.title, config.get_localized_string( 30106)) # 'Se ha quitado de lista de descargas' xbmc.executebuiltin("Container.Refresh") salir = True elif opciones[seleccion] == config.get_localized_string( 30157): #"Añadir a lista de descargas": from core import downloadtools download_title = item.fulltitle download_thumbnail = item.thumbnail download_plot = item.plot if item.hasContentDetails == "true": download_title = item.contentTitle download_thumbnail = item.contentThumbnail download_plot = item.contentPlot keyboard = xbmc.Keyboard( downloadtools.limpia_nombre_excepto_1(download_title)) keyboard.doModal() if keyboard.isConfirmed(): download_title = keyboard.getText() from channels import descargas descargas.savebookmark(titulo=download_title, url=item.url, thumbnail=download_thumbnail, server=item.server, plot=download_plot, fulltitle=download_title) advertencia = xbmcgui.Dialog() resultado = advertencia.ok( config.get_localized_string(30101), download_title, config.get_localized_string( 30109)) # 'se ha añadido a la lista de descargas' salir = True return salir
def onPlayBackStopped(self): logger.info("CustomPlayer.onPlayBackStopped PLAYBACK STOPPED") self.stopped=True self.force_stop_download_thread()
def find_videos(data): encontrados = set() devuelve = [] patronvideos = 'youtube(?:-nocookie)?\.com/(?:(?:(?:v/|embed/))|(?:(?:watch(?:_popup)?(?:\.php)?)?(?:\?|#!?)(?:.+&)?v=))?([0-9A-Za-z_-]{11})' #'"http://www.youtube.com/v/([^"]+)"' logger.info(" #" + patronvideos + "#") matches = re.compile(patronvideos, re.DOTALL).findall(data) for match in matches: titulo = "[YouTube]" url = "http://www.youtube.com/watch?v=" + match if url != '': if url not in encontrados: logger.info(" url=" + url) devuelve.append([titulo, url, 'youtube']) encontrados.add(url) else: logger.info(" url duplicada=" + url) patronvideos = 'www.youtube.*?v(?:=|%3D)([0-9A-Za-z_-]{11})' logger.info(" #" + patronvideos + "#") matches = re.compile(patronvideos, re.DOTALL).findall(data) for match in matches: titulo = "[YouTube]" url = "http://www.youtube.com/watch?v=" + match if url not in encontrados: logger.info(" url=" + url) devuelve.append([titulo, url, 'youtube']) encontrados.add(url) else: logger.info(" url duplicada=" + url) #http://www.youtube.com/v/AcbsMOMg2fQ patronvideos = 'youtube.com/v/([0-9A-Za-z_-]{11})' logger.info(" #" + patronvideos + "#") matches = re.compile(patronvideos, re.DOTALL).findall(data) for match in matches: titulo = "[YouTube]" url = "http://www.youtube.com/watch?v=" + match if url not in encontrados: logger.info(" url=" + url) devuelve.append([titulo, url, 'youtube']) encontrados.add(url) else: logger.info(" url duplicada=" + url) patronvideos = 'youtu.be/([0-9A-Za-z_-]{11})' logger.info(" #" + patronvideos + "#") matches = re.compile(patronvideos, re.DOTALL).findall(data) for match in matches: titulo = "[YouTube]" url = "http://www.youtube.com/watch?v=" + match if url not in encontrados: logger.info(" url=" + url) devuelve.append([titulo, url, 'youtube']) encontrados.add(url) else: logger.info(" url duplicada=" + url) # https://www.youtube.com/shared?ci=iNqg0OGr0M4 patronvideos = 'youtube.com/shared\?ci=([0-9A-z_-]+)' logger.info(" #" + patronvideos + "#") matches = re.compile(patronvideos, re.DOTALL).findall(data) for match in matches: titulo = "[YouTube]" url = "https://www.youtube.com/shared?ci=" + match if url not in encontrados: logger.info(" url=" + url) devuelve.append([titulo, url, 'youtube']) encontrados.add(url) else: logger.info(" url duplicada=" + url) return devuelve
def force_stop(self): logger.info("DownloadThread.force_stop...") force_stop_file = open( self.force_stop_file_name , "w" ) force_stop_file.write("0") force_stop_file.close()
class DownloadThread(threading.Thread): def __init__(self, url, file_name, download_path): logger.info("DownloadThread.__init__ "+repr(file)) self.url = url self.download_path = download_path self.file_name = os.path.join( download_path , file_name ) self.progress = 0 self.force_stop_file_name = os.path.join( self.download_path , "force_stop.tmp" ) self.velocidad=0 self.tiempofalta=0 self.actual_size=0 self.total_size=0 if os.path.exists(self.force_stop_file_name): os.remove(self.force_stop_file_name) threading.Thread.__init__(self) def run(self): logger.info("DownloadThread.run Download starts...") if "megacrypter.com" in self.url: self.download_file_megacrypter() else: self.download_file() logger.info("DownloadThread.run Download ends") def force_stop(self): logger.info("DownloadThread.force_stop...") force_stop_file = open( self.force_stop_file_name , "w" ) force_stop_file.write("0") force_stop_file.close() def get_progress(self): return self.progress; def get_file_name(self): return self.file_name def get_speed(self): return self.velocidad def get_remaining_time(self): return self.tiempofalta def get_actual_size(self): return self.actual_size def get_total_size(self): return self.total_size def download_file_megacrypter(self): logger.info("DownloadThread.download_file Megacrypter downloader") comando = "./megacrypter.sh" logger.info("DownloadThread.download_file comando="+comando) oldcwd = os.getcwd() logger.info("DownloadThread.download_file oldcwd="+oldcwd) cwd = os.path.join( config.get_runtime_path() , "tools") logger.info("DownloadThread.download_file cwd="+cwd) os.chdir(cwd) logger.info("DownloadThread.download_file directory changed to="+os.getcwd()) logger.info("DownloadThread.download_file destino="+self.download_path) os.system( comando+" '"+self.url+ "' \"" + self.download_path+"\"" ) #p = subprocess.Popen([comando , self.url , self.download_path], cwd=cwd, stdout=subprocess.PIPE , stderr=subprocess.PIPE ) #out, err = p.communicate() #logger.info("DownloadThread.download_file out="+out) os.chdir(oldcwd) def download_file(self): logger.info("DownloadThread.download_file Direct download") headers=[] # Ensures that the file can be created logger.info("DownloadThread.download_file nombrefichero="+self.file_name) self.file_name = xbmc.makeLegalFilename(self.file_name) logger.info("DownloadThread.download_file nombrefichero="+self.file_name) logger.info("DownloadThread.download_file url="+self.url) # Create the file existSize = 0 f = open(self.file_name, 'wb') grabado = 0 # Interprets the headers in a URL like in XBMC if "|" in self.url: additional_headers = self.url.split("|")[1] if "&" in additional_headers: additional_headers = additional_headers.split("&") else: additional_headers = [ additional_headers ] for additional_header in additional_headers: logger.info("DownloadThread.download_file additional_header: "+additional_header) name = re.findall( "(.*?)=.*?" , additional_header )[0] value = urllib.unquote_plus(re.findall( ".*?=(.*?)$" , additional_header )[0]) headers.append( [ name,value ] ) self.url = self.url.split("|")[0] logger.info("DownloadThread.download_file url="+self.url) # Timeout del socket a 60 segundos socket.setdefaulttimeout(60) # Create the request and add the headers h=urllib2.HTTPHandler(debuglevel=0) request = urllib2.Request(self.url) for header in headers: logger.info("DownloadThread.download_file Header="+header[0]+": "+header[1]) request.add_header(header[0],header[1]) # Launch request opener = urllib2.build_opener(h) urllib2.install_opener(opener) try: connexion = opener.open(request) except urllib2.HTTPError,e: logger.info("DownloadThread.download_file error %d (%s) al abrir la url %s" % (e.code,e.msg,self.url)) #print e.code #print e.msg #print e.hdrs #print e.fp f.close() # El error 416 es que el rango pedido es mayor que el fichero => es que ya está completo if e.code==416: return 0 else: return -2 try: totalfichero = int(connexion.headers["Content-Length"]) except: totalfichero = 1 self.total_size = int(float(totalfichero) / float(1024*1024)) logger.info("Content-Length=%s" % totalfichero) blocksize = 100*1024 bloqueleido = connexion.read(blocksize) logger.info("DownloadThread.download_file Iniciando descarga del fichero, bloqueleido=%s" % len(bloqueleido)) maxreintentos = 10 while len(bloqueleido)>0: try: if os.path.exists(self.force_stop_file_name): logger.info("DownloadThread.download_file Detectado fichero force_stop, se interrumpe la descarga") f.close() xbmc.executebuiltin((u'XBMC.Notification("Cancelado", "Descarga en segundo plano cancelada", 300)')) return # Escribe el bloque leido #try: # import xbmcvfs # f.write( bloqueleido ) #except: f.write(bloqueleido) grabado = grabado + len(bloqueleido) logger.info("DownloadThread.download_file grabado=%d de %d" % (grabado,totalfichero) ) percent = int(float(grabado)*100/float(totalfichero)) self.progress=percent; totalmb = float(float(totalfichero)/(1024*1024)) descargadosmb = float(float(grabado)/(1024*1024)) self.actual_size = int(descargadosmb) # Lee el siguiente bloque, reintentando para no parar todo al primer timeout reintentos = 0 while reintentos <= maxreintentos: try: before = time.time() bloqueleido = connexion.read(blocksize) after = time.time() if (after - before) > 0: self.velocidad=len(bloqueleido)/((after - before)) falta=totalfichero-grabado if self.velocidad>0: self.tiempofalta=falta/self.velocidad else: self.tiempofalta=0 break except: reintentos = reintentos + 1 logger.info("DownloadThread.download_file ERROR en la descarga del bloque, reintento %d" % reintentos) for line in sys.exc_info(): logger.error( "%s" % line ) # Ha habido un error en la descarga if reintentos > maxreintentos: logger.info("DownloadThread.download_file ERROR en la descarga del fichero") f.close() return -2 except: import traceback,sys from pprint import pprint exc_type, exc_value, exc_tb = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_tb) for line in lines: line_splits = line.split("\n") for line_split in line_splits: logger.error(line_split) f.close() return -2 return
def extract_videos(video_id): fmt_value = { 5: "240p h263 flv", 6: "240p h263 flv", 18: "360p h264 mp4", 22: "720p h264 mp4", 26: "???", 33: "???", 34: "360p h264 flv", 35: "480p h264 flv", 36: "3gpp", 37: "1080p h264 mp4", 38: "4K h264 mp4", 43: "360p vp8 webm", 44: "480p vp8 webm", 45: "720p vp8 webm", 46: "1080p vp8 webm", 59: "480p h264 mp4", 78: "480p h264 mp4", 82: "360p h264 3D", 83: "480p h264 3D", 84: "720p h264 3D", 85: "1080p h264 3D", 100: "360p vp8 3D", 101: "480p vp8 3D", 102: "720p vp8 3D" } url = 'http://www.youtube.com/get_video_info?video_id=%s&eurl=https://youtube.googleapis.com/v/%s&ssl_stream=1' % \ (video_id, video_id) data = httptools.downloadpage(url).data video_urls = [] params = dict(urlparse.parse_qsl(data)) if params.get('hlsvp'): video_urls.append(["(LIVE .m3u8) [youtube]", params['hlsvp']]) return video_urls if config.is_xbmc(): import xbmc xbmc_version = int( xbmc.getInfoLabel("System.BuildVersion").split(".", 1)[0]) if xbmc_version > 16 and xbmc.getCondVisibility('System.HasAddon(inputstream.adaptive)') \ and params.get('dashmpd'): if params.get('use_cipher_signature', '') != 'True': video_urls.append( ['mpd HD [youtube]', params['dashmpd'], 0, '', True]) js_signature = "" youtube_page_data = httptools.downloadpage( "http://www.youtube.com/watch?v=%s" % video_id).data params = extract_flashvars(youtube_page_data) if params.get('url_encoded_fmt_stream_map'): data_flashvars = params["url_encoded_fmt_stream_map"].split(",") for url_desc in data_flashvars: url_desc_map = dict(urlparse.parse_qsl(url_desc)) if not url_desc_map.get("url") and not url_desc_map.get("stream"): continue try: key = int(url_desc_map["itag"]) if not fmt_value.get(key): continue if url_desc_map.get("url"): url = urllib.unquote(url_desc_map["url"]) elif url_desc_map.get("conn") and url_desc_map.get("stream"): url = urllib.unquote(url_desc_map["conn"]) if url.rfind("/") < len(url) - 1: url += "/" url += urllib.unquote(url_desc_map["stream"]) elif url_desc_map.get( "stream") and not url_desc_map.get("conn"): url = urllib.unquote(url_desc_map["stream"]) if url_desc_map.get("sig"): url += "&signature=" + url_desc_map["sig"] elif url_desc_map.get("s"): sig = url_desc_map["s"] if not js_signature: urljs = scrapertools.find_single_match( youtube_page_data, '"assets":.*?"js":\s*"([^"]+)"') urljs = urljs.replace("\\", "") if urljs: if not re.search(r'https?://', urljs): urljs = urlparse.urljoin( "https://www.youtube.com", urljs) data_js = httptools.downloadpage(urljs).data from jsinterpreter import JSInterpreter funcname = scrapertools.find_single_match( data_js, '\.sig\|\|([A-z0-9$]+)\(') if not funcname: funcname = scrapertools.find_single_match( data_js, '["\']signature["\']\s*,\s*' '([A-z0-9$]+)\(') jsi = JSInterpreter(data_js) js_signature = jsi.extract_function(funcname) signature = js_signature([sig]) url += "&signature=" + signature url = url.replace(",", "%2C") video_urls.append(["" + fmt_value[key] + " -YouTube", url]) except: import traceback logger.info(traceback.format_exc()) return video_urls
def download_file(self): logger.info("DownloadThread.download_file Direct download") headers=[] # Ensures that the file can be created logger.info("DownloadThread.download_file nombrefichero="+self.file_name) self.file_name = xbmc.makeLegalFilename(self.file_name) logger.info("DownloadThread.download_file nombrefichero="+self.file_name) logger.info("DownloadThread.download_file url="+self.url) # Create the file existSize = 0 f = open(self.file_name, 'wb') grabado = 0 # Interprets the headers in a URL like in XBMC if "|" in self.url: additional_headers = self.url.split("|")[1] if "&" in additional_headers: additional_headers = additional_headers.split("&") else: additional_headers = [ additional_headers ] for additional_header in additional_headers: logger.info("DownloadThread.download_file additional_header: "+additional_header) name = re.findall( "(.*?)=.*?" , additional_header )[0] value = urllib.unquote_plus(re.findall( ".*?=(.*?)$" , additional_header )[0]) headers.append( [ name,value ] ) self.url = self.url.split("|")[0] logger.info("DownloadThread.download_file url="+self.url) # Timeout del socket a 60 segundos socket.setdefaulttimeout(60) # Create the request and add the headers h=urllib2.HTTPHandler(debuglevel=0) request = urllib2.Request(self.url) for header in headers: logger.info("DownloadThread.download_file Header="+header[0]+": "+header[1]) request.add_header(header[0],header[1]) # Launch request opener = urllib2.build_opener(h) urllib2.install_opener(opener) try: connexion = opener.open(request) except urllib2.HTTPError,e: logger.info("DownloadThread.download_file error %d (%s) al abrir la url %s" % (e.code,e.msg,self.url)) #print e.code #print e.msg #print e.hdrs #print e.fp f.close() # El error 416 es que el rango pedido es mayor que el fichero => es que ya está completo if e.code==416: return 0 else: return -2
def run(): logger.info("dss.platformcode.launcher run") # Extract item from sys.argv if sys.argv[2]: item = Item().fromurl(sys.argv[2]) # If no item, this is mainlist else: item = Item(channel="channelselector", action="getmainlist", viewmode="movie") if item.action != "actualiza": logger.info("dss.platformcode.launcher " + item.tostring()) try: if item.action == "editor_keymap": from platformcode import editor_keymap return editor_keymap.start() # If item has no action, stops here if item.action == "": logger.info("dss.platformcode.launcher Item sin accion") return # Action for main menu in channelselector if item.action == "getmainlist": import channelselector itemlist = channelselector.getmainlist() # Check for updates only on first screen if config.get_setting("updatecheck") == "true": logger.info("Check for plugin updates enabled") from core import updater try: update, version_publicada, message, url_repo, serv = updater.check( ) if update: new_item = Item( title="Descargar versión " + version_publicada, channel="updater", action="actualiza", thumbnail=channelselector.get_thumbnail_path() + "Crystal_Clear_action_info.png", version=version_publicada, url=url_repo, server=serv) if config.get_setting("updateauto") == "true": updater.actualiza(new_item) new_item = Item( title= "Info para ver los cambios en la nueva versión instalada", plot=message, action="", channel="", thumbnail=channelselector.get_thumbnail_path() + "Crystal_Clear_action_info.png", text_color="red") itemlist.insert(0, new_item) else: platformtools.dialog_ok( "Versión " + version_publicada + " disponible", message) itemlist.insert(0, new_item) except: import traceback logger.info(traceback.format_exc()) logger.info( "dss.platformcode.launcher Fallo al verificar la actualización" ) else: logger.info( "dss.platformcode.launcher Check for plugin updates disabled" ) if not config.get_setting("primer_uso_matchcenter"): config.set_setting("primer_uso_matchcenter", "true") platformtools.dialog_ok( "MatchCenter activado", "Reinicia Kodi para usarlo (pulsar tecla U)", "La tecla, botones y otras opciones pueden cambiarse en Configuración -> Preferencias -> MatchCenter" ) file_keyboard = xbmc.translatePath( "special://profile/keymaps/deportesalacarta.xml") if config.get_setting( "matchcenter_enabled" ) == "true" and not os.path.exists(file_keyboard): tecla = "61525" tecla_guardada = config.get_setting("keymap_edit", "editor_keymap") if tecla_guardada: tecla = tecla_guardada from core import filetools data = '<keymap><global><keyboard><key id="%s">' % tecla + 'runplugin(plugin://plugin.video.dss/?ewogICAgImFjdGlvbiI6ICJzdGFydCIsIAogICAgImNoYW5uZWwiOiAibWF0Y2hjZW50ZXIiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D))</key></keyboard></global></keymap>' filetools.write(file_keyboard, data) elif config.get_setting( "matchcenter_enabled") == "false" and os.path.exists( file_keyboard): from core import filetools try: filetools.remove(file_keyboard) except: pass platformtools.render_items(itemlist, item) # Action for updating plugin elif item.action == "actualiza": from core import updater updater.actualiza(item) xbmc.executebuiltin("Container.Refresh") # Action for channel listing on channelselector elif item.action == "filterchannels": import channelselector itemlist = channelselector.filterchannels(item.channel_type) platformtools.render_items(itemlist, item) # Action in certain channel specified in "action" and "channel" parameters else: can_open_channel = True # Checks if channel exists channel_file = os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py") logger.info("dss.platformcode.launcher channel_file=%s" % channel_file) channel = None if os.path.exists(channel_file): try: channel = __import__('channels.%s' % item.channel, None, None, ["channels.%s" % item.channel]) except ImportError: exec "import channels." + item.channel + " as channel" logger.info( "deportesalacarta.platformcode.launcher running channel " + channel.__name__ + " " + channel.__file__) # Special play action if item.action == "play": logger.info("dss.platformcode.launcher play") # logger.debug("item_toPlay: " + "\n" + item.tostring('\n')) # First checks if channel has a "play" function if hasattr(channel, 'play'): logger.info( "dss.platformcode.launcher executing channel 'play' method" ) itemlist = channel.play(item) b_favourite = item.isFavourite # Play should return a list of playable URLS if len(itemlist) > 0 and isinstance(itemlist[0], Item): item = itemlist[0] if b_favourite: item.isFavourite = True platformtools.play_video(item) #Permitir varias calidades desde play en el canal elif len(itemlist) > 0 and isinstance(itemlist[0], list): item.video_urls = itemlist platformtools.play_video(item) # If not, shows user an error message else: platformtools.dialog_ok("plugin", "There is nothing to play") # If player don't have a "play" function, not uses the standard play from platformtools else: logger.info( "dss.platformcode.launcher executing core 'play' method" ) platformtools.play_video(item) # Special action for findvideos, where the plugin looks for known urls elif item.action == "findvideos": # First checks if channel has a "findvideos" function if hasattr(channel, 'findvideos'): itemlist = getattr(channel, item.action)(item) # If not, uses the generic findvideos function else: logger.info( "dss.platformcode.launcher no channel 'findvideos' method, " "executing core method") from core import servertools itemlist = servertools.find_video_items(item) platformtools.render_items(itemlist, item) # Special action for searching, first asks for the words then call the "search" function elif item.action == "search": logger.info("dss.platformcode.launcher search") tecleado = platformtools.dialog_input("") if tecleado is not None: tecleado = tecleado.replace(" ", "+") # TODO revisar 'personal.py' porque no tiene función search y daría problemas itemlist = channel.search(item, tecleado) else: itemlist = [] platformtools.render_items(itemlist, item) # For all other actions else: logger.info("dss.platformcode.launcher executing channel '" + item.action + "' method") itemlist = getattr(channel, item.action)(item) platformtools.render_items(itemlist, item) except urllib2.URLError, e: import traceback logger.error("dss.platformcode.launcher " + traceback.format_exc()) # Grab inner and third party errors if hasattr(e, 'reason'): logger.info("dss.platformcode.launcher Razon del error, codigo: " + str(e.reason[0]) + ", Razon: " + str(e.reason[1])) texto = config.get_localized_string( 30050) # "No se puede conectar con el sitio web" platformtools.dialog_ok("plugin", texto) # Grab server response errors elif hasattr(e, 'code'): logger.info("dss.platformcode.launcher codigo de error HTTP : %d" % e.code) # "El sitio web no funciona correctamente (error http %d)" platformtools.dialog_ok( "plugin", config.get_localized_string(30051) % e.code)
def download_and_play(url,file_name,download_path): # Lanza thread logger.info("[download_and_play.py] Active threads "+str(threading.active_count())) logger.info("[download_and_play.py] "+repr(threading.enumerate())) logger.info("[download_and_play.py] Starting download thread...") download_thread = DownloadThread(url,file_name,download_path) download_thread.start() logger.info("[download_and_play.py] Download thread started") logger.info("[download_and_play.py] Active threads "+str(threading.active_count())) logger.info("[download_and_play.py] "+repr(threading.enumerate())) # Espera logger.info("[download_and_play.py] Waiting...") while True: cancelled=False dialog = xbmcgui.DialogProgress() dialog.create('Downloading...', 'Close this window to start playback') dialog.update(0) while not cancelled and download_thread.isAlive(): dialog.update( download_thread.get_progress() , "Cancel this window to start playback", "Speed: "+str(int(download_thread.get_speed()/1024))+" KB/s "+str(download_thread.get_actual_size())+"MB from "+str(download_thread.get_total_size())+"MB" , "Time left: "+str( downloadtools.sec_to_hms(download_thread.get_remaining_time())) ) xbmc.sleep(1000) if dialog.iscanceled(): cancelled=True break dialog.close() logger.info("[download_and_play.py] End of waiting") # Lanza el reproductor player = CustomPlayer() player.set_download_thread(download_thread) player.PlayStream( download_thread.get_file_name() ) # Fin de reproducción logger.info("[download_and_play.py] End of reproduction") if player.is_stopped(): logger.info("[download_and_play.py] Terminado por el usuario") break else: if not download_thread.isAlive(): logger.info("[download_and_play.py] Finished by the user") break else: logger.info("[download_and_play.py] Continue download") # Cuando el reproductor acaba, si continúa descargando lo para ahora logger.info("[download_and_play.py] Download thread alive="+str(download_thread.isAlive())) if download_thread.isAlive(): logger.info("[download_and_play.py] Killing download thread") download_thread.force_stop()