This commit is contained in:
Dmitry Belyaev 2024-02-22 18:24:36 +03:00
parent ca89a74c4b
commit 44be3416c0
Signed by: b4tman
GPG Key ID: 41A00BF15EA7E5F3
18 changed files with 102 additions and 11 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ __pycache__
*.pyo
*.pyc
.env*
site/
docs/api/
docs/src/

1
docs/index.md Normal file
View File

@ -0,0 +1 @@
--8<-- "README.md"

17
mkapi_conf.py Normal file
View File

@ -0,0 +1,17 @@
"""Config functions."""
from __future__ import annotations
import sys
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from mkdocs.config.defaults import MkDocsConfig
from mkapi.plugins import MkAPIPlugin
def before_on_config(config: MkDocsConfig, plugin: MkAPIPlugin) -> None: # noqa: ARG001
"""Called before `on_config` event of MkAPI plugin."""
if "." not in sys.path:
sys.path.insert(0, ".")

14
mkdocs.yml Normal file
View File

@ -0,0 +1,14 @@
site_name: pddnsc
theme: material
markdown_extensions:
- pymdownx.snippets
plugins:
- search
- mkapi:
config: mkapi_conf.py
nav:
- Home: index.md
- Reference: $api/pddnsc.***

View File

@ -0,0 +1 @@
""" Возможно клиент DDNS """

View File

@ -5,12 +5,16 @@ from netaddr import valid_ipv4, valid_ipv6
class IPAddreses(NamedTuple):
"""набор из названия источника и IP адресов, результат одного из источников"""
source_name: str
ipv4: str
ipv6: str
class BaseSourceProvider(ABC):
"""базовый класс для провайдеров источников"""
_childs = {}
registred = {}
@ -23,7 +27,9 @@ class BaseSourceProvider(ABC):
)
self.post_init()
def post_init(self): ...
def post_init(self):
"""метод для переопределения пост инициализации"""
...
def __str__(self):
return f"{self.__class__.__name__}: {self.name}"
@ -58,13 +64,19 @@ class BaseSourceProvider(ABC):
cls.registred[name] = provider(name, config, ipv4t, ipv6t)
@abstractmethod
async def fetch_v4(self) -> str: ...
async def fetch_v4(self) -> str:
"""необходимый метод для реализации получения ipv4"""
...
@abstractmethod
async def fetch_v6(self) -> str: ...
async def fetch_v6(self) -> str:
"""необходимый метод для реализации получения ipv6"""
...
class BaseOutputProvider(ABC):
"""базовый класс для провайдеров вывода"""
_childs = {}
registred = {}
@ -73,7 +85,9 @@ class BaseOutputProvider(ABC):
self.ipv4t, self.ipv6t = ipv4t, ipv6t
self.post_init()
def post_init(self): ...
def post_init(self):
"""метод для переопределения пост инициализации"""
...
def __init_subclass__(cls) -> None:
BaseOutputProvider._childs[cls.__name__] = cls
@ -107,10 +121,14 @@ class BaseOutputProvider(ABC):
return await self.set_addrs_imp(source_provider, addr_v4, addr_v6)
@abstractmethod
async def set_addrs_imp(self, source_provider, addr_v4, addr_v6): ...
async def set_addrs_imp(self, source_provider, addr_v4, addr_v6):
"""необходимый метод для реализации отправки/вывода IP аддресов"""
...
class BaseFilterProvider(ABC):
"""базовый класс для провайдеров фильтров"""
_childs = {}
registred = {}
@ -119,7 +137,9 @@ class BaseFilterProvider(ABC):
self.ipv4t, self.ipv6t = ipv4t, ipv6t
self.post_init()
def post_init(self): ...
def post_init(self):
"""метод для переопределения пост инициализации"""
...
def __init_subclass__(cls) -> None:
BaseFilterProvider._childs[cls.__name__] = cls
@ -153,12 +173,16 @@ class BaseFilterProvider(ABC):
return await self.check_imp(source_provider, addr_v4, addr_v6)
@abstractmethod
async def check_imp(self, source_provider, addr_v4, addr_v6): ...
async def check_imp(self, source_provider, addr_v4, addr_v6):
"""необходимый метод реализации проверки"""
...
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

