# -*- coding: utf-8 -*- """ 设置管理器:SQLite settings 表 + config.py 默认值合并 - get_setting(key, default) / set_setting(key, value) / all_settings() / save_all(dict) - 提供 LLM / 邮件 / 监控 三段配置的便捷读取 """ from database import query, execute, query_one from config import LLM_BASE_URL, LLM_API_KEY, LLM_MODEL, LLM_MAX_TOKENS, \ LLM_TEMPERATURE, LLM_TIMEOUT, MAIL_DEFAULTS, MONITOR_DEFAULTS, TRACKING_DEFAULTS def get_setting(key, default=""): r = query_one("SELECT value FROM settings WHERE key=?", (key,)) return r["value"] if r else default def set_setting(key, value): execute("INSERT OR REPLACE INTO settings(key, value) VALUES(?,?)", (key, str(value))) def all_settings(): rows = query("SELECT key, value FROM settings") return {r["key"]: r["value"] for r in rows} def save_all(pairs): """pairs: {key: value},仅保存存在的 key(白名单)""" for k, v in pairs.items(): set_setting(k, v) # ===================================================================== LLM def llm_config(): """运行时 LLM 配置(设置 > 默认)""" return { "base_url": get_setting("llm_base_url", LLM_BASE_URL).rstrip("/"), "api_key": get_setting("llm_api_key", LLM_API_KEY), "model": get_setting("llm_model", LLM_MODEL), "max_tokens": int(get_setting("llm_max_tokens", LLM_MAX_TOKENS)), "temperature": float(get_setting("llm_temperature", LLM_TEMPERATURE)), "timeout": int(get_setting("llm_timeout", LLM_TIMEOUT)), } # ===================================================================== 邮件 def mail_config(): return { "smtp_host": get_setting("smtp_host", MAIL_DEFAULTS["smtp_host"]), "smtp_port": int(get_setting("smtp_port", MAIL_DEFAULTS["smtp_port"])), "smtp_user": get_setting("smtp_user", MAIL_DEFAULTS["smtp_user"]), "smtp_pass": get_setting("smtp_pass", MAIL_DEFAULTS["smtp_pass"]), "smtp_mode": get_setting("smtp_mode", MAIL_DEFAULTS["smtp_mode"]), "email_to": get_setting("email_to", MAIL_DEFAULTS["email_to"]), "sender_name": get_setting("sender_name", MAIL_DEFAULTS["sender_name"]), "email_enabled": get_setting("email_enabled", "1") == "1", } # ===================================================================== 监控 def monitor_config(): cats = get_setting("monitor_categories", "").strip() # 关键词去重保序 kws = get_setting("monitor_keywords", MONITOR_DEFAULTS["monitor_keywords"]) kw_list = [] for k in kws.split(","): k = k.strip() if k and k not in kw_list: kw_list.append(k) return { "enabled": get_setting("monitor_enabled", "1") == "1", "interval_min": max(5, int(get_setting("monitor_interval", MONITOR_DEFAULTS["monitor_interval"]))), "categories": [c for c in cats.split(",") if c] if cats else [], "sentiment_weight": float(get_setting("monitor_sentiment", MONITOR_DEFAULTS["monitor_sentiment"])), "importance_threshold": float(get_setting("monitor_importance", MONITOR_DEFAULTS["monitor_importance"])), "keywords": kw_list, } def monitor_state(): """监控运行状态(最近处理 id / 上次扫描时间)""" return { "last_news_id": int(get_setting("monitor_last_news_id", "0")), "last_scan": get_setting("monitor_last_scan", ""), "last_sent_count": int(get_setting("monitor_last_sent", "0")), } def set_monitor_state(last_news_id=None, last_scan=None, last_sent=None): if last_news_id is not None: set_setting("monitor_last_news_id", last_news_id) if last_scan is not None: set_setting("monitor_last_scan", last_scan) if last_sent is not None: set_setting("monitor_last_sent", last_sent) # ===================================================================== 持仓跟踪 def tracking_config(): return { "enabled": get_setting("tracking_enabled", TRACKING_DEFAULTS["tracking_enabled"]) == "1", "interval_min": max(15, int(get_setting("tracking_interval", TRACKING_DEFAULTS["tracking_interval"]))), "notify": get_setting("tracking_notify", TRACKING_DEFAULTS["tracking_notify"]) == "1", "impact_threshold": float(get_setting("tracking_impact_threshold", TRACKING_DEFAULTS["tracking_impact_threshold"])), } def tracking_state(): return { "last_run": get_setting("tracking_last_run", ""), "last_stock": get_setting("tracking_last_stock", ""), "last_alert": int(get_setting("tracking_last_alert", "0")), } def set_tracking_state(last_run=None, last_stock=None, last_alert=None): if last_run is not None: set_setting("tracking_last_run", last_run) if last_stock is not None: set_setting("tracking_last_stock", last_stock) if last_alert is not None: set_setting("tracking_last_alert", last_alert)