gitscope
← marzneshin / v0.6.1 / app/models/proxy.py
https://dev.kronoz.win/r/marzneshin.git
app/models/proxy.py · Python
Blame Raw
  1from enum import Enum
  2
  3from pydantic import ConfigDict, BaseModel, Field, field_validator
  4
  5from app.models.node import Node
  6
  7
  8class ProxyTypes(str, Enum):
  9    # proxy_type = protocol
 10    VMess = "vmess"
 11    VLESS = "vless"
 12    Trojan = "trojan"
 13    Shadowsocks = "shadowsocks"
 14    Hysteria2 = "hysteria2"
 15
 16
 17class InboundHostSecurity(str, Enum):
 18    inbound_default = "inbound_default"
 19    none = "none"
 20    tls = "tls"
 21
 22
 23InboundHostALPN = Enum(
 24    "ProxyHostALPN",
 25    {
 26        "none": "none",
 27        "h2": "h2",
 28        "http/1.1": "http/1.1",
 29        "h2,http/1.1": "h2,http/1.1",
 30        "h3": "h3",
 31        "h3,h2": "h3,h2",
 32        "h3,h2,http/1.1": "h3,h2,http/1.1",
 33    },
 34)
 35
 36
 37InboundHostFingerprint = Enum(
 38    "ProxyHostFingerprint",
 39    {
 40        "none": "",
 41        "chrome": "chrome",
 42        "firefox": "firefox",
 43        "safari": "safari",
 44        "ios": "ios",
 45        "android": "android",
 46        "edge": "edge",
 47        "360": "360",
 48        "qq": "qq",
 49        "random": "random",
 50        "randomized": "randomized",
 51    },
 52)
 53
 54
 55class FormatVariables(dict):
 56    def __missing__(self, key):
 57        return key.join("{}")
 58
 59
 60class FragmentSettings(BaseModel):
 61    packets: str = Field(pattern=r"^(:?tlshello|[\d-]{1,32})$")
 62    length: str = Field(pattern=r"^[\d-]{1,32}$")
 63    interval: str = Field(pattern=r"^[\d-]{1,32}$")
 64
 65
 66class InboundHost(BaseModel):
 67    remark: str
 68    address: str
 69    port: int | None = Field(None)
 70    sni: str | None = Field(None)
 71    host: str | None = Field(None)
 72    path: str | None = Field(None)
 73    security: InboundHostSecurity = InboundHostSecurity.inbound_default
 74    alpn: InboundHostALPN = InboundHostALPN.none
 75    fingerprint: InboundHostFingerprint = InboundHostFingerprint.none
 76    allowinsecure: bool | None = None
 77    is_disabled: bool | None = None
 78    mux: bool = Field(False)
 79    fragment: FragmentSettings | None = Field(None)
 80    weight: int = 1
 81    model_config = ConfigDict(from_attributes=True)
 82
 83    @field_validator("remark", "address", "path")
 84    @classmethod
 85    def validate_fmt_variables(cls, v: str) -> str:
 86        if not v:
 87            return v
 88
 89        v.format_map(FormatVariables())
 90
 91        return v
 92
 93    @field_validator("alpn", mode="before")
 94    @classmethod
 95    def validate_alpn(cls, v):
 96        if not v:
 97            return InboundHostALPN.none
 98        return v
 99
100
101class InboundHostResponse(InboundHost):
102    id: int
103
104
105class Inbound(BaseModel):
106    id: int
107    tag: str
108    protocol: ProxyTypes
109    config: str
110    node: Node
111    service_ids: list[int]
112    model_config = ConfigDict(from_attributes=True)