From cccae9abc904b7c288f34cfef9fd2c405e9066a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 11:23:06 -0600 Subject: [PATCH 01/10] Adding PyTest --- requirements.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/requirements.txt b/requirements.txt index 6f40933..c8c7cba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,15 @@ blinker==1.9.0 click==8.1.8 +exceptiongroup==1.2.2 Flask==3.1.0 +iniconfig==2.0.0 itsdangerous==2.2.0 Jinja2==3.1.5 MarkupSafe==3.0.2 +packaging==24.2 +pluggy==1.5.0 psycopg2-binary==2.9.10 +pytest==8.3.4 python-dotenv==1.0.1 +tomli==2.2.1 Werkzeug==3.1.3 From d0771f08021095c5348be8519cc02e790802a734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 13:19:39 -0600 Subject: [PATCH 02/10] Including ORM file --- data/orm.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 data/orm.py diff --git a/data/orm.py b/data/orm.py new file mode 100644 index 0000000..dab81a1 --- /dev/null +++ b/data/orm.py @@ -0,0 +1,71 @@ + +import psycopg2 +from psycopg2.extras import RealDictCursor + +class ORM(): + _table_name = None + + def __init__(self, **kwargs): + for key, value in kwargs.items(): + setattr(self, key, value) + + + @classmethod + def _get_connection(cls): + return psycopg2.connect( + dbname = 'users', + user = 'tester', + password = 'Tester669$', + host = 'localhost', + port = '5432' + ) + + + @classmethod + def find(cls, **kwargs): + conn = cls._get_connection() + try: + with conn.cursor(cursor_factory=RealDictCursor) as cur: + where_clause = ' AND '.join([f"{key} = %s" for key in kwargs]) + query = f"SELECT * FROM {cls._table_name or cls.__name__.lower()} WHERE {where_clause}" + cur.execute(query, tuple(kwargs.values())) + result = cur.fetchone() + ins = cls(**result) if result else None + return ins + finally: + conn.close() + + + def save(self): + conn = self._get_connection() + try: + with conn.cursor() as cur: + attributes = { k: v for k, v in self.__dict__.items() if not k.startswith('_') } + if hasattr(self, 'id'): + set_clause = ", ".join([f"{key} = %s" for key in attributes if key != 'id']) + query = f"UPDATE {self._table_name or self.__class__.__name__.lower()} SET {set_clause} WHERE id = %s" + cur.execute(query, tuple(attributes.values()) + (self.id,)) + else: + columns = ", ".join(attributes.keys()) + placeholders = ", ".join(["%s"] * len(attributes)) + query = f"INSERT INTO {self._table_name or self.__class__.__name__.lower()} ({columns}) VALUES ({placeholders}) RETURNING id" + cur.execute(query, tuple(attributes.values())) + self.id = cur.fetchone()[0] + finally: + conn.close() + + + def delete(self): + if not hasattr(self, 'id') or not self.id: + raise ValueError("Cannot delete unsaved record") + conn = self._get_connection() + try: + with conn.cursor() as cur: + query = f"DELETE FROM {self._table_name or self.__class__.__name__.lower()} WHERE id = %s" + cur.execute(query, (self.id,)) + conn.commit() + finally: + conn.close() + + + From 002f0644f180af862c857635f6553fceb91750c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 13:49:34 -0600 Subject: [PATCH 03/10] Final version ORM --- data/__init__.py | 3 ++- data/orm.py | 22 +++++++++++++++------- test.py | 26 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 test.py diff --git a/data/__init__.py b/data/__init__.py index c6736f4..ee88a05 100644 --- a/data/__init__.py +++ b/data/__init__.py @@ -1 +1,2 @@ -from .db import User, Permission, DBException, DB \ No newline at end of file +from .db import User, Permission, DBException, DB +from .orm import ORM \ No newline at end of file diff --git a/data/orm.py b/data/orm.py index dab81a1..7185236 100644 --- a/data/orm.py +++ b/data/orm.py @@ -1,9 +1,11 @@ import psycopg2 from psycopg2.extras import RealDictCursor +import datetime class ORM(): _table_name = None + _exclude_fields = ['created_at', 'updated_at', 'update_at', 'id'] def __init__(self, **kwargs): for key, value in kwargs.items(): @@ -40,17 +42,23 @@ def save(self): conn = self._get_connection() try: with conn.cursor() as cur: - attributes = { k: v for k, v in self.__dict__.items() if not k.startswith('_') } + attributes = { k: v for k, v in self.__dict__.items() if k not in self._exclude_fields } if hasattr(self, 'id'): set_clause = ", ".join([f"{key} = %s" for key in attributes if key != 'id']) - query = f"UPDATE {self._table_name or self.__class__.__name__.lower()} SET {set_clause} WHERE id = %s" + query = f"UPDATE {self._table_name or self.__class__.__name__.lower()} SET {set_clause} WHERE id = %s" + + print(query) + print(tuple(attributes.values()) + (self.id,)) + cur.execute(query, tuple(attributes.values()) + (self.id,)) + conn.commit() else: - columns = ", ".join(attributes.keys()) - placeholders = ", ".join(["%s"] * len(attributes)) - query = f"INSERT INTO {self._table_name or self.__class__.__name__.lower()} ({columns}) VALUES ({placeholders}) RETURNING id" - cur.execute(query, tuple(attributes.values())) - self.id = cur.fetchone()[0] + columns = ", ".join(attributes.keys()) + placeholders = ", ".join(["%s"] * len(attributes)) + query = f"INSERT INTO {self._table_name or self.__class__.__name__.lower()} ({columns}) VALUES ({placeholders}) RETURNING id" + cur.execute(query, tuple(attributes.values())) + self.id = cur.fetchone()[0] + conn.commit() finally: conn.close() diff --git a/test.py b/test.py new file mode 100644 index 0000000..52eb182 --- /dev/null +++ b/test.py @@ -0,0 +1,26 @@ +from data import ORM + +class Users(ORM): + pass + +class Modules(ORM) : + pass + + +if __name__ == '__main__': + user = Users.find(id=8) + user.delete() + + data = { + 'name': 'Test', + 'lastname': 'Test lastname', + 'email': 'gogo@gogo.com' , + 'password': 'asdasdfsadff', + 'hash': 'asdasdfsadff', + 'role_id':6 + } + + # user = Users(**data) + # user.save() + # print(user.__dict__) + From c256ffb9c3cd966bcc96d6e74794cdaab623dbcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 14:30:10 -0600 Subject: [PATCH 04/10] Unit testing --- data/__init__.py | 4 +-- data/db.py | 69 +--------------------------------------------- data/models.py | 31 ++++++++------------- test.py | 35 ++++++++++++++--------- tests/__init__.py | 0 tests/test_data.py | 49 ++++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 102 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_data.py diff --git a/data/__init__.py b/data/__init__.py index ee88a05..01f69a0 100644 --- a/data/__init__.py +++ b/data/__init__.py @@ -1,2 +1,2 @@ -from .db import User, Permission, DBException, DB -from .orm import ORM \ No newline at end of file +from .orm import ORM +from .models import Users, Modules, Roles, Permissions \ No newline at end of file diff --git a/data/db.py b/data/db.py index b7d2ebb..a1df5c8 100644 --- a/data/db.py +++ b/data/db.py @@ -1,68 +1 @@ -import psycopg2 - -from .models import User, Permission - - -class DBException(Exception): - pass - - -class DB(): - db_params = None - connection = None - - def __init__(self, db_params): - self.db_params = db_params - - - def connect(self): - self.connection = psycopg2.connect(**self.db_params) - return self - - - def tuple_to_user(self, data): - user = User() - user.id = data[0] - user.name = data[1] - user.lastname = data[2] - user.email = data[3] - user.password = data[4] - user.role = data[5] - user.created_at = data[6] - user.updated_at = data[7] - return user - - - def get_user(self, id): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users WHERE id = %s" - cursor = self.connection.cursor() - cursor.execute(query, (str(id))) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return self.tuple_to_user(result) - - - def get_user_by_email(self, email): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users WHERE email = %s" - cursor = self.connection.cursor() - cursor.execute(query, (email, )) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return self.tuple_to_user(result) - - - def get_users(self): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users" - cursor = self.connection.cursor() - cursor.execute(query) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return [self.tuple_to_user(row) for row in result] - - +import psycopg2 \ No newline at end of file diff --git a/data/models.py b/data/models.py index 1066b37..6e97168 100644 --- a/data/models.py +++ b/data/models.py @@ -1,23 +1,16 @@ -import datetime +from .orm import ORM -class Permission(): - name: str - can_update: bool - can_write: bool - can_delete: bool - can_read: bool +class Users(ORM): + pass -class User(): - name : str - lastname :str - email : str - role : str - password : str - created_at : datetime - updated_at : datetime - permissions : [Permission] # type: ignore +class Modules(ORM): + pass - def login(self, password): - return self.password == password - + +class Roles(ORM): + pass + + +class Permissions(ORM): + pass \ No newline at end of file diff --git a/test.py b/test.py index 52eb182..3a6b03d 100644 --- a/test.py +++ b/test.py @@ -1,26 +1,35 @@ from data import ORM +from data.models import Users, Modules, Roles, Permissions -class Users(ORM): - pass +if __name__ == '__main__': -class Modules(ORM) : - pass + module = Modules() + module.name = 'Testing' + module.save() + role = Roles() + role.name = 'Tester' + role.save() -if __name__ == '__main__': - user = Users.find(id=8) - user.delete() + permission = Permissions() + permission.role_id = role.id + permission.module_id = module.id + permission.can_write = True + permission.can_read = True + permission.can_update = True + permission.can_delete = True + permission.save() data = { - 'name': 'Test', + 'name': 'Tester', 'lastname': 'Test lastname', - 'email': 'gogo@gogo.com' , + 'email': 'tester@gogo.com' , 'password': 'asdasdfsadff', 'hash': 'asdasdfsadff', - 'role_id':6 + 'role_id': role.id } - # user = Users(**data) - # user.save() - # print(user.__dict__) + user = Users(**data) + user.save() + print(user.__dict__) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_data.py b/tests/test_data.py new file mode 100644 index 0000000..7533091 --- /dev/null +++ b/tests/test_data.py @@ -0,0 +1,49 @@ +import pytest +from data import Users, Modules, Roles, Permissions + + +def test_user_flow(): + module = Modules() + module.name = 'Testing' + module.save() + + assert type(module.id) is int + + role = Roles() + role.name = 'Tester' + role.save() + + assert type(role.id) is int + + + permission = Permissions() + permission.role_id = role.id + permission.module_id = module.id + permission.can_write = True + permission.can_read = True + permission.can_update = True + permission.can_delete = True + permission.save() + + assert type(permission.id) is int + + + data = { + 'name': 'Tester', + 'lastname': 'Test lastname', + 'email': 'lllllll@gogo.com' , + 'password': 'asdasdfsadff', + 'hash': 'asdasdfsadff', + 'role_id': role.id + } + + user = Users(**data) + user.save() + + assert type(user.id) is int + print(user.__dict__) + + user.delete() + permission.delete() + role.delete() + module.delete() \ No newline at end of file From ee0c7aa2a3dfbe65713b99eba937b0d5a05eb0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 15:02:53 -0600 Subject: [PATCH 05/10] Enviroment Vars --- data/orm.py | 16 +++++++++------- requirements.txt | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/data/orm.py b/data/orm.py index 7185236..3421713 100644 --- a/data/orm.py +++ b/data/orm.py @@ -2,6 +2,9 @@ import psycopg2 from psycopg2.extras import RealDictCursor import datetime +from dotenv import load_dotenv +import os + class ORM(): _table_name = None @@ -15,13 +18,12 @@ def __init__(self, **kwargs): @classmethod def _get_connection(cls): return psycopg2.connect( - dbname = 'users', - user = 'tester', - password = 'Tester669$', - host = 'localhost', - port = '5432' - ) - + dbname = os.environ.get('DB_NAME'), + user = os.environ.get('DB_USER'), + password = os.environ.get('DB_PASSWORD'), + host = os.environ.get('DB_HOST'), + port = os.environ.get('DB_PORT') + ) @classmethod def find(cls, **kwargs): diff --git a/requirements.txt b/requirements.txt index c8c7cba..31ec4f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ packaging==24.2 pluggy==1.5.0 psycopg2-binary==2.9.10 pytest==8.3.4 +pytest-dotenv==0.5.2 python-dotenv==1.0.1 tomli==2.2.1 Werkzeug==3.1.3 From 94d845c1d220989a918feddde9146ebf4f02c58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 16:07:39 -0600 Subject: [PATCH 06/10] Template --- app.py | 27 ++++----------------------- data/orm.py | 4 ---- templates/base.html | 42 ++++++++++++++++++++++++++++++++++++++++++ templates/login.html | 28 ++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 templates/base.html create mode 100644 templates/login.html diff --git a/app.py b/app.py index 4720bd1..67aaa2e 100644 --- a/app.py +++ b/app.py @@ -1,22 +1,13 @@ from flask import Flask, render_template, request, redirect, url_for, render_template_string from flask import session -from data.db import DB -from dotenv import load_dotenv +from data import Users, Roles, Permissions, Modules import os import psycopg2 app = Flask(__name__) -load_dotenv() app.secret_key = os.environ.get('SECRET_KEY') -base = { - 'dbname': os.environ.get('DB_NAME'), - 'user': os.environ.get('DB_USER'), - 'password': os.environ.get('DB_PASSWORD'), - 'host': os.environ.get('DB_HOST'), - 'port': os.environ.get('DB_PORT') -} @app.route('/', methods=['GET', 'POST']) def login(): @@ -30,26 +21,16 @@ def login(): else: error = "El Usuario o Contraseña son Incorrectos." - return render_template_string(""" - {% if error %} -

