Files
trendyol-analiz/start.py
furkanyigit34 c7be57064b Initial commit: Trendyol Analiz platform
- FastAPI backend with Python
- React + Vite admin panel
- PostgreSQL database
- Trendyol marketplace analytics
- GitHub Actions CI/CD workflow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 00:14:38 +03:00

293 lines
10 KiB
Python
Executable File
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.
#!/usr/bin/env python3
"""
Trendyol Analytics Dashboard - Otomatik Başlatma Scripti
Tüm kontrolleri yapar, ayarları düzeltir ve projeyi başlatır.
"""
import os
import sys
import json
import time
import socket
import subprocess
from pathlib import Path
from typing import Optional, Tuple
# Renkli terminal çıktısı
class Colors:
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BLUE = '\033[94m'
BOLD = '\033[1m'
END = '\033[0m'
def print_status(emoji: str, message: str, color: str = Colors.GREEN):
"""Renkli status mesajı yazdır"""
print(f"{color}{emoji} {message}{Colors.END}")
def print_header(title: str):
"""Başlık yazdır"""
print(f"\n{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}")
print(f"{Colors.BOLD}{Colors.BLUE}{title.center(60)}{Colors.END}")
print(f"{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}\n")
def check_port_available(port: int) -> bool:
"""Port'un kullanılabilir olup olmadığını kontrol et"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('127.0.0.1', port)) != 0
def find_available_port(start_port: int, max_attempts: int = 10) -> Optional[int]:
"""Kullanılabilir port bul"""
for port in range(start_port, start_port + max_attempts):
if check_port_available(port):
return port
return None
def kill_process_on_port(port: int):
"""Belirtilen porttaki process'i öldür"""
try:
result = subprocess.run(
f"lsof -ti:{port} | xargs kill -9",
shell=True,
capture_output=True,
text=True
)
if result.returncode == 0:
print_status("🔪", f"Port {port} üzerindeki process sonlandırıldı", Colors.YELLOW)
time.sleep(1)
return True
except Exception:
pass
return False
def check_and_fix_env_file(project_root: Path, backend_port: int) -> bool:
"""Environment dosyasını kontrol et ve düzelt"""
env_file = project_root / "admin-panel" / ".env"
expected_url = f"VITE_API_URL=http://127.0.0.1:{backend_port}"
try:
if env_file.exists():
content = env_file.read_text().strip()
if content != expected_url:
print_status("⚙️", f".env dosyası güncelleniyor: {expected_url}", Colors.YELLOW)
env_file.write_text(expected_url + "\n")
return True
else:
print_status("", ".env dosyası doğru yapılandırılmış")
return False
else:
print_status("📝", ".env dosyası oluşturuluyor", Colors.YELLOW)
env_file.write_text(expected_url + "\n")
return True
except Exception as e:
print_status("", f".env dosyası hatası: {e}", Colors.RED)
return False
def check_dependencies(project_root: Path) -> Tuple[bool, bool]:
"""Bağımlılıkları kontrol et"""
print_header("BAĞIMLILIK KONTROLÜ")
# Python bağımlılıkları
python_ok = True
try:
import fastapi
import uvicorn
import sqlalchemy
print_status("", "Python bağımlılıkları yüklü")
except ImportError as e:
print_status("", f"Python bağımlılıkları eksik: {e}", Colors.RED)
print_status("💡", "Çözüm: cd backend && pip install -r requirements.txt", Colors.YELLOW)
python_ok = False
# Node.js bağımlılıkları
node_modules = project_root / "admin-panel" / "node_modules"
node_ok = node_modules.exists()
if node_ok:
print_status("", "Node.js bağımlılıkları yüklü")
else:
print_status("", "Node.js bağımlılıkları eksik", Colors.RED)
print_status("💡", "Çözüm: cd admin-panel && npm install", Colors.YELLOW)
return python_ok, node_ok
def start_backend(project_root: Path, port: int) -> Optional[subprocess.Popen]:
"""Backend'i başlat"""
backend_dir = project_root / "backend"
try:
print_status("🚀", f"Backend başlatılıyor (port {port})...", Colors.BLUE)
# Backend process'ini başlat
process = subprocess.Popen(
[sys.executable, "main.py"],
cwd=backend_dir,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Backend'in başlamasını bekle
time.sleep(3)
# Backend'in çalıştığını kontrol et
if not check_port_available(port):
print_status("", f"Backend başarıyla başlatıldı: http://127.0.0.1:{port}")
return process
else:
print_status("", "Backend başlatılamadı", Colors.RED)
return None
except Exception as e:
print_status("", f"Backend başlatma hatası: {e}", Colors.RED)
return None
def start_frontend(project_root: Path) -> Optional[subprocess.Popen]:
"""Frontend'i başlat"""
frontend_dir = project_root / "admin-panel"
try:
print_status("🚀", "Frontend başlatılıyor...", Colors.BLUE)
# Frontend process'ini başlat
process = subprocess.Popen(
["npm", "run", "dev"],
cwd=frontend_dir,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Frontend'in başlamasını bekle ve port'u yakala
time.sleep(5)
# Frontend çıktısını kontrol et
frontend_port = None
for _ in range(10):
line = process.stdout.readline()
if "Local:" in line and "http://localhost:" in line:
# Port'u yakala: "Local: http://localhost:5174/"
frontend_port = line.split("http://localhost:")[1].split("/")[0]
break
time.sleep(0.5)
if frontend_port:
print_status("", f"Frontend başarıyla başlatıldı: http://localhost:{frontend_port}")
return process
else:
print_status("⚠️", "Frontend başlatıldı ancak port tespit edilemedi", Colors.YELLOW)
return process
except Exception as e:
print_status("", f"Frontend başlatma hatası: {e}", Colors.RED)
return None
def main():
"""Ana başlatma fonksiyonu"""
project_root = Path(__file__).parent
print_header("TRENDYOL ANALYTICS DASHBOARD")
print_status("📁", f"Proje dizini: {project_root}")
# 1. Bağımlılıkları kontrol et
python_ok, node_ok = check_dependencies(project_root)
if not python_ok or not node_ok:
print_status("", "Önce bağımlılıkları yükleyin!", Colors.RED)
sys.exit(1)
# 2. Port kontrolü ve yönetimi
print_header("PORT YÖNETİMİ")
BACKEND_PORT = 8001
FRONTEND_PORT = 5173
# Backend port kontrolü
if not check_port_available(BACKEND_PORT):
print_status("⚠️", f"Port {BACKEND_PORT} kullanımda", Colors.YELLOW)
if input(f"Port {BACKEND_PORT}'i temizlemek ister misiniz? (e/h): ").lower() == 'e':
kill_process_on_port(BACKEND_PORT)
else:
# Alternatif port bul
BACKEND_PORT = find_available_port(8001)
if not BACKEND_PORT:
print_status("", "Kullanılabilir port bulunamadı!", Colors.RED)
sys.exit(1)
print_status("🔄", f"Alternatif backend portu: {BACKEND_PORT}", Colors.YELLOW)
else:
print_status("", f"Backend portu {BACKEND_PORT} kullanılabilir")
# Frontend port kontrolü
if not check_port_available(FRONTEND_PORT):
print_status("⚠️", f"Port {FRONTEND_PORT} kullanımda (Vite otomatik alternatif seçecek)", Colors.YELLOW)
else:
print_status("", f"Frontend portu {FRONTEND_PORT} kullanılabilir")
# 3. Environment dosyasını kontrol et ve düzelt
print_header("YAPILANDIRMA KONTROLÜ")
env_changed = check_and_fix_env_file(project_root, BACKEND_PORT)
if env_changed:
print_status("🔄", "Yapılandırma güncellendi, frontend yeniden başlatılacak", Colors.YELLOW)
# 4. Servisleri başlat
print_header("SERVİSLERİ BAŞLAT")
# Backend'i başlat
backend_process = start_backend(project_root, BACKEND_PORT)
if not backend_process:
print_status("", "Backend başlatılamadı, çıkılıyor...", Colors.RED)
sys.exit(1)
# Frontend'i başlat
frontend_process = start_frontend(project_root)
if not frontend_process:
print_status("", "Frontend başlatılamadı", Colors.RED)
backend_process.terminate()
sys.exit(1)
# 5. Özet ve erişim bilgileri
print_header("✅ BAŞARILI - SİSTEM HAZIR")
print_status("🌐", f"Backend API: http://127.0.0.1:{BACKEND_PORT}")
print_status("💻", "Frontend: http://localhost:5173 veya 5174 (konsolu kontrol edin)")
print_status("📊", "Kategorileri görmek için ana sayfaya gidin")
print_status("📝", "Rapor oluşturmak için 'Rapor Oluştur' sekmesine gidin")
print()
print_status("⚠️", "Durdurmak için: CTRL+C", Colors.YELLOW)
# Process'leri çalışır durumda tut
try:
while True:
time.sleep(1)
# Process'lerin hala çalıştığını kontrol et
if backend_process.poll() is not None:
print_status("", "Backend beklenmedik şekilde durdu!", Colors.RED)
break
if frontend_process.poll() is not None:
print_status("", "Frontend beklenmedik şekilde durdu!", Colors.RED)
break
except KeyboardInterrupt:
print()
print_status("🛑", "Sistem kapatılıyor...", Colors.YELLOW)
# Process'leri temiz şekilde kapat
backend_process.terminate()
frontend_process.terminate()
time.sleep(2)
# Hala çalışıyorlarsa zorla kapat
if backend_process.poll() is None:
backend_process.kill()
if frontend_process.poll() is None:
frontend_process.kill()
print_status("", "Sistem temiz bir şekilde kapatıldı")
if __name__ == "__main__":
main()