diff --git a/app.py b/app.py index a513254..9c60370 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,6 @@ # Validate configuration before starting the app from functions.validate_config import validate_config -from config import item_attributes, sql_conf +from config import item_attributes, sql_conf, app_secret_key config_status = validate_config(item_attributes) if config_status != "Ok": @@ -21,7 +21,7 @@ from routes.upload import upload_bp from routes.confirm_save import confirm_save_bp app = Flask(__name__) -app.secret_key = 'your_secret_key' # Required for flashing messages and session +app.secret_key = app_secret_key # Required for flashing messages and session app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql://{sql_conf.SQL_USER}:{sql_conf.SQL_PASSWORD}@{sql_conf.SQL_HOST}/{sql_conf.SQL_DB}' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) @@ -35,8 +35,14 @@ app.register_blueprint(delete_bp) app.register_blueprint(upload_bp) app.register_blueprint(confirm_save_bp) +# Create database table if it doesn't exist with app.app_context(): - db.create_all() + try: + db.create_all() + except exc.SQLAlchemyError as e: + # Log the error and exit gracefully + print(f"Database Error: Failed to create tables. {str(e)}") + raise SystemExit("Database connection failed. Please check your configuration.") @app.route('/') def index(): diff --git a/config.py b/config.py index 69fa98d..77ca50a 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,7 @@ from definitions.attribute import textAttribute, intAttribute, dateAttribute, selectAttribute +app_secret_key = "test_phase_secret_key" + # MySQL information class sql_conf: SQL_USER = "assetadmin" @@ -23,7 +25,7 @@ item_attributes = [ display_name="Host Name", required=True, unique=True, - regex=r"^[a-z0-9._-]+$" # Lowercase letters, numbers, dots, underscores, hyphens + allowed_chars="abcdefghijklmnopqrstuvwxyz0123456789.-_", # Lowercase letters, numbers, dots, underscores, hyphens ), dateAttribute( attrib_name="warrantyfrom", diff --git a/definitions/attribute.py b/definitions/attribute.py index 2ef308a..2886896 100644 --- a/definitions/attribute.py +++ b/definitions/attribute.py @@ -46,11 +46,15 @@ class textAttribute(Attribute): attrib_name: str, display_name: str, regex: Optional[str] = None, - max_length: int = 50, + min_length: Optional[int] = None, + max_length: Optional[int] = 50, + allowed_chars: Optional[str] = None, **kwargs ): super().__init__(attrib_name, display_name, html_input_type="text", **kwargs) self.regex = regex + self.allowed_chars = allowed_chars + self.min_length = min_length self.max_length = max_length def validate(self) -> Optional[str]: @@ -61,6 +65,10 @@ class textAttribute(Attribute): if self.default_val is not None and self.regex is not None: if not re.match(self.regex, str(self.default_val)): return f"Invalid default value for '{self.attrib_name}'. It must match the pattern: {self.regex}" + if self.allowed_chars is not None and self.default_val is not None: + for char in self.default_val: + if char not in self.allowed_chars: + return f"Invalid character '{char}' in default value for '{self.attrib_name}'. Allowed characters are: {self.allowed_chars}" return None diff --git a/templates/create.html b/templates/create.html index babcb76..fc9d364 100644 --- a/templates/create.html +++ b/templates/create.html @@ -39,6 +39,11 @@ {% if attrib.min_val is not none %} min="{{ attrib.min_val }}" {% endif %} {% if attrib.max_val is not none %} max="{{ attrib.max_val }}" {% endif %} {% endif %} + {% if attrib.html_input_type == "text" %} + {% if attrib.max_length is not none %} maxlength="{{ attrib.max_length }}" {% endif %} + {% if attrib.min_length is not none %} minlength="{{ attrib.min_length }}" {% endif %} + {% if attrib.regex is not none %} pattern="{{ attrib.regex }}" {% endif %} + {% endif %} {% if attrib.default_val is not none %} value="{{ attrib.default_val }}" {% endif %} /> {% endif %}