246 lines
6.7 KiB
Python
246 lines
6.7 KiB
Python
import os
|
|
import json
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Dict, List, Optional, Any, Union
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 更新默认设置以包含浏览器配置文件
|
|
DEFAULT_SETTINGS = {
|
|
"api_key": "",
|
|
"message_interval": 5,
|
|
"auto_start": False,
|
|
"theme": "system",
|
|
"color_theme": "blue",
|
|
"profiles_dir": os.path.join(os.path.expanduser("~"), "DouYinBot_Browser_Cache"),
|
|
"browser_profiles": [],
|
|
}
|
|
|
|
|
|
class UserProfile(BaseModel):
|
|
"""Chrome用户配置文件模型."""
|
|
|
|
profile_id: str
|
|
profile_name: str
|
|
douyin_account: Optional[str] = None
|
|
profile_path: Optional[str] = None
|
|
enabled: bool = True
|
|
auto_reply_enabled: bool = True
|
|
|
|
|
|
class ReplyTemplate(BaseModel):
|
|
"""回复模板模型."""
|
|
|
|
template_id: str
|
|
name: str
|
|
content: str
|
|
keywords: List[str] = Field(default_factory=list)
|
|
is_default: bool = False
|
|
|
|
|
|
class Settings(BaseModel):
|
|
"""应用程序设置模型."""
|
|
|
|
chrome_executable_path: Optional[str] = None
|
|
profiles: List[UserProfile] = Field(default_factory=list)
|
|
reply_templates: List[ReplyTemplate] = Field(default_factory=list)
|
|
check_interval_seconds: int = 60
|
|
headless: bool = False
|
|
auto_start_on_launch: bool = False
|
|
|
|
|
|
class BrowserProfile(BaseModel):
|
|
"""浏览器用户配置文件模型."""
|
|
|
|
profile_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
profile_name: str
|
|
profile_dir: str
|
|
enabled: bool = True
|
|
douyin_account: Optional[str] = None
|
|
auto_reply_enabled: bool = True
|
|
creation_time: str = Field(default_factory=lambda: datetime.now().isoformat())
|
|
last_used_time: Optional[str] = None
|
|
|
|
|
|
def get_config_dir() -> Path:
|
|
"""获取配置目录."""
|
|
config_dir = Path.home() / ".douyin-imbot"
|
|
config_dir.mkdir(exist_ok=True)
|
|
return config_dir
|
|
|
|
|
|
def get_config_path() -> Path:
|
|
"""获取配置文件路径."""
|
|
return get_config_dir() / "settings.json"
|
|
|
|
|
|
def load_settings() -> Settings:
|
|
"""加载应用程序设置."""
|
|
config_path = get_config_path()
|
|
|
|
if not config_path.exists():
|
|
# 创建默认设置
|
|
settings = Settings()
|
|
save_settings(settings)
|
|
return settings
|
|
|
|
try:
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
return Settings.model_validate(data)
|
|
except Exception as e:
|
|
print(f"加载设置时出错: {e}")
|
|
# 返回默认设置
|
|
return Settings()
|
|
|
|
|
|
def save_settings(settings: Settings) -> None:
|
|
"""保存应用程序设置."""
|
|
config_path = get_config_path()
|
|
|
|
try:
|
|
with open(config_path, "w", encoding="utf-8") as f:
|
|
json.dump(settings.model_dump(), f, ensure_ascii=False, indent=2)
|
|
except Exception as e:
|
|
print(f"保存设置时出错: {e}")
|
|
|
|
|
|
def find_chrome_installations() -> List[str]:
|
|
"""查找系统中的Chrome安装."""
|
|
possible_paths = []
|
|
|
|
# Windows上的常见Chrome安装路径
|
|
if os.name == "nt":
|
|
program_files = os.environ.get("PROGRAMFILES", "C:\\Program Files")
|
|
program_files_x86 = os.environ.get(
|
|
"PROGRAMFILES(X86)", "C:\\Program Files (x86)"
|
|
)
|
|
|
|
paths = [
|
|
Path(program_files) / "Google" / "Chrome" / "Application" / "chrome.exe",
|
|
Path(program_files_x86)
|
|
/ "Google"
|
|
/ "Chrome"
|
|
/ "Application"
|
|
/ "chrome.exe",
|
|
Path(os.environ.get("LOCALAPPDATA", ""))
|
|
/ "Google"
|
|
/ "Chrome"
|
|
/ "Application"
|
|
/ "chrome.exe",
|
|
]
|
|
|
|
for path in paths:
|
|
if path.exists():
|
|
possible_paths.append(str(path))
|
|
|
|
# macOS上的Chrome路径
|
|
elif sys.platform == "darwin":
|
|
paths = [
|
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
f"/Users/{os.getlogin()}/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
]
|
|
|
|
for path in paths:
|
|
if os.path.exists(path):
|
|
possible_paths.append(path)
|
|
|
|
# Linux上的Chrome路径
|
|
elif sys.platform.startswith("linux"):
|
|
paths = ["/usr/bin/google-chrome", "/usr/bin/google-chrome-stable"]
|
|
|
|
for path in paths:
|
|
if os.path.exists(path):
|
|
possible_paths.append(path)
|
|
|
|
return possible_paths
|
|
|
|
|
|
def find_chrome_user_data_dir() -> Optional[str]:
|
|
"""尝试找到Chrome用户数据目录."""
|
|
if os.name == "nt": # Windows
|
|
return os.path.join(
|
|
os.environ.get("LOCALAPPDATA", ""), "Google", "Chrome", "User Data"
|
|
)
|
|
elif sys.platform == "darwin": # macOS
|
|
return os.path.expanduser("~/Library/Application Support/Google/Chrome")
|
|
elif sys.platform.startswith("linux"): # Linux
|
|
return os.path.expanduser("~/.config/google-chrome")
|
|
|
|
return None
|
|
|
|
|
|
def load_settings():
|
|
"""
|
|
从配置文件加载设置,如果文件不存在则使用默认设置
|
|
|
|
Returns:
|
|
dict: 设置字典
|
|
"""
|
|
settings_path = get_settings_path()
|
|
|
|
try:
|
|
if os.path.exists(settings_path):
|
|
with open(settings_path, "r", encoding="utf-8") as f:
|
|
settings = json.load(f)
|
|
logger.info("已从文件加载设置")
|
|
|
|
# 确保所有默认设置键都存在
|
|
for key, value in DEFAULT_SETTINGS.items():
|
|
if key not in settings:
|
|
settings[key] = value
|
|
|
|
# 确保浏览器配置文件列表存在
|
|
if "browser_profiles" not in settings:
|
|
settings["browser_profiles"] = []
|
|
|
|
return settings
|
|
except Exception as e:
|
|
logger.error(f"加载设置时出错: {str(e)}")
|
|
|
|
logger.info("使用默认设置")
|
|
return DEFAULT_SETTINGS.copy()
|
|
|
|
|
|
def save_settings(settings):
|
|
"""
|
|
将设置保存到配置文件
|
|
|
|
Args:
|
|
settings (dict): 要保存的设置字典
|
|
|
|
Returns:
|
|
bool: 保存成功返回True,否则返回False
|
|
"""
|
|
settings_path = get_settings_path()
|
|
|
|
# 确保目录存在
|
|
os.makedirs(os.path.dirname(settings_path), exist_ok=True)
|
|
|
|
try:
|
|
with open(settings_path, "w", encoding="utf-8") as f:
|
|
json.dump(settings, f, ensure_ascii=False, indent=2)
|
|
logger.info("设置已保存到文件")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"保存设置时出错: {str(e)}")
|
|
return False
|
|
|
|
|
|
def get_settings_path():
|
|
"""
|
|
获取设置文件的路径
|
|
|
|
Returns:
|
|
str: 设置文件路径
|
|
"""
|
|
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
|
return os.path.join(base_dir, "config", "settings.json")
|