refactor: изменение классов OutboundSpec, OutboundFactory и Outbound для использования класса Target
This commit is contained in:
@@ -11,6 +11,7 @@ from urllib.parse import parse_qs, quote, unquote, urlencode, urlparse
|
|||||||
from .outbound_fields import OUTBOUND_FIELDS
|
from .outbound_fields import OUTBOUND_FIELDS
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from .target import Target, TargetStorage
|
||||||
from .xray_config import XrayConfig
|
from .xray_config import XrayConfig
|
||||||
from .xray_manager_config import XrayManagerConfig
|
from .xray_manager_config import XrayManagerConfig
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ if TYPE_CHECKING:
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class OutboundSpec:
|
class OutboundSpec:
|
||||||
protocol: str
|
protocol: str
|
||||||
target: str
|
target_id: str
|
||||||
|
|
||||||
|
|
||||||
O = TypeVar("O", bound="Outbound")
|
O = TypeVar("O", bound="Outbound")
|
||||||
@@ -50,22 +51,19 @@ class OutboundFactory:
|
|||||||
return list(cls._registry)
|
return list(cls._registry)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_link(
|
def from_link(cls, target_storage: TargetStorage, link: str) -> Outbound:
|
||||||
cls, xray_manager_config: XrayManagerConfig, link: str
|
|
||||||
) -> Outbound:
|
|
||||||
scheme = link.split("://", 1)[0]
|
scheme = link.split("://", 1)[0]
|
||||||
|
|
||||||
if scheme not in cls._scheme_registry:
|
if scheme not in cls._scheme_registry:
|
||||||
raise ValueError(f"Unsupported link scheme: {scheme}")
|
raise ValueError(f"Unsupported link scheme: {scheme}")
|
||||||
|
|
||||||
outbound_cls = cls._scheme_registry[scheme]
|
outbound_cls = cls._scheme_registry[scheme]
|
||||||
targets = xray_manager_config.targets
|
return outbound_cls.from_link(target_storage, link)
|
||||||
return outbound_cls.from_link(targets, link)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_inbound(
|
def from_inbound(
|
||||||
cls,
|
cls,
|
||||||
xray_manager_config: XrayManagerConfig,
|
target_storage: TargetStorage,
|
||||||
host: str,
|
host: str,
|
||||||
client: dict,
|
client: dict,
|
||||||
inbound: dict,
|
inbound: dict,
|
||||||
@@ -76,9 +74,8 @@ class OutboundFactory:
|
|||||||
raise ValueError(f"Unsupported protocol: {protocol}")
|
raise ValueError(f"Unsupported protocol: {protocol}")
|
||||||
|
|
||||||
outbound_cls = cls._registry[protocol]
|
outbound_cls = cls._registry[protocol]
|
||||||
targets = xray_manager_config.targets
|
|
||||||
username, outbound = outbound_cls.from_inbound(
|
username, outbound = outbound_cls.from_inbound(
|
||||||
targets, host, client, inbound
|
target_storage, host, client, inbound
|
||||||
)
|
)
|
||||||
return username, outbound
|
return username, outbound
|
||||||
|
|
||||||
@@ -86,26 +83,18 @@ class OutboundFactory:
|
|||||||
def from_spec(
|
def from_spec(
|
||||||
cls,
|
cls,
|
||||||
xray_config: XrayConfig,
|
xray_config: XrayConfig,
|
||||||
xray_manager_config: XrayManagerConfig,
|
target_storage: TargetStorage,
|
||||||
spec: OutboundSpec,
|
spec: OutboundSpec,
|
||||||
) -> Outbound:
|
) -> Outbound:
|
||||||
if spec.protocol not in cls._registry:
|
if spec.protocol not in cls._registry:
|
||||||
raise ValueError(f"Unsupported protocol: {spec.protocol}")
|
raise ValueError(f"Unsupported protocol: {spec.protocol}")
|
||||||
|
|
||||||
if spec.target not in xray_manager_config.get_targets_list():
|
target = target_storage.load_by_id(spec.target_id)
|
||||||
raise ValueError(f"Target {spec.target} not found")
|
|
||||||
|
|
||||||
inbound = xray_config.find_managed_inbound_by_protocol(spec.protocol)
|
inbound = xray_config.find_managed_inbound_by_protocol(spec.protocol)
|
||||||
outbound_cls = cls._registry[spec.protocol]
|
outbound_cls = cls._registry[spec.protocol]
|
||||||
|
|
||||||
targets = xray_manager_config.targets
|
return outbound_cls.from_scratch(target, xray_config.host, inbound)
|
||||||
target_pretty_name = targets.get(spec.target, {}).get(
|
|
||||||
"pretty_name", spec.target
|
|
||||||
)
|
|
||||||
|
|
||||||
return outbound_cls.from_scratch(
|
|
||||||
spec.target, target_pretty_name, xray_config.host, inbound
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Outbound(ABC):
|
class Outbound(ABC):
|
||||||
@@ -115,14 +104,14 @@ class Outbound(ABC):
|
|||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def from_link(
|
def from_link(
|
||||||
cls, targets: dict[str, dict[str, str]], link: str
|
cls, target_storage: TargetStorage, link: str
|
||||||
) -> Outbound: ...
|
) -> Outbound: ...
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def from_inbound(
|
def from_inbound(
|
||||||
cls,
|
cls,
|
||||||
targets: dict[str, dict[str, str]],
|
target_storage: TargetStorage,
|
||||||
host: str,
|
host: str,
|
||||||
client: dict,
|
client: dict,
|
||||||
inbound: dict,
|
inbound: dict,
|
||||||
@@ -131,7 +120,7 @@ class Outbound(ABC):
|
|||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def from_scratch(
|
def from_scratch(
|
||||||
cls, target: str, target_pretty_name: str, host: str, inbound: dict
|
cls, target: Target, host: str, inbound: dict
|
||||||
) -> Outbound: ...
|
) -> Outbound: ...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -184,7 +173,7 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_link(
|
def from_link(
|
||||||
cls, targets: dict[str, dict[str, str]], link: str
|
cls, target_storage: TargetStorage, link: str
|
||||||
) -> ShadowsocksOutbound:
|
) -> ShadowsocksOutbound:
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
@@ -198,15 +187,12 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
method, server_password, client_password = prefix_str.split(":")
|
method, server_password, client_password = prefix_str.split(":")
|
||||||
|
|
||||||
target_pretty_name = unquote(quoted_target_pretty_name)
|
target_pretty_name = unquote(quoted_target_pretty_name)
|
||||||
target = cls.find_target_by_pretty_name(targets, target_pretty_name)
|
target = target_storage.load_by_pretty(target_pretty_name)
|
||||||
if target is None:
|
|
||||||
target = "unknown"
|
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
target=target,
|
target=target,
|
||||||
target_pretty_name=target_pretty_name,
|
|
||||||
method=method,
|
method=method,
|
||||||
server_password=server_password,
|
server_password=server_password,
|
||||||
client_password=client_password,
|
client_password=client_password,
|
||||||
@@ -215,7 +201,7 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_inbound(
|
def from_inbound(
|
||||||
cls,
|
cls,
|
||||||
targets: dict[str, dict[str, str]],
|
target_storage: TargetStorage,
|
||||||
host: str,
|
host: str,
|
||||||
client: dict,
|
client: dict,
|
||||||
inbound: dict,
|
inbound: dict,
|
||||||
@@ -225,15 +211,15 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
server_password = inbound["settings"]["password"]
|
server_password = inbound["settings"]["password"]
|
||||||
client_password = client["password"]
|
client_password = client["password"]
|
||||||
email = client["email"]
|
email = client["email"]
|
||||||
username, target = cls.split_client_email(email)
|
|
||||||
|
|
||||||
target_pretty_name = targets.get(target, {}).get("pretty_name", target)
|
username, target_id = cls.split_client_email(email)
|
||||||
|
|
||||||
|
target = target_storage.load_by_id(target_id)
|
||||||
|
|
||||||
outbound = cls(
|
outbound = cls(
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
target=target,
|
target=target,
|
||||||
target_pretty_name=target_pretty_name,
|
|
||||||
method=method,
|
method=method,
|
||||||
server_password=server_password,
|
server_password=server_password,
|
||||||
client_password=client_password,
|
client_password=client_password,
|
||||||
@@ -242,7 +228,7 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_scratch(
|
def from_scratch(
|
||||||
cls, target: str, target_pretty_name: str, host: str, inbound: dict
|
cls, target: Target, host: str, inbound: dict
|
||||||
) -> ShadowsocksOutbound:
|
) -> ShadowsocksOutbound:
|
||||||
port = inbound["port"]
|
port = inbound["port"]
|
||||||
method = inbound["settings"]["method"]
|
method = inbound["settings"]["method"]
|
||||||
@@ -253,7 +239,6 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
target=target,
|
target=target,
|
||||||
target_pretty_name=target_pretty_name,
|
|
||||||
method=method,
|
method=method,
|
||||||
server_password=server_password,
|
server_password=server_password,
|
||||||
client_password=client_password,
|
client_password=client_password,
|
||||||
@@ -264,7 +249,7 @@ class ShadowsocksOutbound(_ShadowsocksFields, Outbound):
|
|||||||
|
|
||||||
prefix = f"{self.method}:{self.server_password}:{self.client_password}"
|
prefix = f"{self.method}:{self.server_password}:{self.client_password}"
|
||||||
prefix_b64 = base64.urlsafe_b64encode(prefix.encode()).decode()
|
prefix_b64 = base64.urlsafe_b64encode(prefix.encode()).decode()
|
||||||
tag = quote(self.target_pretty_name)
|
tag = quote(self.target.pretty)
|
||||||
link = f"ss://{prefix_b64}@{self.host}:{self.port}#{tag}"
|
link = f"ss://{prefix_b64}@{self.host}:{self.port}#{tag}"
|
||||||
return link
|
return link
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user