mirror of
https://github.com/cnlimiter/codex-register.git
synced 2026-06-27 18:22:03 +08:00
4
This commit is contained in:
@@ -7,7 +7,7 @@ from datetime import datetime, timedelta
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import and_, or_, desc, asc, func
|
||||
|
||||
from .models import Account, EmailService, RegistrationTask, Setting
|
||||
from .models import Account, EmailService, RegistrationTask, Setting, Proxy
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -18,6 +18,9 @@ def create_account(
|
||||
db: Session,
|
||||
email: str,
|
||||
email_service: str,
|
||||
password: Optional[str] = None,
|
||||
client_id: Optional[str] = None,
|
||||
session_token: Optional[str] = None,
|
||||
email_service_id: Optional[str] = None,
|
||||
account_id: Optional[str] = None,
|
||||
workspace_id: Optional[str] = None,
|
||||
@@ -25,11 +28,15 @@ def create_account(
|
||||
refresh_token: Optional[str] = None,
|
||||
id_token: Optional[str] = None,
|
||||
proxy_used: Optional[str] = None,
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
expires_at: Optional['datetime'] = None,
|
||||
extra_data: Optional[Dict[str, Any]] = None
|
||||
) -> Account:
|
||||
"""创建新账户"""
|
||||
db_account = Account(
|
||||
email=email,
|
||||
password=password,
|
||||
client_id=client_id,
|
||||
session_token=session_token,
|
||||
email_service=email_service,
|
||||
email_service_id=email_service_id,
|
||||
account_id=account_id,
|
||||
@@ -38,7 +45,8 @@ def create_account(
|
||||
refresh_token=refresh_token,
|
||||
id_token=id_token,
|
||||
proxy_used=proxy_used,
|
||||
metadata=metadata or {},
|
||||
expires_at=expires_at,
|
||||
extra_data=extra_data or {},
|
||||
registered_at=datetime.utcnow()
|
||||
)
|
||||
db.add(db_account)
|
||||
@@ -369,4 +377,120 @@ def delete_setting(db: Session, key: str) -> bool:
|
||||
|
||||
db.delete(db_setting)
|
||||
db.commit()
|
||||
return True
|
||||
return True
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 代理 CRUD
|
||||
# ============================================================================
|
||||
|
||||
def create_proxy(
|
||||
db: Session,
|
||||
name: str,
|
||||
type: str,
|
||||
host: str,
|
||||
port: int,
|
||||
username: Optional[str] = None,
|
||||
password: Optional[str] = None,
|
||||
enabled: bool = True,
|
||||
priority: int = 0
|
||||
) -> Proxy:
|
||||
"""创建代理配置"""
|
||||
db_proxy = Proxy(
|
||||
name=name,
|
||||
type=type,
|
||||
host=host,
|
||||
port=port,
|
||||
username=username,
|
||||
password=password,
|
||||
enabled=enabled,
|
||||
priority=priority
|
||||
)
|
||||
db.add(db_proxy)
|
||||
db.commit()
|
||||
db.refresh(db_proxy)
|
||||
return db_proxy
|
||||
|
||||
|
||||
def get_proxy_by_id(db: Session, proxy_id: int) -> Optional[Proxy]:
|
||||
"""根据 ID 获取代理"""
|
||||
return db.query(Proxy).filter(Proxy.id == proxy_id).first()
|
||||
|
||||
|
||||
def get_proxies(
|
||||
db: Session,
|
||||
enabled: Optional[bool] = None,
|
||||
skip: int = 0,
|
||||
limit: int = 100
|
||||
) -> List[Proxy]:
|
||||
"""获取代理列表"""
|
||||
query = db.query(Proxy)
|
||||
|
||||
if enabled is not None:
|
||||
query = query.filter(Proxy.enabled == enabled)
|
||||
|
||||
query = query.order_by(desc(Proxy.created_at)).offset(skip).limit(limit)
|
||||
return query.all()
|
||||
|
||||
|
||||
def get_enabled_proxies(db: Session) -> List[Proxy]:
|
||||
"""获取所有启用的代理"""
|
||||
return db.query(Proxy).filter(Proxy.enabled == True).all()
|
||||
|
||||
|
||||
def update_proxy(
|
||||
db: Session,
|
||||
proxy_id: int,
|
||||
**kwargs
|
||||
) -> Optional[Proxy]:
|
||||
"""更新代理配置"""
|
||||
db_proxy = get_proxy_by_id(db, proxy_id)
|
||||
if not db_proxy:
|
||||
return None
|
||||
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(db_proxy, key):
|
||||
setattr(db_proxy, key, value)
|
||||
|
||||
db.commit()
|
||||
db.refresh(db_proxy)
|
||||
return db_proxy
|
||||
|
||||
|
||||
def delete_proxy(db: Session, proxy_id: int) -> bool:
|
||||
"""删除代理配置"""
|
||||
db_proxy = get_proxy_by_id(db, proxy_id)
|
||||
if not db_proxy:
|
||||
return False
|
||||
|
||||
db.delete(db_proxy)
|
||||
db.commit()
|
||||
return True
|
||||
|
||||
|
||||
def update_proxy_last_used(db: Session, proxy_id: int) -> bool:
|
||||
"""更新代理最后使用时间"""
|
||||
db_proxy = get_proxy_by_id(db, proxy_id)
|
||||
if not db_proxy:
|
||||
return False
|
||||
|
||||
db_proxy.last_used = datetime.utcnow()
|
||||
db.commit()
|
||||
return True
|
||||
|
||||
|
||||
def get_random_proxy(db: Session) -> Optional[Proxy]:
|
||||
"""随机获取一个启用的代理"""
|
||||
import random
|
||||
proxies = get_enabled_proxies(db)
|
||||
if not proxies:
|
||||
return None
|
||||
return random.choice(proxies)
|
||||
|
||||
|
||||
def get_proxies_count(db: Session, enabled: Optional[bool] = None) -> int:
|
||||
"""获取代理数量"""
|
||||
query = db.query(func.count(Proxy.id))
|
||||
if enabled is not None:
|
||||
query = query.filter(Proxy.enabled == enabled)
|
||||
return query.scalar()
|
||||
@@ -34,18 +34,20 @@ class Account(Base):
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
email = Column(String(255), nullable=False, unique=True, index=True)
|
||||
password_hash = Column(String(255))
|
||||
password = Column(String(255)) # 注册密码(明文存储)
|
||||
access_token = Column(Text)
|
||||
refresh_token = Column(Text)
|
||||
id_token = Column(Text)
|
||||
session_token = Column(Text) # 会话令牌(优先刷新方式)
|
||||
client_id = Column(String(255)) # OAuth Client ID
|
||||
account_id = Column(String(255))
|
||||
workspace_id = Column(String(255))
|
||||
email_service = Column(String(50), nullable=False) # 'tempmail', 'outlook', 'custom_domain'
|
||||
email_service_id = Column(String(255)) # 邮箱服务中的ID
|
||||
proxy_used = Column(String(255))
|
||||
registered_at = Column(DateTime, default=datetime.utcnow)
|
||||
last_refresh = Column(DateTime)
|
||||
expires_at = Column(DateTime)
|
||||
last_refresh = Column(DateTime) # 最后刷新时间
|
||||
expires_at = Column(DateTime) # Token 过期时间
|
||||
status = Column(String(20), default='active') # 'active', 'expired', 'banned', 'failed'
|
||||
extra_data = Column(JSONEncodedDict) # 额外信息存储
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
@@ -56,10 +58,14 @@ class Account(Base):
|
||||
return {
|
||||
'id': self.id,
|
||||
'email': self.email,
|
||||
'password': self.password,
|
||||
'client_id': self.client_id,
|
||||
'email_service': self.email_service,
|
||||
'account_id': self.account_id,
|
||||
'workspace_id': self.workspace_id,
|
||||
'registered_at': self.registered_at.isoformat() if self.registered_at else None,
|
||||
'last_refresh': self.last_refresh.isoformat() if self.last_refresh else None,
|
||||
'expires_at': self.expires_at.isoformat() if self.expires_at else None,
|
||||
'status': self.status,
|
||||
'proxy_used': self.proxy_used,
|
||||
'created_at': self.created_at.isoformat() if self.created_at else None,
|
||||
@@ -110,4 +116,59 @@ class Setting(Base):
|
||||
value = Column(Text)
|
||||
description = Column(Text)
|
||||
category = Column(String(50), default='general') # 'general', 'email', 'proxy', 'openai'
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Proxy(Base):
|
||||
"""代理列表表"""
|
||||
__tablename__ = 'proxies'
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(100), nullable=False) # 代理名称
|
||||
type = Column(String(20), nullable=False, default='http') # http, socks5
|
||||
host = Column(String(255), nullable=False)
|
||||
port = Column(Integer, nullable=False)
|
||||
username = Column(String(100))
|
||||
password = Column(String(255))
|
||||
enabled = Column(Boolean, default=True)
|
||||
priority = Column(Integer, default=0) # 优先级(保留字段)
|
||||
last_used = Column(DateTime) # 最后使用时间
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
def to_dict(self, include_password: bool = False) -> Dict[str, Any]:
|
||||
"""转换为字典"""
|
||||
result = {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'type': self.type,
|
||||
'host': self.host,
|
||||
'port': self.port,
|
||||
'username': self.username,
|
||||
'enabled': self.enabled,
|
||||
'priority': self.priority,
|
||||
'last_used': self.last_used.isoformat() if self.last_used else None,
|
||||
'created_at': self.created_at.isoformat() if self.created_at else None,
|
||||
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
if include_password:
|
||||
result['password'] = self.password
|
||||
else:
|
||||
result['has_password'] = bool(self.password)
|
||||
return result
|
||||
|
||||
@property
|
||||
def proxy_url(self) -> str:
|
||||
"""获取完整的代理 URL"""
|
||||
if self.type == "http":
|
||||
scheme = "http"
|
||||
elif self.type == "socks5":
|
||||
scheme = "socks5"
|
||||
else:
|
||||
scheme = self.type
|
||||
|
||||
auth = ""
|
||||
if self.username and self.password:
|
||||
auth = f"{self.username}:{self.password}@"
|
||||
|
||||
return f"{scheme}://{auth}{self.host}:{self.port}"
|
||||
Reference in New Issue
Block a user