-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMD-DownloadManager.py
142 lines (114 loc) · 5.45 KB
/
CMD-DownloadManager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import os
import re
import requests
import sys
import time
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from urllib.parse import urlparse
def solicitar_datos_usuario():
# Solicita al usuario la URL, el nombre del archivo y la ubicación de descarga
url = input("Introduce la URL del archivo: ")
nombre = input("Introduce el nombre del archivo: ")
ubicacion = input("Introduce la ubicación donde se guardará el archivo: ")
return url, nombre, ubicacion
def validar_datos(url, ubicacion):
# Valida que la URL y la ubicación de descarga sean válidas
if not validar_url(url):
print('La URL no es válida.')
return False
if not validar_ubicacion(ubicacion):
print('La ubicación no es válida.')
return False
return True
def validar_url(url):
# Valida que la URL sea válida utilizando el módulo urlparse
try:
resultado = urlparse(url)
return all([resultado.scheme, resultado.netloc])
except ValueError:
return False
def validar_ubicacion(ubicacion):
# Valida que la ubicación de descarga sea un directorio válido y tenga permisos de escritura
return os.path.isdir(ubicacion) and os.access(ubicacion, os.W_OK)
def descargar_archivo(url, nombre, ubicacion):
# Descarga el archivo desde la URL especificada y lo guarda en la ubicación de descarga especificada
try:
respuesta = requests.get(url, stream=True, verify=True)
respuesta.raise_for_status()
if respuesta.status_code == 200:
extension = url.split(".")[-1]
ruta_archivo = f"{ubicacion}/{nombre}.{extension}"
with open(ruta_archivo, "wb") as archivo:
tamano_archivo = int(respuesta.headers.get("content-length", 0))
progreso = tqdm(total=tamano_archivo, unit="B", unit_scale=True)
tiempo_inicial = time.time()
for datos in respuesta.iter_content(chunk_size=1024):
archivo.write(datos)
progreso.update(len(datos))
tiempo_transcurrido = time.time() - tiempo_inicial
if tiempo_transcurrido > 0:
velocidad = progreso.n / (1024 * tiempo_transcurrido)
progreso.set_postfix({"Velocidad": f"{velocidad:.2f} kbps",
"Tiempo restante": f"{(tamano_archivo - progreso.n) / (velocidad * 1024):.0f} s"})
progreso.close()
print("Archivo descargado con éxito.")
else:
print("No se pudo descargar el archivo.")
except KeyboardInterrupt:
print("\nDescarga interrumpida por el usuario.")
if 'ruta_archivo' in locals() and os.path.exists(ruta_archivo):
os.remove(ruta_archivo)
except requests.exceptions.HTTPError as e:
print(f"Error al descargar el archivo: {e}")
except Exception as e:
print(f"Error: {e}")
def descargar_archivo_paralelo(url, nombre, ubicacion, num_hilos):
# Descarga el archivo desde la URL especificada en paralelo utilizando múltiples hilos
try:
respuesta = requests.get(url, stream=True, verify=True)
respuesta.raise_for_status()
if respuesta.status_code == 200:
extension = url.split(".")[-1]
ruta_archivo = f"{ubicacion}/{nombre}.{extension}"
with open(ruta_archivo, "wb") as archivo:
tamano_archivo = int(respuesta.headers.get("content-length", 0))
progreso = tqdm(total=tamano_archivo, unit="B", unit_scale=True)
tiempo_inicial = time.time()
hilos = []
with ThreadPoolExecutor(max_workers=num_hilos) as executor:
for datos in respuesta.iter_content(chunk_size=1024):
hilo = executor.submit(archivo.write, datos)
hilos.append(hilo)
for hilo in tqdm(hilos, total=len(hilos), desc="Descargando", leave=False):
hilo.result()
progreso.update(1024)
tiempo_transcurrido = time.time() - tiempo_inicial
if tiempo_transcurrido > 0:
velocidad = progreso.n / (1024 * tiempo_transcurrido)
progreso.set_postfix({"Velocidad": f"{velocidad:.2f} kbps",
"Tiempo restante": f"{(tamano_archivo - progreso.n) / (velocidad * 1024):.0f} s"})
progreso.close()
print("Archivo descargado con éxito.")
else:
print("No se pudo descargar el archivo.")
except KeyboardInterrupt:
print("\nDescarga interrumpida por el usuario.")
if 'ruta_archivo' in locals() and os.path.exists(ruta_archivo):
os.remove(ruta_archivo)
except requests.exceptions.HTTPError as e:
print(f"Error al descargar el archivo: {e}")
except Exception as e:
print(f"Error: {e}")
def main():
try:
# Solicita al usuario URL, el nombre del archivo y la ubicación de descarga
url, nombre, ubicacion = solicitar_datos_usuario()
# Valida los datos de entrada
if validar_datos(url, ubicacion):
# Descarga el archivo utilizando un solo hilo
descargar_archivo(url, nombre, ubicacion)
except KeyboardInterrupt:
print("\nPrograma interrumpido por el usuario.")
if __name__ == "__main__":
main()