import json import os from typing import List, Dict, Optional from app.models.schemas import Project, ScanResult, IntelSource from loguru import logger class ProjectService: def __init__(self, storage_dir: str = "data"): self.storage_dir = storage_dir self.projects_path = os.path.join(storage_dir, "projects.json") self.scans_path = os.path.join(storage_dir, "scans.json") self.sources_path = os.path.join(storage_dir, "sources.json") self.projects: Dict[str, Project] = {} self.scans: Dict[str, ScanResult] = {} self.intel_sources: List[IntelSource] = [] self._ensure_storage() self._load_data() def _ensure_storage(self): os.makedirs(self.storage_dir, exist_ok=True) for path in [self.projects_path, self.scans_path, self.sources_path]: if not os.path.exists(path): with open(path, "w") as f: json.dump([] if "sources" in path else {}, f) def _load_data(self): try: with open(self.projects_path, "r") as f: p_data = json.load(f) self.projects = {pid: Project(**pd) for pid, pd in p_data.items()} with open(self.scans_path, "r") as f: s_data = json.load(f) self.scans = {sid: ScanResult(**sd) for sid, sd in s_data.items()} with open(self.sources_path, "r") as f: src_data = json.load(f) self.intel_sources = [IntelSource(**sd) for sd in src_data] except Exception as e: logger.error(f"Failed to load data: {e}") def save_project(self, project: Project): self.projects[project.id] = project self._sync_projects() logger.info(f"Project saved: {project.name}") def save_scan(self, scan: ScanResult): self.scans[scan.scan_id] = scan self._sync_scans() logger.info(f"Scan result saved for {scan.target}") def get_scans_by_project(self, project_id: str) -> List[ScanResult]: return [s for s in self.scans.values() if s.project_id == project_id] def get_projects(self) -> List[Project]: return list(self.projects.values()) def get_project(self, project_id: str) -> Optional[Project]: return self.projects.get(project_id) def save_intel_source(self, source: IntelSource): self.intel_sources.append(source) self._sync_sources() logger.info(f"Intel source saved: {source.name}") def _sync_projects(self): with open(self.projects_path, "w") as f: data = {pid: p.model_dump(mode='json') for pid, p in self.projects.items()} json.dump(data, f, indent=4) def _sync_scans(self): with open(self.scans_path, "w") as f: data = {sid: s.model_dump(mode='json') for sid, s in self.scans.items()} json.dump(data, f, indent=4) def _sync_sources(self): with open(self.sources_path, "w") as f: data = [s.model_dump(mode='json') for s in self.intel_sources] json.dump(data, f, indent=4) project_service = ProjectService()