Spaces:
Sleeping
Sleeping
Upload 10 files
Browse files- core/config.py +6 -0
- core/storage.py +27 -0
core/config.py
CHANGED
|
@@ -52,6 +52,7 @@ class RetryConfig(BaseModel):
|
|
| 52 |
account_failure_threshold: int = Field(default=3, ge=1, le=10, description="账户失败阈值")
|
| 53 |
rate_limit_cooldown_seconds: int = Field(default=600, ge=60, le=3600, description="429冷却时间(秒)")
|
| 54 |
session_cache_ttl_seconds: int = Field(default=3600, ge=300, le=86400, description="会话缓存时间(秒)")
|
|
|
|
| 55 |
|
| 56 |
|
| 57 |
class PublicDisplayConfig(BaseModel):
|
|
@@ -282,6 +283,11 @@ class ConfigManager:
|
|
| 282 |
"""会话缓存时间(秒)"""
|
| 283 |
return self._config.retry.session_cache_ttl_seconds
|
| 284 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
# ==================== 全局配置管理器 ====================
|
| 287 |
|
|
|
|
| 52 |
account_failure_threshold: int = Field(default=3, ge=1, le=10, description="账户失败阈值")
|
| 53 |
rate_limit_cooldown_seconds: int = Field(default=600, ge=60, le=3600, description="429冷却时间(秒)")
|
| 54 |
session_cache_ttl_seconds: int = Field(default=3600, ge=300, le=86400, description="会话缓存时间(秒)")
|
| 55 |
+
auto_refresh_accounts_seconds: int = Field(default=60, ge=0, le=600, description="自动刷新账号间隔(秒,0禁用)")
|
| 56 |
|
| 57 |
|
| 58 |
class PublicDisplayConfig(BaseModel):
|
|
|
|
| 283 |
"""会话缓存时间(秒)"""
|
| 284 |
return self._config.retry.session_cache_ttl_seconds
|
| 285 |
|
| 286 |
+
@property
|
| 287 |
+
def auto_refresh_accounts_seconds(self) -> int:
|
| 288 |
+
"""自动刷新账号间隔(秒,0禁用)"""
|
| 289 |
+
return self._config.retry.auto_refresh_accounts_seconds
|
| 290 |
+
|
| 291 |
|
| 292 |
# ==================== 全局配置管理器 ====================
|
| 293 |
|
core/storage.py
CHANGED
|
@@ -159,6 +159,33 @@ async def load_accounts() -> Optional[list]:
|
|
| 159 |
return None
|
| 160 |
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
async def save_accounts(accounts: list) -> bool:
|
| 163 |
"""Save account configuration to database when enabled."""
|
| 164 |
if not is_database_enabled():
|
|
|
|
| 159 |
return None
|
| 160 |
|
| 161 |
|
| 162 |
+
async def get_accounts_updated_at() -> Optional[float]:
|
| 163 |
+
"""
|
| 164 |
+
Get the accounts updated_at timestamp (epoch seconds).
|
| 165 |
+
Return None if database is not enabled or failed.
|
| 166 |
+
"""
|
| 167 |
+
if not is_database_enabled():
|
| 168 |
+
return None
|
| 169 |
+
try:
|
| 170 |
+
pool = await _get_pool()
|
| 171 |
+
async with pool.acquire() as conn:
|
| 172 |
+
row = await conn.fetchrow(
|
| 173 |
+
"SELECT EXTRACT(EPOCH FROM updated_at) AS ts FROM kv_store WHERE key = $1",
|
| 174 |
+
"accounts",
|
| 175 |
+
)
|
| 176 |
+
if not row or row["ts"] is None:
|
| 177 |
+
return None
|
| 178 |
+
return float(row["ts"])
|
| 179 |
+
except Exception as e:
|
| 180 |
+
logger.error(f"[STORAGE] Database accounts updated_at failed: {e}")
|
| 181 |
+
return None
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
def get_accounts_updated_at_sync() -> Optional[float]:
|
| 185 |
+
"""Sync wrapper for get_accounts_updated_at."""
|
| 186 |
+
return _run_in_db_loop(get_accounts_updated_at())
|
| 187 |
+
|
| 188 |
+
|
| 189 |
async def save_accounts(accounts: list) -> bool:
|
| 190 |
"""Save account configuration to database when enabled."""
|
| 191 |
if not is_database_enabled():
|