diff --git a/Dockerfile.prod b/Dockerfile.prod index acfe82339..c08c80858 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -8,8 +8,9 @@ RUN apk add --no-cache mysql-client \ # Set the working directory in the container to /app WORKDIR /app -# Copy the contents of the local app/ directory to the /app directory in the container +# Copy files COPY app/ ./app +COPY core/ ./core # Copy requirements.txt into the working directory /app COPY requirements.txt . diff --git a/app/__init__.py b/app/__init__.py index a328c58a9..36de9ab2a 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,14 +1,15 @@ import os -import logging -from flask import Flask, render_template +from flask import Flask from flask_login import current_user from flask_sqlalchemy import SQLAlchemy from dotenv import load_dotenv from flask_migrate import Migrate -from app.managers.blueprint_manager import BlueprintManager -from app.managers.config_manager import ConfigManager +from core.managers.blueprint_manager import BlueprintManager +from core.managers.config_manager import ConfigManager +from core.managers.error_handler_manager import ErrorHandlerManager +from core.managers.logging_manager import LoggingManager # Load environment variables load_dotenv() @@ -43,12 +44,13 @@ def load_user(user_id): from app.blueprints.auth.models import User return User.query.get(int(user_id)) - # Logging - logging.basicConfig(filename='app.log', level=logging.ERROR, - format='%(asctime)s:%(levelname)s:%(message)s') + # Set up logging + logging_manager = LoggingManager(app) + logging_manager.setup_logging() - # Custom error handlers - register_error_handlers(app) + # Initialize error handler manager + error_handler_manager = ErrorHandlerManager(app) + error_handler_manager.register_error_handlers() # Injecting environment variables into jinja context @app.context_processor @@ -62,28 +64,6 @@ def inject_vars_into_jinja(): return app -def register_error_handlers(app): - @app.errorhandler(500) - def base_error_handler(e): - app.logger.error('Internal Server Error: %s', str(e)) # Error logging - return render_template('500.html'), 500 - - @app.errorhandler(404) - def error_404_handler(e): - app.logger.warning('Page Not Found: %s', str(e)) # Warning logging - return render_template('404.html'), 404 - - @app.errorhandler(401) - def error_401_handler(e): - app.logger.warning('Unauthorized Access: %s', str(e)) # Warning logging - return render_template('401.html'), 401 - - @app.errorhandler(400) - def error_400_handler(e): - app.logger.warning('Bad Request: %s', str(e)) # Warning logging - return render_template('400.html'), 400 - - def get_test_client(): """ Function to get the test client of the application. diff --git a/app/blueprints/auth/seeders.py b/app/blueprints/auth/seeders.py index 14397315b..99237cbd0 100644 --- a/app/blueprints/auth/seeders.py +++ b/app/blueprints/auth/seeders.py @@ -1,6 +1,6 @@ from app.blueprints.auth.models import User from app.blueprints.profile.models import UserProfile -from app.seeders.BaseSeeder import BaseSeeder +from core.seeders.BaseSeeder import BaseSeeder class AuthSeeder(BaseSeeder): diff --git a/app/blueprints/profile/repositories.py b/app/blueprints/profile/repositories.py index 9b6717730..dbc35e377 100644 --- a/app/blueprints/profile/repositories.py +++ b/app/blueprints/profile/repositories.py @@ -1,5 +1,5 @@ from app.blueprints.profile.models import UserProfile -from app.repositories.BaseRepository import BaseRepository +from core.repositories.BaseRepository import BaseRepository class UserProfileRepository(BaseRepository): diff --git a/app/blueprints/profile/services.py b/app/blueprints/profile/services.py index 61b4c72a6..4c66b2cc0 100644 --- a/app/blueprints/profile/services.py +++ b/app/blueprints/profile/services.py @@ -1,5 +1,5 @@ from app.blueprints.profile.repositories import UserProfileRepository -from app.services.BaseService import BaseService +from core.services.BaseService import BaseService class UserProfileService(BaseService): diff --git a/app/blueprints/zenodo/repositories.py b/app/blueprints/zenodo/repositories.py index 8ee608d98..79b822b08 100644 --- a/app/blueprints/zenodo/repositories.py +++ b/app/blueprints/zenodo/repositories.py @@ -1,5 +1,5 @@ from app.blueprints.zenodo.models import Zenodo -from app.repositories.BaseRepository import BaseRepository +from core.repositories.BaseRepository import BaseRepository class ZenodoRepository(BaseRepository): diff --git a/app/blueprints/zenodo/services.py b/app/blueprints/zenodo/services.py index 2d7393182..3e3febbc3 100644 --- a/app/blueprints/zenodo/services.py +++ b/app/blueprints/zenodo/services.py @@ -1,5 +1,5 @@ from app.blueprints.zenodo.repositories import ZenodoRepository -from app.services.BaseService import BaseService +from core.services.BaseService import BaseService import os diff --git a/app/managers/__init__.py b/core/__init__.py similarity index 100% rename from app/managers/__init__.py rename to core/__init__.py diff --git a/app/repositories/__init__.py b/core/managers/__init__.py similarity index 100% rename from app/repositories/__init__.py rename to core/managers/__init__.py diff --git a/app/managers/blueprint_manager.py b/core/managers/blueprint_manager.py similarity index 100% rename from app/managers/blueprint_manager.py rename to core/managers/blueprint_manager.py diff --git a/app/managers/config_manager.py b/core/managers/config_manager.py similarity index 100% rename from app/managers/config_manager.py rename to core/managers/config_manager.py diff --git a/core/managers/error_handler_manager.py b/core/managers/error_handler_manager.py new file mode 100644 index 000000000..ecb631ee4 --- /dev/null +++ b/core/managers/error_handler_manager.py @@ -0,0 +1,27 @@ +from flask import render_template + + +class ErrorHandlerManager: + def __init__(self, app): + self.app = app + + def register_error_handlers(self): + @self.app.errorhandler(500) + def internal_error(e): + self.app.logger.error('Internal Server Error: %s', str(e)) + return render_template('500.html'), 500 + + @self.app.errorhandler(404) + def not_found_error(e): + self.app.logger.warning('Page Not Found: %s', str(e)) + return render_template('404.html'), 404 + + @self.app.errorhandler(401) + def unauthorized_error(e): + self.app.logger.warning('Unauthorized Access: %s', str(e)) + return render_template('401.html'), 401 + + @self.app.errorhandler(400) + def bad_request_error(e): + self.app.logger.warning('Bad Request: %s', str(e)) + return render_template('400.html'), 400 diff --git a/core/managers/logging_manager.py b/core/managers/logging_manager.py new file mode 100644 index 000000000..85fc8ad47 --- /dev/null +++ b/core/managers/logging_manager.py @@ -0,0 +1,29 @@ +import logging +from logging.handlers import RotatingFileHandler + + +class LoggingManager: + def __init__(self, app): + self.app = app + + def setup_logging(self): + # Configure log format + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + + # Configure the log file with file rotation + file_handler = RotatingFileHandler('app.log', maxBytes=10240, backupCount=10) + file_handler.setLevel(logging.ERROR) + file_handler.setFormatter(formatter) + + # Add handler to app logger + self.app.logger.addHandler(file_handler) + + # Configure console log if necessary + if self.app.debug: + stream_handler = logging.StreamHandler() + stream_handler.setLevel(logging.INFO) + stream_handler.setFormatter(formatter) + self.app.logger.addHandler(stream_handler) + + # Set the overall log level + self.app.logger.setLevel(logging.INFO) diff --git a/app/repositories/BaseRepository.py b/core/repositories/BaseRepository.py similarity index 100% rename from app/repositories/BaseRepository.py rename to core/repositories/BaseRepository.py diff --git a/app/seeders/__init__.py b/core/repositories/__init__.py similarity index 100% rename from app/seeders/__init__.py rename to core/repositories/__init__.py diff --git a/app/seeders/BaseSeeder.py b/core/seeders/BaseSeeder.py similarity index 100% rename from app/seeders/BaseSeeder.py rename to core/seeders/BaseSeeder.py diff --git a/app/services/__init__.py b/core/seeders/__init__.py similarity index 100% rename from app/services/__init__.py rename to core/seeders/__init__.py diff --git a/app/services/BaseService.py b/core/services/BaseService.py similarity index 100% rename from app/services/BaseService.py rename to core/services/BaseService.py diff --git a/core/services/__init__.py b/core/services/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/public/.gitignore b/public/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/public/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/rosemary/commands/db_seed.py b/rosemary/commands/db_seed.py index 65068b0f8..8349d1e17 100644 --- a/rosemary/commands/db_seed.py +++ b/rosemary/commands/db_seed.py @@ -4,7 +4,7 @@ import click from flask.cli import with_appcontext -from app.seeders.BaseSeeder import BaseSeeder +from core.seeders.BaseSeeder import BaseSeeder from rosemary.commands.db_reset import db_reset diff --git a/rosemary/commands/linter.py b/rosemary/commands/linter.py index 33e7fbd09..def19ea15 100644 --- a/rosemary/commands/linter.py +++ b/rosemary/commands/linter.py @@ -6,7 +6,7 @@ def linter(): # Define the directories to be checked with flake8 - directories = ["/app/app", "/app/rosemary"] + directories = ["/app/app", "/app/rosemary", "/app/core"] # Run flake8 in each directory for directory in directories: diff --git a/rosemary/templates/blueprint_repositories.py.j2 b/rosemary/templates/blueprint_repositories.py.j2 index 1f627c368..a56c460a5 100644 --- a/rosemary/templates/blueprint_repositories.py.j2 +++ b/rosemary/templates/blueprint_repositories.py.j2 @@ -1,5 +1,5 @@ from app.blueprints.{{ blueprint_name }}.models import {{ blueprint_name | pascalcase }} -from app.repositories.BaseRepository import BaseRepository +from core.repositories.BaseRepository import BaseRepository class {{ blueprint_name | pascalcase }}Repository(BaseRepository): diff --git a/rosemary/templates/blueprint_seeders.py.j2 b/rosemary/templates/blueprint_seeders.py.j2 index 52e87a24a..c59bbe0c5 100644 --- a/rosemary/templates/blueprint_seeders.py.j2 +++ b/rosemary/templates/blueprint_seeders.py.j2 @@ -1,4 +1,4 @@ -from app.seeders.BaseSeeder import BaseSeeder +from core.seeders.BaseSeeder import BaseSeeder class {{ blueprint_name | pascalcase }}Seeder(BaseSeeder): diff --git a/rosemary/templates/blueprint_services.py.j2 b/rosemary/templates/blueprint_services.py.j2 index 3b28efa59..38a90bff1 100644 --- a/rosemary/templates/blueprint_services.py.j2 +++ b/rosemary/templates/blueprint_services.py.j2 @@ -1,5 +1,5 @@ from app.blueprints.{{ blueprint_name }}.repositories import {{ blueprint_name | pascalcase }}Repository -from app.services.BaseService import BaseService +from core.services.BaseService import BaseService class {{ blueprint_name | pascalcase }}(BaseService):