gallery-for-aav/README.md
2026-02-19 17:46:46 +03:00

153 lines
6.3 KiB
Markdown
Raw 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.

# Галерея фотографий (PHP)
Локальный проект галереи, который:
- читает категории и фото из `photos/` (туда можно загружать по FTP),
- при каждом открытии страницы проверяет, появились ли новые/обновлённые фото,
- создаёт и обновляет превью в `thumbs/`,
- показывает категории и фото в веб-интерфейсе,
- открывает большую фотографию в лайтбоксе.
## Структура
```text
photo-gallery/
├─ index.php # основной скрипт: индексация + HTML
├─ style.css # стили (material-like, строгий)
├─ app.js # лайтбокс + защита от простого скачивания
├─ deploy.php # webhook-триггер деплоя
├─ admin.php # закрытая админка (папки/фото/сортировка)
├─ deploy-config.php.example # пример конфига webhook
├─ photos/ # исходные фото по категориям (папкам)
├─ thumbs/ # автогенерируемые превью
└─ data/
├─ last_indexed.txt # timestamp последней индексации
└─ sort.json # порядок категорий и фото
```
## Как работает индексация
1. Скрипт читает `data/last_indexed.txt`.
2. Сканирует `photos/<категория>/`.
3. Для каждого изображения (`jpg/jpeg/png/webp/gif`):
- если файл новее `last_indexed`,
- или превью не существует,
- или превью старее оригинала,
тогда создаётся/обновляется превью (`.jpg`) в `thumbs/<категория>/`.
4. Записывает новый timestamp в `last_indexed.txt`.
Индексация выполняется **на каждом обращении к `index.php`**.
Также на публичной странице категории показываются с обложкой (берётся превью первой фотографии по текущей сортировке).
## Требования
- PHP 8.2+ (8.3 тоже ок)
- Расширение GD **или** Imagick
- если есть Imagick — будет использоваться он,
- иначе используется GD.
## Локальный запуск
Из папки `photo-gallery`:
```bash
php -S 127.0.0.1:8080
```
Открыть в браузере:
- `http://127.0.0.1:8080`
## Загрузка фото
Через FTP кладите файлы в:
- `photos/Свадьба/001.jpg`
- `photos/Портреты/img_10.png`
- и т.д.
Папка верхнего уровня = категория.
## Деплой (Timeweb shared hosting)
В проекте есть скрипт:
- `scripts/deploy.sh`
Он:
1. делает `git fetch`,
2. жёстко переключает код на `origin/<branch>`,
3. сохраняет runtime-папки (`photos`, `thumbs`, `data`),
4. создаёт `data/last_indexed.txt` при первом запуске.
Запуск на хостинге:
```bash
cd ~/www/photo-gallery
bash scripts/deploy.sh
```
По умолчанию ветка `main`. Для другой ветки:
```bash
BRANCH=master bash scripts/deploy.sh
```
## Админка загрузки (по токену)
Админка использует тот же `token`, что и `deploy.php`, из файла `deploy-config.php`.
Ссылка входа:
```text
https://<домен>/admin.php?token=<твой_секрет>
```
В админке можно:
- создавать папки-категории,
- переименовывать/удалять категории,
- задавать порядок (индекс сортировки) категорий,
- загружать фото в выбранную папку,
- переименовывать/удалять фото,
- задавать порядок (индекс сортировки) фото внутри категории,
- видеть превью фото в таблице админки,
- автоматически очищать `data/sort.json` от несуществующих папок/файлов.
Ограничения загрузки:
- только изображения: JPG/PNG/WEBP/GIF,
- максимум 3 МБ на файл,
- MIME-тип и расширение проверяются на сервере.
Загрузка новых фото выполняется в секции выбранной категории (чтобы нельзя было загрузить в неправильную папку).
## Удалённый запуск деплоя по ссылке (webhook)
1. На хостинге создай конфиг из примера:
```bash
cp deploy-config.php.example deploy-config.php
```
2. Заполни в `deploy-config.php` минимум:
- `token` (длинный секрет)
- при желании `allowed_ips`
- при желании `basic_auth_user/basic_auth_pass`
3. Запуск деплоя:
```text
https://<домен>/deploy.php?token=<твой_секрет>
```
Рекомендация: включить IP whitelist и Basic Auth.
## Примечания
- Превью генерируются в формате JPEG с качеством ~82.
- При первом заходе на большую папку возможно небольшое ожидание (генерация превью).
- CSS/JS и favicon подключаются с cache-busting параметром `?v=<filemtime>`, чтобы после деплоя пользователю не приходилось чистить кеш вручную.
- В футере публичной страницы есть ненавязчивое авторство со ссылкой: `https://t.me/andr33vru`.
- Для production обычно лучше вынести индексацию в cron/очередь, но для текущей задачи это intentionally on-request.