From 1f4473e5404ee893625062affcb93709e06b7caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D1=83=D0=BB=D1=8C=D0=B1=D0=B0?= <81091299+ulbwa@users.noreply.github.com> Date: Wed, 23 Mar 2022 18:19:13 +0500 Subject: [PATCH] 2022.03.23.1 pydantic models --- MockupEngineer/__init__.py | 4 +- MockupEngineer/templates/__init__.py | 146 ++++++++++++++------------- deploy.py | 15 +-- requirements.txt | 3 +- setup.py | 2 +- 5 files changed, 91 insertions(+), 79 deletions(-) diff --git a/MockupEngineer/__init__.py b/MockupEngineer/__init__.py index c99e5bf..d65b731 100644 --- a/MockupEngineer/__init__.py +++ b/MockupEngineer/__init__.py @@ -6,7 +6,7 @@ from typing import List, Optional from PIL import Image from MockupEngineer import templates -from MockupEngineer.templates import Device, ALL_TEMPLATES +from MockupEngineer.templates import Device, ALL_TEMPLATES, parse_config from MockupEngineer.utils import random_string, get_title from MockupEngineer.utils.about import author @@ -25,7 +25,7 @@ class MockupEngineerInstance: for template in ALL_TEMPLATES: try: - self.templates.append(Device(template)) + self.templates.append(parse_config(template)) except Exception as e: self.logger.warning('Failed to load "{}" module: {}'.format(template, e)) diff --git a/MockupEngineer/templates/__init__.py b/MockupEngineer/templates/__init__.py index f28c4d7..46f8e78 100644 --- a/MockupEngineer/templates/__init__.py +++ b/MockupEngineer/templates/__init__.py @@ -2,9 +2,9 @@ import hashlib import os from configparser import ConfigParser, NoOptionError, NoSectionError -from dataclasses import dataclass +from pydantic import BaseModel from pathlib import Path -from typing import Optional +from typing import Optional, List from MockupEngineer.utils.about import author, author_url @@ -21,14 +21,12 @@ ALL_TEMPLATES = sorted(__list_all_templates__()) __all__ = ALL_TEMPLATES + ["ALL_TEMPLATES"] -@dataclass(frozen=False) -class DeviceColor: +class DeviceColor(BaseModel): color: str path: str -@dataclass(frozen=False) -class DeviceImage: +class DeviceImage(BaseModel): width: int height: int x: int @@ -38,80 +36,92 @@ class DeviceImage: rotate: bool -@dataclass(frozen=False) -class About: +class About(BaseModel): author: str url: str -@dataclass(frozen=False) -class Device: - def __init__(self, path: str): - self.__path__ = path +class Device(BaseModel): + id: str + manufacturer: str + name: str + type: str + year: int + width: int + height: int + resolution: str + preview: str + colors: List[DeviceColor] + image: DeviceImage + about: About + __path__: str - config = ConfigParser() - config.read(os.path.join(templates_path, path, 'config.ini')) - if int(config.get('info', 'width')) < int(config.get('info', 'height')): - height = config.get('info', 'width') - width = config.get('info', 'height') - config['info']['width'] = width - config['info']['height'] = height - self.__write_config__(config) +def write_config(path: str, config: ConfigParser) -> None: + with open(os.path.join(templates_path, path, 'config.ini'), 'w', encoding='utf8') as f: + config.write(f) - self.id = hashlib.md5(str({s: dict(config.items(s)) for s in config.sections()}).encode()).hexdigest() - self.manufacturer: str = str(config.get('info', 'manufacturer')) - self.name: str = str(config.get('info', 'name')) - self.type: str = str(config.get('info', 'type')) - self.year: int = int(config.get('info', 'year')) - self.width: int = int(config.get('info', 'width')) - self.height: int = int(config.get('info', 'height')) - self.resolution: str = '{width} x {height}'.format( - width=self.width, height=self.height) - self.preview: str = str(os.path.join(templates_path, path, 'preview.png')) - self.colors = [DeviceColor( - color=str(key).title(), path=str(os.path.join(templates_path, path, item)) - ) for key, item in config['colors'].items()] +def get_author(path: str, config: ConfigParser) -> str: + try: + return config.get('about', 'author') + except (NoOptionError, NoSectionError): + if 'about' not in config.sections(): + config.add_section('about') + config['about']['author'] = author() + write_config(path, config) - self.image = DeviceImage( - width=int(config.get('image', 'width')), - height=int(config.get('image', 'height')), - x=int(config.get('image', 'x')), - y=int(config.get('image', 'y')), - mask=config.get('image', 'mask') == 'true', - mask_path=os.path.join(templates_path, path, 'mask.png') if config.get('image', 'mask') == 'true' else None, - rotate=config.get('image', 'rotate') == 'true') - self.about = About( - author=self.__get_author__(config), - url=self.__get_url__(config) - ) +def get_url(path, config: ConfigParser) -> str: + try: + return config.get('about', 'url') + except (NoOptionError, NoSectionError): + if 'about' not in config.sections(): + config.add_section('about') + config['about']['url'] = author_url() + write_config(path, config) - def __str__(self): - return ''.format(self.manufacturer, self.name, self.year) - def __post_init__(self): - self.colors = sorted(self.colors, key=lambda a: a.color) +def parse_config(path: str) -> Device: + kwargs = dict(__path__=path) - def __write_config__(self, config: ConfigParser) -> None: - with open(os.path.join(templates_path, self.__path__, 'config.ini'), 'w', encoding='utf8') as f: - config.write(f) + config = ConfigParser() + config.read(os.path.join(templates_path, path, 'config.ini')) - def __get_author__(self, config: ConfigParser) -> str: - try: - return config.get('about', 'author') - except (NoOptionError, NoSectionError): - if 'about' not in config.sections(): - config.add_section('about') - config['about']['author'] = author() - self.__write_config__(config) + if int(config.get('info', 'width')) < int(config.get('info', 'height')): + height = config.get('info', 'width') + width = config.get('info', 'height') + config['info']['width'] = width + config['info']['height'] = height + write_config(path, config) - def __get_url__(self, config: ConfigParser) -> str: - try: - return config.get('about', 'url') - except (NoOptionError, NoSectionError): - if 'about' not in config.sections(): - config.add_section('about') - config['about']['url'] = author_url() - self.__write_config__(config) + kwargs['id']: str = hashlib.md5(str({s: dict(config.items(s)) for s in config.sections()}).encode()).hexdigest() + kwargs['manufacturer']: str = str(config.get('info', 'manufacturer')) + kwargs['name']: str = str(config.get('info', 'name')) + kwargs['type']: str = str(config.get('info', 'type')) + kwargs['year']: int = int(config.get('info', 'year')) + kwargs['width']: int = int(config.get('info', 'width')) + kwargs['height']: int = int(config.get('info', 'height')) + kwargs['resolution']: str = '{width} x {height}'.format( + width=kwargs['width'], height=kwargs['height']) + kwargs['preview']: str = str(os.path.join(templates_path, path, 'preview.png')) + + kwargs['colors'] = sorted([DeviceColor( + color=str(key).title(), path=str(os.path.join(templates_path, path, item)) + ) for key, item in config['colors'].items()], key=lambda a: a.color) + + kwargs['image'] = DeviceImage( + width=int(config.get('image', 'width')), + height=int(config.get('image', 'height')), + x=int(config.get('image', 'x')), + y=int(config.get('image', 'y')), + mask=config.get('image', 'mask') == 'true', + mask_path=os.path.join(templates_path, path, 'mask.png') if config.get('image', 'mask') == 'true' else None, + rotate=config.get('image', 'rotate') == 'true') + + kwargs['about'] = About( + author=get_author(path, config), + url=get_url(path, config) + ) + + return Device(**kwargs) diff --git a/deploy.py b/deploy.py index 0882313..f8f1a55 100644 --- a/deploy.py +++ b/deploy.py @@ -68,15 +68,16 @@ def bump_version(): def run_pypi(): + print(f'cd "{os.path.dirname(os.path.abspath(__file__))}"') + print('python setup.py sdist') + print('execute: twine upload dist/*') os.chdir(os.path.dirname(os.path.abspath(__file__))) - os.system("python3 setup.py sdist") - os.system("twine upload dist/*") - os.system("rm -rf \"dist\"") - os.system("rm -rf \"MockupEngineer.egg-info\"") + os.remove('dist') + os.remove('MockupEngineer.egg-info') if __name__ == '__main__': - create_readme() - create_examples() - bump_version() + # create_readme() + # create_examples() + # bump_version() run_pypi() diff --git a/requirements.txt b/requirements.txt index a39d5a8..77fe1dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ setuptools>=60.5.0 asyncio>=3.4.3 TemporaryStorage>=2022.1.31.2 -Pillow>=8.4.0 \ No newline at end of file +Pillow>=8.4.0 +pydantic>=1.9.0 \ No newline at end of file diff --git a/setup.py b/setup.py index c9266bf..6331ad9 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages setup( name='MockupEngineer', - version='2022.02.24.1', + version='2022.03.23.1', packages=find_packages(), url='https://github.com/ulbwazhine/MockupEngineer', license='MIT',