66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
"""
|
||
CDN 工具函數
|
||
用於靜態資源加速
|
||
"""
|
||
from flask import current_app, url_for as flask_url_for
|
||
import os
|
||
|
||
def cdn_url_for(endpoint, **values):
|
||
"""
|
||
CDN化的 url_for 函數
|
||
自動將靜態資源指向CDN域名
|
||
"""
|
||
if endpoint == 'static':
|
||
cdn_domain = current_app.config.get('CDN_DOMAIN', '').strip()
|
||
if cdn_domain:
|
||
# 確保CDN域名格式正確
|
||
if not cdn_domain.startswith(('http://', 'https://')):
|
||
cdn_domain = f"https://{cdn_domain}"
|
||
|
||
filename = values.get('filename', '')
|
||
if filename:
|
||
# 移除開頭的斜線
|
||
filename = filename.lstrip('/')
|
||
return f"{cdn_domain.rstrip('/')}/static/{filename}"
|
||
|
||
# 非靜態資源或未配置CDN時使用原始url_for
|
||
return flask_url_for(endpoint, **values)
|
||
|
||
def get_static_url(filename):
|
||
"""
|
||
獲取靜態資源URL
|
||
自動判斷使用CDN還是本地路徑
|
||
"""
|
||
return cdn_url_for('static', filename=filename)
|
||
|
||
def is_cdn_enabled():
|
||
"""檢查是否啟用CDN"""
|
||
return bool(current_app.config.get('CDN_DOMAIN', '').strip())
|
||
|
||
class CDNHelper:
|
||
"""CDN輔助類"""
|
||
|
||
def __init__(self, app=None):
|
||
if app:
|
||
self.init_app(app)
|
||
|
||
def init_app(self, app):
|
||
"""初始化應用"""
|
||
app.jinja_env.globals['cdn_url_for'] = cdn_url_for
|
||
app.jinja_env.globals['get_static_url'] = get_static_url
|
||
app.jinja_env.globals['is_cdn_enabled'] = is_cdn_enabled
|
||
|
||
# 添加模板過濾器
|
||
app.jinja_env.filters['cdn'] = self._cdn_filter
|
||
|
||
def _cdn_filter(self, filename):
|
||
"""Jinja2過濾器:將靜態檔案路徑轉換為CDN URL"""
|
||
if filename.startswith('/static/'):
|
||
filename = filename[8:] # 移除 '/static/' 前綴
|
||
elif filename.startswith('static/'):
|
||
filename = filename[7:] # 移除 'static/' 前綴
|
||
|
||
return get_static_url(filename)
|
||
|
||
# 全局CDN輔助實例
|
||
cdn_helper = CDNHelper() |