import os import sys import re # Import re for nl2br filter # DON'T CHANGE THIS !!! sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from flask import Flask, redirect, url_for, session, request, flash, render_template # Added render_template from jinja2 import pass_eval_context # Use pass_eval_context from markupsafe import Markup, escape # Import Markup and escape from markupsafe from src.extensions import db, migrate # Import from extensions from src.decorators import login_required # Import from decorators # --- Custom Jinja Filter --- _paragraph_re = re.compile(r'\r\n|\r|\n') @pass_eval_context def nl2br(eval_ctx, value): """Converts newlines into <p> and <br />s.""" # Ensure value is treated as string before splitting value_str = str(escape(value)) result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br />\n')) for p in _paragraph_re.split(value_str)) if eval_ctx.autoescape: result = Markup(result) return result def create_app(): """Application Factory Pattern""" app = Flask(__name__, static_folder=os.path.join(os.path.dirname(__file__), 'static'), template_folder=os.path.join(os.path.dirname(__file__), 'templates')) # --- Configuration --- app.config['SECRET_KEY'] = os.urandom(24) basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # Base directory is polisage_app app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'polisage.db') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # --- Initialize Extensions --- db.init_app(app) migrate.init_app(app, db) # --- Register Custom Filters --- app.jinja_env.filters['nl2br'] = nl2br # --- Import and Register Blueprints --- # Import blueprints inside the factory function to avoid circular imports from src.routes.auth import auth_bp from src.routes.drafting import drafting_bp from src.routes.amendment import amendment_bp from src.routes.monitoring import monitoring_bp from src.routes.analysis import analysis_bp from src.routes.recommendation import recommendation_bp # Import dashboard blueprint later if created # from src.routes.dashboard import dashboard_bp app.register_blueprint(auth_bp) app.register_blueprint(drafting_bp) app.register_blueprint(amendment_bp) app.register_blueprint(monitoring_bp) app.register_blueprint(analysis_bp) app.register_blueprint(recommendation_bp) # app.register_blueprint(dashboard_bp) # --- Import Models (Needed for Flask-Migrate context) --- # Although models are used within routes/extensions, importing them here # ensures they are known to Flask-Migrate when running commands. with app.app_context(): from src.models import user, legislation, draft, amendment, monitoring, analysis, recommendation, cross_reference # --- Basic Routes --- @app.route('/') @login_required def index(): # Redirect to a default page, e.g., drafts list or a future dashboard return redirect(url_for('drafting.list_drafts')) # Add a simple dashboard route placeholder @app.route('/dashboard') @login_required def dashboard(): # Placeholder for a real dashboard username = session.get('username', 'Guest') # Query some basic stats later draft_count = draft.Draft.query.count() analysis_count = analysis.ImpactAnalysis.query.count() rec_count = recommendation.Recommendation.query.count() return render_template('dashboard.html', username=username, draft_count=draft_count, analysis_count=analysis_count, rec_count=rec_count) return app # Create the app instance using the factory app = create_app() # --- Main Execution (for running with 'python src/main.py') --- if __name__ == '__main__': # Note: Recommended to run using 'flask run' after setting FLASK_APP=src.main:app app.run(host='0.0.0.0', port=7860, debug=True)