2022.03.23.1

pydantic models
This commit is contained in:
ульба 2022-03-23 18:19:13 +05:00
parent a701f4ffc3
commit 1f4473e540
5 changed files with 91 additions and 79 deletions

View File

@ -6,7 +6,7 @@ from typing import List, Optional
from PIL import Image from PIL import Image
from MockupEngineer import templates 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 import random_string, get_title
from MockupEngineer.utils.about import author from MockupEngineer.utils.about import author
@ -25,7 +25,7 @@ class MockupEngineerInstance:
for template in ALL_TEMPLATES: for template in ALL_TEMPLATES:
try: try:
self.templates.append(Device(template)) self.templates.append(parse_config(template))
except Exception as e: except Exception as e:
self.logger.warning('Failed to load "{}" module: {}'.format(template, e)) self.logger.warning('Failed to load "{}" module: {}'.format(template, e))

View File

@ -2,9 +2,9 @@ import hashlib
import os import os
from configparser import ConfigParser, NoOptionError, NoSectionError from configparser import ConfigParser, NoOptionError, NoSectionError
from dataclasses import dataclass from pydantic import BaseModel
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional, List
from MockupEngineer.utils.about import author, author_url from MockupEngineer.utils.about import author, author_url
@ -21,14 +21,12 @@ ALL_TEMPLATES = sorted(__list_all_templates__())
__all__ = ALL_TEMPLATES + ["ALL_TEMPLATES"] __all__ = ALL_TEMPLATES + ["ALL_TEMPLATES"]
@dataclass(frozen=False) class DeviceColor(BaseModel):
class DeviceColor:
color: str color: str
path: str path: str
@dataclass(frozen=False) class DeviceImage(BaseModel):
class DeviceImage:
width: int width: int
height: int height: int
x: int x: int
@ -38,80 +36,92 @@ class DeviceImage:
rotate: bool rotate: bool
@dataclass(frozen=False) class About(BaseModel):
class About:
author: str author: str
url: str url: str
@dataclass(frozen=False) class Device(BaseModel):
class Device: id: str
def __init__(self, path: str): manufacturer: str
self.__path__ = path 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')): def write_config(path: str, config: ConfigParser) -> None:
height = config.get('info', 'width') with open(os.path.join(templates_path, path, 'config.ini'), 'w', encoding='utf8') as f:
width = config.get('info', 'height') config.write(f)
config['info']['width'] = width
config['info']['height'] = height
self.__write_config__(config)
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( def get_author(path: str, config: ConfigParser) -> str:
color=str(key).title(), path=str(os.path.join(templates_path, path, item)) try:
) for key, item in config['colors'].items()] 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( def get_url(path, config: ConfigParser) -> str:
author=self.__get_author__(config), try:
url=self.__get_url__(config) 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 '<MockupEngineer.templates.Device {} {} {}>'.format(self.manufacturer, self.name, self.year)
def __post_init__(self): def parse_config(path: str) -> Device:
self.colors = sorted(self.colors, key=lambda a: a.color) kwargs = dict(__path__=path)
def __write_config__(self, config: ConfigParser) -> None: config = ConfigParser()
with open(os.path.join(templates_path, self.__path__, 'config.ini'), 'w', encoding='utf8') as f: config.read(os.path.join(templates_path, path, 'config.ini'))
config.write(f)
def __get_author__(self, config: ConfigParser) -> str: if int(config.get('info', 'width')) < int(config.get('info', 'height')):
try: height = config.get('info', 'width')
return config.get('about', 'author') width = config.get('info', 'height')
except (NoOptionError, NoSectionError): config['info']['width'] = width
if 'about' not in config.sections(): config['info']['height'] = height
config.add_section('about') write_config(path, config)
config['about']['author'] = author()
self.__write_config__(config)
def __get_url__(self, config: ConfigParser) -> str: kwargs['id']: str = hashlib.md5(str({s: dict(config.items(s)) for s in config.sections()}).encode()).hexdigest()
try: kwargs['manufacturer']: str = str(config.get('info', 'manufacturer'))
return config.get('about', 'url') kwargs['name']: str = str(config.get('info', 'name'))
except (NoOptionError, NoSectionError): kwargs['type']: str = str(config.get('info', 'type'))
if 'about' not in config.sections(): kwargs['year']: int = int(config.get('info', 'year'))
config.add_section('about') kwargs['width']: int = int(config.get('info', 'width'))
config['about']['url'] = author_url() kwargs['height']: int = int(config.get('info', 'height'))
self.__write_config__(config) 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)

View File

@ -68,15 +68,16 @@ def bump_version():
def run_pypi(): 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.chdir(os.path.dirname(os.path.abspath(__file__)))
os.system("python3 setup.py sdist") os.remove('dist')
os.system("twine upload dist/*") os.remove('MockupEngineer.egg-info')
os.system("rm -rf \"dist\"")
os.system("rm -rf \"MockupEngineer.egg-info\"")
if __name__ == '__main__': if __name__ == '__main__':
create_readme() # create_readme()
create_examples() # create_examples()
bump_version() # bump_version()
run_pypi() run_pypi()

View File

@ -1,4 +1,5 @@
setuptools>=60.5.0 setuptools>=60.5.0
asyncio>=3.4.3 asyncio>=3.4.3
TemporaryStorage>=2022.1.31.2 TemporaryStorage>=2022.1.31.2
Pillow>=8.4.0 Pillow>=8.4.0
pydantic>=1.9.0

View File

@ -3,7 +3,7 @@ from setuptools import setup, find_packages
setup( setup(
name='MockupEngineer', name='MockupEngineer',
version='2022.02.24.1', version='2022.03.23.1',
packages=find_packages(), packages=find_packages(),
url='https://github.com/ulbwazhine/MockupEngineer', url='https://github.com/ulbwazhine/MockupEngineer',
license='MIT', license='MIT',