Пример #1
0
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
Пример #2
0
    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
Пример #3
0
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