diff --git a/app.py b/app.py index d81555a..c228c54 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,27 @@ import psycopg2 + +from psycopg2 import pool + +# Crear un pool de conexiones global +connection_pool = psycopg2.pool.SimpleConnectionPool( + minconn=1, + maxconn=10, # Define el tamaño máximo del pool + dbname=os.getenv("DBNAME"), + user=os.getenv("DBUSER"), + password=os.getenv("DBPASSWORD"), + host=os.getenv("DBHOST"), + port=os.getenv("DBPORT") +) + +def get_db_connection(): + """Obtiene una conexión del pool""" + return connection_pool.getconn() + +def release_db_connection(conn): + """Libera una conexión y la devuelve al pool""" + connection_pool.putconn(conn) + + from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By @@ -29,19 +52,19 @@ service = Service('/usr/bin/chromedriver') driver = None def insert_alumno_extraccion(datos_html: str, materias_html: str, historial_html: str = 'error', materias_actuales_html: str = 'error'): + conn = get_db_connection() # Obtener una conexión del pool try: - conn = psycopg2.connect( - dbname=os.getenv("DBNAME"), - user=os.getenv("DBUSER"), - password=os.getenv("DBPASSWORD"), - host=os.getenv("DBHOST"), - port=os.getenv("DBPORT") - ) cur = conn.cursor() insert_query = """ - INSERT INTO public.alumno_extraccion ("Usuario_claveULSA", datos_html, materias_html, historial_html, materias_actuales_html) VALUES (%s, TRIM(%s), TRIM(%s), TRIM(%s)::JSONB, TRIM(%s)) - ON CONFLICT ("Usuario_claveULSA") DO UPDATE SET datos_html = EXCLUDED.datos_html, materias_html = EXCLUDED.materias_html, error_message = NULL, registrado = DEFAULT, historial_html = EXCLUDED.historial_html; + INSERT INTO public.alumno_extraccion ("Usuario_claveULSA", datos_html, materias_html, historial_html, materias_actuales_html) + VALUES (%s, TRIM(%s), TRIM(%s), TRIM(%s)::JSONB, TRIM(%s)) + ON CONFLICT ("Usuario_claveULSA") DO UPDATE + SET datos_html = EXCLUDED.datos_html, + materias_html = EXCLUDED.materias_html, + error_message = NULL, + registrado = DEFAULT, + historial_html = EXCLUDED.historial_html; """ cur.execute(insert_query, (username_integer, datos_html, materias_html, historial_html, materias_actuales_html)) @@ -55,23 +78,19 @@ def insert_alumno_extraccion(datos_html: str, materias_html: str, historial_html print(f"Error: {e}") finally: cur.close() - conn.close() + release_db_connection(conn) # Liberar la conexión + def update_alumno_extraccion_error(error: str): + conn = get_db_connection() # Obtener una conexión del pool try: - - conn = psycopg2.connect( - dbname=os.getenv("DBNAME"), - user=os.getenv("DBUSER"), - password=os.getenv("DBPASSWORD"), - host=os.getenv("DBHOST"), - port=os.getenv("DBPORT") - ) cur = conn.cursor() update_query = """ INSERT INTO public.alumno_extraccion ("Usuario_claveULSA", error_message) VALUES (%s, %s) - ON CONFLICT ("Usuario_claveULSA") DO UPDATE SET error_message = EXCLUDED.error_message, - materias_html = DEFAULT, registrado = DEFAULT; + ON CONFLICT ("Usuario_claveULSA") DO UPDATE + SET error_message = EXCLUDED.error_message, + materias_html = DEFAULT, + registrado = DEFAULT; """ cur.execute(update_query, (username_integer, error[:255])) @@ -79,10 +98,31 @@ def update_alumno_extraccion_error(error: str): print("Data updated successfully") except psycopg2.ProgrammingError as e: print(f"Error de sintaxis: {e}") - finally: cur.close() - conn.close() + release_db_connection(conn) # Liberar la conexión + +def se_puede_extraer(): + conn = get_db_connection() # Obtener una conexión del pool + try: + with conn.cursor() as cursor: + query = """ + SELECT 1 + FROM alumno_extraccion_fecha + WHERE CURRENT_DATE BETWEEN fecha_inicio AND fecha_fin + ORDER BY CREATED_AT DESC + LIMIT 1; + """ + cursor.execute(query) + result = cursor.fetchone() + return result is not None + except psycopg2.Error as e: + print(f"Error en la base de datos: {e}") + except Exception as e: + print(f"Error general: {e}") + finally: + release_db_connection(conn) # Liberar la conexión + def extract(username: str, password: str): url_credentials = f'https://{username}:{password}@sgu.ulsa.edu.mx/psulsa/alumnos/consultainformacionalumnos/consultainformacion.aspx' @@ -131,58 +171,22 @@ def extract(username: str, password: str): except NoSuchElementException as e: update_alumno_extraccion_error(str(e)) -def se_puede_extraer(): - try: - # Establece la conexión a la base de datos usando with para gestionar automáticamente el cierre - with psycopg2.connect( - dbname=os.getenv("DBNAME"), - user=os.getenv("DBUSER"), - password=os.getenv("DBPASSWORD"), - host=os.getenv("DBHOST"), - port=os.getenv("DBPORT") - ) as conn: - with conn.cursor() as cursor: - # SELECCIONAR ÚLTIMA planeacion - query = """ - SELECT 1 - FROM alumno_extraccion_fecha - WHERE CURRENT_DATE BETWEEN fecha_inicio AND fecha_fin - ORDER BY CREATED_AT DESC - LIMIT 1; - """ - # Ejecuta la consulta - cursor.execute(query) - result = cursor.fetchone() - - # Verifica si se obtuvo algún resultado - return result is not None - except psycopg2.Error as e: - # Maneja errores específicos de la base de datos - print(f"Error en la base de datos: {e}") - except Exception as e: - # Maneja otros tipos de errores - print(f"Error general: {e}") - return False app = Flask(__name__) @app.route('/calificaciones', methods=['POST']) def main(): - global driver - # Initialize the WebDriver - driver = webdriver.Chrome(service=service, options=chrome_options) - - username = request.form.get('clave') - password = request.form.get('password') - se_puede = se_puede_extraer() - if se_puede: - query = extract(username, password) - - # Close the session - driver.quit() - - return jsonify({"message": "Data extracted successfully", "en-fecha": se_puede}) - -if __name__ == '__main__': - serve(app, host='0.0.0.0', port=5000) + driver = None + try: + # Inicializa el WebDriver + driver = webdriver.Chrome(service=service, options=chrome_options) + username = request.form.get('clave') + password = request.form.get('password') + se_puede = se_puede_extraer() + if se_puede: + query = extract(username, password) + return jsonify({"message": "Data extracted successfully", "en-fecha": se_puede}) + finally: + if driver is not None: + driver.quit() # Asegura que el driver se cierre