Files
2025-09-25 08:44:44 +08:00

130 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, redirect, url_for, render_template
from flask_login import LoginManager, current_user
from flask_apscheduler import APScheduler
from flask_caching import Cache
from models import db, User
from routes.auth import auth_bp
from routes.temp_spec import temp_spec_bp
from routes.upload import upload_bp
from routes.admin import admin_bp
from routes.api import api_bp
from cdn_utils import cdn_helper
import redis
app = Flask(__name__)
app.config.from_object('config.Config')
# 初始化資料庫
db.init_app(app)
# 初始化Redis快取
cache = Cache(app)
# 初始化CDN輔助
cdn_helper.init_app(app)
# 初始化Redis連接用於會話
try:
redis_client = redis.from_url(app.config['CACHE_REDIS_URL'])
app.config['SESSION_REDIS'] = redis_client
except Exception as e:
app.logger.warning(f"Redis連接失敗使用本地快取: {e}")
app.config['CACHE_TYPE'] = 'simple'
# 初始化排程器
scheduler = APScheduler()
scheduler.init_app(app)
scheduler.start()
# 初始化登入管理
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'auth.login'
login_manager.login_message = "請先登入以存取此頁面。"
login_manager.login_message_category = "info"
# 預設首頁導向登入畫面
@app.route('/')
def index():
# 檢查使用者是否已經通過驗證 (已登入)
if current_user.is_authenticated:
# 如果已登入,直接導向到暫規總表
return redirect(url_for('temp_spec.spec_list'))
else:
# 如果未登入,才導向到登入頁面
return redirect(url_for('auth.login'))
# 載入登入使用者
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# 註冊 Blueprint 模組路由
app.register_blueprint(auth_bp)
app.register_blueprint(temp_spec_bp)
app.register_blueprint(upload_bp)
app.register_blueprint(admin_bp)
app.register_blueprint(api_bp)
# 註冊自訂模板 filter
from utils.timezone import format_taiwan_time
@app.template_filter('taiwan_time')
def taiwan_time_filter(dt, format_str='%Y-%m-%d %H:%M:%S'):
"""將 datetime 轉換為台灣時間格式字符串"""
return format_taiwan_time(dt, format_str)
@app.template_filter('taiwan_date')
def taiwan_date_filter(dt):
"""將 datetime 轉換為台灣日期格式字符串"""
return format_taiwan_time(dt, '%Y-%m-%d')
# 導入任務
from tasks import check_expiring_specs
# 註冊排程任務:每天凌晨 2:00 執行一次
@scheduler.task('cron', id='check_expiring_specs_job', hour=2, minute=0)
def scheduled_job():
check_expiring_specs(app)
# 註冊錯誤處理函式
@app.errorhandler(404)
def not_found_error(error):
return render_template('404.html'), 404
@app.errorhandler(403)
def forbidden_error(error):
return render_template('403.html'), 403
if __name__ == '__main__':
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(levelname)s %(name)s: %(message)s',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
app.logger.setLevel(logging.INFO)
app.logger.addHandler(logging.StreamHandler(sys.stdout))
print('=== 暫規系統 V4 啟動 ===')
print('📘 Log 等級: INFO')
print('=' * 50)
print('✅ 系統服務啟動完成')
print('')
print('🔑 登入入口:')
print(' 本機: http://localhost:12010/login')
print(' 容器: http://127.0.0.1:12010/login')
print('')
print('🗂️ OnlyOffice 位址:')
print(' URL: http://localhost:12011')
print('')
print('🔐 提示: 請使用系統註冊帳號登入')
print('=' * 50)
app.run(host='0.0.0.0', port=5000, debug=False)