115 lines
3.9 KiB
Python
115 lines
3.9 KiB
Python
"""Модуль для работы с конфигурацией"""
|
||
|
||
import os
|
||
import yaml
|
||
from pathlib import Path
|
||
from typing import Dict, Any, List, Optional
|
||
|
||
|
||
class Config:
|
||
"""Класс для хранения и загрузки конфигурации"""
|
||
|
||
def __init__(self, config_path: str = "config/config.yaml"):
|
||
self.config_path = Path(config_path)
|
||
self.sources_path = Path("config/sources.yaml")
|
||
self.config: Dict[str, Any] = {}
|
||
self.sources: List[Dict[str, str]] = []
|
||
|
||
self._load_config()
|
||
self._load_sources()
|
||
|
||
def _load_config(self) -> None:
|
||
"""Загружает основной конфиг"""
|
||
if not self.config_path.exists():
|
||
raise FileNotFoundError(
|
||
f"Конфиг не найден: {self.config_path}\n"
|
||
f"Скопируйте config/config.example.yaml в config/config.yaml и настройте его"
|
||
)
|
||
|
||
with open(self.config_path, 'r', encoding='utf-8') as f:
|
||
self.config = yaml.safe_load(f)
|
||
|
||
# Проверяем обязательные поля
|
||
required_fields = ['homeserver', 'bot_user_id', 'access_token']
|
||
for field in required_fields:
|
||
if field not in self.config:
|
||
raise ValueError(f"В конфиге отсутствует обязательное поле: {field}")
|
||
|
||
def _load_sources(self) -> None:
|
||
"""Загружает список RSS источников"""
|
||
if not self.sources_path.exists():
|
||
raise FileNotFoundError(
|
||
f"Файл с источниками не найден: {self.sources_path}\n"
|
||
f"Скопируйте config/sources.example.yaml в config/sources.yaml и настройте его"
|
||
)
|
||
|
||
with open(self.sources_path, 'r', encoding='utf-8') as f:
|
||
data = yaml.safe_load(f)
|
||
self.sources = data.get('sources', [])
|
||
|
||
if not self.sources:
|
||
raise ValueError("Не найдено ни одного RSS источника в конфиге")
|
||
|
||
@property
|
||
def homeserver(self) -> str:
|
||
return self.config['homeserver']
|
||
|
||
@property
|
||
def bot_user_id(self) -> str:
|
||
return self.config['bot_user_id']
|
||
|
||
@property
|
||
def access_token(self) -> str:
|
||
return self.config['access_token']
|
||
|
||
@property
|
||
def check_interval(self) -> int:
|
||
return self.config.get('check_interval', 600)
|
||
|
||
@property
|
||
def delay_between_posts(self) -> int:
|
||
return self.config.get('delay_between_posts', 1)
|
||
|
||
@property
|
||
def history_file(self) -> str:
|
||
return self.config.get('history_file', 'data/sent_history.json')
|
||
|
||
@property
|
||
def history_days(self) -> int:
|
||
return self.config.get('history_days', 15)
|
||
|
||
@property
|
||
def max_history_size(self) -> int:
|
||
return self.config.get('max_history_size', 2000)
|
||
|
||
@property
|
||
def images_dir(self) -> str:
|
||
return self.config.get('images_dir', 'data/news_images')
|
||
|
||
@property
|
||
def cleanup_images_every(self) -> int:
|
||
return self.config.get('cleanup_images_every', 144)
|
||
|
||
@property
|
||
def compress_images(self) -> bool:
|
||
return self.config.get('compress_images', True)
|
||
|
||
@property
|
||
def max_image_size_mb(self) -> float:
|
||
return self.config.get('max_image_size_mb', 0.5)
|
||
|
||
@property
|
||
def max_image_width(self) -> int:
|
||
return self.config.get('max_image_width', 1200)
|
||
|
||
@property
|
||
def max_image_height(self) -> int:
|
||
return self.config.get('max_image_height', 1200)
|
||
|
||
@property
|
||
def log_level(self) -> str:
|
||
return self.config.get('log_level', 'INFO')
|
||
|
||
@property
|
||
def log_file(self) -> Optional[str]:
|
||
return self.config.get('log_file', None) |