mirror of
https://gitverse.ru/kpa39l/vesti.git
synced 2026-09-29 09:55:03 +00:00
60 lines
2.5 KiB
Markdown
60 lines
2.5 KiB
Markdown
## Design
|
||
|
||
### Роут в web/app.py
|
||
|
||
После `/bundle/...` (в конце файла) добавить:
|
||
|
||
```python
|
||
from fastapi.responses import FileResponse
|
||
|
||
MEDIA_DIRS = [
|
||
BASE_DIR / "media", # свежие: media/<file>
|
||
BASE_DIR / "media" / "media" # старые: media/media/<file>
|
||
]
|
||
|
||
@app.get("/media/{filename}")
|
||
def media(request: Request, filename: str):
|
||
"""Отдаёт медиа-файл поста (из media/ или media/media/). Авторизация."""
|
||
_require_auth(request)
|
||
name = os.path.basename(filename) # защита от path traversal
|
||
if not name:
|
||
return HTMLResponse("bad filename", status_code=400)
|
||
for d in MEDIA_DIRS:
|
||
f = (d / name).resolve()
|
||
if f.exists() and f.is_file():
|
||
# отдаём с корректным MIME по расширению
|
||
return FileResponse(f)
|
||
return HTMLResponse("not found", status_code=404)
|
||
```
|
||
|
||
Примечание: `FileResponse` уже есть в fastapi.responses (импортировать).
|
||
`MEDIA_DIRS` можно вынести в константы рядом с `STATIC_DIR`.
|
||
|
||
### Шаблоны
|
||
|
||
В `candidates.html` (и `published.html`), заменить блок бейджа:
|
||
|
||
```html
|
||
{% if p.media_path %}
|
||
<span class="badge bg-light text-dark ms-2">🖼 медиа</span>
|
||
{# маленькое превью: изображение или видео #}
|
||
{% set media_src = '/media/' ~ p.media_path.split('/')[-1] %}
|
||
{% if p.media_path.lower().endswith(('.jpg','.jpeg','.png','.gif','.webp')) %}
|
||
<img src="{{ media_src }}" class="img-fluid rounded mt-2" style="max-height:180px" alt="медиа">
|
||
{% elif p.media_path.lower().endswith(('.mp4','.webm','.mov')) %}
|
||
<video src="{{ media_src }}" controls class="mt-2" style="max-height:180px"></video>
|
||
{% endif %}
|
||
{% endif %}
|
||
```
|
||
|
||
В `candidates.html` строка 49: заменить бейдж на блок с превью.
|
||
В `published.html` — аналогично (там сейчас бейдж медиа? проверить).
|
||
|
||
### Верификация
|
||
|
||
- `openspec validate web-media-preview` — чисто.
|
||
- Перезапуск веба: `sudo systemctl restart vesti-web`.
|
||
- Открыть /candidates — у поста с media_path видно изображение/видео.
|
||
- `/media/LinuxMastery_1079.jpg` — 200 (файл есть).
|
||
- Старый пост с media/media/<file> — тоже 200.
|
||
- Несуществующий файл — 404. |