diff --git a/.gitignore b/.gitignore index 1375413..cc0083a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ venv/ ENV/ env/ +.env # IDE .idea/ diff --git a/backend/config.py b/backend/config.py index 8b84b19..41ddff6 100644 --- a/backend/config.py +++ b/backend/config.py @@ -42,9 +42,8 @@ def setup_logging(): class Settings(BaseSettings): """Настройки приложения""" - # ProxyAPI (OpenAI-совместимый) - proxy_api_key: str = os.getenv("PROXY_API_KEY", "") - proxy_api_base_url: str = "https://api.proxyapi.ru/openai/v1" + # OpenAI + openai_api_key: str = os.getenv("OPENAI_API_KEY", "") openai_model: str = os.getenv("OPENAI_MODEL", "gpt-4o-mini") openai_vision_model: str = os.getenv("OPENAI_VISION_MODEL", "gpt-4o-mini") diff --git a/backend/services/openai_service.py b/backend/services/openai_service.py index b164f13..65c99a2 100644 --- a/backend/services/openai_service.py +++ b/backend/services/openai_service.py @@ -1,6 +1,5 @@ """ -Сервис для работы с ProxyAPI (OpenAI-совместимый API) -https://proxyapi.ru/docs/openai-text-generation +Сервис для работы с OpenAI API """ import base64 import json @@ -19,20 +18,20 @@ class OpenAIService: - """Сервис для анализа через ProxyAPI""" + """Сервис для анализа через OpenAI""" def __init__(self): logger.info("=" * 50) logger.info("Инициализация OpenAI сервиса") - logger.info(f" Base URL: {settings.proxy_api_base_url}") logger.info(f" Модель текста: {settings.openai_model}") logger.info(f" Модель vision: {settings.openai_vision_model}") - logger.info(f" API ключ: {'*' * 10}...{settings.proxy_api_key[-4:] if settings.proxy_api_key else 'НЕ ЗАДАН'}") + logger.info( + f" API ключ: {'*' * 10}..." + f"{settings.openai_api_key[-4:] if settings.openai_api_key else 'НЕ ЗАДАН'}" + ) - # ProxyAPI - OpenAI-совместимый API для России self.client = OpenAI( - api_key=settings.proxy_api_key, - base_url=settings.proxy_api_base_url + api_key=settings.openai_api_key, ) self.model = settings.openai_model self.vision_model = settings.openai_vision_model @@ -147,11 +146,14 @@ async def analyze_image(self, image_base64: str, mime_type: str = "image/jpeg") "marketing_insights": ["инсайт 1", "инсайт 2", ...], "visual_style_score": 7, "visual_style_analysis": "Анализ визуального стиля конкурента", + "design_score": 7, + "design_analysis": "Анализ дизайна конкурента", "recommendations": ["рекомендация 1", "рекомендация 2", ...] } Важно: - visual_style_score от 0 до 10 +- design_score от 0 до 10 - Каждый массив должен содержать 3-5 пунктов - Пиши на русском языке - Оценивай: цветовую палитру, типографику, композицию, UX/UI элементы""" diff --git a/desktop/CompetitorMonitor.spec b/desktop/CompetitorMonitor.spec index b307273..ea2a928 100644 --- a/desktop/CompetitorMonitor.spec +++ b/desktop/CompetitorMonitor.spec @@ -36,3 +36,9 @@ exe = EXE( codesign_identity=None, entitlements_file=None, ) +app = BUNDLE( + exe, + name='CompetitorMonitor.app', + icon=None, + bundle_identifier=None, +) diff --git a/desktop/build.py b/desktop/build.py index 1c685e5..f44e01c 100644 --- a/desktop/build.py +++ b/desktop/build.py @@ -1,5 +1,9 @@ """ -Скрипт сборки .exe файла для Windows +Скрипт сборки desktop-приложения (PyInstaller) + +Поддерживаемые платформы: +- Windows: сборка .exe +- macOS: сборка .app """ import os import sys @@ -9,7 +13,7 @@ def build_exe(): - """Собрать .exe файл""" + """Собрать desktop-приложение""" print("=" * 60) print("🔨 СБОРКА DESKTOP ПРИЛОЖЕНИЯ") print("=" * 60) @@ -64,20 +68,32 @@ def build_exe(): result = subprocess.run(pyinstaller_args, cwd=current_dir) if result.returncode == 0: - exe_path = current_dir / "dist" / f"{app_name}.exe" + # Определяем путь к итоговому файлу в зависимости от ОС + if sys.platform.startswith("win"): + artifact_path = current_dir / "dist" / f"{app_name}.exe" + elif sys.platform == "darwin": + # На macOS PyInstaller создаёт .app-бандл + artifact_path = current_dir / "dist" / f"{app_name}.app" + else: + # На Linux обычно создаётся исполняемый файл без расширения + artifact_path = current_dir / "dist" / app_name - if exe_path.exists(): - size_mb = exe_path.stat().st_size / (1024 * 1024) + if artifact_path.exists(): print("\n" + "=" * 60) print("✅ СБОРКА ЗАВЕРШЕНА УСПЕШНО!") print("=" * 60) - print(f"\n📁 Файл: {exe_path}") - print(f"📊 Размер: {size_mb:.1f} MB") + print(f"\n📁 Файл: {artifact_path}") print("\n💡 Для запуска:") - print(f" 1. Запустите backend: python run.py") - print(f" 2. Запустите {app_name}.exe") + print(" 1. В корне проекта запустите backend: python run.py") + if sys.platform == "darwin": + print(f" 2. Откройте {app_name}.app (в папке dist)") + elif sys.platform.startswith("win"): + print(f" 2. Запустите {app_name}.exe (в папке dist)") + else: + print(f" 2. Запустите файл {artifact_path.name} (в папке dist)") else: - print("\n❌ Ошибка: .exe файл не найден") + print("\n❌ Ошибка: файл сборки не найден (ожидался путь:") + print(f" {artifact_path})") else: print("\n❌ Ошибка сборки") sys.exit(1) diff --git a/history.json b/history.json index ed2d56b..478253f 100644 --- a/history.json +++ b/history.json @@ -1,4 +1,18 @@ [ + { + "id": "b7c857fa-75c5-4176-93f6-7992dd2eb73a", + "timestamp": "2026-02-09T14:31:25.427730", + "request_type": "image", + "request_summary": "Изображение: Zerocoder_PEm08_test_image.jpg", + "response_summary": "Сайт Zerocoder представляет собой образовательную платформу с фокусом на мультимодальные приложения и продвинутые технологии. Интерфейс имеет темный фон с яркими элементами и текстами. Содержит тексто" + }, + { + "id": "ad6f2f7f-9b4f-4871-a069-4ec46d83f245", + "timestamp": "2026-02-09T14:20:59.422119", + "request_type": "parse", + "request_summary": "URL: https://psnprofiles.com/scalar_syllable9", + "response_summary": "Сайт psnprofiles.com предоставляет пользователям удобный и красивый интерфейс для отслеживания их тр" + }, { "id": "f168066d-21bb-45d7-beed-be63ba35b31d", "timestamp": "2025-12-05T11:50:01.282016", diff --git a/run.py b/run.py index 66126bc..50d1cbe 100644 --- a/run.py +++ b/run.py @@ -20,7 +20,7 @@ print() print(f"🤖 Модель текста: {settings.openai_model}") print(f"👁️ Модель vision: {settings.openai_vision_model}") - print(f"🔑 API ключ: {'✓ Настроен' if settings.proxy_api_key else '✗ НЕ ЗАДАН!'}") + print(f"🔑 API ключ: {'✓ Настроен' if settings.openai_api_key else '✗ НЕ ЗАДАН!'}") print() print("-" * 60) print("Логи запросов будут отображаться ниже...")