Закончил показ. Теперь полная переделка
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
# Production Environment Variables
|
||||
# ВАЖНО: Измените все значения перед деплоем!
|
||||
|
||||
# Django Settings
|
||||
DEBUG=False
|
||||
ENVIRONMENT=production
|
||||
|
||||
@@ -1,396 +0,0 @@
|
||||
# Сводка изменений: Асинхронная обработка данных Lyngsat
|
||||
|
||||
## Обзор
|
||||
|
||||
Реализована полная асинхронная обработка данных Lyngsat с использованием Celery, Redis и детальным логированием.
|
||||
|
||||
## Ключевые улучшения
|
||||
|
||||
### 1. ✅ Асинхронная обработка
|
||||
- Задачи выполняются в фоновом режиме
|
||||
- Веб-интерфейс не блокируется
|
||||
- Можно обрабатывать несколько задач одновременно
|
||||
|
||||
### 2. ✅ Отслеживание прогресса
|
||||
- Прогресс-бар в реальном времени
|
||||
- Текущий статус обработки
|
||||
- Процент выполнения
|
||||
|
||||
### 3. ✅ Детальное логирование
|
||||
- Логи на уровне задачи
|
||||
- Логи на уровне спутника
|
||||
- Логи на уровне источника
|
||||
- Все ошибки записываются в лог
|
||||
|
||||
### 4. ✅ Результаты и статистика
|
||||
- Количество обработанных спутников
|
||||
- Количество обработанных источников
|
||||
- Количество созданных/обновленных записей
|
||||
- Список всех ошибок
|
||||
|
||||
## Новые файлы
|
||||
|
||||
### Backend
|
||||
1. **dbapp/dbapp/celery.py** - конфигурация Celery
|
||||
2. **dbapp/dbapp/__init__.py** - инициализация Celery app
|
||||
3. **dbapp/lyngsatapp/tasks.py** - асинхронная задача заполнения данных
|
||||
4. **dbapp/start_celery_worker.sh** - скрипт запуска worker
|
||||
|
||||
### Frontend
|
||||
5. **dbapp/mainapp/templates/mainapp/lyngsat_task_status.html** - страница отслеживания прогресса
|
||||
|
||||
### Документация
|
||||
6. **ASYNC_LYNGSAT_GUIDE.md** - полное руководство
|
||||
7. **QUICKSTART_ASYNC.md** - быстрый старт
|
||||
8. **ASYNC_CHANGES_SUMMARY.md** - этот файл
|
||||
|
||||
## Измененные файлы
|
||||
|
||||
### Конфигурация
|
||||
1. **dbapp/requirements.txt**
|
||||
- Добавлено: `celery>=5.4.0`
|
||||
- Добавлено: `django-celery-results>=2.5.1`
|
||||
|
||||
2. **dbapp/dbapp/settings/base.py**
|
||||
- Добавлено: `django_celery_results` в INSTALLED_APPS
|
||||
- Добавлено: полная конфигурация Celery (брокер, результаты, таймауты, логирование)
|
||||
|
||||
3. **docker-compose.yaml**
|
||||
- Добавлено: сервис Redis
|
||||
- Добавлено: сервис FlareSolver
|
||||
- Добавлено: volume для Redis
|
||||
|
||||
### Backend логика
|
||||
4. **dbapp/lyngsatapp/utils.py**
|
||||
- Добавлено: параметр `task_id` для логирования
|
||||
- Добавлено: параметр `update_progress` для обновления прогресса
|
||||
- Добавлено: детальное логирование на всех уровнях
|
||||
- Добавлено: логирование каждые 10 источников
|
||||
- Улучшено: обработка ошибок с логированием
|
||||
|
||||
5. **dbapp/mainapp/views.py**
|
||||
- Изменено: `FillLyngsatDataView` теперь запускает асинхронную задачу
|
||||
- Добавлено: `LyngsatTaskStatusView` - страница отслеживания
|
||||
- Добавлено: `LyngsatTaskStatusAPIView` - API для проверки статуса
|
||||
|
||||
6. **dbapp/mainapp/urls.py**
|
||||
- Добавлено: `/lyngsat-task-status/` - страница статуса
|
||||
- Добавлено: `/lyngsat-task-status/<task_id>/` - статус конкретной задачи
|
||||
- Добавлено: `/api/lyngsat-task-status/<task_id>/` - API endpoint
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Архитектура
|
||||
|
||||
```
|
||||
User Request → Django View → Celery Task → Redis Broker
|
||||
↓
|
||||
Celery Worker
|
||||
↓
|
||||
┌───────────┴───────────┐
|
||||
↓ ↓
|
||||
LyngSat Parser PostgreSQL
|
||||
↓ ↓
|
||||
FlareSolver Save Results
|
||||
```
|
||||
|
||||
### Поток данных
|
||||
|
||||
1. **Пользователь отправляет форму**
|
||||
- Django view получает данные
|
||||
- Создается асинхронная задача Celery
|
||||
- Возвращается task_id
|
||||
- Перенаправление на страницу статуса
|
||||
|
||||
2. **Celery Worker обрабатывает задачу**
|
||||
- Логирует начало обработки
|
||||
- Вызывает `fill_lyngsat_data` с callback
|
||||
- Обновляет прогресс через `update_state`
|
||||
- Логирует каждый шаг
|
||||
- Сохраняет результат в кеш
|
||||
|
||||
3. **Страница статуса отслеживает прогресс**
|
||||
- JavaScript опрашивает API каждые 2 секунды
|
||||
- Обновляет прогресс-бар
|
||||
- Показывает текущий статус
|
||||
- Отображает результаты при завершении
|
||||
|
||||
### Логирование
|
||||
|
||||
#### Уровни логирования
|
||||
- **INFO**: Основные события (начало, завершение, прогресс)
|
||||
- **DEBUG**: Детальная информация (каждая запись)
|
||||
- **WARNING**: Некритичные ошибки (спутник не найден)
|
||||
- **ERROR**: Критичные ошибки (с traceback)
|
||||
|
||||
#### Формат логов
|
||||
```
|
||||
[Timestamp: Level/Process][Task Name(Task ID)] [Task ID] Message
|
||||
```
|
||||
|
||||
Пример:
|
||||
```
|
||||
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Начало обработки данных Lyngsat
|
||||
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Спутники: Astra 4A, Hotbird 13G
|
||||
[2024-01-15 10:30:46: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Получено данных по 2 спутникам
|
||||
[2024-01-15 10:31:00: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Обработка спутника 1/2: Astra 4A
|
||||
[2024-01-15 10:31:00: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Найдено 150 источников для Astra 4A
|
||||
[2024-01-15 10:31:05: DEBUG/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Создана запись для Astra 4A 11766.0 МГц
|
||||
[2024-01-15 10:31:10: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Обработано 10/150 источников для Astra 4A
|
||||
```
|
||||
|
||||
### API Endpoints
|
||||
|
||||
#### GET /api/lyngsat-task-status/<task_id>/
|
||||
|
||||
**Ответ при выполнении:**
|
||||
```json
|
||||
{
|
||||
"task_id": "abc123",
|
||||
"state": "PROGRESS",
|
||||
"status": "Обработка Astra 4A...",
|
||||
"current": 1,
|
||||
"total": 2,
|
||||
"percent": 50
|
||||
}
|
||||
```
|
||||
|
||||
**Ответ при успехе:**
|
||||
```json
|
||||
{
|
||||
"task_id": "abc123",
|
||||
"state": "SUCCESS",
|
||||
"status": "Задача завершена успешно",
|
||||
"result": {
|
||||
"total_satellites": 2,
|
||||
"total_sources": 300,
|
||||
"created": 250,
|
||||
"updated": 50,
|
||||
"errors": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Ответ при ошибке:**
|
||||
```json
|
||||
{
|
||||
"task_id": "abc123",
|
||||
"state": "FAILURE",
|
||||
"status": "Ошибка при выполнении задачи",
|
||||
"error": "Connection timeout"
|
||||
}
|
||||
```
|
||||
|
||||
## Настройки Celery
|
||||
|
||||
### Основные параметры
|
||||
```python
|
||||
CELERY_BROKER_URL = 'redis://localhost:6379/0'
|
||||
CELERY_RESULT_BACKEND = 'django-db'
|
||||
CELERY_TASK_TRACK_STARTED = True
|
||||
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 минут
|
||||
```
|
||||
|
||||
### Переменные окружения
|
||||
Можно переопределить через `.env`:
|
||||
```bash
|
||||
CELERY_BROKER_URL=redis://redis:6379/0
|
||||
```
|
||||
|
||||
## Зависимости
|
||||
|
||||
### Обязательные сервисы
|
||||
1. **Redis** - брокер сообщений Celery
|
||||
2. **FlareSolver** - обход Cloudflare
|
||||
3. **PostgreSQL** - хранение данных и результатов
|
||||
|
||||
### Python пакеты
|
||||
- `celery>=5.4.0` - асинхронная обработка
|
||||
- `django-celery-results>=2.5.1` - хранение результатов
|
||||
- `redis>=6.4.0` - клиент Redis
|
||||
|
||||
## Команды для работы
|
||||
|
||||
### Запуск сервисов
|
||||
```bash
|
||||
# Redis и FlareSolver
|
||||
docker-compose up -d redis flaresolverr
|
||||
|
||||
# Celery Worker
|
||||
celery -A dbapp worker --loglevel=info
|
||||
|
||||
# Celery Worker в фоне
|
||||
celery -A dbapp worker --loglevel=info --logfile=logs/celery_worker.log --detach
|
||||
```
|
||||
|
||||
### Мониторинг
|
||||
```bash
|
||||
# Просмотр логов
|
||||
tail -f dbapp/logs/celery_worker.log
|
||||
|
||||
# Flower (веб-интерфейс)
|
||||
pip install flower
|
||||
celery -A dbapp flower
|
||||
# Откройте http://localhost:5555
|
||||
```
|
||||
|
||||
### Отладка
|
||||
```bash
|
||||
# Проверка Redis
|
||||
redis-cli ping
|
||||
|
||||
# Проверка FlareSolver
|
||||
curl http://localhost:8191/v1
|
||||
|
||||
# Django shell
|
||||
python manage.py shell
|
||||
>>> from celery.result import AsyncResult
|
||||
>>> task = AsyncResult('task_id')
|
||||
>>> print(task.state, task.info)
|
||||
```
|
||||
|
||||
## Производственное развертывание
|
||||
|
||||
### Systemd сервис
|
||||
```bash
|
||||
sudo systemctl enable celery-worker
|
||||
sudo systemctl start celery-worker
|
||||
sudo systemctl status celery-worker
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
```bash
|
||||
sudo supervisorctl start celery-worker
|
||||
sudo supervisorctl status celery-worker
|
||||
```
|
||||
|
||||
### Docker
|
||||
Можно добавить Celery worker в docker-compose.yaml:
|
||||
```yaml
|
||||
celery-worker:
|
||||
build: ./dbapp
|
||||
command: celery -A dbapp worker --loglevel=info
|
||||
depends_on:
|
||||
- redis
|
||||
- db
|
||||
environment:
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Проверка системы
|
||||
```bash
|
||||
# 1. Проверка Django
|
||||
python manage.py check
|
||||
|
||||
# 2. Проверка миграций
|
||||
python manage.py migrate --check
|
||||
|
||||
# 3. Проверка Celery
|
||||
celery -A dbapp inspect ping
|
||||
|
||||
# 4. Проверка Redis
|
||||
redis-cli ping
|
||||
|
||||
# 5. Проверка FlareSolver
|
||||
curl http://localhost:8191/v1
|
||||
```
|
||||
|
||||
### Тестовый запуск
|
||||
```python
|
||||
# Django shell
|
||||
python manage.py shell
|
||||
|
||||
from lyngsatapp.tasks import fill_lyngsat_data_task
|
||||
|
||||
# Запуск задачи
|
||||
task = fill_lyngsat_data_task.delay(['Astra 4A'], ['europe'])
|
||||
print(f"Task ID: {task.id}")
|
||||
|
||||
# Проверка статуса
|
||||
print(task.state)
|
||||
print(task.info)
|
||||
```
|
||||
|
||||
## Метрики и мониторинг
|
||||
|
||||
### Что отслеживать
|
||||
- Количество активных workers
|
||||
- Количество задач в очереди
|
||||
- Среднее время выполнения задачи
|
||||
- Количество ошибок
|
||||
- Использование памяти Redis
|
||||
|
||||
### Инструменты
|
||||
- **Flower** - веб-интерфейс для Celery
|
||||
- **Redis Commander** - GUI для Redis
|
||||
- **Prometheus + Grafana** - метрики и дашборды
|
||||
|
||||
## Безопасность
|
||||
|
||||
### Рекомендации
|
||||
1. Используйте пароль для Redis в production
|
||||
2. Ограничьте доступ к Redis только для localhost
|
||||
3. Используйте SSL для Redis в production
|
||||
4. Ограничьте время выполнения задач
|
||||
5. Логируйте все действия
|
||||
|
||||
### Пример конфигурации Redis с паролем
|
||||
```python
|
||||
CELERY_BROKER_URL = 'redis://:password@localhost:6379/0'
|
||||
```
|
||||
|
||||
## Масштабирование
|
||||
|
||||
### Горизонтальное масштабирование
|
||||
Запустите несколько workers:
|
||||
```bash
|
||||
# Worker 1
|
||||
celery -A dbapp worker --loglevel=info -n worker1@%h
|
||||
|
||||
# Worker 2
|
||||
celery -A dbapp worker --loglevel=info -n worker2@%h
|
||||
|
||||
# Worker 3
|
||||
celery -A dbapp worker --loglevel=info -n worker3@%h
|
||||
```
|
||||
|
||||
### Приоритеты задач
|
||||
Можно настроить разные очереди для разных типов задач:
|
||||
```python
|
||||
@shared_task(queue='high_priority')
|
||||
def urgent_task():
|
||||
pass
|
||||
|
||||
@shared_task(queue='low_priority')
|
||||
def background_task():
|
||||
pass
|
||||
```
|
||||
|
||||
## Следующие шаги
|
||||
|
||||
1. ✅ Применить миграции
|
||||
2. ✅ Запустить Redis и FlareSolver
|
||||
3. ✅ Запустить Celery Worker
|
||||
4. ✅ Протестировать через веб-интерфейс
|
||||
5. ⏳ Настроить production окружение
|
||||
6. ⏳ Добавить периодические задачи (Celery Beat)
|
||||
7. ⏳ Настроить email уведомления
|
||||
8. ⏳ Настроить мониторинг (Flower)
|
||||
|
||||
## Заключение
|
||||
|
||||
Система асинхронной обработки данных Lyngsat обеспечивает:
|
||||
- ✅ Неблокирующий веб-интерфейс
|
||||
- ✅ Отслеживание прогресса в реальном времени
|
||||
- ✅ Детальное логирование всех операций
|
||||
- ✅ Масштабируемость (несколько workers)
|
||||
- ✅ Надежность (retry при ошибках)
|
||||
- ✅ Мониторинг и отладка
|
||||
- ✅ Production-ready решение
|
||||
|
||||
Для получения дополнительной помощи:
|
||||
- Полное руководство: `ASYNC_LYNGSAT_GUIDE.md`
|
||||
- Быстрый старт: `QUICKSTART_ASYNC.md`
|
||||
- Документация Celery: https://docs.celeryproject.org/
|
||||
@@ -1,420 +0,0 @@
|
||||
# Руководство по асинхронному заполнению данных Lyngsat
|
||||
|
||||
## Обзор
|
||||
|
||||
Система заполнения данных Lyngsat теперь работает асинхронно с использованием Celery. Это позволяет:
|
||||
- Не блокировать веб-интерфейс во время долгих операций
|
||||
- Отслеживать прогресс выполнения задачи в реальном времени
|
||||
- Просматривать детальные логи обработки
|
||||
- Получать уведомления о завершении задачи
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Django │─────▶│ Celery │─────▶│ Redis │
|
||||
│ Web App │ │ Worker │ │ Broker │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
│ │
|
||||
│ ▼
|
||||
│ ┌─────────────┐
|
||||
└─────────────▶│ PostgreSQL │
|
||||
│ Database │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## Установка и настройка
|
||||
|
||||
### 1. Установка зависимостей
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Новые зависимости:
|
||||
- `celery>=5.4.0` - асинхронная обработка задач
|
||||
- `django-celery-results>=2.5.1` - хранение результатов в БД
|
||||
|
||||
### 2. Применение миграций
|
||||
|
||||
```bash
|
||||
cd dbapp
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
Это создаст таблицы для хранения результатов Celery.
|
||||
|
||||
### 3. Запуск Redis
|
||||
|
||||
Redis используется как брокер сообщений для Celery.
|
||||
|
||||
#### Вариант 1: Docker Compose (рекомендуется)
|
||||
```bash
|
||||
docker-compose up -d redis
|
||||
```
|
||||
|
||||
#### Вариант 2: Локальная установка
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install redis-server
|
||||
sudo systemctl start redis
|
||||
|
||||
# macOS
|
||||
brew install redis
|
||||
brew services start redis
|
||||
|
||||
# Проверка
|
||||
redis-cli ping
|
||||
# Должно вернуть: PONG
|
||||
```
|
||||
|
||||
### 4. Запуск FlareSolver
|
||||
|
||||
FlareSolver необходим для обхода защиты Cloudflare.
|
||||
|
||||
```bash
|
||||
docker-compose up -d flaresolverr
|
||||
```
|
||||
|
||||
Или отдельно:
|
||||
```bash
|
||||
docker run -d -p 8191:8191 --name flaresolverr ghcr.io/flaresolverr/flaresolverr:latest
|
||||
```
|
||||
|
||||
### 5. Запуск Celery Worker
|
||||
|
||||
#### Вариант 1: Используя скрипт
|
||||
```bash
|
||||
cd dbapp
|
||||
./start_celery_worker.sh
|
||||
```
|
||||
|
||||
#### Вариант 2: Напрямую
|
||||
```bash
|
||||
cd dbapp
|
||||
celery -A dbapp worker --loglevel=info
|
||||
```
|
||||
|
||||
#### Вариант 3: В фоновом режиме (Linux/macOS)
|
||||
```bash
|
||||
cd dbapp
|
||||
celery -A dbapp worker --loglevel=info --logfile=logs/celery_worker.log --detach
|
||||
```
|
||||
|
||||
## Использование
|
||||
|
||||
### 1. Запуск задачи через веб-интерфейс
|
||||
|
||||
1. Откройте страницу действий: `http://localhost:8000/actions/`
|
||||
2. Нажмите "Заполнить данные Lyngsat"
|
||||
3. Выберите спутники и регионы
|
||||
4. Нажмите "Заполнить данные"
|
||||
5. Вы будете перенаправлены на страницу отслеживания прогресса
|
||||
|
||||
### 2. Отслеживание прогресса
|
||||
|
||||
На странице статуса задачи вы увидите:
|
||||
- **Прогресс-бар** с процентом выполнения
|
||||
- **Текущий статус** (например, "Обработка Astra 4A...")
|
||||
- **Состояние задачи** (PENDING, PROGRESS, SUCCESS, FAILURE)
|
||||
- **Результаты** после завершения:
|
||||
- Количество обработанных спутников
|
||||
- Количество обработанных источников
|
||||
- Количество созданных записей
|
||||
- Количество обновленных записей
|
||||
- Список ошибок (если есть)
|
||||
|
||||
Страница автоматически обновляется каждые 2 секунды.
|
||||
|
||||
### 3. Просмотр логов
|
||||
|
||||
Логи Celery worker содержат детальную информацию о процессе:
|
||||
|
||||
```bash
|
||||
# Просмотр логов в реальном времени
|
||||
tail -f dbapp/logs/celery_worker.log
|
||||
|
||||
# Поиск по логам
|
||||
grep "Task" dbapp/logs/celery_worker.log
|
||||
grep "ERROR" dbapp/logs/celery_worker.log
|
||||
```
|
||||
|
||||
Формат логов:
|
||||
```
|
||||
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Начало обработки данных Lyngsat
|
||||
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Спутники: Astra 4A, Hotbird 13G
|
||||
[2024-01-15 10:30:46: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Получено данных по 2 спутникам
|
||||
[2024-01-15 10:31:00: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Обработка спутника 1/2: Astra 4A
|
||||
```
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Структура задачи
|
||||
|
||||
**Файл**: `dbapp/lyngsatapp/tasks.py`
|
||||
|
||||
```python
|
||||
@shared_task(bind=True, name='lyngsatapp.fill_lyngsat_data_async')
|
||||
def fill_lyngsat_data_task(self, target_sats, regions=None):
|
||||
# Логирование начала
|
||||
# Обновление прогресса
|
||||
# Вызов функции заполнения
|
||||
# Сохранение результата в кеш
|
||||
# Обработка ошибок
|
||||
```
|
||||
|
||||
### Обновление прогресса
|
||||
|
||||
Функция `fill_lyngsat_data` теперь принимает callback `update_progress`:
|
||||
|
||||
```python
|
||||
def update_progress(current, total, status):
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': current,
|
||||
'total': total,
|
||||
'status': status
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### API для проверки статуса
|
||||
|
||||
**Endpoint**: `/api/lyngsat-task-status/<task_id>/`
|
||||
|
||||
**Ответ**:
|
||||
```json
|
||||
{
|
||||
"task_id": "abc123",
|
||||
"state": "PROGRESS",
|
||||
"status": "Обработка Astra 4A...",
|
||||
"current": 1,
|
||||
"total": 2,
|
||||
"percent": 50
|
||||
}
|
||||
```
|
||||
|
||||
### Логирование
|
||||
|
||||
Используется стандартный модуль `logging` Python:
|
||||
|
||||
```python
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger.info(f"[Task {task_id}] Начало обработки")
|
||||
logger.debug(f"[Task {task_id}] Детальная информация")
|
||||
logger.warning(f"[Task {task_id}] Предупреждение")
|
||||
logger.error(f"[Task {task_id}] Ошибка", exc_info=True)
|
||||
```
|
||||
|
||||
## Настройки Celery
|
||||
|
||||
**Файл**: `dbapp/dbapp/settings/base.py`
|
||||
|
||||
```python
|
||||
# Брокер сообщений
|
||||
CELERY_BROKER_URL = 'redis://localhost:6379/0'
|
||||
|
||||
# Хранение результатов
|
||||
CELERY_RESULT_BACKEND = 'django-db'
|
||||
|
||||
# Таймауты
|
||||
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 минут
|
||||
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # 25 минут
|
||||
|
||||
# Отслеживание прогресса
|
||||
CELERY_TASK_TRACK_STARTED = True
|
||||
```
|
||||
|
||||
## Мониторинг и отладка
|
||||
|
||||
### Flower - веб-интерфейс для мониторинга Celery
|
||||
|
||||
Установка:
|
||||
```bash
|
||||
pip install flower
|
||||
```
|
||||
|
||||
Запуск:
|
||||
```bash
|
||||
celery -A dbapp flower
|
||||
```
|
||||
|
||||
Откройте: `http://localhost:5555`
|
||||
|
||||
### Проверка статуса задачи через Django shell
|
||||
|
||||
```python
|
||||
python manage.py shell
|
||||
|
||||
from celery.result import AsyncResult
|
||||
|
||||
task_id = 'abc123'
|
||||
task = AsyncResult(task_id)
|
||||
|
||||
print(f"State: {task.state}")
|
||||
print(f"Info: {task.info}")
|
||||
print(f"Result: {task.result}")
|
||||
```
|
||||
|
||||
### Очистка старых результатов
|
||||
|
||||
```bash
|
||||
# Удалить результаты старше 1 дня
|
||||
python manage.py celery_results_cleanup --days=1
|
||||
```
|
||||
|
||||
## Решение проблем
|
||||
|
||||
### Проблема: Worker не запускается
|
||||
|
||||
**Решение**:
|
||||
1. Проверьте, что Redis запущен: `redis-cli ping`
|
||||
2. Проверьте настройки в `.env`: `CELERY_BROKER_URL`
|
||||
3. Проверьте логи: `tail -f logs/celery_worker.log`
|
||||
|
||||
### Проблема: Задача зависла в состоянии PENDING
|
||||
|
||||
**Решение**:
|
||||
1. Проверьте, что worker запущен: `ps aux | grep celery`
|
||||
2. Перезапустите worker
|
||||
3. Проверьте соединение с Redis
|
||||
|
||||
### Проблема: Задача завершается с ошибкой
|
||||
|
||||
**Решение**:
|
||||
1. Проверьте логи worker
|
||||
2. Проверьте, что FlareSolver запущен: `curl http://localhost:8191/v1`
|
||||
3. Проверьте, что спутники существуют в базе данных
|
||||
|
||||
### Проблема: Прогресс не обновляется
|
||||
|
||||
**Решение**:
|
||||
1. Откройте консоль браузера (F12) и проверьте ошибки
|
||||
2. Проверьте, что API endpoint доступен: `/api/lyngsat-task-status/<task_id>/`
|
||||
3. Очистите кеш браузера
|
||||
|
||||
## Производственное развертывание
|
||||
|
||||
### Systemd сервис для Celery Worker
|
||||
|
||||
Создайте файл `/etc/systemd/system/celery-worker.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Celery Worker for Django Lyngsat
|
||||
After=network.target redis.service
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/path/to/dbapp
|
||||
Environment="PATH=/path/to/venv/bin"
|
||||
ExecStart=/path/to/venv/bin/celery -A dbapp worker --loglevel=info --logfile=/var/log/celery/worker.log --detach
|
||||
ExecStop=/path/to/venv/bin/celery -A dbapp control shutdown
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Запуск:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable celery-worker
|
||||
sudo systemctl start celery-worker
|
||||
sudo systemctl status celery-worker
|
||||
```
|
||||
|
||||
### Supervisor (альтернатива)
|
||||
|
||||
Установка:
|
||||
```bash
|
||||
sudo apt-get install supervisor
|
||||
```
|
||||
|
||||
Конфигурация `/etc/supervisor/conf.d/celery.conf`:
|
||||
```ini
|
||||
[program:celery-worker]
|
||||
command=/path/to/venv/bin/celery -A dbapp worker --loglevel=info
|
||||
directory=/path/to/dbapp
|
||||
user=www-data
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/var/log/celery/worker.log
|
||||
stderr_logfile=/var/log/celery/worker_error.log
|
||||
```
|
||||
|
||||
Запуск:
|
||||
```bash
|
||||
sudo supervisorctl reread
|
||||
sudo supervisorctl update
|
||||
sudo supervisorctl start celery-worker
|
||||
```
|
||||
|
||||
## Дополнительные возможности
|
||||
|
||||
### Периодические задачи (Celery Beat)
|
||||
|
||||
Для автоматического обновления данных по расписанию:
|
||||
|
||||
1. Установите `django-celery-beat`:
|
||||
```bash
|
||||
pip install django-celery-beat
|
||||
```
|
||||
|
||||
2. Добавьте в `INSTALLED_APPS`:
|
||||
```python
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
'django_celery_beat',
|
||||
]
|
||||
```
|
||||
|
||||
3. Примените миграции:
|
||||
```bash
|
||||
python manage.py migrate django_celery_beat
|
||||
```
|
||||
|
||||
4. Создайте периодическую задачу через админ-панель Django
|
||||
|
||||
5. Запустите beat scheduler:
|
||||
```bash
|
||||
celery -A dbapp beat --loglevel=info
|
||||
```
|
||||
|
||||
### Уведомления по email
|
||||
|
||||
Добавьте в задачу отправку email при завершении:
|
||||
|
||||
```python
|
||||
from django.core.mail import send_mail
|
||||
|
||||
@shared_task(bind=True)
|
||||
def fill_lyngsat_data_task(self, target_sats, regions=None):
|
||||
# ... обработка ...
|
||||
|
||||
# Отправка email
|
||||
send_mail(
|
||||
'Задача Lyngsat завершена',
|
||||
f'Обработано {stats["total_satellites"]} спутников',
|
||||
'noreply@example.com',
|
||||
['admin@example.com'],
|
||||
)
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Асинхронная обработка данных Lyngsat обеспечивает:
|
||||
- ✅ Неблокирующий веб-интерфейс
|
||||
- ✅ Отслеживание прогресса в реальном времени
|
||||
- ✅ Детальное логирование
|
||||
- ✅ Масштабируемость (можно запустить несколько workers)
|
||||
- ✅ Надежность (автоматический retry при ошибках)
|
||||
|
||||
Для получения дополнительной помощи обратитесь к документации:
|
||||
- [Celery Documentation](https://docs.celeryproject.org/)
|
||||
- [Django Celery Results](https://django-celery-results.readthedocs.io/)
|
||||
@@ -1,133 +0,0 @@
|
||||
# Сводка изменений: Модернизация функциональности Lyngsat
|
||||
|
||||
## Обзор
|
||||
|
||||
Реализована новая функциональность для заполнения данных о транспондерах спутников с сайта Lyngsat через веб-интерфейс.
|
||||
|
||||
## Основные изменения
|
||||
|
||||
### 1. Удалена карточка с картами 2D/3D
|
||||
- **Файл**: `dbapp/mainapp/templates/mainapp/actions.html`
|
||||
- **Изменение**: Заменена карточка "Карты" на карточку "Заполнение данных Lyngsat"
|
||||
|
||||
### 2. Создана новая форма для заполнения данных
|
||||
- **Файл**: `dbapp/mainapp/forms.py`
|
||||
- **Добавлено**: Класс `FillLyngsatDataForm` с полями:
|
||||
- `satellites` - мультивыбор спутников из базы данных
|
||||
- `regions` - мультивыбор регионов (Europe, Asia, America, Atlantic)
|
||||
|
||||
### 3. Создан новый view для обработки формы
|
||||
- **Файл**: `dbapp/mainapp/views.py`
|
||||
- **Добавлено**: Класс `FillLyngsatDataView` для обработки запросов
|
||||
- **Функциональность**:
|
||||
- Валидация формы
|
||||
- Вызов функции заполнения данных
|
||||
- Отображение статистики и ошибок
|
||||
|
||||
### 4. Добавлен новый URL
|
||||
- **Файл**: `dbapp/mainapp/urls.py`
|
||||
- **Добавлено**: `path('fill-lyngsat-data/', views.FillLyngsatDataView.as_view(), name='fill_lyngsat_data')`
|
||||
|
||||
### 5. Создан новый шаблон
|
||||
- **Файл**: `dbapp/mainapp/templates/mainapp/fill_lyngsat_data.html`
|
||||
- **Содержимое**:
|
||||
- Форма с мультивыбором спутников и регионов
|
||||
- Информационные блоки
|
||||
- Валидация на стороне клиента
|
||||
|
||||
### 6. Доработана функция fill_lyngsat_data
|
||||
- **Файл**: `dbapp/lyngsatapp/utils.py`
|
||||
- **Изменения**:
|
||||
- Добавлен параметр `regions` для выбора регионов
|
||||
- Реализовано частичное заполнение данных
|
||||
- Добавлена детальная статистика обработки:
|
||||
- Количество обработанных спутников
|
||||
- Количество обработанных источников
|
||||
- Количество созданных записей
|
||||
- Количество обновленных записей
|
||||
- Список ошибок
|
||||
- Улучшена обработка ошибок (процесс не прерывается при ошибке)
|
||||
- Добавлена валидация данных перед сохранением
|
||||
|
||||
### 7. Исправлен parser.py
|
||||
- **Файл**: `dbapp/lyngsatapp/parser.py`
|
||||
- **Изменение**: Удален тестовый код выполнения в конце файла
|
||||
|
||||
### 8. Добавлено приложение lyngsatapp в настройки
|
||||
- **Файл**: `dbapp/dbapp/settings/base.py`
|
||||
- **Изменение**: Добавлено `'lyngsatapp'` в `INSTALLED_APPS`
|
||||
|
||||
### 9. Исправлен admin для LyngSat
|
||||
- **Файл**: `dbapp/lyngsatapp/admin.py`
|
||||
- **Изменение**: Обновлены поля в `list_display`, `search_fields`, `ordering` в соответствии с моделью
|
||||
|
||||
### 10. Создана миграция для LyngSat
|
||||
- **Файл**: `dbapp/lyngsatapp/migrations/0001_initial.py`
|
||||
- **Содержимое**: Создание модели LyngSat
|
||||
|
||||
## Новые файлы
|
||||
|
||||
1. `dbapp/mainapp/templates/mainapp/fill_lyngsat_data.html` - шаблон формы
|
||||
2. `dbapp/lyngsatapp/migrations/0001_initial.py` - миграция базы данных
|
||||
3. `LYNGSAT_FILL_GUIDE.md` - руководство пользователя
|
||||
4. `CHANGES_SUMMARY.md` - этот файл
|
||||
|
||||
## Измененные файлы
|
||||
|
||||
1. `dbapp/mainapp/forms.py` - добавлена форма `FillLyngsatDataForm`
|
||||
2. `dbapp/mainapp/views.py` - добавлен view `FillLyngsatDataView`
|
||||
3. `dbapp/mainapp/urls.py` - добавлен URL для новой функциональности
|
||||
4. `dbapp/mainapp/templates/mainapp/actions.html` - заменена карточка
|
||||
5. `dbapp/lyngsatapp/utils.py` - доработана функция `fill_lyngsat_data`
|
||||
6. `dbapp/lyngsatapp/parser.py` - удален тестовый код
|
||||
7. `dbapp/lyngsatapp/admin.py` - исправлены поля админки
|
||||
8. `dbapp/dbapp/settings/base.py` - добавлено приложение в INSTALLED_APPS
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Зависимости
|
||||
- FlareSolver должен быть запущен на `http://localhost:8191`
|
||||
- Спутники должны быть предварительно добавлены в базу данных
|
||||
|
||||
### Модель данных
|
||||
Модель `LyngSat` содержит следующие поля:
|
||||
- `id_satellite` - связь со спутником
|
||||
- `frequency` - частота в МГц
|
||||
- `polarization` - поляризация сигнала
|
||||
- `modulation` - тип модуляции
|
||||
- `standard` - стандарт передачи
|
||||
- `sym_velocity` - символьная скорость
|
||||
- `last_update` - дата последнего обновления
|
||||
- `channel_info` - информация о канале
|
||||
- `fec` - коэффициент коррекции ошибок
|
||||
- `url` - ссылка на страницу Lyngsat
|
||||
|
||||
### Процесс работы
|
||||
1. Пользователь выбирает спутники и регионы
|
||||
2. Система подключается к Lyngsat через FlareSolver
|
||||
3. Парсит данные для каждого спутника
|
||||
4. Создает или обновляет записи в базе данных
|
||||
5. Возвращает статистику обработки
|
||||
|
||||
## Тестирование
|
||||
|
||||
Выполнены следующие проверки:
|
||||
- ✅ `python manage.py check` - нет ошибок
|
||||
- ✅ `python manage.py makemigrations` - миграция создана
|
||||
- ✅ Проверка диагностики кода - нет критических ошибок
|
||||
- ✅ Проверка импортов - все импорты корректны
|
||||
|
||||
## Следующие шаги
|
||||
|
||||
Для полного тестирования необходимо:
|
||||
1. Применить миграции: `python manage.py migrate`
|
||||
2. Запустить FlareSolver: `docker run -p 8191:8191 ghcr.io/flaresolverr/flaresolverr:latest`
|
||||
3. Добавить спутники в базу данных (если еще не добавлены)
|
||||
4. Протестировать форму заполнения данных через веб-интерфейс
|
||||
|
||||
## Примечания
|
||||
|
||||
- Процесс заполнения может занять продолжительное время (несколько минут на спутник)
|
||||
- Рекомендуется начинать с небольшого количества спутников
|
||||
- Все ошибки логируются и отображаются пользователю
|
||||
- Существующие записи обновляются, новые создаются
|
||||
@@ -1,18 +1,3 @@
|
||||
# Руководство по установке асинхронной системы Lyngsat
|
||||
|
||||
## Вариант 1: Полная установка с Celery (рекомендуется)
|
||||
|
||||
### Шаг 1: Установка зависимостей
|
||||
|
||||
```bash
|
||||
pip install -r dbapp/requirements.txt
|
||||
```
|
||||
|
||||
Это установит:
|
||||
- `celery>=5.4.0`
|
||||
- `django-celery-results>=2.5.1`
|
||||
- И все остальные зависимости
|
||||
|
||||
### Шаг 2: Применение миграций
|
||||
|
||||
```bash
|
||||
@@ -58,57 +43,6 @@ celery -A dbapp worker --loglevel=info
|
||||
|
||||
---
|
||||
|
||||
## Вариант 2: Базовая установка без Celery
|
||||
|
||||
Если вы не хотите использовать асинхронную обработку, система будет работать в синхронном режиме.
|
||||
|
||||
### Шаг 1: Установка базовых зависимостей
|
||||
|
||||
```bash
|
||||
# Установите все зависимости кроме Celery
|
||||
pip install -r dbapp/requirements.txt --ignore-installed celery django-celery-results
|
||||
```
|
||||
|
||||
Или вручную удалите из `requirements.txt`:
|
||||
- `celery>=5.4.0`
|
||||
- `django-celery-results>=2.5.1`
|
||||
|
||||
Затем:
|
||||
```bash
|
||||
pip install -r dbapp/requirements.txt
|
||||
```
|
||||
|
||||
### Шаг 2: Применение миграций
|
||||
|
||||
```bash
|
||||
cd dbapp
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
### Шаг 3: Запуск FlareSolver
|
||||
|
||||
```bash
|
||||
docker-compose up -d flaresolverr
|
||||
```
|
||||
|
||||
### Шаг 4: Запуск Django
|
||||
|
||||
```bash
|
||||
cd dbapp
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
### Ограничения базовой установки
|
||||
|
||||
⚠️ **Внимание**: В синхронном режиме:
|
||||
- Веб-интерфейс будет заблокирован во время обработки
|
||||
- Нет отслеживания прогресса в реальном времени
|
||||
- Нет детального логирования
|
||||
- Обработка может занять много времени
|
||||
|
||||
---
|
||||
|
||||
## Проверка установки
|
||||
|
||||
### Проверка Django
|
||||
```bash
|
||||
@@ -136,25 +70,6 @@ curl http://localhost:8191/v1
|
||||
|
||||
---
|
||||
|
||||
## Решение проблем при установке
|
||||
|
||||
### Проблема: ModuleNotFoundError: No module named 'celery'
|
||||
|
||||
**Решение 1**: Установите Celery
|
||||
```bash
|
||||
pip install celery django-celery-results
|
||||
```
|
||||
|
||||
**Решение 2**: Используйте базовую установку (см. Вариант 2)
|
||||
|
||||
### Проблема: Redis connection refused
|
||||
|
||||
**Решение**: Запустите Redis
|
||||
```bash
|
||||
docker-compose up -d redis
|
||||
# или
|
||||
sudo systemctl start redis
|
||||
```
|
||||
|
||||
### Проблема: FlareSolver не отвечает
|
||||
|
||||
@@ -165,72 +80,6 @@ docker-compose up -d flaresolverr
|
||||
docker run -d -p 8191:8191 ghcr.io/flaresolverr/flaresolverr:latest
|
||||
```
|
||||
|
||||
### Проблема: Миграции не применяются
|
||||
|
||||
**Решение**: Проверьте подключение к базе данных
|
||||
```bash
|
||||
# Проверьте .env файл
|
||||
cat dbapp/.env
|
||||
|
||||
# Проверьте PostgreSQL
|
||||
docker-compose up -d db
|
||||
docker-compose logs db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
Создайте файл `dbapp/.env` (если еще не создан):
|
||||
|
||||
```bash
|
||||
# Database
|
||||
DB_ENGINE=django.contrib.gis.db.backends.postgis
|
||||
DB_NAME=geodb
|
||||
DB_USER=geralt
|
||||
DB_PASSWORD=123456
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
|
||||
# Django
|
||||
SECRET_KEY=your-secret-key-here
|
||||
DEBUG=True
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
|
||||
# Celery (опционально)
|
||||
CELERY_BROKER_URL=redis://localhost:6379/0
|
||||
|
||||
# FlareSolver
|
||||
FLARESOLVERR_URL=http://localhost:8191/v1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Следующие шаги
|
||||
|
||||
После успешной установки:
|
||||
|
||||
1. **Прочитайте документацию**:
|
||||
- `QUICKSTART_ASYNC.md` - быстрый старт
|
||||
- `ASYNC_LYNGSAT_GUIDE.md` - полное руководство
|
||||
- `ASYNC_CHANGES_SUMMARY.md` - технические детали
|
||||
|
||||
2. **Настройте production окружение** (если необходимо):
|
||||
- Настройте Systemd/Supervisor для Celery
|
||||
- Настройте Nginx/Apache
|
||||
- Настройте SSL
|
||||
- Настройте мониторинг
|
||||
|
||||
3. **Добавьте данные**:
|
||||
- Добавьте спутники через админ-панель
|
||||
- Запустите заполнение данных Lyngsat
|
||||
|
||||
4. **Настройте мониторинг**:
|
||||
- Установите Flower для мониторинга Celery
|
||||
- Настройте логирование
|
||||
- Настройте алерты
|
||||
|
||||
---
|
||||
|
||||
## Дополнительные инструменты
|
||||
|
||||
@@ -263,39 +112,6 @@ docker run -d -p 5050:80 --name pgadmin \
|
||||
|
||||
---
|
||||
|
||||
## Обновление системы
|
||||
|
||||
### Обновление зависимостей
|
||||
|
||||
```bash
|
||||
pip install --upgrade -r dbapp/requirements.txt
|
||||
```
|
||||
|
||||
### Применение новых миграций
|
||||
|
||||
```bash
|
||||
cd dbapp
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
### Перезапуск сервисов
|
||||
|
||||
```bash
|
||||
# Перезапуск Docker контейнеров
|
||||
docker-compose restart
|
||||
|
||||
# Перезапуск Celery Worker
|
||||
# Найдите PID процесса
|
||||
ps aux | grep celery
|
||||
# Остановите процесс
|
||||
kill <PID>
|
||||
# Запустите снова
|
||||
celery -A dbapp worker --loglevel=info
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Удаление системы
|
||||
|
||||
### Остановка сервисов
|
||||
|
||||
@@ -321,27 +137,31 @@ find dbapp -path "*/migrations/*.py" -not -name "__init__.py" -delete
|
||||
find dbapp -path "*/migrations/*.pyc" -delete
|
||||
```
|
||||
|
||||
---
|
||||
# Systemd service для запуска с хоста
|
||||
|
||||
[Unit]
|
||||
Description=Django Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/path/to/your/app
|
||||
Environment=PATH=/path/to/venv/bin
|
||||
Environment=DATABASE_URL=postgresql://user:pass@localhost/geodb
|
||||
ExecStart=/path/to/venv/bin/python manage.py runserver 0.0.0.0:8000
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
TimeoutSec=300
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
## Поддержка
|
||||
|
||||
Если у вас возникли проблемы:
|
||||
|
||||
1. Проверьте логи:
|
||||
- Django: консоль где запущен runserver
|
||||
- Celery: `dbapp/logs/celery_worker.log`
|
||||
- Docker: `docker-compose logs`
|
||||
|
||||
2. Проверьте документацию:
|
||||
- `ASYNC_LYNGSAT_GUIDE.md`
|
||||
- `QUICKSTART_ASYNC.md`
|
||||
- `ASYNC_CHANGES_SUMMARY.md`
|
||||
|
||||
3. Проверьте статус сервисов:
|
||||
```bash
|
||||
docker-compose ps
|
||||
ps aux | grep celery
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
4. Создайте issue в репозитории с описанием проблемы и логами
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# Руководство по заполнению данных Lyngsat
|
||||
|
||||
## Описание
|
||||
|
||||
Новая функциональность позволяет автоматически загружать данные о транспондерах спутников с сайта Lyngsat.
|
||||
|
||||
## Как использовать
|
||||
|
||||
1. **Перейдите на страницу действий**
|
||||
- Откройте главную страницу приложения
|
||||
- Нажмите на "Действия" в меню навигации
|
||||
|
||||
2. **Откройте форму заполнения данных Lyngsat**
|
||||
- На странице действий найдите карточку "Заполнение данных Lyngsat"
|
||||
- Нажмите кнопку "Заполнить данные Lyngsat"
|
||||
|
||||
3. **Заполните форму**
|
||||
- **Выберите спутники**: Выберите один или несколько спутников из списка (удерживайте Ctrl/Cmd для множественного выбора)
|
||||
- **Выберите регионы**: Выберите регионы для парсинга (Europe, Asia, America, Atlantic)
|
||||
|
||||
4. **Запустите процесс**
|
||||
- Нажмите кнопку "Заполнить данные"
|
||||
- Дождитесь завершения процесса (может занять несколько минут)
|
||||
|
||||
## Что происходит при заполнении
|
||||
|
||||
1. Система подключается к сайту Lyngsat через FlareSolver (требуется запущенный сервис)
|
||||
2. Парсит данные о транспондерах для выбранных спутников
|
||||
3. Создает или обновляет записи в базе данных:
|
||||
- Частота
|
||||
- Поляризация
|
||||
- Модуляция
|
||||
- Стандарт (DVB-S, DVB-S2 и т.д.)
|
||||
- Символьная скорость
|
||||
- FEC (коэффициент коррекции ошибок)
|
||||
- Информация о канале
|
||||
- Дата последнего обновления
|
||||
|
||||
## Требования
|
||||
|
||||
- **FlareSolver**: Должен быть запущен на `http://localhost:8191`
|
||||
- **Спутники в базе**: Спутники должны быть предварительно добавлены в базу данных
|
||||
- **Интернет-соединение**: Требуется для доступа к сайту Lyngsat
|
||||
|
||||
## Результаты
|
||||
|
||||
После завершения процесса вы увидите:
|
||||
- Количество обработанных спутников
|
||||
- Количество обработанных источников
|
||||
- Количество созданных записей
|
||||
- Количество обновленных записей
|
||||
- Список ошибок (если есть)
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Функция `fill_lyngsat_data`
|
||||
|
||||
Функция была доработана для поддержки:
|
||||
- Частичного заполнения данных
|
||||
- Выбора регионов
|
||||
- Детальной статистики обработки
|
||||
- Обработки ошибок без прерывания процесса
|
||||
|
||||
### Изменения в коде
|
||||
|
||||
1. **Новая форма**: `FillLyngsatDataForm` в `mainapp/forms.py`
|
||||
2. **Новый view**: `FillLyngsatDataView` в `mainapp/views.py`
|
||||
3. **Новый URL**: `/fill-lyngsat-data/` в `mainapp/urls.py`
|
||||
4. **Новый шаблон**: `fill_lyngsat_data.html`
|
||||
5. **Обновленная функция**: `fill_lyngsat_data` в `lyngsatapp/utils.py`
|
||||
6. **Обновленный шаблон**: `actions.html` (заменена карточка с картами)
|
||||
|
||||
## Примечания
|
||||
|
||||
- Процесс может занять продолжительное время в зависимости от количества выбранных спутников
|
||||
- Рекомендуется выбирать небольшое количество спутников для первого запуска
|
||||
- Существующие записи будут обновлены, новые - созданы
|
||||
- Все ошибки логируются и отображаются пользователю
|
||||
@@ -10,11 +10,8 @@ import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
# Determine the environment from DJANGO_ENVIRONMENT variable
|
||||
# Defaults to 'development' for safety
|
||||
ENVIRONMENT = os.getenv('DJANGO_ENVIRONMENT', 'development').lower()
|
||||
|
||||
if ENVIRONMENT == 'production':
|
||||
|
||||
@@ -46,3 +46,10 @@ INTERNAL_IPS = [
|
||||
|
||||
# Use console backend for development
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
# ============================================================================
|
||||
# STATIC FILES CONFIGURATION FOR DEVELOPMENT
|
||||
# ============================================================================
|
||||
|
||||
# Define STATIC_ROOT for collectstatic command to work in development
|
||||
STATIC_ROOT = BASE_DIR.parent / "staticfiles"
|
||||
@@ -408,6 +408,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source Type Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Тип источника:</label>
|
||||
<div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_source_type" id="has_source_type_1"
|
||||
value="1" {% if has_source_type == '1' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_source_type_1">Есть (ТВ)</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_source_type" id="has_source_type_0"
|
||||
value="0" {% if has_source_type == '0' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_source_type_0">Нет</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sigma Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Sigma:</label>
|
||||
<div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_sigma" id="has_sigma_1"
|
||||
value="1" {% if has_sigma == '1' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_sigma_1">Есть</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_sigma" id="has_sigma_0"
|
||||
value="0" {% if has_sigma == '0' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_sigma_0">Нет</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Дата ГЛ:</label>
|
||||
@@ -759,6 +793,8 @@
|
||||
|
||||
setupRadioLikeCheckboxes('has_kupsat');
|
||||
setupRadioLikeCheckboxes('has_valid');
|
||||
setupRadioLikeCheckboxes('has_source_type');
|
||||
setupRadioLikeCheckboxes('has_sigma');
|
||||
|
||||
// Date range quick selection functions
|
||||
window.setDateRange = function (period) {
|
||||
|
||||
@@ -792,6 +792,20 @@ class ObjItemListView(LoginRequiredMixin, View):
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
# Filter by source type (lyngsat_source)
|
||||
has_source_type = request.GET.get("has_source_type")
|
||||
if has_source_type == "1":
|
||||
objects = objects.filter(lyngsat_source__isnull=False)
|
||||
elif has_source_type == "0":
|
||||
objects = objects.filter(lyngsat_source__isnull=True)
|
||||
|
||||
# Filter by sigma (sigma parameters)
|
||||
has_sigma = request.GET.get("has_sigma")
|
||||
if has_sigma == "1":
|
||||
objects = objects.filter(parameter_obj__sigma_parameter__isnull=False)
|
||||
elif has_sigma == "0":
|
||||
objects = objects.filter(parameter_obj__sigma_parameter__isnull=True)
|
||||
|
||||
if search_query:
|
||||
search_query = search_query.strip()
|
||||
if search_query:
|
||||
@@ -955,23 +969,19 @@ class ObjItemListView(LoginRequiredMixin, View):
|
||||
comment = obj.geo_obj.comment or "-"
|
||||
is_average = "Да" if obj.geo_obj.is_average else "Нет" if obj.geo_obj.is_average is not None else "-"
|
||||
|
||||
# Check if LyngSat source is linked
|
||||
source_type = "ТВ" if obj.lyngsat_source else "-"
|
||||
|
||||
# Check if SigmaParameter is linked
|
||||
has_sigma = False
|
||||
sigma_info = "-"
|
||||
if param:
|
||||
sigma_count = param.sigma_parameter.count()
|
||||
if sigma_count > 0:
|
||||
has_sigma = True
|
||||
# Get first sigma parameter for preview
|
||||
first_sigma = param.sigma_parameter.first()
|
||||
if first_sigma:
|
||||
sigma_freq = f"{first_sigma.frequency:.3f}" if first_sigma.frequency else "-"
|
||||
sigma_freq = f"{first_sigma.transfer_frequency:.3f}" if first_sigma.transfer_frequency else "-"
|
||||
sigma_range = f"{first_sigma.freq_range:.3f}" if first_sigma.freq_range else "-"
|
||||
sigma_pol = first_sigma.polarization.name if first_sigma.polarization else "-"
|
||||
# Сокращаем поляризацию
|
||||
sigma_pol_short = sigma_pol[0] if sigma_pol and sigma_pol != "-" else "-"
|
||||
sigma_info = f"{sigma_freq}/{sigma_range}/{sigma_pol_short}"
|
||||
|
||||
@@ -1008,6 +1018,10 @@ class ObjItemListView(LoginRequiredMixin, View):
|
||||
modulations = Modulation.objects.all()
|
||||
polarizations = Polarization.objects.all()
|
||||
|
||||
# Get the new filter values
|
||||
has_source_type = request.GET.get("has_source_type")
|
||||
has_sigma = request.GET.get("has_sigma")
|
||||
|
||||
context = {
|
||||
"satellites": satellites,
|
||||
"selected_satellite_id": selected_sat_id,
|
||||
@@ -1035,6 +1049,8 @@ class ObjItemListView(LoginRequiredMixin, View):
|
||||
"has_valid": has_valid,
|
||||
"date_from": date_from,
|
||||
"date_to": date_to,
|
||||
"has_source_type": has_source_type,
|
||||
"has_sigma": has_sigma,
|
||||
"modulations": modulations,
|
||||
"polarizations": polarizations,
|
||||
"full_width_page": True,
|
||||
|
||||
@@ -41,6 +41,7 @@ dependencies = [
|
||||
"scikit-learn>=1.7.2",
|
||||
"selenium>=4.38.0",
|
||||
"setuptools>=80.9.0",
|
||||
"uvicorn>=0.38.0",
|
||||
]
|
||||
|
||||
|
||||
|
||||
15
dbapp/uv.lock
generated
15
dbapp/uv.lock
generated
@@ -386,6 +386,7 @@ dependencies = [
|
||||
{ name = "scikit-learn" },
|
||||
{ name = "selenium" },
|
||||
{ name = "setuptools" },
|
||||
{ name = "uvicorn" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
@@ -426,6 +427,7 @@ requires-dist = [
|
||||
{ name = "scikit-learn", specifier = ">=1.7.2" },
|
||||
{ name = "selenium", specifier = ">=4.38.0" },
|
||||
{ name = "setuptools", specifier = ">=80.9.0" },
|
||||
{ name = "uvicorn", specifier = ">=0.38.0" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
@@ -1578,6 +1580,19 @@ socks = [
|
||||
{ name = "pysocks" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.38.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vine"
|
||||
version = "5.1.0"
|
||||
|
||||
@@ -38,40 +38,17 @@ services:
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
# web:
|
||||
# build:
|
||||
# context: ./dbapp
|
||||
# dockerfile: Dockerfile
|
||||
# container_name: django-app-dev
|
||||
# nginx:
|
||||
# image: nginx:alpine
|
||||
# container_name: nginx
|
||||
# restart: unless-stopped
|
||||
# environment:
|
||||
# - DEBUG=True
|
||||
# - ENVIRONMENT=development
|
||||
# - DJANGO_SETTINGS_MODULE=dbapp.settings.development
|
||||
# - SECRET_KEY=django-insecure-dev-key-change-in-production
|
||||
# - DB_ENGINE=django.contrib.gis.db.backends.postgis
|
||||
# - DB_NAME=geodb
|
||||
# - DB_USER=geralt
|
||||
# - DB_PASSWORD=123456
|
||||
# - DB_HOST=db
|
||||
# - DB_PORT=5432
|
||||
# - ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0
|
||||
# ports:
|
||||
# - "8000:8000"
|
||||
# - "80:80"
|
||||
# # - "443:443"
|
||||
# volumes:
|
||||
# # Монтируем только код приложения, не весь проект
|
||||
# - ./dbapp/dbapp:/app/dbapp
|
||||
# - ./dbapp/mainapp:/app/mainapp
|
||||
# - ./dbapp/mapsapp:/app/mapsapp
|
||||
# - ./dbapp/lyngsatapp:/app/lyngsatapp
|
||||
# - ./dbapp/static:/app/static
|
||||
# - ./dbapp/manage.py:/app/manage.py
|
||||
# - static_volume_dev:/app/staticfiles
|
||||
# - media_volume_dev:/app/media
|
||||
# - logs_volume_dev:/app/logs
|
||||
# depends_on:
|
||||
# db:
|
||||
# condition: service_healthy
|
||||
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
# - ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||
# - ./dbapp/staticfiles:/app/staticfiles:ro
|
||||
# networks:
|
||||
# - app-network
|
||||
|
||||
@@ -92,9 +69,6 @@ services:
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
# static_volume_dev:
|
||||
# media_volume_dev:
|
||||
# logs_volume_dev:
|
||||
# tileserver_config_dev:
|
||||
|
||||
networks:
|
||||
|
||||
17
nginx/conf.d/default.conf
Normal file
17
nginx/conf.d/default.conf
Normal file
@@ -0,0 +1,17 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
location /static/ {
|
||||
alias /home/vesemir/DataStorage/dbapp/staticfiles/;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://host.docker.internal:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
39
nginx/nginx.conf
Normal file
39
nginx/nginx.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Log format
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
||||
|
||||
# Proxy settings
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
# gzip_proxied expired no-cache no-store private must-revalidate auth;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||
|
||||
# Include server blocks
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
Reference in New Issue
Block a user