View File

@ -1,3 +1,5 @@
""" модуль запуска """
import httpx
import asyncio
import toml

View File

@ -1,3 +1,5 @@
""" Фильтры для проверки адресов перед отправкой """
from pddnsc.loaders import load_plugins
load_plugins(__file__)

View File

@ -1,3 +1,5 @@
""" функции загрузки файлов плагинов """
import os
import traceback
from importlib import util

View File

@ -1,3 +1,5 @@
""" Модули вывода """
from pddnsc.loaders import load_plugins
load_plugins(__file__)

View File

@ -1,3 +1,5 @@
""" модуль взаимодействия и регистрации плагинов """
from .base import BaseSourceProvider, BaseFilterProvider, BaseOutputProvider
from . import sources
from . import outputs

View File

@ -1,3 +1,5 @@
""" Модули источников IP адресов """
from pddnsc.loaders import load_plugins
load_plugins(__file__)

View File

@ -1,9 +1,13 @@
""" модуль имитации получения IP аддресов """
import asyncio
from pddnsc.base import BaseSourceProvider
class DummySource(BaseSourceProvider):
"""имитация получения пустых адресов"""
async def fetch_v4(self) -> str:
result = await asyncio.sleep(self.config.get("delay", 1), result=None)
return result
@ -14,6 +18,8 @@ class DummySource(BaseSourceProvider):
class FakeSource(BaseSourceProvider):
"""имитация получения заданных в конфигурации адресов"""
async def fetch_v4(self) -> str:
result = await asyncio.sleep(
self.config.get("delay", 1), result=self.config.get("ipv4", "127.0.0.1")

View File

@ -4,6 +4,8 @@ from pddnsc.base import BaseSourceProvider, filter_ipv4, filter_ipv6
class GenericHttpSource(BaseSourceProvider):
"""базовый провайдер получения IP адресов по http/https ссылкам в виде текста"""
def post_init(self):
self.url_v4 = self.config.get("url_v4")
self.url_v6 = self.config.get("url_v6")
@ -37,6 +39,8 @@ class GenericHttpSource(BaseSourceProvider):
class GenericHttpJsonSource(BaseSourceProvider):
"""базовый провайдер получения IP адресов по http/https ссылкам в виде json"""
def post_init(self):
self.url_v4 = self.config.get("url_v4")
self.url_v6 = self.config.get("url_v6")

View File

@ -1,8 +1,9 @@
from pddnsc.sources.http import GenericHttpSource
# https://www.ipify.org/
class IPIFYSource(GenericHttpSource):
"""https://www.ipify.org/"""
def post_init(self):
super().post_init()
self.url_v4 = "https://api4.ipify.org"

View File

@ -1,8 +1,9 @@
from pddnsc.sources.http import GenericHttpSource
# https://ip.sb/api
class IPSB(GenericHttpSource):
"""https://ip.sb/api"""
def post_init(self):
super().post_init()
self.url_v4 = "https://api-ipv4.ip.sb/ip"

View File

@ -1,9 +1,12 @@
from pddnsc.sources.http import GenericHttpSource
# https://wtfismyip.com/
# https://gitlab.com/wtfismyip/wtfismyip
class WTFIsMyIP(GenericHttpSource):
"""
https://wtfismyip.com/
https://gitlab.com/wtfismyip/wtfismyip
"""
def post_init(self):
super().post_init()
self.url_v4 = "https://text.ipv4.myip.wtf"

4
requirements.docs.txt Normal file
View File

@ -0,0 +1,4 @@
mkdocs>=1.5,<2
pymdown-extensions>=10.7,<11
mkapi>=2.1,<3
mkdocs-material>=9.5.10,<10