admin_transporte_backend/project/api/management/commands/procesa_zip.py

141 lines
4.4 KiB
Python

from django.core.management.base import BaseCommand
from django.utils import timezone
from django.db import connection
from api.models import GtfsArchivo, RedTransporte
from decouple import config
import os
import csv
import zipfile
import tempfile
import threading
class Command(BaseCommand):
help = 'Procesa los archivos gtfs en formato comprimido (zip)'
def handle(self, *args, **options):
# Lógica de tu comando aquí
folder = config('GTFS_UPLOADS','/tmp')
redes = RedTransporte.objects.filter(vigente=True)
for red in redes:
self.stdout.write(self.style.SUCCESS(f'nombre red: {red.nombre_red}'))
gtfs_archivo = GtfsArchivo.objects \
.filter(vigente=False, id_red = red.id_red, status = 'PENDIENTE') \
.order_by('-created') \
.first()
if gtfs_archivo != None:
gtfs_archivo.status = 'PROCESANDO'
gtfs_archivo.save()
filepath = os.path.join(folder, gtfs_archivo.ruta_archivo)
print(f'procesa: {filepath}')
procesa_zip(filepath)
registro_anterior = GtfsArchivo.objects.filter(vigente=True, id_red = red.id_red).first()
if registro_anterior:
registro_anterior.vigente = False
registro_anterior.save()
gtfs_archivo.status = 'GTFS CARGADO'
gtfs_archivo.vigente = True
gtfs_archivo.save()
self.stdout.write(self.style.SUCCESS('¡Comando ejecutado con éxito!'))
def procesa_zip(filepath):
carpeta_destino = tempfile.gettempdir()
# descomprimir archivo zip
archivo_zip = zipfile.ZipFile(filepath, "r")
password=''
try:
# Extraer todos los archivos del archivo ZIP
archivo_zip.extractall(pwd=password, path=carpeta_destino)
print("Archivos extraídos con éxito", flush=True)
except Exception as e:
print("Error al extraer archivos:", e, flush=True)
finally:
archivo_zip.close()
# Lista de archivos GTFS para cargar en la base de datos
gtfs_files = [
"agency.txt",
"calendar.txt",
"feed_info.txt",
"routes.txt",
"shapes.txt",
"stops.txt",
"stop_times.txt",
"trips.txt"
]
try:
# Crear las tablas en el esquema y cargar los datos
cur = connection.cursor()
for file in gtfs_files:
filepath = os.path.join(carpeta_destino, file)
if os.path.exists(filepath):
create_and_load_table(filepath, file, cur)
os.remove(filepath)
procesa_tablas_z(cur)
cur.close()
connection.commit()
except Exception as e:
print(f'ERROR: {e}', flush=True)
finally:
print('==============', flush=True)
print(f'fin proceso archivo: {archivo_zip}', flush=True)
# Función para crear la definición de la tabla como texto y cargar los datos
def create_and_load_table(filepath, file_name, cursor):
with open(filepath, 'r', encoding='utf-8-sig') as file:
reader = csv.reader(file)
columns = next(reader)
table_name = "z_"+file_name.replace('.txt', '')
column_definitions = ',\n'.join([f"{column_name} TEXT" for column_name in columns])
create_table = f"CREATE TABLE IF NOT EXISTS {table_name} (\n{column_definitions}\n);"
print(f'SQL> {create_table}', flush=True)
cursor.execute(create_table)
print('', flush=True)
truncate_table = f"truncate table {table_name}; commit;"
print(f'SQL> {truncate_table}', flush=True)
cursor.execute(truncate_table)
print('', flush=True)
file.seek(0)
next(reader)
insert_query = f"COPY {table_name} ({', '.join(columns)}) FROM STDIN WITH CSV"
print(f'SQL> {insert_query}', flush=True)
cursor.copy_expert(sql=insert_query, file=file)
print('', flush=True)
def procesa_tablas_z(cursor):
current_folder = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(current_folder, 'actualiza_GTFS.sql'),'r') as file:
content = ''.join(file.readlines())
arr_sql = content.split('-----')
for sql in arr_sql:
sql = sql.strip()
if sql > ' ':
print(f'SQL> {sql}', flush=True)
cursor.execute(sql)
print('', flush=True)