2026-02-02 12:27:27 +05:30
|
|
|
import logging
|
|
|
|
|
import logging.handlers
|
|
|
|
|
import os
|
2026-01-10 16:49:46 +05:30
|
|
|
from flask import Flask, redirect, url_for
|
2025-12-11 10:16:43 +05:30
|
|
|
from app.config import Config
|
2026-01-10 01:04:21 +05:30
|
|
|
from app.services.db_service import db
|
2025-12-11 10:16:43 +05:30
|
|
|
|
|
|
|
|
def create_app():
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
app.config.from_object(Config)
|
|
|
|
|
|
2026-01-10 13:05:13 +05:30
|
|
|
# Initialize extensions
|
2025-12-11 10:16:43 +05:30
|
|
|
db.init_app(app)
|
2026-02-02 12:27:27 +05:30
|
|
|
|
|
|
|
|
# Configure logging
|
|
|
|
|
setup_logging(app)
|
2025-12-11 10:16:43 +05:30
|
|
|
|
2026-01-10 13:05:13 +05:30
|
|
|
# Register blueprints
|
|
|
|
|
register_blueprints(app)
|
|
|
|
|
# Register error handlers
|
|
|
|
|
register_error_handlers(app)
|
|
|
|
|
|
2026-01-10 16:49:46 +05:30
|
|
|
# ROOT → LOGIN
|
|
|
|
|
@app.route("/")
|
|
|
|
|
def index():
|
|
|
|
|
return redirect(url_for("auth.login"))
|
|
|
|
|
|
2026-01-10 13:05:13 +05:30
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
2026-02-02 12:27:27 +05:30
|
|
|
def setup_logging(app):
|
|
|
|
|
"""Configure comprehensive logging for debugging"""
|
|
|
|
|
|
|
|
|
|
# Ensure logs directory exists
|
|
|
|
|
logs_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs')
|
|
|
|
|
os.makedirs(logs_dir, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
# Create logger
|
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
|
|
# Remove existing handlers
|
|
|
|
|
logger.handlers.clear()
|
|
|
|
|
|
|
|
|
|
# Create formatters
|
|
|
|
|
detailed_formatter = logging.Formatter(
|
|
|
|
|
'%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
|
|
|
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# File handler for all logs
|
|
|
|
|
file_handler = logging.handlers.RotatingFileHandler(
|
|
|
|
|
os.path.join(logs_dir, 'app.log'),
|
|
|
|
|
maxBytes=10485760, # 10MB
|
|
|
|
|
backupCount=5
|
|
|
|
|
)
|
|
|
|
|
file_handler.setLevel(logging.DEBUG)
|
|
|
|
|
file_handler.setFormatter(detailed_formatter)
|
|
|
|
|
logger.addHandler(file_handler)
|
|
|
|
|
|
|
|
|
|
# File handler for RA bill fetching only
|
|
|
|
|
ra_bill_handler = logging.handlers.RotatingFileHandler(
|
|
|
|
|
os.path.join(logs_dir, 'ra_bill_fetch.log'),
|
|
|
|
|
maxBytes=5242880, # 5MB
|
|
|
|
|
backupCount=5
|
|
|
|
|
)
|
|
|
|
|
ra_bill_handler.setLevel(logging.DEBUG)
|
|
|
|
|
ra_bill_handler.setFormatter(detailed_formatter)
|
|
|
|
|
|
|
|
|
|
# Only attach to relevant loggers
|
|
|
|
|
ra_loggers = ['app.routes.dashboard', 'app.routes.file_report']
|
|
|
|
|
for logger_name in ra_loggers:
|
|
|
|
|
logging.getLogger(logger_name).addHandler(ra_bill_handler)
|
|
|
|
|
|
|
|
|
|
# Console handler for important messages
|
|
|
|
|
console_handler = logging.StreamHandler()
|
|
|
|
|
console_handler.setLevel(logging.INFO)
|
|
|
|
|
console_formatter = logging.Formatter(
|
|
|
|
|
'%(levelname)s - %(name)s - %(message)s'
|
|
|
|
|
)
|
|
|
|
|
console_handler.setFormatter(console_formatter)
|
|
|
|
|
logger.addHandler(console_handler)
|
|
|
|
|
|
|
|
|
|
# Suppress verbose libraries
|
|
|
|
|
logging.getLogger('werkzeug').setLevel(logging.WARNING)
|
|
|
|
|
logging.getLogger('sqlalchemy.engine').setLevel(logging.WARNING)
|
|
|
|
|
|
|
|
|
|
app.logger.info("Logging initialized successfully")
|
|
|
|
|
app.logger.info(f"Log files location: {logs_dir}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-01-10 13:05:13 +05:30
|
|
|
def register_blueprints(app):
|
2026-01-10 01:04:21 +05:30
|
|
|
from app.routes.auth import auth_bp
|
|
|
|
|
from app.routes.user import user_bp
|
2025-12-11 10:16:43 +05:30
|
|
|
from app.routes.dashboard import dashboard_bp
|
2026-01-10 01:04:21 +05:30
|
|
|
from app.routes.subcontractor_routes import subcontractor_bp
|
2025-12-11 10:16:43 +05:30
|
|
|
from app.routes.file_import import file_import_bp
|
2025-12-12 11:38:54 +05:30
|
|
|
from app.routes.file_report import file_report_bp
|
2025-12-13 18:50:27 +05:30
|
|
|
from app.routes.generate_comparison_report import generate_report_bp
|
2026-01-10 13:05:13 +05:30
|
|
|
from app.routes.file_format import file_format_bp
|
2025-12-23 15:02:04 +05:30
|
|
|
|
2026-01-24 13:41:52 +05:30
|
|
|
app.register_blueprint(auth_bp)
|
2026-01-10 01:04:21 +05:30
|
|
|
app.register_blueprint(user_bp)
|
2025-12-11 10:16:43 +05:30
|
|
|
app.register_blueprint(dashboard_bp)
|
2026-01-10 01:04:21 +05:30
|
|
|
app.register_blueprint(subcontractor_bp)
|
2025-12-11 10:16:43 +05:30
|
|
|
app.register_blueprint(file_import_bp)
|
2025-12-12 11:38:54 +05:30
|
|
|
app.register_blueprint(file_report_bp)
|
2025-12-13 18:50:27 +05:30
|
|
|
app.register_blueprint(generate_report_bp)
|
2026-01-10 13:05:13 +05:30
|
|
|
app.register_blueprint(file_format_bp )
|
2025-12-11 10:16:43 +05:30
|
|
|
|
2026-01-10 13:05:13 +05:30
|
|
|
|
|
|
|
|
def register_error_handlers(app):
|
|
|
|
|
@app.errorhandler(404)
|
|
|
|
|
def page_not_found(e):
|
|
|
|
|
return "Page Not Found", 404
|
|
|
|
|
|
|
|
|
|
@app.errorhandler(500)
|
|
|
|
|
def internal_error(e):
|
|
|
|
|
return "Internal Server Error", 500
|