sources refactor
This commit is contained in:
parent
20ef74f32b
commit
3131f2d0a0
@ -6,7 +6,7 @@ from httpx import AsyncHTTPTransport
|
||||
|
||||
|
||||
class IPAddreses(NamedTuple):
|
||||
"""набор из названия источника и IP адресов, результат одного из источников"""
|
||||
"""Набор из названия источника и IP адресов, результат одного из источников"""
|
||||
|
||||
source_name: str
|
||||
ipv4: str
|
||||
@ -14,7 +14,7 @@ class IPAddreses(NamedTuple):
|
||||
|
||||
|
||||
class BaseSourceProvider(ABC):
|
||||
"""базовый класс для провайдеров источников"""
|
||||
"""Базовый класс для провайдеров источников"""
|
||||
|
||||
_childs = {}
|
||||
registred = {}
|
||||
@ -35,14 +35,22 @@ class BaseSourceProvider(ABC):
|
||||
self.post_init()
|
||||
|
||||
def post_init(self):
|
||||
"""метод для переопределения пост инициализации"""
|
||||
"""Метод для переопределения пост инициализации"""
|
||||
...
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.__class__.__name__}: {self.name}"
|
||||
|
||||
def filter_ipv4(self, value: str) -> str:
|
||||
"""Функция для проверки валидности IPv4 адреса, возвращает "" если адрес неправильный или пустой"""
|
||||
return value if value and valid_ipv4(value) else ""
|
||||
|
||||
def filter_ipv6(self, value: str) -> str:
|
||||
"""Функция для проверки валидности IPv6 адреса, возвращает "" если адрес неправильный или пустой"""
|
||||
return value if value and valid_ipv6(value) else ""
|
||||
|
||||
async def fetch_all(self) -> IPAddreses:
|
||||
"""метод для получения всех ip адресов сразу"""
|
||||
"""Метод для получения всех IP адресов сразу"""
|
||||
results = await asyncio.gather(
|
||||
self.fetch_v4(), self.fetch_v6(), return_exceptions=True
|
||||
)
|
||||
@ -51,13 +59,23 @@ class BaseSourceProvider(ABC):
|
||||
self.name, *("" if isinstance(i, Exception) else i for i in results)
|
||||
)
|
||||
|
||||
async def fetch_v4(self) -> str:
|
||||
"""Метод внешнего интерфейса для получения IPv4"""
|
||||
ipv4 = await self.fetch_v4_impl()
|
||||
return self.filter_ipv4(ipv4)
|
||||
|
||||
async def fetch_v6(self) -> str:
|
||||
"""Метод внешнего интерфейса для получения IPv6"""
|
||||
ipv6 = await self.fetch_v6_impl()
|
||||
return self.filter_ipv6(ipv6)
|
||||
|
||||
def __init_subclass__(cls) -> None:
|
||||
BaseSourceProvider._childs[cls.__name__] = cls
|
||||
return super().__init_subclass__()
|
||||
|
||||
@classmethod
|
||||
def validate_source_config(cls, name: str, config: dict):
|
||||
"""метод валидации конфигурации для провайдера"""
|
||||
"""Метод валидации конфигурации для провайдера"""
|
||||
if "provider" not in config:
|
||||
return False
|
||||
prov_name = config["provider"]
|
||||
@ -73,7 +91,7 @@ class BaseSourceProvider(ABC):
|
||||
ipv4t: AsyncHTTPTransport,
|
||||
ipv6t: AsyncHTTPTransport,
|
||||
):
|
||||
"""метод регистрации провайдера по конфигурации"""
|
||||
"""Метод регистрации провайдера по конфигурации"""
|
||||
|
||||
if not cls.validate_source_config(name, config):
|
||||
return
|
||||
@ -81,18 +99,18 @@ class BaseSourceProvider(ABC):
|
||||
cls.registred[name] = provider(name, config, ipv4t, ipv6t)
|
||||
|
||||
@abstractmethod
|
||||
async def fetch_v4(self) -> str:
|
||||
"""необходимый метод для реализации получения ipv4"""
|
||||
async def fetch_v4_impl(self) -> Optional[str]:
|
||||
"""Необходимый метод для реализации получения IPv4"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def fetch_v6(self) -> str:
|
||||
"""необходимый метод для реализации получения ipv6"""
|
||||
async def fetch_v6_impl(self) -> Optional[str]:
|
||||
"""Необходимый метод для реализации получения IPv6"""
|
||||
...
|
||||
|
||||
|
||||
class BaseOutputProvider(ABC):
|
||||
"""базовый класс для провайдеров вывода"""
|
||||
"""Базовый класс для провайдеров вывода"""
|
||||
|
||||
_childs = {}
|
||||
registred = {}
|
||||
@ -109,7 +127,7 @@ class BaseOutputProvider(ABC):
|
||||
self.post_init()
|
||||
|
||||
def post_init(self):
|
||||
"""метод для переопределения пост инициализации"""
|
||||
"""Метод для переопределения пост инициализации"""
|
||||
...
|
||||
|
||||
def __init_subclass__(cls) -> None:
|
||||
@ -120,14 +138,14 @@ class BaseOutputProvider(ABC):
|
||||
return f"{self.__class__.__name__}: {self.name}"
|
||||
|
||||
def best_transport(self, addr_v4: str, addr_v6: str) -> AsyncHTTPTransport:
|
||||
"""метод выбирает лучший транспорт для отправки адресов (либо ipv4 либо ipv6)"""
|
||||
"""Метод выбирает лучший транспорт для отправки адресов (либо ipv4 либо ipv6)"""
|
||||
if addr_v6:
|
||||
return self.ipv6t
|
||||
return self.ipv4t
|
||||
|
||||
@classmethod
|
||||
def validate_source_config(cls, name: str, config: dict):
|
||||
"""метод валидации конфигурации для провайдера"""
|
||||
"""Метод валидации конфигурации для провайдера"""
|
||||
|
||||
if "provider" not in config:
|
||||
return False
|
||||
@ -144,24 +162,24 @@ class BaseOutputProvider(ABC):
|
||||
ipv4t: AsyncHTTPTransport,
|
||||
ipv6t: AsyncHTTPTransport,
|
||||
):
|
||||
"""метод регистрации провайдера по конфигурации"""
|
||||
"""Метод регистрации провайдера по конфигурации"""
|
||||
if not cls.validate_source_config(name, config):
|
||||
return
|
||||
provider = cls._childs[config["provider"]]
|
||||
cls.registred[name] = provider(name, config, ipv4t, ipv6t)
|
||||
|
||||
async def set_addrs(self, source_provider: str, addr_v4: str, addr_v6: str):
|
||||
"""метод внешнего интерфейса для отправки адресов"""
|
||||
"""Метод внешнего интерфейса для отправки адресов"""
|
||||
return await self.set_addrs_imp(source_provider, addr_v4, addr_v6)
|
||||
|
||||
@abstractmethod
|
||||
async def set_addrs_imp(self, source_provider: str, addr_v4: str, addr_v6: str):
|
||||
"""необходимый метод для реализации отправки/вывода IP аддресов"""
|
||||
"""Необходимый метод для реализации отправки/вывода IP аддресов"""
|
||||
...
|
||||
|
||||
|
||||
class BaseFilterProvider(ABC):
|
||||
"""базовый класс для провайдеров фильтров"""
|
||||
"""Базовый класс для провайдеров фильтров"""
|
||||
|
||||
_childs = {}
|
||||
registred = {}
|
||||
@ -178,7 +196,7 @@ class BaseFilterProvider(ABC):
|
||||
self.post_init()
|
||||
|
||||
def post_init(self):
|
||||
"""метод для переопределения пост инициализации"""
|
||||
"""Метод для переопределения пост инициализации"""
|
||||
...
|
||||
|
||||
def __init_subclass__(cls) -> None:
|
||||
@ -190,7 +208,7 @@ class BaseFilterProvider(ABC):
|
||||
|
||||
@classmethod
|
||||
def validate_source_config(cls, name: str, config: dict) -> bool:
|
||||
"""метод валидации конфигурации для провайдера"""
|
||||
"""Метод валидации конфигурации для провайдера"""
|
||||
|
||||
if "provider" not in config:
|
||||
return False
|
||||
@ -207,7 +225,7 @@ class BaseFilterProvider(ABC):
|
||||
ipv4t: AsyncHTTPTransport,
|
||||
ipv6t: AsyncHTTPTransport,
|
||||
):
|
||||
"""метод регистрации провайдера по конфигурации"""
|
||||
"""Метод регистрации провайдера по конфигурации"""
|
||||
|
||||
if not cls.validate_source_config(name, config):
|
||||
return
|
||||
@ -215,20 +233,10 @@ class BaseFilterProvider(ABC):
|
||||
cls.registred[name] = provider(name, config, ipv4t, ipv6t)
|
||||
|
||||
async def check(self, source_provider: str, addr_v4: str, addr_v6: str) -> bool:
|
||||
"""метод внешнего интерфейса для проверки адресов"""
|
||||
"""Метод внешнего интерфейса для проверки адресов"""
|
||||
return await self.check_imp(source_provider, addr_v4, addr_v6)
|
||||
|
||||
@abstractmethod
|
||||
async def check_imp(self, source_provider: str, addr_v4: str, addr_v6: str) -> bool:
|
||||
"""необходимый метод реализации проверки"""
|
||||
"""Необходимый метод реализации проверки"""
|
||||
...
|
||||
|
||||
|
||||
def filter_ipv4(value: str) -> Optional[str]:
|
||||
"""функция для проверки валидности IPv4 адреса, возвращает None если адрес неправильный или пустой"""
|
||||
return value and valid_ipv4(value) and value or None
|
||||
|
||||
|
||||
def filter_ipv6(value: str) -> Optional[str]:
|
||||
"""функция для проверки валидности IPv6 адреса, возвращает None если адрес неправильный или пустой"""
|
||||
return value and valid_ipv6(value) and value or None
|
||||
|
@ -6,27 +6,33 @@ from pddnsc.base import BaseSourceProvider
|
||||
|
||||
|
||||
class DummySource(BaseSourceProvider):
|
||||
"""имитация получения пустых адресов"""
|
||||
"""Имитация получения пустых адресов"""
|
||||
|
||||
async def fetch_v4(self) -> str:
|
||||
async def fetch_v4_impl(self) -> str:
|
||||
result = await asyncio.sleep(self.config.get("delay", 1), result="")
|
||||
return result
|
||||
|
||||
async def fetch_v6(self) -> str:
|
||||
async def fetch_v6_impl(self) -> str:
|
||||
result = await asyncio.sleep(self.config.get("delay", 1), result="")
|
||||
return result
|
||||
|
||||
|
||||
class FakeSource(BaseSourceProvider):
|
||||
"""имитация получения заданных в конфигурации адресов"""
|
||||
"""Имитация получения заданных в конфигурации адресов
|
||||
|
||||
async def fetch_v4(self) -> str:
|
||||
Конфигурация:
|
||||
|
||||
- ipv4: строка IPv4, по умолчанию "127.0.0.1"
|
||||
- ipv6: строка IPv6, по умолчанию "::1"
|
||||
"""
|
||||
|
||||
async def fetch_v4_impl(self) -> str:
|
||||
result = await asyncio.sleep(
|
||||
self.config.get("delay", 1), result=self.config.get("ipv4", "127.0.0.1")
|
||||
)
|
||||
return result
|
||||
|
||||
async def fetch_v6(self) -> str:
|
||||
async def fetch_v6_impl(self) -> str:
|
||||
result = await asyncio.sleep(
|
||||
self.config.get("delay", 1), result=self.config.get("ipv6", "::1")
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
from typing import Optional
|
||||
import httpx
|
||||
|
||||
from pddnsc.base import BaseSourceProvider, filter_ipv4, filter_ipv6
|
||||
from pddnsc.base import BaseSourceProvider
|
||||
|
||||
|
||||
class GenericHttpSource(BaseSourceProvider):
|
||||
@ -18,7 +19,7 @@ class GenericHttpSource(BaseSourceProvider):
|
||||
self.url_v6 = self.config.get("url_v6")
|
||||
self.headers = self.config.get("headers", {})
|
||||
|
||||
async def fetch_v4(self) -> str:
|
||||
async def fetch_v4_impl(self) -> Optional[str]:
|
||||
if not self.url_v4:
|
||||
return None
|
||||
|
||||
@ -29,9 +30,9 @@ class GenericHttpSource(BaseSourceProvider):
|
||||
response = await client.get(self.url_v4)
|
||||
if response.is_success:
|
||||
result = response.text.strip()
|
||||
return filter_ipv4(result)
|
||||
return result
|
||||
|
||||
async def fetch_v6(self) -> str:
|
||||
async def fetch_v6_impl(self) -> Optional[str]:
|
||||
if not self.url_v6:
|
||||
return None
|
||||
|
||||
@ -42,7 +43,7 @@ class GenericHttpSource(BaseSourceProvider):
|
||||
response = await client.get(self.url_v6)
|
||||
if response.is_success:
|
||||
result = response.text.strip()
|
||||
return filter_ipv6(result)
|
||||
return result
|
||||
|
||||
|
||||
class GenericHttpJsonSource(BaseSourceProvider):
|
||||
@ -68,7 +69,7 @@ class GenericHttpJsonSource(BaseSourceProvider):
|
||||
headers = {}
|
||||
self.headers = headers.update(self.config.get("headers", {}))
|
||||
|
||||
async def fetch_v4(self) -> str:
|
||||
async def fetch_v4_impl(self) -> Optional[str]:
|
||||
if not self.url_v4 or self.key_v4 is None:
|
||||
return None
|
||||
|
||||
@ -79,9 +80,9 @@ class GenericHttpJsonSource(BaseSourceProvider):
|
||||
response = await client.get(self.url_v4)
|
||||
if response.is_success:
|
||||
result = response.json()[self.key_v4].strip()
|
||||
return filter_ipv4(result)
|
||||
return result
|
||||
|
||||
async def fetch_v6(self) -> str:
|
||||
async def fetch_v6_impl(self) -> Optional[str]:
|
||||
if not self.url_v6 or self.key_v6 is None:
|
||||
return None
|
||||
|
||||
@ -92,4 +93,4 @@ class GenericHttpJsonSource(BaseSourceProvider):
|
||||
response = await client.get(self.url_v6)
|
||||
if response.is_success:
|
||||
result = response.json()[self.key_v6].strip()
|
||||
return filter_ipv6(result)
|
||||
return result
|
||||
|
Loading…
Reference in New Issue
Block a user