准备创建mysqlv1分支的提交

This commit is contained in:
huangzhenpc
2025-04-01 15:43:27 +08:00
parent cc2a3a34e3
commit 7dad9f6b2f
13 changed files with 1248 additions and 149 deletions

327
init_database.py Normal file
View File

@@ -0,0 +1,327 @@
#!/usr/bin/env python3
"""
数据库初始化脚本
用于自动创建MySQL数据库、用户和表结构并配置Redis
"""
import os
import sys
import getpass
import asyncio
import yaml
import pymysql
import redis
from loguru import logger
# 默认配置
DEFAULT_CONFIG = {
"database": {
"host": "localhost",
"port": 3306,
"username": "auto_cursor_reg",
"password": "auto_cursor_pass",
"database": "auto_cursor_reg",
"pool_size": 10,
"use_redis": True
},
"redis": {
"host": "127.0.0.1",
"port": 6379,
"password": "",
"db": 0
}
}
# 数据库表结构
EMAIL_ACCOUNTS_TABLE = '''
CREATE TABLE IF NOT EXISTS email_accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
client_id VARCHAR(255) NOT NULL,
refresh_token TEXT NOT NULL,
in_use BOOLEAN DEFAULT 0,
cursor_password VARCHAR(255),
cursor_cookie TEXT,
cursor_token TEXT,
sold BOOLEAN DEFAULT 0,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_status_inuse_sold (status, in_use, sold)
)
'''
def setup_logger():
"""设置日志"""
logger.remove()
logger.add(sys.stderr, level="INFO")
logger.add("init_database.log", rotation="1 MB", level="DEBUG")
def get_mysql_root_credentials():
"""获取MySQL root用户凭据"""
print("\n===== MySQL配置 =====")
print("请输入MySQL root用户凭据以创建数据库和用户")
mysql_host = input("MySQL 主机地址 [localhost]: ") or "localhost"
mysql_port = input("MySQL 端口 [3306]: ") or "3306"
try:
mysql_port = int(mysql_port)
except ValueError:
mysql_port = 3306
print("端口无效,使用默认端口 3306")
mysql_root = input("MySQL root用户名 [root]: ") or "root"
mysql_root_password = getpass.getpass("MySQL root密码: ")
return {
"host": mysql_host,
"port": mysql_port,
"user": mysql_root,
"password": mysql_root_password
}
def get_app_database_config():
"""获取应用数据库配置"""
print("\n请设置应用程序的数据库配置:")
db_name = input("数据库名称 [auto_cursor_reg]: ") or "auto_cursor_reg"
db_user = input("数据库用户名 [auto_cursor_reg]: ") or "auto_cursor_reg"
db_pass = getpass.getpass(f"为用户 {db_user} 设置密码 [auto_cursor_pass]: ")
if not db_pass:
db_pass = "auto_cursor_pass"
return {
"database": db_name,
"username": db_user,
"password": db_pass
}
def get_redis_config():
"""获取Redis配置"""
use_redis = input("\n是否使用Redis缓存? (y/n) [y]: ").lower() != "n"
if not use_redis:
return {"use_redis": False}
print("\n===== Redis配置 =====")
redis_host = input("Redis 主机地址 [127.0.0.1]: ") or "127.0.0.1"
redis_port = input("Redis 端口 [6379]: ") or "6379"
try:
redis_port = int(redis_port)
except ValueError:
redis_port = 6379
print("端口无效,使用默认端口 6379")
redis_password = getpass.getpass("Redis 密码 (如无密码请直接回车): ")
redis_db = input("Redis 数据库索引 [0]: ") or "0"
try:
redis_db = int(redis_db)
except ValueError:
redis_db = 0
print("数据库索引无效,使用默认值 0")
return {
"use_redis": True,
"redis": {
"host": redis_host,
"port": redis_port,
"password": redis_password,
"db": redis_db
}
}
def test_mysql_connection(config):
"""测试MySQL连接"""
try:
conn = pymysql.connect(**config)
conn.close()
return True
except Exception as e:
logger.error(f"MySQL连接失败: {str(e)}")
return False
def test_redis_connection(config):
"""测试Redis连接"""
try:
r = redis.Redis(
host=config["host"],
port=config["port"],
password=config["password"] if config["password"] else None,
db=config["db"]
)
r.ping()
r.close()
return True
except Exception as e:
logger.error(f"Redis连接失败: {str(e)}")
return False
def setup_mysql(root_config, app_config):
"""设置MySQL数据库和用户"""
logger.info("开始设置MySQL数据库...")
try:
# 连接到MySQL
conn = pymysql.connect(**root_config)
cursor = conn.cursor()
db_name = app_config["database"]
db_user = app_config["username"]
db_pass = app_config["password"]
# 创建数据库
logger.info(f"创建数据库: {db_name}")
cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{db_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
# 创建用户并授权
logger.info(f"创建用户: {db_user}")
# 检查用户是否已存在
cursor.execute(f"SELECT User FROM mysql.user WHERE User = '{db_user}'")
user_exists = cursor.fetchone()
if user_exists:
logger.info(f"用户 {db_user} 已存在,更新密码")
cursor.execute(f"ALTER USER '{db_user}'@'localhost' IDENTIFIED BY '{db_pass}'")
cursor.execute(f"ALTER USER '{db_user}'@'%' IDENTIFIED BY '{db_pass}'")
else:
# 创建用户 (同时创建本地和远程连接权限)
try:
cursor.execute(f"CREATE USER '{db_user}'@'localhost' IDENTIFIED BY '{db_pass}'")
cursor.execute(f"CREATE USER '{db_user}'@'%' IDENTIFIED BY '{db_pass}'")
except pymysql.err.MySQLError as e:
logger.warning(f"创建用户时出现警告 (可能用户已存在): {str(e)}")
# 授权
cursor.execute(f"GRANT ALL PRIVILEGES ON `{db_name}`.* TO '{db_user}'@'localhost'")
cursor.execute(f"GRANT ALL PRIVILEGES ON `{db_name}`.* TO '{db_user}'@'%'")
cursor.execute("FLUSH PRIVILEGES")
# 切换到新创建的数据库
cursor.execute(f"USE `{db_name}`")
# 创建表
logger.info("创建数据表: email_accounts")
cursor.execute(EMAIL_ACCOUNTS_TABLE)
conn.commit()
cursor.close()
conn.close()
logger.success("MySQL数据库设置成功")
return True
except Exception as e:
logger.error(f"设置MySQL失败: {str(e)}")
return False
def update_config_file(db_config, redis_config=None):
"""更新配置文件"""
logger.info("更新配置文件...")
config_file = "config.yaml"
try:
# 读取现有配置
with open(config_file, "r", encoding="utf-8") as f:
config = yaml.safe_load(f)
# 更新数据库配置
config["database"].update({
"host": db_config.get("host", "localhost"),
"port": db_config.get("port", 3306),
"username": db_config["username"],
"password": db_config["password"],
"database": db_config["database"],
"use_redis": db_config.get("use_redis", False)
})
# 如果启用Redis更新Redis配置
if redis_config and db_config.get("use_redis"):
config["redis"] = redis_config
# 备份原配置文件
if os.path.exists(config_file):
os.rename(config_file, f"{config_file}.bak")
logger.info(f"已备份原配置文件为 {config_file}.bak")
# 写入新配置
with open(config_file, "w", encoding="utf-8") as f:
yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
logger.success(f"配置文件已更新: {config_file}")
return True
except Exception as e:
logger.error(f"更新配置文件失败: {str(e)}")
return False
def main():
"""主函数"""
setup_logger()
logger.info("开始初始化数据库")
# 获取MySQL root凭据
root_config = get_mysql_root_credentials()
# 测试MySQL连接
if not test_mysql_connection(root_config):
logger.error("无法连接到MySQL请检查凭据和服务状态")
return
# 获取应用数据库配置
db_config = get_app_database_config()
# 获取Redis配置
redis_info = get_redis_config()
db_config["use_redis"] = redis_info["use_redis"]
# 如果启用了Redis测试连接
if redis_info["use_redis"]:
redis_config = redis_info["redis"]
if not test_redis_connection(redis_config):
use_anyway = input("Redis连接测试失败是否继续? (y/n) [n]: ").lower() == "y"
if not use_anyway:
logger.warning("用户取消了初始化")
return
else:
redis_config = None
# 设置MySQL
if not setup_mysql(root_config, db_config):
return
# 合并配置
final_db_config = {
"host": root_config["host"],
"port": root_config["port"],
"username": db_config["username"],
"password": db_config["password"],
"database": db_config["database"],
"use_redis": db_config["use_redis"]
}
# 更新配置文件
update_config_file(final_db_config, redis_config)
logger.success("数据库初始化完成!")
print("\n===== 初始化完成 =====")
print("您现在可以运行以下命令导入邮箱账号:")
print(" python import_emails.py")
print("\n然后运行主程序开始注册:")
print(" python main.py")
if __name__ == "__main__":
main()