From 4e1176b1d53aa55b5294f3f76f006443d56aeda1 Mon Sep 17 00:00:00 2001 From: Dave Walker Date: Thu, 20 Feb 2025 10:47:33 +0000 Subject: [PATCH 1/2] Added the 'supports gender recording' flag to the category --- ...ad3_added_supports_gender_category_flag.py | 24 ++ .../versions/5ce1dfff9cd4_add_rbac_support.py | 9 +- alembic/versions/version_history.md | 8 + run_tests.sh | 10 + .../data_exchange_helper_base.py | 2 +- src/naturerec_model/logic/categories.py | 8 +- src/naturerec_model/model/category.py | 6 +- .../categories/categories_blueprint.py | 8 +- .../templates/categories/categories.html | 8 + .../categories/templates/categories/edit.html | 6 + .../sightings/sightings_blueprint.py | 22 +- .../sightings/templates/sightings/edit.html | 26 +- .../static/fontawesome/js/regular.js | 280 ------------------ 13 files changed, 118 insertions(+), 299 deletions(-) create mode 100644 alembic/versions/2cdd34308ad3_added_supports_gender_category_flag.py create mode 100644 alembic/versions/version_history.md create mode 100755 run_tests.sh delete mode 100644 src/naturerec_web/static/fontawesome/js/regular.js diff --git a/alembic/versions/2cdd34308ad3_added_supports_gender_category_flag.py b/alembic/versions/2cdd34308ad3_added_supports_gender_category_flag.py new file mode 100644 index 0000000..40dc819 --- /dev/null +++ b/alembic/versions/2cdd34308ad3_added_supports_gender_category_flag.py @@ -0,0 +1,24 @@ +"""Added 'supports gender' category flag + +Revision ID: 2cdd34308ad3 +Revises: b8960906cfcb +Create Date: 2025-02-20 09:27:58.112087 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '2cdd34308ad3' +down_revision = 'b8960906cfcb' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.add_column('Categories', sa.Column('Supports_Gender', sa.Integer, nullable=False, server_default="1")) + + +def downgrade() -> None: + op.drop_column('Categories', 'Supports_Gender') diff --git a/alembic/versions/5ce1dfff9cd4_add_rbac_support.py b/alembic/versions/5ce1dfff9cd4_add_rbac_support.py index f0bbb7e..de98fb9 100644 --- a/alembic/versions/5ce1dfff9cd4_add_rbac_support.py +++ b/alembic/versions/5ce1dfff9cd4_add_rbac_support.py @@ -52,11 +52,14 @@ def upgrade() -> None: user_ids = [user.id for user in users] user_ids.sort() + # Identify the "default" user ID, accounting for the fact that there may not be any users yet + user_id = user_ids[0] if len(user_ids) > 0 else 0 + # Create the roles, using the first user as the creator for name in ["Administrator", "Reporter", "Reader"]: session.add(Role(name=name, - created_by=user_ids[0], - updated_by=user_ids[0], + created_by=user_id, + updated_by=user_id, date_created=datetime.now(), date_updated=datetime.now())) @@ -64,7 +67,7 @@ def upgrade() -> None: admin_role = session.query(Role).filter(Role.name=="Administrator").first() for user_id in user_ids: bind.execute(f"INSERT INTO UserRoles ( user_id, role_id, created_by, date_created ) " - f"VALUES ( {user_id}, {admin_role.id}, {user_ids[0]}, '{str(datetime.now())}')") + f"VALUES ( {user_id}, {admin_role.id}, {user_id}, '{str(datetime.now())}')") session.commit() diff --git a/alembic/versions/version_history.md b/alembic/versions/version_history.md new file mode 100644 index 0000000..ed50c43 --- /dev/null +++ b/alembic/versions/version_history.md @@ -0,0 +1,8 @@ +| File | Revision | Down | +| ------------------------------------------------ | ------------ | ------------ | +| 5a2e355711a1_initial_migration | 5a2e355711a1 | - | +| 560b0df5ff2a_add_user_audit_columns | 560b0df5ff2a | 5a2e355711a1 | +| e95d3cceae06_add_date_audit_columns | e95d3cceae06 | 560b0df5ff2a | +| 5ce1dfff9cd4_add_rbac_support | 5ce1dfff9cd4 | e95d3cceae06 | +| b8960906cfcb_add_species_scientific_name | b8960906cfcb | 5ce1dfff9cd4 | +| 2cdd34308ad3_added_supports_gender_category_flag | 2cdd34308ad3 | b8960906cfcb | diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 0000000..2d1ceb3 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,10 @@ +#!/bin/sh -f + +export PROJECT_ROOT=$( cd "$( dirname "$0" )" && pwd ) +. $PROJECT_ROOT/venv/bin/activate +export PYTHONPATH=$PROJECT_ROOT/src + +echo "Project root = $PROJECT_ROOT" +echo "Python Path = $PYTHONPATH" + +python -m unittest diff --git a/src/naturerec_model/data_exchange/data_exchange_helper_base.py b/src/naturerec_model/data_exchange/data_exchange_helper_base.py index e8b988b..47dbbd1 100644 --- a/src/naturerec_model/data_exchange/data_exchange_helper_base.py +++ b/src/naturerec_model/data_exchange/data_exchange_helper_base.py @@ -73,7 +73,7 @@ def create_species(self, category_name, species_name, scientific_name): try: category = get_category(tidied_category_name) except ValueError: - category = create_category(tidied_category_name, self._user) + category = create_category(tidied_category_name, True, self._user) return create_species(category.id, tidied_species_name, tidied_scientific_name, self._user).id # See if the species exists against the existing category. If so, just return its ID diff --git a/src/naturerec_model/logic/categories.py b/src/naturerec_model/logic/categories.py index 0369d2e..a78ba1a 100644 --- a/src/naturerec_model/logic/categories.py +++ b/src/naturerec_model/logic/categories.py @@ -21,11 +21,12 @@ def _check_for_existing_records(session, name): return [category.id for category in categories] -def create_category(name, user): +def create_category(name, supports_gender, user): """ Create a new species category :param name: Category name + :param supports_gender: True if the category supports entry of gender against sightings :param user: Current user :returns: An instance of the Category class for the created record :raises ValueError: If the specified name is None, an empty string or consists solely of whitespace @@ -41,6 +42,7 @@ def create_category(name, user): raise ValueError("Duplicate category found") category = Category(name=tidied, + supports_gender=supports_gender, created_by=user.id, updated_by=user.id, date_created=dt.utcnow(), @@ -52,12 +54,13 @@ def create_category(name, user): return category -def update_category(category_id, name, user): +def update_category(category_id, name, supports_gender, user): """ Update an existing species category :param category_id: ID for the category record to update :param name: Category name + :param supports_gender: True if the category supports entry of gender against sightings :param user: Current user :returns: An instance of the Category class for the updated record :raises ValueError: If the specified name is None, an empty string or consists solely of whitespace @@ -85,6 +88,7 @@ def update_category(category_id, name, user): raise ValueError("Category not found") category.name = tidied + category.supports_gender = supports_gender category.updated_by = user.id category.date_updated = dt.utcnow() except IntegrityError as e: diff --git a/src/naturerec_model/model/category.py b/src/naturerec_model/model/category.py index 8d4661f..a6cf2cf 100644 --- a/src/naturerec_model/model/category.py +++ b/src/naturerec_model/model/category.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, Integer, String, UniqueConstraint, CheckConstraint, DateTime +from sqlalchemy import Column, Integer, String, UniqueConstraint, CheckConstraint, DateTime, Boolean from sqlalchemy.orm import relationship from .base import Base @@ -13,6 +13,8 @@ class Category(Base): id = Column(Integer, primary_key=True) #: Category name name = Column(String, nullable=False, unique=True) + #: Whether the category supports entry of gender via the UI + supports_gender = Column(Integer, nullable=False, default=1) #: Audit columns created_by = Column(Integer, nullable=False) updated_by = Column(Integer, nullable=False) @@ -29,4 +31,4 @@ class Category(Base): CheckConstraint("LENGTH(TRIM(name)) > 0")) def __repr__(self): - return f"{type(self).__name__}(Id={self.id!r}, name={self.name!r})" + return f"{type(self).__name__}(Id={self.id!r}, name={self.name!r}, supports_gender={self.supports_gender!r})" diff --git a/src/naturerec_web/categories/categories_blueprint.py b/src/naturerec_web/categories/categories_blueprint.py index 40cc516..160e573 100644 --- a/src/naturerec_web/categories/categories_blueprint.py +++ b/src/naturerec_web/categories/categories_blueprint.py @@ -67,11 +67,15 @@ def edit(category_id): :return: The HTML for the category entry page or a response object redirecting to the category list page """ if request.method == "POST": + # The "supports gender" flag is a check box and is only POSTed if it's checked. If it's unchecked, it + # won't appear in the form data + supports_gender = True if "supports_gender" in request.form else False + try: if category_id: - _ = update_category(category_id, request.form["name"], current_user) + _ = update_category(category_id, request.form["name"], supports_gender, current_user) else: - _ = create_category(request.form["name"], current_user) + _ = create_category(request.form["name"], supports_gender, current_user) return redirect("/categories/list") except ValueError as e: return _render_category_editing_page(category_id, e) diff --git a/src/naturerec_web/categories/templates/categories/categories.html b/src/naturerec_web/categories/templates/categories/categories.html index 338e0b5..a49e273 100644 --- a/src/naturerec_web/categories/templates/categories/categories.html +++ b/src/naturerec_web/categories/templates/categories/categories.html @@ -2,6 +2,7 @@ + {% if edit_enabled %} @@ -11,6 +12,13 @@ {% for category in categories %} + {% if edit_enabled %}
NameSupports Gender Recording
{{ category.name }} + {% if category.supports_gender %} + Yes + {% else %} + No + {% endif %} + diff --git a/src/naturerec_web/categories/templates/categories/edit.html b/src/naturerec_web/categories/templates/categories/edit.html index a71d600..65c5890 100644 --- a/src/naturerec_web/categories/templates/categories/edit.html +++ b/src/naturerec_web/categories/templates/categories/edit.html @@ -2,10 +2,12 @@ {% set title = "Edit Category" %} {% set submit_title = "Save Category" %} {% set name = category.name %} + {% set supports_gender = "checked" if category.supports_gender else "" %} {% else %} {% set title = "Add Category" %} {% set submit_title = "Add Category" %} {% set name = "" %} + {% set supports_gender = "" %} {% endif %} {% extends "layout.html" %} @@ -21,6 +23,10 @@

{{ title }}

+
+ + +