114 lines
4.3 KiB
Python
114 lines
4.3 KiB
Python
"""
|
|
Cross-platform data storage for scientific-surfing.
|
|
Handles configuration and subscription data storage using YAML format.
|
|
"""
|
|
|
|
import os
|
|
import platform
|
|
import yaml
|
|
from pathlib import Path
|
|
from typing import Optional, Dict
|
|
|
|
from scientific_surfing.models import SubscriptionsData
|
|
|
|
|
|
class StorageManager:
|
|
"""Manages cross-platform data storage for subscriptions and configuration."""
|
|
|
|
def __init__(self):
|
|
self.config_dir = self._get_config_dir()
|
|
self.config_file = self.config_dir / "config.yaml"
|
|
self.subscriptions_file = self.config_dir / "subscriptions.yaml"
|
|
self._ensure_config_dir()
|
|
|
|
def _get_config_dir(self) -> Path:
|
|
"""Get the appropriate configuration directory for the current platform."""
|
|
system = platform.system().lower()
|
|
|
|
if system == "windows":
|
|
# Windows: %APPDATA%/scientific_surfing
|
|
app_data = os.environ.get("APPDATA")
|
|
if app_data:
|
|
return Path(app_data) / "scientific_surfing"
|
|
else:
|
|
return Path.home() / "AppData" / "Roaming" / "scientific_surfing"
|
|
|
|
elif system == "darwin":
|
|
# macOS: ~/Library/Application Support/scientific_surfing
|
|
return Path.home() / "Library" / "Application Support" / "scientific_surfing"
|
|
|
|
else:
|
|
# Linux and other Unix-like systems: ~/.config/scientific_surfing
|
|
xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
|
|
if xdg_config_home:
|
|
return Path(xdg_config_home) / "scientific_surfing"
|
|
else:
|
|
return Path.home() / ".config" / "scientific_surfing"
|
|
|
|
def _ensure_config_dir(self) -> None:
|
|
"""Ensure the configuration directory exists."""
|
|
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
def load_subscriptions(self) -> SubscriptionsData:
|
|
"""Load subscriptions from YAML file."""
|
|
if not self.subscriptions_file.exists():
|
|
return SubscriptionsData()
|
|
|
|
try:
|
|
with open(self.subscriptions_file, 'r', encoding='utf-8') as f:
|
|
data = yaml.safe_load(f)
|
|
if isinstance(data, dict):
|
|
return SubscriptionsData(**data)
|
|
return SubscriptionsData()
|
|
except (yaml.YAMLError, IOError) as e:
|
|
print(f"Warning: Failed to load subscriptions: {e}")
|
|
return SubscriptionsData()
|
|
|
|
def save_subscriptions(self, subscriptions: SubscriptionsData) -> bool:
|
|
"""Save subscriptions to YAML file."""
|
|
try:
|
|
with open(self.subscriptions_file, 'w', encoding='utf-8') as f:
|
|
# Convert Pydantic model to dict for YAML serialization
|
|
data = subscriptions.dict()
|
|
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
return True
|
|
except (yaml.YAMLError, IOError, ValueError) as e:
|
|
print(f"Error: Failed to save subscriptions: {e}")
|
|
return False
|
|
|
|
def load_config(self) -> dict:
|
|
"""Load configuration from YAML file."""
|
|
if not self.config_file.exists():
|
|
return {}
|
|
|
|
try:
|
|
with open(self.config_file, 'r', encoding='utf-8') as f:
|
|
data = yaml.safe_load(f)
|
|
if isinstance(data, dict):
|
|
return data
|
|
return {}
|
|
except (yaml.YAMLError, IOError) as e:
|
|
print(f"Warning: Failed to load config: {e}")
|
|
return {}
|
|
|
|
def save_config(self, config: dict) -> bool:
|
|
"""Save configuration to YAML file."""
|
|
try:
|
|
with open(self.config_file, 'w', encoding='utf-8') as f:
|
|
# Convert Pydantic model to dict for YAML serialization
|
|
data = config
|
|
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
return True
|
|
except (yaml.YAMLError, IOError, ValueError) as e:
|
|
print(f"Error: Failed to save config: {e}")
|
|
return False
|
|
|
|
def get_storage_info(self) -> Dict[str, str]:
|
|
"""Get information about the storage location."""
|
|
return {
|
|
'config_dir': str(self.config_dir),
|
|
'config_file': str(self.config_file),
|
|
'subscriptions_file': str(self.subscriptions_file),
|
|
'platform': platform.system(),
|
|
'exists': str(self.config_dir.exists())
|
|
} |