-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
121 lines (94 loc) · 3.26 KB
/
config.py
File metadata and controls
121 lines (94 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""Config loader for config.yaml."""
from __future__ import annotations
from dataclasses import dataclass, field
from pathlib import Path
from typing import List, Optional
import yaml
@dataclass
class RepoConfig:
owner: str
name: str
display_name: str
short_name: str = "" # optional nickname for compact chart labels
enabled: bool = True
@property
def full_name(self) -> str:
return f"{self.owner}/{self.name}"
@property
def label(self) -> str:
"""Preferred label for compact spots (charts, badges)."""
return self.short_name or self.display_name
@dataclass
class CollectionConfig:
max_issues: int = 50
max_prs: int = 30
max_commits_per_branch: int = 20
max_releases: int = 10
@dataclass
class ScheduleConfig:
publish_time: str = "08:00"
timezone: str = "Asia/Shanghai"
@dataclass
class StorageConfig:
db_path: str = "./data/github-daily.db"
trending_dir: str = "./data/trending"
@dataclass
class AnalysisConfig:
claude_bin: str = "claude"
models: dict = field(default_factory=dict)
def model_for(self, role: str) -> str:
return self.models.get(role) or "claude-sonnet-4-6"
@dataclass
class Config:
repos: List[RepoConfig] = field(default_factory=list)
collection: CollectionConfig = field(default_factory=CollectionConfig)
schedule: ScheduleConfig = field(default_factory=ScheduleConfig)
storage: StorageConfig = field(default_factory=StorageConfig)
analysis: AnalysisConfig = field(default_factory=AnalysisConfig)
@property
def enabled_repos(self) -> List[RepoConfig]:
return [r for r in self.repos if r.enabled]
def load_config(config_path: Optional[str | Path] = None) -> Config:
path = Path(config_path) if config_path else Path(__file__).parent / "config.yaml"
if not path.exists():
raise FileNotFoundError(f"Config file not found: {path}")
raw = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
repos = [
RepoConfig(
owner=r["owner"],
name=r["name"],
display_name=r.get("display_name", f"{r['owner']}/{r['name']}"),
short_name=r.get("short_name", ""),
enabled=r.get("enabled", True),
)
for r in raw.get("repos", [])
]
col = raw.get("collection", {}) or {}
collection = CollectionConfig(
max_issues=col.get("max_issues", 50),
max_prs=col.get("max_prs", 30),
max_commits_per_branch=col.get("max_commits_per_branch", 20),
max_releases=col.get("max_releases", 10),
)
sched = raw.get("schedule", {}) or {}
schedule = ScheduleConfig(
publish_time=sched.get("publish_time", "08:00"),
timezone=sched.get("timezone", "Asia/Shanghai"),
)
stor = raw.get("storage", {}) or {}
storage = StorageConfig(
db_path=stor.get("db_path", "./data/github-daily.db"),
trending_dir=stor.get("trending_dir", "./data/trending"),
)
anal = raw.get("analysis", {}) or {}
analysis = AnalysisConfig(
claude_bin=anal.get("claude_bin", "claude"),
models=anal.get("models", {}) or {},
)
return Config(
repos=repos,
collection=collection,
schedule=schedule,
storage=storage,
analysis=analysis,
)