fuck yeah!

This commit is contained in:
Vic Sergeev 2026-06-10 17:33:12 +03:00
parent ccb53d9091
commit da10f5e132
44 changed files with 3260 additions and 448 deletions

View file

@ -0,0 +1,191 @@
"""
Главный контроллер приложения - связывает модель и представление
"""
from PySide6.QtCore import QObject, Signal
from datetime import datetime
from pathlib import Path
import numpy as np
from models.api_model import HelioviewerAPI
from models.image_model import ImageModel
from views.main_window import MainWindow
from utils.image_processor import ImageProcessor
from utils.metadata_parser import MetadataParser
class AppController(QObject):
"""Главный контроллер приложения"""
def __init__(self):
super().__init__()
self.image_model = ImageModel()
self.api = HelioviewerAPI()
self.main_window = None
self.timelapse_controller = None
# Подключаем сигналы модели
self.image_model.layer_added.connect(self.on_layer_added)
self.image_model.layer_removed.connect(self.on_layer_removed)
self.image_model.layer_visibility_changed.connect(self.on_layer_visibility_changed)
self.image_model.layer_opacity_changed.connect(self.on_layer_opacity_changed)
self.image_model.layer_selected.connect(self.on_layer_selected)
# Папка для сохранения по умолчанию
self.download_folder = Path.home() / "SolarImages"
self.download_folder.mkdir(exist_ok=True)
def show_main_window(self):
"""Показывает главное окно"""
self.main_window = MainWindow(self)
self.main_window.show()
# Подключаем сигналы от панели управления
control_panel = self.main_window.get_control_panel()
control_panel.load_image_requested.connect(self.load_image_from_api)
def load_image_from_api(self, source_id: int, date: datetime):
"""Загружает изображение из API"""
self.main_window.update_status(f"Загрузка изображения: {date.strftime('%Y-%m-%d %H:%M')} UTC")
# Скачиваем изображение
filepath = self.api.download_image(source_id, date, self.download_folder)
if filepath:
# Загружаем данные изображения
img_data = ImageProcessor.load_jp2(str(filepath))
if img_data is not None:
# Извлекаем метаданные
metadata = MetadataParser.extract_metadata(str(filepath))
# Получаем информацию о спектре
source_info = self.api.SOURCES.get(source_id, {})
wavelength = source_info.get("wavelength", "Unknown")
# Добавляем слой в модель
layer_id = self.image_model.add_layer(
filepath, source_id, date, wavelength, img_data, metadata
)
self.main_window.update_status(f"✓ Загружено: {filepath.name}")
else:
self.main_window.update_status("✗ Ошибка обработки изображения")
else:
self.main_window.update_status("✗ Ошибка загрузки изображения")
def on_layer_added(self, layer):
"""Обработчик добавления слоя"""
self.main_window.update_layer_list(self.image_model.get_all_layers())
self.main_window.canvas.set_image(layer.id, layer.image_data)
def on_layer_removed(self, layer_id):
"""Обработчик удаления слоя"""
self.main_window.layer_widget.remove_layer(layer_id)
self.main_window.canvas.remove_layer(layer_id)
if not self.image_model.get_all_layers():
self.main_window.metadata_viewer.clear()
def on_layer_visibility_changed(self, layer_id, visible):
"""Обработчик изменения видимости слоя"""
self.main_window.canvas.set_layer_visibility(layer_id, visible)
def on_layer_opacity_changed(self, layer_id, opacity):
"""Обработчик изменения прозрачности слоя"""
self.main_window.canvas.set_layer_opacity(layer_id, opacity)
def on_layer_selected(self, layer_id):
"""Обработчик выбора слоя"""
for layer in self.image_model.get_all_layers():
if layer.id == layer_id:
if layer.metadata:
self.main_window.metadata_viewer.display_metadata(layer.metadata)
break
def set_layer_visibility(self, layer_id, visible):
self.image_model.set_layer_visibility(layer_id, visible)
def set_layer_opacity(self, layer_id, opacity):
self.image_model.set_layer_opacity(layer_id, opacity)
def clear_all_layers(self):
self.image_model.clear()
self.main_window.canvas.clear_all_layers()
self.main_window.metadata_viewer.clear()
# Добавьте эти методы в класс AppController:
def create_timelapse(self, source_id: int, start_date: datetime,
end_date: datetime, output_path: Path,
fps: int = 10, output_format: str = "mp4"):
"""Создает таймлапс"""
from controllers.timelapse_controller import TimelapseController
self.timelapse_controller = TimelapseController()
# Подключаем сигналы
self.timelapse_controller.progress_updated.connect(self.on_timelapse_progress)
self.timelapse_controller.log_message.connect(self.on_timelapse_log)
self.timelapse_controller.finished.connect(self.on_timelapse_finished)
# Запускаем
self.timelapse_controller.create_timelapse(
source_id, start_date, end_date, output_path, fps, output_format
)
def cancel_timelapse(self):
"""Отменяет создание таймлапса"""
if hasattr(self, 'timelapse_controller'):
self.timelapse_controller.cancel()
def on_timelapse_progress(self, current, total, message):
"""Прогресс таймлапса"""
if self.main_window:
self.main_window.update_status(f"Таймлапс: {message}")
def on_timelapse_log(self, message):
"""Лог таймлапса"""
print(f"[Timelapse] {message}")
def on_timelapse_finished(self, success, message):
"""Завершение таймлапса"""
if self.main_window:
if success:
self.main_window.update_status(f"✅ Таймлапс создан")
from PySide6.QtWidgets import QMessageBox
QMessageBox.information(self.main_window, "Готово", f"Таймлапс сохранен:\n{message}")
else:
self.main_window.update_status(f"❌ Ошибка: {message}")
# Добавьте метод:
def create_timelapse(self, source_id, start_date, end_date, output_path, fps=10, output_format="mp4"):
"""Создает таймлапс"""
print(f"[DEBUG] AppController.create_timelapse вызван")
from controllers.timelapse_controller import TimelapseController
self.timelapse_controller = TimelapseController()
# Подключаем сигналы
self.timelapse_controller.progress_updated.connect(self.on_timelapse_progress)
self.timelapse_controller.log_message.connect(self.on_timelapse_log)
self.timelapse_controller.finished.connect(self.on_timelapse_finished)
# Запускаем
self.timelapse_controller.create_timelapse(
source_id, start_date, end_date, output_path, fps, output_format
)
print(f"[DEBUG] TimelapseController создан и запущен")
def on_timelapse_log(self, message):
"""Лог таймлапса"""
print(f"[TIMELAPSE] {message}")
if self.main_window:
self.main_window.update_status(f"Таймлапс: {message}")
def create_timelapse(self, source_id, start_date, end_date, output_path, fps=10, output_format="mp4"):
"""Создает таймлапс - заглушка, реальный вызов из диалога"""
# Реальная реализация в диалоге
pass
def cancel_timelapse(self):
pass