SEO helper

This commit is contained in:
2026-03-20 19:22:34 +03:00
parent 1155027dc8
commit 6cbf59bc1f
2 changed files with 454 additions and 10 deletions

144
server.py
View File

@@ -17,6 +17,7 @@ import uvicorn
from pathlib import Path
import traceback
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from seo_helpers import generate_resume_seo_tags, generate_vacancy_seo_tags, inject_seo_tags
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
@@ -766,11 +767,62 @@ async def get_vacancies():
@app.get("/vacancy/{vacancy_id}", response_class=HTMLResponse)
async def get_vacancy_detail(vacancy_id: int):
"""Страница конкретной вакансии"""
file_path = TEMPLATES_DIR / "vacancy_detail.html"
return FileResponse(file_path) if file_path.exists() else HTMLResponse(
content=f"<h1>Вакансия #{vacancy_id}</h1><p>Создайте файл templates/vacancy_detail.html</p>")
async def get_vacancy_page(request: Request, vacancy_id: int):
"""Страница детального просмотра вакансии с SEO-тегами на сервере"""
try:
with get_db() as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT v.*,
COALESCE(c.name, u.full_name) as company_name,
c.description as company_description,
c.website as company_website,
c.address as company_address,
u.full_name as user_name,
u.email as user_email,
u.telegram as user_telegram
FROM vacancies v
JOIN users u ON v.user_id = u.id
LEFT JOIN companies c ON v.user_id = c.user_id
WHERE v.id = ?
""", (vacancy_id,))
vacancy = cursor.fetchone()
if not vacancy:
return HTMLResponse(content="<h1>Вакансия не найдена</h1>")
# Получаем теги
cursor.execute("""
SELECT t.name FROM tags t
JOIN vacancy_tags vt ON t.id = vt.tag_id
WHERE vt.vacancy_id = ?
""", (vacancy_id,))
tags = [t["name"] for t in cursor.fetchall()]
vacancy_data = dict(vacancy)
vacancy_data["tags"] = tags
# Генерируем SEO-теги
seo_tags = generate_vacancy_seo_tags(vacancy_data, vacancy_id)
# Читаем HTML шаблон
file_path = TEMPLATES_DIR / "vacancy_detail.html"
if not file_path.exists():
return HTMLResponse(content="<h1>Страница не найдена</h1>")
with open(file_path, "r", encoding="utf-8") as f:
html = f.read()
# Внедряем SEO-теги в HTML
html = inject_seo_tags(html, seo_tags)
return HTMLResponse(content=html)
except Exception as e:
print(f"❌ Ошибка: {e}")
traceback.print_exc()
return HTMLResponse(content=f"<h1>Ошибка</h1><p>{str(e)}</p>")
@app.get("/resumes", response_class=HTMLResponse)
@@ -782,11 +834,83 @@ async def get_resumes():
@app.get("/resume/{resume_id}", response_class=HTMLResponse)
async def get_resume_detail(resume_id: int):
"""Страница конкретного резюме"""
file_path = TEMPLATES_DIR / "resume_detail.html"
return FileResponse(file_path) if file_path.exists() else HTMLResponse(
content=f"<h1>Резюме #{resume_id}</h1><p>Создайте файл templates/resume_detail.html</p>")
async def get_resume_page(request: Request, resume_id: int):
"""Страница детального просмотра резюме с SEO-тегами на сервере"""
try:
with get_db() as conn:
cursor = conn.cursor()
# Получаем резюме с данными пользователя
cursor.execute("""
SELECT r.*, u.full_name, u.email, u.phone, u.telegram
FROM resumes r
JOIN users u ON r.user_id = u.id
WHERE r.id = ?
""", (resume_id,))
resume = cursor.fetchone()
if not resume:
file_path = TEMPLATES_DIR / "resume_detail.html"
if file_path.exists():
with open(file_path, "r", encoding="utf-8") as f:
html = f.read()
html = html.replace('<title id="pageTitle">Резюме | Rabota.Today</title>',
'<title>Резюме не найдено | Rabota.Today</title>')
return HTMLResponse(content=html)
return HTMLResponse(content="<h1>Резюме не найдено</h1>")
# Получаем теги
cursor.execute("""
SELECT t.name FROM tags t
JOIN resume_tags rt ON t.id = rt.tag_id
WHERE rt.resume_id = ?
""", (resume_id,))
tags = [t["name"] for t in cursor.fetchall()]
# Получаем опыт работы
cursor.execute("""
SELECT position, company, period, description
FROM work_experience
WHERE resume_id = ?
ORDER BY period DESC
""", (resume_id,))
work_experience = cursor.fetchall()
# Получаем образование
cursor.execute("""
SELECT institution, specialty, graduation_year
FROM education
WHERE resume_id = ?
ORDER BY graduation_year DESC
""", (resume_id,))
education = cursor.fetchall()
# Формируем данные для SEO
resume_data = dict(resume)
resume_data["tags"] = tags
resume_data["work_experience"] = [dict(exp) for exp in work_experience]
resume_data["education"] = [dict(edu) for edu in education]
# Генерируем SEO-теги
seo_tags = generate_resume_seo_tags(resume_data, resume_id)
# Читаем HTML шаблон
file_path = TEMPLATES_DIR / "resume_detail.html"
if not file_path.exists():
return HTMLResponse(content="<h1>Страница не найдена</h1>")
with open(file_path, "r", encoding="utf-8") as f:
html = f.read()
# Внедряем SEO-теги в HTML
html = inject_seo_tags(html, seo_tags)
return HTMLResponse(content=html)
except Exception as e:
print(f"❌ Ошибка при загрузке страницы резюме: {e}")
traceback.print_exc()
return HTMLResponse(content=f"<h1>Ошибка</h1><p>{str(e)}</p>")
@app.get("/favorites", response_class=HTMLResponse)