From fef078f8faad7aa23d1faaa4212e7d7a88226d2f Mon Sep 17 00:00:00 2001 From: William Moreno Date: Sun, 3 Mar 2024 20:40:19 -0600 Subject: [PATCH 1/2] release: v0.0.1a14.dev20240303 (#44) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Next release (#41) * Tests: Valida more views Signed-off-by: William José Moreno Reyes * Test: Validate more tests Signed-off-by: William José Moreno Reyes * test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test: validate more views Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Remove setup.py file Signed-off-by: William José Moreno Reyes * chore: Update copyrithg notice Signed-off-by: William José Moreno Reyes * build: Remove black from test requeriments Signed-off-by: William José Moreno Reyes * build: Update dev dependencies Signed-off-by: William José Moreno Reyes * build: cleanup Signed-off-by: William José Moreno Reyes * build: update requeriments Signed-off-by: William José Moreno Reyes * build: Update build metadata Signed-off-by: William José Moreno Reyes * docs: update config Signed-off-by: William José Moreno Reyes * build: update docker base image Signed-off-by: William José Moreno Reyes * build: Update coverga report Signed-off-by: William José Moreno Reyes * buil: clean Signed-off-by: William José Moreno Reyes * build: update atributes Signed-off-by: William José Moreno Reyes * build: Update setup Signed-off-by: William José Moreno Reyes * build: Test coverage update Signed-off-by: William José Moreno Reyes * test: More tests Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 Signed-off-by: William José Moreno Reyes * build: Update config Signed-off-by: William José Moreno Reyes * feat: Configure mail backend with Flask-Mailman (#39) * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 (#35) * Tests: Valida more views Signed-off-by: William José Moreno Reyes * Test: Validate more tests Signed-off-by: William José Moreno Reyes * test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test: validate more views Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Remove setup.py file Signed-off-by: William José Moreno Reyes * chore: Update copyrithg notice Signed-off-by: William José Moreno Reyes * build: Remove black from test requeriments Signed-off-by: William José Moreno Reyes * build: Update dev dependencies Signed-off-by: William José Moreno Reyes * build: cleanup Signed-off-by: William José Moreno Reyes * build: update requeriments Signed-off-by: William José Moreno Reyes * build: Update build metadata Signed-off-by: William José Moreno Reyes * docs: update config Signed-off-by: William José Moreno Reyes * build: update docker base image Signed-off-by: William José Moreno Reyes * build: Update coverga report Signed-off-by: William José Moreno Reyes * buil: clean Signed-off-by: William José Moreno Reyes * build: update atributes Signed-off-by: William José Moreno Reyes * build: Update setup Signed-off-by: William José Moreno Reyes * build: Test coverage update Signed-off-by: William José Moreno Reyes * test: More tests Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Use flask-mailman Signed-off-by: William Moreno Reyes * feat: Setup email backend with Flask-Mailman Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno * build: Update config Signed-off-by: William José Moreno Reyes * build: update Signed-off-by: William José Moreno Reyes * build: Update config Signed-off-by: William José Moreno Reyes * build: Update entrypoint Signed-off-by: William José Moreno Reyes * test: Update test Signed-off-by: William José Moreno Reyes * build: Clean Signed-off-by: William José Moreno Reyes * build: Update test Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240302 Signed-off-by: William José Moreno Reyes * build: Add huey and gevent as dependencies Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno * Calendar (#43) * build: Remove setup.py Signed-off-by: William José Moreno Reyes * feat: initial work in calendar view Signed-off-by: William José Moreno Reyes * Fix: import errors Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 (#35) * Tests: Valida more views Signed-off-by: William José Moreno Reyes * Test: Validate more tests Signed-off-by: William José Moreno Reyes * test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test: validate more views Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Remove setup.py file Signed-off-by: William José Moreno Reyes * chore: Update copyrithg notice Signed-off-by: William José Moreno Reyes * build: Remove black from test requeriments Signed-off-by: William José Moreno Reyes * build: Update dev dependencies Signed-off-by: William José Moreno Reyes * build: cleanup Signed-off-by: William José Moreno Reyes * build: update requeriments Signed-off-by: William José Moreno Reyes * build: Update build metadata Signed-off-by: William José Moreno Reyes * docs: update config Signed-off-by: William José Moreno Reyes * build: update docker base image Signed-off-by: William José Moreno Reyes * build: Update coverga report Signed-off-by: William José Moreno Reyes * buil: clean Signed-off-by: William José Moreno Reyes * build: update atributes Signed-off-by: William José Moreno Reyes * build: Update setup Signed-off-by: William José Moreno Reyes * build: Test coverage update Signed-off-by: William José Moreno Reyes * test: More tests Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240302 (#38) * Tests: Valida more views Signed-off-by: William José Moreno Reyes * Test: Validate more tests Signed-off-by: William José Moreno Reyes * test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test: validate more views Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Remove setup.py file Signed-off-by: William José Moreno Reyes * chore: Update copyrithg notice Signed-off-by: William José Moreno Reyes * build: Remove black from test requeriments Signed-off-by: William José Moreno Reyes * build: Update dev dependencies Signed-off-by: William José Moreno Reyes * build: cleanup Signed-off-by: William José Moreno Reyes * build: update requeriments Signed-off-by: William José Moreno Reyes * build: Update build metadata Signed-off-by: William José Moreno Reyes * docs: update config Signed-off-by: William José Moreno Reyes * build: update docker base image Signed-off-by: William José Moreno Reyes * build: Update coverga report Signed-off-by: William José Moreno Reyes * buil: clean Signed-off-by: William José Moreno Reyes * build: update atributes Signed-off-by: William José Moreno Reyes * build: Update setup Signed-off-by: William José Moreno Reyes * build: Test coverage update Signed-off-by: William José Moreno Reyes * test: More tests Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 Signed-off-by: William José Moreno Reyes * build: Update config Signed-off-by: William José Moreno Reyes * feat: Configure mail backend with Flask-Mailman (#39) * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 (#35) * Tests: Valida more views Signed-off-by: William José Moreno Reyes * Test: Validate more tests Signed-off-by: William José Moreno Reyes * test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test Signed-off-by: William José Moreno Reyes * Test: validate more views Signed-off-by: William José Moreno Reyes * Update password hasher to argon2 (#37) * feat: Replace bcryp with argon2 for password hash References: - https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes - https://pypi.org/project/argon2-cffi/ - https://pypi.org/project/bcrypt/ Signed-off-by: William José Moreno Reyes * docs: Update docs Signed-off-by: William José Moreno Reyes * Test: Update test Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Remove setup.py file Signed-off-by: William José Moreno Reyes * chore: Update copyrithg notice Signed-off-by: William José Moreno Reyes * build: Remove black from test requeriments Signed-off-by: William José Moreno Reyes * build: Update dev dependencies Signed-off-by: William José Moreno Reyes * build: cleanup Signed-off-by: William José Moreno Reyes * build: update requeriments Signed-off-by: William José Moreno Reyes * build: Update build metadata Signed-off-by: William José Moreno Reyes * docs: update config Signed-off-by: William José Moreno Reyes * build: update docker base image Signed-off-by: William José Moreno Reyes * build: Update coverga report Signed-off-by: William José Moreno Reyes * buil: clean Signed-off-by: William José Moreno Reyes * build: update atributes Signed-off-by: William José Moreno Reyes * build: Update setup Signed-off-by: William José Moreno Reyes * build: Test coverage update Signed-off-by: William José Moreno Reyes * test: More tests Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240223 Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes * build: Use flask-mailman Signed-off-by: William Moreno Reyes * feat: Setup email backend with Flask-Mailman Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno * build: Update config Signed-off-by: William José Moreno Reyes * build: update Signed-off-by: William José Moreno Reyes * build: Update config Signed-off-by: William José Moreno Reyes * build: Update entrypoint Signed-off-by: William José Moreno Reyes * test: Update test Signed-off-by: William José Moreno Reyes * build: Clean Signed-off-by: William José Moreno Reyes * build: Update test Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240302 Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno * build: Update config Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno * Pagos (#42) * feat: initial work in payments Signed-off-by: William José Moreno Reyes * feat: Inital work in payments Signed-off-by: William José Moreno Reyes * Update python-package.yml Signed-off-by: William Moreno * Update python-package.yml Signed-off-by: William Moreno * Update publish.yml Signed-off-by: William Moreno --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno * test: Update test Signed-off-by: William José Moreno Reyes * build: Update coverage Signed-off-by: William José Moreno Reyes * build: Update coverage Signed-off-by: William José Moreno Reyes * release: v0.0.1a14.dev20240303 Signed-off-by: William José Moreno Reyes --------- Signed-off-by: William José Moreno Reyes Signed-off-by: William Moreno Reyes Signed-off-by: William Moreno --- .github/workflows/publish.yml | 5 +- .github/workflows/python-package.yml | 4 +- .lint.sh | 12 +-- .mypy.ini | 4 +- MANIFEST.in | 1 - now_lms/__init__.py | 2 + now_lms/auth.py | 2 +- now_lms/db/__init__.py | 35 ++++++-- now_lms/misc.py | 4 +- now_lms/static/package-lock.json | 66 ++++++++++++-- now_lms/static/package.json | 6 +- now_lms/version.py | 6 +- now_lms/vistas/calendar.py | 73 ++++++++++++++++ package-lock.json | 123 +++++++++++++++++++++++++++ package.json | 9 ++ requirements.txt | 4 + tests/test_vistas.py | 6 ++ tests/x_forms_data.py | 1 - 18 files changed, 328 insertions(+), 35 deletions(-) create mode 100644 now_lms/vistas/calendar.py create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1474c2fb..09a3387a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,8 +1,9 @@ name: Publish to PyPi on: - push: - branches: [main] + workflow_run: + workflows: ["CI"] + types: [completed] jobs: build: diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index a95a4252..a7b73154 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -1,13 +1,13 @@ # This workflow will install Python dependencies, run tests and lint with a variety of Python versions # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: Python package +name: CI on: push: branches: [main, development] pull_request: - branches: [main, development] + branches: [main, development, next-release] jobs: build: diff --git a/.lint.sh b/.lint.sh index 48921c3f..014d0ea9 100644 --- a/.lint.sh +++ b/.lint.sh @@ -1,18 +1,18 @@ #!/bin/bash -echo ------------------------------------------------- +echo ---------------------------------------------------- echo Check python code with ruff -echo ------------------------------------------------- +echo ---------------------------------------------------- echo python -m ruff now_lms echo -echo ------------------------------------------------- +echo ---------------------------------------------------- echo Check python types -echo ------------------------------------------------- +echo ---------------------------------------------------- echo python -m mypy now_lms --install-types --non-interactive echo -echo ------------------------------------------------- +echo ---------------------------------------------------- echo Lint html files wiht curlylint -echo ------------------------------------------------- +echo ---------------------------------------------------- echo # python -m curlylint now_lms/templates/ diff --git a/.mypy.ini b/.mypy.ini index fd6d8805..c46bd932 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,6 +1,6 @@ [mypy] -exclude = (?x)(^test\. # or files starting with "three." - ) +exclude = (?x)(^test\. # or files starting with "test." + ignore_missing_imports = True show_error_codes = True disable_error_code = union-attr, name-defined diff --git a/MANIFEST.in b/MANIFEST.in index ed2000d2..792b2069 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ include LICENSE include wsgi.py -include passenger_wsgi.py include Procfile include pyproject.toml graft now_lms/static diff --git a/now_lms/__init__.py b/now_lms/__init__.py index 91ee7f8a..351e5e0f 100644 --- a/now_lms/__init__.py +++ b/now_lms/__init__.py @@ -107,6 +107,7 @@ markdown_to_clean_hmtl, ) from now_lms.version import VERSION +from now_lms.vistas.calendar import calendar from now_lms.vistas.categories import category from now_lms.vistas.certificates import certificate from now_lms.vistas.courses import course @@ -180,6 +181,7 @@ def registrar_modulos_en_la_aplicacion_principal(flask_app: Flask): flask_app.register_blueprint(moderator_profile) flask_app.register_blueprint(user_profile) flask_app.register_blueprint(web_error) + flask_app.register_blueprint(calendar) # --------------------------------------------------------------------------------------- diff --git a/now_lms/auth.py b/now_lms/auth.py index 15a7ff21..e737e6f8 100644 --- a/now_lms/auth.py +++ b/now_lms/auth.py @@ -116,7 +116,7 @@ def proteger_secreto(password): ) key = base64.urlsafe_b64encode(kdf.derive(current_app.config.get("SECRET_KEY").encode())) f = Fernet(key) - return f.encrypt(password.encode()) + return f.encrypt(password) def descifrar_secreto(hash): diff --git a/now_lms/db/__init__.py b/now_lms/db/__init__.py index b1b168ee..18771e5e 100644 --- a/now_lms/db/__init__.py +++ b/now_lms/db/__init__.py @@ -154,13 +154,16 @@ class Curso(database.Model, BaseTabla): auditable = database.Column(database.Boolean()) precio = database.Column(database.Numeric()) capacidad = database.Column(database.Integer()) - fecha_inicio = database.Column(database.Date()) - fecha_fin = database.Column(database.Date()) - duracion = database.Column(database.Integer()) portada = database.Column(database.Boolean()) nivel = database.Column(database.Integer()) + # CEO promocionado = database.Column(database.Boolean()) fecha_promocionado = database.Column(database.DateTime, nullable=True) + # Duración del evento. + temporalidad = database.Column(database.String(10), nullable=True) + fecha_inicio = database.Column(database.Date()) + fecha_fin = database.Column(database.Date()) + duracion = database.Column(database.Integer()) class CursoRecursoDescargable(database.Model, BaseTabla): @@ -197,9 +200,6 @@ class CursoRecurso(database.Model, BaseTabla): # 1: Requerido, 2: Optional, 3: Alternativo requerido = database.Column(database.Integer(), default=1) url = database.Column(database.String(250), unique=False) - fecha = database.Column(database.Date()) - hora_inicio = database.Column(database.Time()) - hora_fin = database.Column(database.Time()) publico = database.Column(database.Boolean()) base_doc_url = database.Column(database.String(50), unique=False) doc = database.Column(database.String(50), unique=True) @@ -207,6 +207,10 @@ class CursoRecurso(database.Model, BaseTabla): text = database.Column(database.String(750)) external_code = database.Column(database.String(500)) notes = database.Column(database.String(20)) + # Temporalidad + fecha = database.Column(database.Date()) + hora_inicio = database.Column(database.Time()) + hora_fin = database.Column(database.Time()) class CursoRecursoAvance(database.Model, BaseTabla): @@ -473,9 +477,26 @@ class Mensaje(database.Model, BaseTabla): parent = database.Column(database.String(26), database.ForeignKey("mensaje.id"), nullable=True, index=True) -class PagosConfig(database.Model): +class StripeUserKey(database.Model): + """Datos de acceso de usuario a la plataforma de Stripe.""" + + id = database.Column( + database.String(26), primary_key=True, nullable=False, index=True, default=generador_de_codigos_unicos + ) + acceso = database.Column(database.LargeBinary(), nullable=False) + usuario = database.Column(database.String(26), database.ForeignKey(LLAVE_FORANEA_USUARIO), nullable=False, index=True) + + +class StripePaymentsConfig(database.Model): """Configuración de pagos.""" id = database.Column( database.String(26), primary_key=True, nullable=False, index=True, default=generador_de_codigos_unicos ) + # Relaciones foraneas + curso = database.Column(database.String(26), database.ForeignKey("curso.id"), nullable=False, index=True) + programa = database.Column(database.String(26), database.ForeignKey("programa.id"), nullable=False, index=True) + # Configuración de la API de Stripe + stripe_price_id = database.Column(database.String(60)) + stripe_product_id = database.Column(database.String(60)) + stripe_payment_url = database.Column(database.String(60)) diff --git a/now_lms/misc.py b/now_lms/misc.py index f171cdb8..62acc70b 100644 --- a/now_lms/misc.py +++ b/now_lms/misc.py @@ -47,7 +47,7 @@ def concatenar_parametros_a_url( argumentos: str = char - if parametros: + if parametros: # pragma: no cover if arg and val: parametros[arg] = val @@ -56,7 +56,7 @@ def concatenar_parametros_a_url( elif arg and val: argumentos = argumentos + "&" + arg + "=" + val - if char is not None and argumentos.find("&") == 1: + if char is not None and argumentos.find("&") == 1: # pragma: no cover argumentos = char + argumentos[2:] return argumentos diff --git a/now_lms/static/package-lock.json b/now_lms/static/package-lock.json index ad8c6996..7e77d4c5 100644 --- a/now_lms/static/package-lock.json +++ b/now_lms/static/package-lock.json @@ -5,13 +5,50 @@ "packages": { "": { "dependencies": { + "@fullcalendar/bootstrap5": "^6.1.11", + "@fullcalendar/core": "^6.1.11", + "@fullcalendar/icalendar": "^6.1.11", + "@fullcalendar/interaction": "^6.1.11", "bootstrap": "^5.2.3", - "bootstrap-icons": "^1.10.3", + "bootstrap-icons": "^1.11.3", "jquery": "^3.6.4", "reveal.js": "^4.4.0", "select2": "^4.1.0-rc.0" } }, + "node_modules/@fullcalendar/bootstrap5": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/bootstrap5/-/bootstrap5-6.1.11.tgz", + "integrity": "sha512-wZ2eYtZoi8VS2tcoe2oeca8wkkY85Nn+rH35JpFx35H77EMB5xBTtGAAEk9AClFkn+QscAwoOz3nyy1z0EqNpA==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11" + } + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz", + "integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==", + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/icalendar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/icalendar/-/icalendar-6.1.11.tgz", + "integrity": "sha512-a1kFIUs/G1ic9kkblL08n8Vwqw+jkBExhgFjbARVQrvyTwx0/SDmRtt0crqlkUYUOnu5nofj3xXPNupdxgPSwg==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11", + "ical.js": "^1.4.0" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz", + "integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -23,9 +60,9 @@ } }, "node_modules/bootstrap": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", - "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", "funding": [ { "type": "github", @@ -41,9 +78,9 @@ } }, "node_modules/bootstrap-icons": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.0.tgz", - "integrity": "sha512-bLTbtACfUqwZf6f/xUYUb7bTRZC68QaQwwy9h1b96NPKfnwqzSatHqDypW6R2CBW7zUE7lP+O93GdZuPY3RIHA==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", "funding": [ { "type": "github", @@ -55,11 +92,26 @@ } ] }, + "node_modules/ical.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", + "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==", + "peer": true + }, "node_modules/jquery": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/reveal.js": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-4.6.1.tgz", diff --git a/now_lms/static/package.json b/now_lms/static/package.json index 2d6513f2..2f454f1e 100644 --- a/now_lms/static/package.json +++ b/now_lms/static/package.json @@ -1,7 +1,11 @@ { "dependencies": { + "@fullcalendar/bootstrap5": "^6.1.11", + "@fullcalendar/core": "^6.1.11", + "@fullcalendar/icalendar": "^6.1.11", + "@fullcalendar/interaction": "^6.1.11", "bootstrap": "^5.2.3", - "bootstrap-icons": "^1.10.3", + "bootstrap-icons": "^1.11.3", "jquery": "^3.6.4", "reveal.js": "^4.4.0", "select2": "^4.1.0-rc.0" diff --git a/now_lms/version.py b/now_lms/version.py index b5bcebd3..3ef449d1 100644 --- a/now_lms/version.py +++ b/now_lms/version.py @@ -54,10 +54,10 @@ # Release string # Refences: # - https://peps.python.org/pep-0440/ -# 0.0.1a14.dev20240302 -if PRERELEASE: +# 0.0.1a14.dev20240303 +if PRERELEASE: # pragma: no cover VERSION = MAYOR + "." + MENOR + "." + PATCH + PRERELEASE + ".dev" + REVISION -else: +else: # pragma: no cover if not POST: VERSION = MAYOR + "." + MENOR + "." + PATCH else: diff --git a/now_lms/vistas/calendar.py b/now_lms/vistas/calendar.py new file mode 100644 index 00000000..aa10aac6 --- /dev/null +++ b/now_lms/vistas/calendar.py @@ -0,0 +1,73 @@ +# Copyright 2022 -2023 BMO Soluciones, S.A. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contributors: +# - William José Moreno Reyes + +""" +NOW Learning Management System. + +Gestión de eventos en una sesión +""" + +# --------------------------------------------------------------------------------------- +# Libreria estandar +# --------------------------------------------------------------------------------------- + + +# --------------------------------------------------------------------------------------- +# Librerias de terceros +# --------------------------------------------------------------------------------------- +from flask import Blueprint +from flask_login import login_required + +# --------------------------------------------------------------------------------------- +# Recursos locales +# --------------------------------------------------------------------------------------- +from now_lms.auth import perfil_requerido +from now_lms.config import DIRECTORIO_PLANTILLAS + +# --------------------------------------------------------------------------------------- +# Interfaz de calendario. +# --------------------------------------------------------------------------------------- + +calendar = Blueprint("calendar", __name__, template_folder=DIRECTORIO_PLANTILLAS) + + +@calendar.route("/calendar/") +@login_required +@perfil_requerido("user") +def calendario(course_ulid: str): + """Genera un calendario ical a partir de los eventos de un curso.""" + + +@calendar.route("/calendar//export") +@login_required +@perfil_requerido("user") +def calendario_export(course_ulid: str): + """Exporta un calendario ical a partir de los eventos de un curso.""" + + +@calendar.route("/calendar//event/") +@login_required +@perfil_requerido("user") +def calendario_evento(course_ulid: str, resource_id: str): + """Genera un evento a partir de un recurso del calendario.""" + + +@calendar.route("/calendar//event//export") +@login_required +@perfil_requerido("user") +def calendario_evento_export(course_ulid: str, resource_id: str): + """Exporta un evento a ical.""" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..f06dcbbb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,123 @@ +{ + "name": "now-lms", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@fullcalendar/bootstrap5": "^6.1.11", + "@fullcalendar/core": "^6.1.11", + "@fullcalendar/icalendar": "^6.1.11", + "@fullcalendar/interaction": "^6.1.11", + "bootstrap-icons": "^1.11.3" + } + }, + "node_modules/@fullcalendar/bootstrap5": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/bootstrap5/-/bootstrap5-6.1.11.tgz", + "integrity": "sha512-wZ2eYtZoi8VS2tcoe2oeca8wkkY85Nn+rH35JpFx35H77EMB5xBTtGAAEk9AClFkn+QscAwoOz3nyy1z0EqNpA==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11" + } + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz", + "integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==", + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/icalendar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/icalendar/-/icalendar-6.1.11.tgz", + "integrity": "sha512-a1kFIUs/G1ic9kkblL08n8Vwqw+jkBExhgFjbARVQrvyTwx0/SDmRtt0crqlkUYUOnu5nofj3xXPNupdxgPSwg==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11", + "ical.js": "^1.4.0" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz", + "integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.11" + } + }, + "node_modules/bootstrap-icons": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ] + }, + "node_modules/ical.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", + "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==", + "peer": true + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + } + }, + "dependencies": { + "@fullcalendar/bootstrap5": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/bootstrap5/-/bootstrap5-6.1.11.tgz", + "integrity": "sha512-wZ2eYtZoi8VS2tcoe2oeca8wkkY85Nn+rH35JpFx35H77EMB5xBTtGAAEk9AClFkn+QscAwoOz3nyy1z0EqNpA==", + "requires": {} + }, + "@fullcalendar/core": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz", + "integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==", + "requires": { + "preact": "~10.12.1" + } + }, + "@fullcalendar/icalendar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/icalendar/-/icalendar-6.1.11.tgz", + "integrity": "sha512-a1kFIUs/G1ic9kkblL08n8Vwqw+jkBExhgFjbARVQrvyTwx0/SDmRtt0crqlkUYUOnu5nofj3xXPNupdxgPSwg==", + "requires": {} + }, + "@fullcalendar/interaction": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz", + "integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==", + "requires": {} + }, + "bootstrap-icons": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==" + }, + "ical.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", + "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==", + "peer": true + }, + "preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..1a7d21a1 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "@fullcalendar/bootstrap5": "^6.1.11", + "@fullcalendar/core": "^6.1.11", + "@fullcalendar/icalendar": "^6.1.11", + "@fullcalendar/interaction": "^6.1.11", + "bootstrap-icons": "^1.11.3" + } +} diff --git a/requirements.txt b/requirements.txt index 86dcd53b..ef31e17e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,10 @@ flask-mde flask-reuploaded flask-sqlalchemy flask-wtf +icalendar +gevent +greenlet +huey loguru markdown python-ulid diff --git a/tests/test_vistas.py b/tests/test_vistas.py index 94c0e463..67601580 100644 --- a/tests/test_vistas.py +++ b/tests/test_vistas.py @@ -255,5 +255,11 @@ def test_email_backend(request, lms_application): follow_redirects=True, ) + from now_lms.auth import proteger_secreto, descifrar_secreto + + password = b"testing123abcqwerty" + + assert password == descifrar_secreto(proteger_secreto(password)) + else: pytest.skip("Not running slow test.") diff --git a/tests/x_forms_data.py b/tests/x_forms_data.py index c81b14ca..bf94cc56 100644 --- a/tests/x_forms_data.py +++ b/tests/x_forms_data.py @@ -1,6 +1,5 @@ from collections import namedtuple from io import BytesIO -from tkinter.messagebox import NO Form = namedtuple("form", ["ruta", "data", "file", "flash"]) From ed556faefdf0a5d13b66fc3c1e30548a63f90fea Mon Sep 17 00:00:00 2001 From: William Moreno Date: Mon, 1 Apr 2024 13:07:02 -0600 Subject: [PATCH 2/2] Create CODE_OF_CONDUCT.md Signed-off-by: William Moreno --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..1450f0f5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +soluciones.bmo@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations.