43 lines
1.7 KiB
Python
43 lines
1.7 KiB
Python
from __future__ import annotations as _annotations
|
|
|
|
from dataclasses import asdict, dataclass
|
|
|
|
|
|
@dataclass
|
|
class Config:
|
|
bot_channel: str = 'breadtube-bot'
|
|
bot_role: str = 'BreadTube'
|
|
bot_channel_scan_interval: float = 30.
|
|
bot_channel_init_retries: int = 3
|
|
bot_message_duration: float = 150.
|
|
request_timeout: float = 3.
|
|
unmanaged_categories: str = ''
|
|
youtube_channel_refresh_interval: float = 3600
|
|
youtube_channel_video_count: int = 10
|
|
youtube_channel_video_message: str = '[{{video_title}}](https://www.youtube.com/video/{{video_id}})'
|
|
|
|
def to_str(self) -> str:
|
|
return '\n'.join(['config', *[f'{k}={v}' for k, v in asdict(self).items()]])
|
|
|
|
@staticmethod
|
|
def from_str(text: str) -> Config:
|
|
annotations = Config.__annotations__
|
|
global_types = globals()['__builtins__']
|
|
config = Config()
|
|
lines = text.strip().splitlines()
|
|
if not lines:
|
|
raise RuntimeError('Cannot load config: empty input')
|
|
if lines[0] != 'config':
|
|
raise RuntimeError('Cannot load config: first line is not "config"')
|
|
config_dict = {}
|
|
for line_number, line in enumerate(lines[1:], start=1):
|
|
key, value = line.split('=', maxsplit=1)
|
|
if key not in annotations:
|
|
raise RuntimeError(f'Invalid config: invalid key {key} at line {line_number}')
|
|
if key in config_dict:
|
|
raise RuntimeError(f'Invalid config: duplicated key {key} at line {line_number}')
|
|
config_dict[key] = value
|
|
|
|
for key, value in config_dict.items():
|
|
setattr(config, key, global_types[annotations[key]](value))
|
|
return config
|