def downloadfileGzipped(url, pathfichero): logger.info("url=" + url) nombrefichero = pathfichero logger.info("nombrefichero=" + nombrefichero) nombrefichero = filetools.makeLegalFilename(nombrefichero) logger.info("nombrefichero=" + nombrefichero) patron = "(http://[^/]+)/.+" matches = re.compile(patron, re.DOTALL).findall(url) if len(matches): logger.info("URL principal :" + 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 = "" # Crea el diálogo de progreso from platformcode import platformtools progreso = platformtools.dialog_progress( "addon", config.get_localized_string(60200), url.split("|")[0], nombrefichero) # Timeout del socket a 60 segundos socket.setdefaulttimeout(10) h = urllib2.HTTPHandler(debuglevel=0) request = urllib2.Request(url, txdata, txheaders) # if existSize > 0: # request.add_header('Range', 'bytes=%d-' % (existSize, )) opener = urllib2.build_opener(h) urllib2.install_opener(opener) try: connexion = opener.open(request) except urllib_error.HTTPError as e: logger.error("error %d (%s) al abrir la url %s" % (e.code, e.msg, url)) progreso.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 nombre_fichero_base = filetools.basename(nombrefichero) if len(nombre_fichero_base) == 0: logger.info("Buscando nombre en el Headers de respuesta") 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( "Nombre del fichero no encontrado, Colocando nombre temporal :sin_nombre.txt" ) titulo = "sin_nombre.txt" nombrefichero = filetools.join(pathfichero, titulo) try: totalfichero = int(connexion.headers["Content-Length"]) except ValueError: totalfichero = 1 # despues f = filetools.file_open(nombrefichero, 'w', vfs=VFS) logger.info("fichero nuevo abierto") 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("Iniciando descarga del fichero, bloqueleido=%s" % len(bloqueleido)) except: logger.error( "ERROR : El archivo a descargar no esta comprimido con Gzip") f.close() progreso.close() return -2 maxreintentos = 10 while len(bloqueleido) > 0: try: # Escribe el bloque leido 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)) # 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) 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 falta " % (descargadosmb, totalmb, percent, old_div(velocidad, 1024), sec_to_hms(tiempofalta))) break except: reintentos += 1 logger.info( "ERROR en la descarga del bloque, reintento %d" % reintentos) for line in sys.exc_info(): logger.error("%s" % line) # El usuario cancelo la descarga if progreso.iscanceled(): logger.info("Descarga del fichero cancelada") f.close() progreso.close() return -1 # Ha habido un error en la descarga if reintentos > maxreintentos: logger.info("ERROR en la descarga del fichero") f.close() progreso.close() return -2 except: logger.info("ERROR en la descarga del fichero") for line in sys.exc_info(): logger.error("%s" % line) f.close() progreso.close() return -2 f.close() # print data progreso.close() logger.info("Fin descarga del fichero") return nombrefichero
def download_file(self): logger.info("Direct download") headers = [] # Se asegura de que el fichero se podrá crear logger.info("nombrefichero=" + self.file_name) self.file_name = filetools.makeLegalFilename(self.file_name) logger.info("nombrefichero=" + self.file_name) logger.info("url=" + self.url) # Crea el fichero existSize = 0 f = open(self.file_name, 'wb') grabado = 0 # Interpreta las cabeceras en una URL como en 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("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("url=" + self.url) # Timeout del socket a 60 segundos socket.setdefaulttimeout(60) # Crea la petición y añade las cabeceras h = urllib2.HTTPHandler(debuglevel=0) request = urllib2.Request(self.url) for header in headers: logger.info("Header=" + header[0] + ": " + header[1]) request.add_header(header[0], header[1]) # Lanza la petición opener = urllib2.build_opener(h) urllib2.install_opener(opener) try: connexion = opener.open(request) except urllib_error.HTTPError as e: logger.error("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("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("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("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 = old_div(len(bloqueleido), ((after - before))) falta = totalfichero - grabado if self.velocidad > 0: self.tiempofalta = old_div(falta, self.velocidad) else: self.tiempofalta = 0 break except: import sys reintentos = reintentos + 1 logger.info("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.error("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 downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False, resumir=True, title="Alfa"): logger.info("url=" + url) logger.info("nombrefichero=" + nombrefichero) if headers is None: headers = [] progreso = None ret = 0 try: # Si no es XBMC, siempre a "Silent" from platformcode import platformtools # antes # f=open(nombrefichero,"wb") nombrefichero = filetools.makeLegalFilename(nombrefichero) logger.info("nombrefichero=" + nombrefichero) # El fichero existe y se quiere continuar if filetools.exists(nombrefichero) and continuar: f = filetools.file_open(nombrefichero, 'r+b', vfs=VFS) if resumir: exist_size = filetools.getsize(nombrefichero) logger.info("el fichero existe, size=%d" % exist_size) grabado = exist_size f.seek(exist_size) else: exist_size = 0 grabado = 0 # el fichero ya existe y no se quiere continuar, se aborta elif filetools.exists(nombrefichero) and not continuar: logger.info("el fichero existe, no se descarga de nuevo") return -3 # el fichero no existe else: exist_size = 0 logger.info("el fichero no existe") f = filetools.file_open(nombrefichero, 'wb', vfs=VFS) grabado = 0 # Crea el diálogo de progreso if not silent: progreso = platformtools.dialog_progress(title, "Descargando...", url, nombrefichero) # Si la plataforma no devuelve un cuadro de diálogo válido, asume modo silencio if progreso is None: silent = True if "|" in url: additional_headers = 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("additional_header: " + additional_header) name = re.findall("(.*?)=.*?", additional_header)[0] value = urllib.unquote_plus( re.findall(".*?=(.*?)$", additional_header)[0]) headers.append([name, value]) url = url.split("|")[0] logger.info("url=" + url) # Timeout del socket a 60 segundos socket.setdefaulttimeout(60) h = urllib2.HTTPHandler(debuglevel=0) request = urllib2.Request(url) for header in headers: logger.info("Header=" + header[0] + ": " + header[1]) request.add_header(header[0], header[1]) if exist_size > 0: request.add_header('Range', 'bytes=%d-' % (exist_size, )) opener = urllib2.build_opener(h) urllib2.install_opener(opener) try: connexion = opener.open(request) except urllib_error.HTTPError as e: logger.error("error %d (%s) al abrir la url %s" % (e.code, e.msg, url)) f.close() if not silent: progreso.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 ValueError: totalfichero = 1 if exist_size > 0: totalfichero = totalfichero + exist_size logger.info("Content-Length=%s" % totalfichero) blocksize = 100 * 1024 bloqueleido = connexion.read(blocksize) logger.info("Iniciando descarga del fichero, bloqueleido=%s" % len(bloqueleido)) maxreintentos = 10 while len(bloqueleido) > 0: try: # Escribe el bloque leido f.write(bloqueleido) grabado += len(bloqueleido) percent = int(float(grabado) * 100 / float(totalfichero)) totalmb = float(float(totalfichero) / (1024 * 1024)) descargadosmb = float(float(grabado) / (1024 * 1024)) # 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: 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)) if not silent: progreso.update( percent, "%.2fMB/%.2fMB (%d%%) %.2f Kb/s %s falta " % (descargadosmb, totalmb, percent, old_div(velocidad, 1024), sec_to_hms(tiempofalta))) break except: reintentos += 1 logger.info( "ERROR en la descarga del bloque, reintento %d" % reintentos) import traceback logger.error(traceback.print_exc()) # El usuario cancelo la descarga try: if progreso.iscanceled(): logger.info("Descarga del fichero cancelada") f.close() progreso.close() return -1 except: pass # Ha habido un error en la descarga if reintentos > maxreintentos: logger.info("ERROR en la descarga del fichero") f.close() if not silent: progreso.close() return -2 except: import traceback logger.error(traceback.print_exc()) f.close() if not silent: progreso.close() # platformtools.dialog_ok('Error al descargar' , 'Se ha producido un error' , 'al descargar el archivo') return -2 except: if url.startswith("rtmp"): error = downloadfileRTMP(url, nombrefichero, silent) if error and not silent: from platformcode import platformtools platformtools.dialog_ok("No puedes descargar ese vídeo", "Las descargas en RTMP aún no", "están soportadas") else: ret = -2 import traceback 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) try: f.close() except: pass if not silent: try: progreso.close() except: pass logger.info("Fin descarga del fichero") return ret