feat: 增加公共文件访问功能并添加favicon和robots.txt
- 新增公共文件访问接口,允许从public目录获取文件 - 添加favicon.ico以改善网站标识 - 新增robots.txt以指导搜索引擎爬虫行为
This commit is contained in:
parent
73f419f1aa
commit
345c571dda
224
app.py
224
app.py
@ -1,109 +1,117 @@
|
|||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse, FileResponse
|
||||||
import markdown
|
import markdown
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
import json, yaml
|
import json, yaml
|
||||||
import os
|
import os
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
|
||||||
# 加载所有问卷数据
|
# Mount all files from public directory to root
|
||||||
def load_all_scales():
|
@app.get("/{filename}")
|
||||||
scales = {}
|
async def get_public_file(filename: str):
|
||||||
tags = []
|
public_path = os.path.join("public", filename)
|
||||||
for root, dirs, files in os.walk(os.path.realpath('scales')):
|
if os.path.isfile(public_path):
|
||||||
for filename in files:
|
return FileResponse(public_path)
|
||||||
if filename.endswith(('.yaml', '.yml')):
|
raise HTTPException(status_code=404, detail="File not found")
|
||||||
try:
|
|
||||||
with open(os.path.join(root, filename), 'r', encoding='utf-8') as f:
|
# 加载所有问卷数据
|
||||||
scale = yaml.safe_load(f)
|
def load_all_scales():
|
||||||
scale['instructions']=markdown.markdown(scale['instructions'], extensions=['fenced_code','tables','mdx_math'])
|
scales = {}
|
||||||
scale['descriptions']=markdown.markdown(scale['descriptions'], extensions=['fenced_code','tables','mdx_math'])
|
tags = []
|
||||||
scale['abstract']=markdown.markdown(scale['abstract'], extensions=['fenced_code','tables','mdx_math'])
|
for root, dirs, files in os.walk(os.path.realpath('scales')):
|
||||||
if 'tag' not in scale:
|
for filename in files:
|
||||||
scale['tag']='其他'
|
if filename.endswith(('.yaml', '.yml')):
|
||||||
if scale['tag'] not in tags:
|
try:
|
||||||
tags.append(scale['tag'])
|
with open(os.path.join(root, filename), 'r', encoding='utf-8') as f:
|
||||||
scale_id = os.path.splitext(filename)[0] # 使用文件名作为标识
|
scale = yaml.safe_load(f)
|
||||||
scales[scale_id] = scale
|
scale['instructions']=markdown.markdown(scale['instructions'], extensions=['fenced_code','tables','mdx_math'])
|
||||||
except Exception as e:
|
scale['descriptions']=markdown.markdown(scale['descriptions'], extensions=['fenced_code','tables','mdx_math'])
|
||||||
print(f"Error loading scale {filename}: {e}")
|
scale['abstract']=markdown.markdown(scale['abstract'], extensions=['fenced_code','tables','mdx_math'])
|
||||||
return tags, scales
|
if 'tag' not in scale:
|
||||||
|
scale['tag']='其他'
|
||||||
@app.get("/", response_class=HTMLResponse)
|
if scale['tag'] not in tags:
|
||||||
async def index(request: Request):
|
tags.append(scale['tag'])
|
||||||
tags, _ = load_all_scales()
|
scale_id = os.path.splitext(filename)[0] # 使用文件名作为标识
|
||||||
# 新增读取README.md的逻辑
|
scales[scale_id] = scale
|
||||||
readme_content = ""
|
except Exception as e:
|
||||||
try:
|
print(f"Error loading scale {filename}: {e}")
|
||||||
with open("README.md", "r", encoding="utf-8") as f:
|
return tags, scales
|
||||||
readme_content = markdown.markdown(f.read())
|
|
||||||
except FileNotFoundError:
|
@app.get("/", response_class=HTMLResponse)
|
||||||
pass # 如果README不存在则静默失败
|
async def index(request: Request):
|
||||||
return templates.TemplateResponse("index.html", {
|
tags, _ = load_all_scales()
|
||||||
"request": request,
|
# 新增读取README.md的逻辑
|
||||||
"tags": tags,
|
readme_content = ""
|
||||||
"readme_content": readme_content # 新增模板变量
|
try:
|
||||||
})
|
with open("README.md", "r", encoding="utf-8") as f:
|
||||||
|
readme_content = markdown.markdown(f.read())
|
||||||
@app.get("/tag/{tag}", response_class=HTMLResponse)
|
except FileNotFoundError:
|
||||||
async def list(request: Request, tag: str):
|
pass # 如果README不存在则静默失败
|
||||||
tags, scales = load_all_scales()
|
return templates.TemplateResponse("index.html", {
|
||||||
return templates.TemplateResponse("list.html", {
|
"request": request,
|
||||||
"request": request,
|
"tags": tags,
|
||||||
"tags": tags,
|
"readme_content": readme_content # 新增模板变量
|
||||||
"scales": scales,
|
})
|
||||||
"tag": tag
|
|
||||||
})
|
@app.get("/tag/{tag}", response_class=HTMLResponse)
|
||||||
|
async def list(request: Request, tag: str):
|
||||||
@app.get("/scales/{scale_id}", response_class=HTMLResponse)
|
tags, scales = load_all_scales()
|
||||||
async def scale(request: Request, scale_id: str):
|
return templates.TemplateResponse("list.html", {
|
||||||
tags, scales = load_all_scales()
|
"request": request,
|
||||||
scale = scales.get(scale_id)
|
"tags": tags,
|
||||||
if scale:
|
"scales": scales,
|
||||||
return templates.TemplateResponse("scale.html", {
|
"tag": tag
|
||||||
"request": request,
|
})
|
||||||
"scale_id": scale_id,
|
|
||||||
"scale": scale,
|
@app.get("/scales/{scale_id}", response_class=HTMLResponse)
|
||||||
"tags":tags
|
async def scale(request: Request, scale_id: str):
|
||||||
})
|
tags, scales = load_all_scales()
|
||||||
raise HTTPException(status_code=404, detail="问卷未找到")
|
scale = scales.get(scale_id)
|
||||||
|
if scale:
|
||||||
@app.post("/scales/{scale_id}", response_class=HTMLResponse)
|
return templates.TemplateResponse("scale.html", {
|
||||||
async def result(request: Request, scale_id: str):
|
"request": request,
|
||||||
form_data = await request.form()
|
"scale_id": scale_id,
|
||||||
tags, scales = load_all_scales()
|
"scale": scale,
|
||||||
scale = scales.get(scale_id)
|
"tags":tags
|
||||||
if scale:
|
})
|
||||||
# 这里可以添加保存数据到数据库等逻辑
|
raise HTTPException(status_code=404, detail="问卷未找到")
|
||||||
responses = {}
|
|
||||||
average = {}
|
@app.post("/scales/{scale_id}", response_class=HTMLResponse)
|
||||||
options = {}
|
async def result(request: Request, scale_id: str):
|
||||||
for subscale, qids in scale['subscales'].items():
|
form_data = await request.form()
|
||||||
responses[subscale] = 0
|
tags, scales = load_all_scales()
|
||||||
min_val = min(scale['options'].keys())
|
scale = scales.get(scale_id)
|
||||||
max_val = max(scale['options'].keys())
|
if scale:
|
||||||
options[subscale] = [min_val*len(qids),max_val*len(qids)]
|
# 这里可以添加保存数据到数据库等逻辑
|
||||||
for qid in qids:
|
responses = {}
|
||||||
if qid<0:
|
average = {}
|
||||||
responses[subscale] += min_val + max_val - int(form_data[str(-qid)])
|
options = {}
|
||||||
else:
|
for subscale, qids in scale['subscales'].items():
|
||||||
responses[subscale] += int(form_data[str(qid)])
|
responses[subscale] = 0
|
||||||
average[subscale] = round(responses[subscale]/len(qids),2)
|
min_val = min(scale['options'].keys())
|
||||||
return templates.TemplateResponse("result.html", {
|
max_val = max(scale['options'].keys())
|
||||||
"request": request,
|
options[subscale] = [min_val*len(qids),max_val*len(qids)]
|
||||||
"responses": responses,
|
for qid in qids:
|
||||||
"average": average,
|
if qid<0:
|
||||||
"options": options,
|
responses[subscale] += min_val + max_val - int(form_data[str(-qid)])
|
||||||
"scale": scale,
|
else:
|
||||||
"tags":tags
|
responses[subscale] += int(form_data[str(qid)])
|
||||||
})
|
average[subscale] = round(responses[subscale]/len(qids),2)
|
||||||
raise HTTPException(status_code=404, detail="问卷未找到")
|
return templates.TemplateResponse("result.html", {
|
||||||
|
"request": request,
|
||||||
|
"responses": responses,
|
||||||
if __name__ == '__main__':
|
"average": average,
|
||||||
|
"options": options,
|
||||||
|
"scale": scale,
|
||||||
|
"tags":tags
|
||||||
|
})
|
||||||
|
raise HTTPException(status_code=404, detail="问卷未找到")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
uvicorn.run(app,host='0.0.0.0',port=8000)
|
uvicorn.run(app,host='0.0.0.0',port=8000)
|
4
public/robots.txt
Normal file
4
public/robots.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Sitemap: /sitemap.xml
|
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 KiB |
@ -8,6 +8,7 @@
|
|||||||
<meta name="keywords" content="心尺, PsychoScales, 心理学量表,专业心理测评,抑郁症测试,焦虑症自评,在线心理测评系统,心理咨询师工具, 心理测验, 报告解读, 测试题">
|
<meta name="keywords" content="心尺, PsychoScales, 心理学量表,专业心理测评,抑郁症测试,焦虑症自评,在线心理测评系统,心理咨询师工具, 心理测验, 报告解读, 测试题">
|
||||||
<meta name="baidu-site-verification" content="codeva-mPOBUr0rLS" />
|
<meta name="baidu-site-verification" content="codeva-mPOBUr0rLS" />
|
||||||
<link rel="stylesheet" href="/static/styles.css">
|
<link rel="stylesheet" href="/static/styles.css">
|
||||||
|
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
||||||
{% block head_extra %}{% endblock %}
|
{% block head_extra %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user