150 lines
7.1 KiB
Python
150 lines
7.1 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
class TimestampMixin:
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime,
|
|
default=datetime.utcnow,
|
|
onupdate=datetime.utcnow,
|
|
nullable=False,
|
|
)
|
|
|
|
|
|
class AppSettingORM(Base, TimestampMixin):
|
|
__tablename__ = "app_settings"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
|
value: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
class SourceORM(Base, TimestampMixin):
|
|
__tablename__ = "sources"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
kind: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
url: Mapped[str] = mapped_column(Text, nullable=False)
|
|
display_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
headers_json: Mapped[str] = mapped_column(Text, default="{}", nullable=False)
|
|
include_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
exclude_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
prefix: Mapped[str] = mapped_column(String(255), default="", nullable=False)
|
|
suffix: Mapped[str] = mapped_column(String(255), default="", nullable=False)
|
|
cache_ttl_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
|
|
|
|
class ProfileORM(Base, TimestampMixin):
|
|
__tablename__ = "profiles"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
|
title: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
provider_interval: Mapped[int] = mapped_column(Integer, default=21600, nullable=False)
|
|
rule_interval: Mapped[int] = mapped_column(Integer, default=86400, nullable=False)
|
|
test_url: Mapped[str] = mapped_column(Text, nullable=False)
|
|
test_interval: Mapped[int] = mapped_column(Integer, default=300, nullable=False)
|
|
main_policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
source_policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
mixed_auto_policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
manual_policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
direct_policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
mode: Mapped[str] = mapped_column(String(50), default="rule", nullable=False)
|
|
allow_lan: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
ipv6: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
mixed_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
socks_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
log_level: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
|
|
source_links: Mapped[list["ProfileSourceORM"]] = relationship(
|
|
back_populates="profile",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
rule_links: Mapped[list["ProfileRuleModuleORM"]] = relationship(
|
|
back_populates="profile",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
groups: Mapped[list["PolicyGroupORM"]] = relationship(
|
|
back_populates="profile",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
|
|
|
|
class ProfileSourceORM(Base):
|
|
__tablename__ = "profile_sources"
|
|
__table_args__ = (UniqueConstraint("profile_id", "source_id", name="uq_profile_source"),)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
|
|
source_id: Mapped[int] = mapped_column(ForeignKey("sources.id"), nullable=False)
|
|
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
|
|
profile: Mapped[ProfileORM] = relationship(back_populates="source_links")
|
|
source: Mapped[SourceORM] = relationship()
|
|
|
|
|
|
class RuleModuleORM(Base, TimestampMixin):
|
|
__tablename__ = "rule_modules"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
|
file_path: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
behavior: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
format: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
policy: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
no_resolve: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
|
payload_json: Mapped[str] = mapped_column(Text, default="[]", nullable=False)
|
|
|
|
profile_links: Mapped[list["ProfileRuleModuleORM"]] = relationship(
|
|
back_populates="rule_module",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
|
|
|
|
class ProfileRuleModuleORM(Base):
|
|
__tablename__ = "profile_rule_modules"
|
|
__table_args__ = (UniqueConstraint("profile_id", "rule_module_id", name="uq_profile_rule_module"),)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
|
|
rule_module_id: Mapped[int] = mapped_column(ForeignKey("rule_modules.id"), nullable=False)
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
policy_override: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
payload_override_json: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
no_resolve_override: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
|
|
|
|
profile: Mapped[ProfileORM] = relationship(back_populates="rule_links")
|
|
rule_module: Mapped[RuleModuleORM] = relationship(back_populates="profile_links")
|
|
|
|
|
|
class PolicyGroupORM(Base, TimestampMixin):
|
|
__tablename__ = "policy_groups"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
|
|
group_kind: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
type: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
proxies_json: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
filter_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
tolerance: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
url: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
interval: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
|
|
profile: Mapped[ProfileORM] = relationship(back_populates="groups")
|