{{ error }}

- {% endif %} -
- Usuario:
- Contraseña:
- -
- """, error=error) + return render_template('login.html', error=error) def is_valid_user(username :str, password :str) -> bool: try: - db = DB(base) - user = db.connect().get_user_by_email(username) + user = Users().find(email=username) if not user: return False - if not user.login(password): + if user.password != password: return False session['user_id'] = user.id diff --git a/data/orm.py b/data/orm.py index 3421713..f29142e 100644 --- a/data/orm.py +++ b/data/orm.py @@ -48,10 +48,6 @@ def save(self): if hasattr(self, 'id'): set_clause = ", ".join([f"{key} = %s" for key in attributes if key != 'id']) query = f"UPDATE {self._table_name or self.__class__.__name__.lower()} SET {set_clause} WHERE id = %s" - - print(query) - print(tuple(attributes.values()) + (self.id,)) - cur.execute(query, tuple(attributes.values()) + (self.id,)) conn.commit() else: diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..d0f2741 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,42 @@ + + + + + + {% block title %}Login App{% endblock %} + + + + + +
+ {% block content %} + {% endblock %} +
+ + + + + + \ No newline at end of file diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..109a577 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,28 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+
+
+
+

Login

+
+
+
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file From 6b23644747632c55e451dd63c9d92316f861fe9d Mon Sep 17 00:00:00 2001 From: AlexGrt221 Date: Fri, 27 Dec 2024 16:09:10 -0600 Subject: [PATCH 07/10] cambios --- .gitignore | 2 +- data/__init__.py | 4 +-- data/db.py | 69 +----------------------------------------------- data/models.py | 31 +++++++++------------- test.py | 36 +++++++++++++++---------- 5 files changed, 38 insertions(+), 104 deletions(-) diff --git a/.gitignore b/.gitignore index 15201ac..b37a122 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ __pycache__/ *.py[cod] *$py.class - +entorno/ # C extensions *.so diff --git a/data/__init__.py b/data/__init__.py index ee88a05..01f69a0 100644 --- a/data/__init__.py +++ b/data/__init__.py @@ -1,2 +1,2 @@ -from .db import User, Permission, DBException, DB -from .orm import ORM \ No newline at end of file +from .orm import ORM +from .models import Users, Modules, Roles, Permissions \ No newline at end of file diff --git a/data/db.py b/data/db.py index b7d2ebb..a1df5c8 100644 --- a/data/db.py +++ b/data/db.py @@ -1,68 +1 @@ -import psycopg2 - -from .models import User, Permission - - -class DBException(Exception): - pass - - -class DB(): - db_params = None - connection = None - - def __init__(self, db_params): - self.db_params = db_params - - - def connect(self): - self.connection = psycopg2.connect(**self.db_params) - return self - - - def tuple_to_user(self, data): - user = User() - user.id = data[0] - user.name = data[1] - user.lastname = data[2] - user.email = data[3] - user.password = data[4] - user.role = data[5] - user.created_at = data[6] - user.updated_at = data[7] - return user - - - def get_user(self, id): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users WHERE id = %s" - cursor = self.connection.cursor() - cursor.execute(query, (str(id))) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return self.tuple_to_user(result) - - - def get_user_by_email(self, email): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users WHERE email = %s" - cursor = self.connection.cursor() - cursor.execute(query, (email, )) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return self.tuple_to_user(result) - - - def get_users(self): - query = "SELECT id, name, lastname, email, password, role_id, created_at, update_at FROM users" - cursor = self.connection.cursor() - cursor.execute(query) - result = cursor.fetchone() - if not result: - raise DBException("User not found") - self.connection.close() - return [self.tuple_to_user(row) for row in result] - - +import psycopg2 \ No newline at end of file diff --git a/data/models.py b/data/models.py index 1066b37..ac2f058 100644 --- a/data/models.py +++ b/data/models.py @@ -1,23 +1,16 @@ -import datetime +from orm import ORM -class Permission(): - name: str - can_update: bool - can_write: bool - can_delete: bool - can_read: bool +class Users(ORM): + pass -class User(): - name : str - lastname :str - email : str - role : str - password : str - created_at : datetime - updated_at : datetime - permissions : [Permission] # type: ignore +class Modules(ORM): + pass - def login(self, password): - return self.password == password - + +class Roles(ORM): + pass + + +class Permissions(ORM): + pass diff --git a/test.py b/test.py index 52eb182..ee7c40c 100644 --- a/test.py +++ b/test.py @@ -1,26 +1,34 @@ from data import ORM +from data.models import Users, Modules, Roles, Permissions -class Users(ORM): - pass +if __name__ == '__main__': -class Modules(ORM) : - pass + module = Modules() + module.name = 'Testing' + module.save() + role = Roles() + role.name = 'Tester' + role.save() -if __name__ == '__main__': - user = Users.find(id=8) - user.delete() + permission = Permissions() + permission.role_id = role.id + permission.module_id = module.id + permission.can_write = True + permission.can_read = True + permission.can_update = True + permission.can_delete = True + permission.save() data = { - 'name': 'Test', + 'name': 'Tester', 'lastname': 'Test lastname', - 'email': 'gogo@gogo.com' , + 'email': 'tester@gogo.com' , 'password': 'asdasdfsadff', 'hash': 'asdasdfsadff', - 'role_id':6 + 'role_id': role.id } - # user = Users(**data) - # user.save() - # print(user.__dict__) - + user = Users(**data) + user.save() + print(user.__dict__) \ No newline at end of file From 6228c3e0787ea630b96fcd54fcdaee9dcd4ad060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Rangel?= Date: Fri, 27 Dec 2024 17:13:29 -0600 Subject: [PATCH 08/10] Modules crud --- app.py | 103 +++++++++++++++++++++++++++++------- data/db.py | 1 - data/orm.py | 17 +++++- templates/base.html | 4 +- templates/modules.html | 41 ++++++++++++++ templates/modules_form.html | 25 +++++++++ templates/welcome.html | 12 +++++ 7 files changed, 179 insertions(+), 24 deletions(-) delete mode 100644 data/db.py create mode 100644 templates/modules.html create mode 100644 templates/modules_form.html create mode 100644 templates/welcome.html diff --git a/app.py b/app.py index 67aaa2e..0563a5b 100644 --- a/app.py +++ b/app.py @@ -43,32 +43,95 @@ def is_valid_user(username :str, password :str) -> bool: @app.route('/datos') def show_data(): try: - connection = psycopg2.connect(**base) - cursor = connection.cursor() + if not session.get('user_id'): + return redirect(url_for('login')) + user = Users().find(id=session.get('user_id')) + return render_template('welcome.html', user=user) + + except Exception as e: + return f"Error: {e}" + + +@app.route('/modules') +def show_modules(): + try: + if not session.get('user_id'): + return redirect(url_for('login')) + user = Users().find(id=session.get('user_id')) + modules = Modules().all() + + return render_template('modules.html', user=user, modules=modules) + + except Exception as e: + return f"Error: {e}" + +@app.route('/modules/create') +def create_modules(): + try: + if not session.get('user_id'): + return redirect(url_for('login')) + + return render_template('modules_form.html', id=0) + + except Exception as e: + return f"Error: {e}" + + + +@app.route('/modules/edit/') +def edit_modules(id: int): + try: if not session.get('user_id'): - return redirect(url_for('login')) - - query = """ - SELECT - a.id, a.name, a.lastname, b."name", d."name", - c.can_read, c.can_write, c.can_update, c.can_delete - FROM - users a - JOIN roles b ON a.role_id = b.id - JOIN permissions c ON c.role_id = b.id - JOIN modules d ON c.module_id = d.id WHERE a.id = %s - """ + return redirect(url_for('login')) - cursor.execute(query, (session['user_id'],)) - records = cursor.fetchall() - - cursor.close() - connection.close() - return render_template('table.html', records=records) + module = Modules().find(id=id) + return render_template('modules_form.html', id=id, module=module) except Exception as e: return f"Error: {e}" + + + +@app.route('/modules/save', methods=['POST']) +def save_modules(): + try: + if not session.get('user_id'): + return redirect(url_for('login')) + + id = int(request.form.get('id')) + name = request.form.get('name') + if name is None or name == '': + return render_template('modules_form.html', id=id, error="El nombre del módulo es requerido.") + + if id == 0: + module = Modules(name=name) + else: + module = Modules().find(id=id) + module.name = name + + module.save() + return redirect(url_for('show_modules')) + + except Exception as e: + return f"Error: {e}" + + +@app.route('/modules/delete/', methods=['GEt']) +def delete_modules(id: int): + try: + if not session.get('user_id'): + return redirect(url_for('login')) + + module = Modules().find(id=id) + if module: + module.delete() + return redirect(url_for('show_modules')) + + except Exception as e: + return f"Error: {e}" + + if __name__ == '__main__': app.run(debug=True) \ No newline at end of file diff --git a/data/db.py b/data/db.py deleted file mode 100644 index a1df5c8..0000000 --- a/data/db.py +++ /dev/null @@ -1 +0,0 @@ -import psycopg2 \ No newline at end of file diff --git a/data/orm.py b/data/orm.py index f29142e..0c21a59 100644 --- a/data/orm.py +++ b/data/orm.py @@ -25,6 +25,7 @@ def _get_connection(cls): port = os.environ.get('DB_PORT') ) + @classmethod def find(cls, **kwargs): conn = cls._get_connection() @@ -37,7 +38,21 @@ def find(cls, **kwargs): ins = cls(**result) if result else None return ins finally: - conn.close() + conn.close() + + + @classmethod + def all(cls, **kwargs)-> list: + conn = cls._get_connection() + try: + with conn.cursor(cursor_factory=RealDictCursor) as cur: + query = f"SELECT * FROM {cls._table_name or cls.__name__.lower()}" + cur.execute(query, tuple(kwargs.values())) + result = cur.fetchall() + return [] if not result else [cls(**row) for row in result] + finally: + conn.close() + def save(self): diff --git a/templates/base.html b/templates/base.html index d0f2741..79f2deb 100644 --- a/templates/base.html +++ b/templates/base.html @@ -15,10 +15,10 @@