4 changed files with 246 additions and 67 deletions
			
			
		@ -0,0 +1,64 @@
					 | 
				
			||||
"""Загрузка настроек приложения. Используется библиотека `configparser`.""" | 
				
			||||
import configparser | 
				
			||||
from os import path | 
				
			||||
 | 
				
			||||
 | 
				
			||||
class AppConfig: | 
				
			||||
    """Класс для хранения настроек сервиса. | 
				
			||||
    TODO: Дописать документацию! | 
				
			||||
    """ | 
				
			||||
 | 
				
			||||
    def __init__(self, path_to_conf_file: str, section: str = "Main"): | 
				
			||||
        """ | 
				
			||||
        Parameters | 
				
			||||
        ---------- | 
				
			||||
        path_to_conf_file: str | 
				
			||||
        Путь к файлу конфига. Можно указывать относительный. | 
				
			||||
 | 
				
			||||
        section: str | 
				
			||||
        Секция в конфиге, которую нужно считывать. По-умолчанию секция `[Main]`. | 
				
			||||
 | 
				
			||||
        Raises | 
				
			||||
        ------ | 
				
			||||
        KeyError | 
				
			||||
        Если в конфиге не найдено указанной секции. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
        """ | 
				
			||||
        cfg: configparser = configparser.ConfigParser() | 
				
			||||
 | 
				
			||||
        try: | 
				
			||||
            cfg.read(path.abspath(path_to_conf_file)) | 
				
			||||
        except FileNotFoundError: | 
				
			||||
            print(f"File {path.abspath(path_to_conf_file)} not found!") | 
				
			||||
 | 
				
			||||
        if section not in cfg.sections(): | 
				
			||||
            raise KeyError(f"Section {section} not found in config file!") | 
				
			||||
 | 
				
			||||
        conf = dict(cfg.items(section)) | 
				
			||||
 | 
				
			||||
        self.template: str = conf["template"] | 
				
			||||
        self.path_for_config: str = conf["path_for_config"] | 
				
			||||
        self.frequency_sec = int(conf["frequency_sec"]) | 
				
			||||
        self.central_host_url: str = conf["central_host_url"] | 
				
			||||
        self.requests_count: int = int(conf["requests_count"]) | 
				
			||||
        self.request_portion: int = int(conf["request_portion"]) | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def configs_path(self) -> str: | 
				
			||||
        """Возвращает абсолютный путь до папки с конфигами.""" | 
				
			||||
        _path = path.abspath(self.path_for_config) | 
				
			||||
        return _path | 
				
			||||
 | 
				
			||||
    def _create_path(self) -> None: | 
				
			||||
        pass | 
				
			||||
 | 
				
			||||
    def __repr__(self): | 
				
			||||
        return ( | 
				
			||||
            f"template = {self.template}\n" | 
				
			||||
            f"path_for_config = {self.path_for_config}\n" | 
				
			||||
            f"{self.frequency_sec}\n" | 
				
			||||
            f"{self.central_host_url}\n" | 
				
			||||
            f"{self.requests_count}\n" | 
				
			||||
            f"{self.request_portion}\n" | 
				
			||||
        ) | 
				
			||||
@ -0,0 +1,33 @@
					 | 
				
			||||
from dataclasses import dataclass | 
				
			||||
import asyncio | 
				
			||||
import os | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@dataclass | 
				
			||||
class ConfigObject: | 
				
			||||
    host: str | 
				
			||||
    conf_body: str | 
				
			||||
    path: str | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def existst(self) -> bool: | 
				
			||||
        """Возвращает True, если файл конфига уже существует.""" | 
				
			||||
        return path.isfile(path) | 
				
			||||
 | 
				
			||||
    async def write(self) -> bool: | 
				
			||||
        """Записывает конфиг файл.""" | 
				
			||||
        _config_file_name: str = path.join(path, f"{host}.conf") | 
				
			||||
 | 
				
			||||
        if not self.existst: | 
				
			||||
            pass | 
				
			||||
        return True | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def read_config_template_file(path_to_file: str) -> str: | 
				
			||||
    """Прочесть шаблон конфига для сервера из файла.""" | 
				
			||||
    template: str = "" | 
				
			||||
    _full_path = os.path.abspath(path_to_file) | 
				
			||||
    with open(_full_path, mode="r", encoding="utf8") as file: | 
				
			||||
        template = file.read() | 
				
			||||
 | 
				
			||||
    return template | 
				
			||||
@ -0,0 +1,47 @@
					 | 
				
			||||
"""Модлуль для конструирования и обработки запросов.""" | 
				
			||||
 | 
				
			||||
from app_config import AppConfig | 
				
			||||
from aiohttp import ClientResponse | 
				
			||||
import asyncio | 
				
			||||
import aiohttp | 
				
			||||
 | 
				
			||||
 | 
				
			||||
class RequestBulder: | 
				
			||||
    def __init__(self, cfg: AppConfig): | 
				
			||||
        self.cfg = cfg | 
				
			||||
 | 
				
			||||
        _conn = aiohttp.TCPConnector(limit=cfg.requests_count) | 
				
			||||
        self.session = aiohttp.ClientSession(connector=_conn) | 
				
			||||
 | 
				
			||||
    async def __check_resp(self, resp: ClientResponse) -> bool: | 
				
			||||
        if not resp.status == 200: | 
				
			||||
            return False | 
				
			||||
 | 
				
			||||
        response = await resp.json() | 
				
			||||
 | 
				
			||||
        if not response["done"]: | 
				
			||||
            return False | 
				
			||||
 | 
				
			||||
        return True | 
				
			||||
 | 
				
			||||
    async def send_request(self, url, json_body) -> dict | bool: | 
				
			||||
        """Выполняет запрос, при успехе возвращает json с ответом, при | 
				
			||||
        неудаче возвращает False.""" | 
				
			||||
        _url = f"{self.cfg.central_host_url}/{url}" | 
				
			||||
 | 
				
			||||
        raw_resp = await self.session.get(_url, json=json_body) | 
				
			||||
 | 
				
			||||
        if await self.__check_resp(raw_resp): | 
				
			||||
            json_resp = await raw_resp.json() | 
				
			||||
            json_resp.pop("done") | 
				
			||||
            return json_resp | 
				
			||||
 | 
				
			||||
        return False | 
				
			||||
 | 
				
			||||
    async def wait(self) -> None: | 
				
			||||
        """Ждет frequency_sec время.""" | 
				
			||||
        await asyncio.sleep(self.cfg.frequency_sec) | 
				
			||||
 | 
				
			||||
    # def __del__(self): | 
				
			||||
    #     if self.session is not None: | 
				
			||||
    #         self.session.close() | 
				
			||||
					Loading…
					
					
				
		Reference in new issue