From 74a88cf3af79972bfe33fbcb701ba2ff5e4d301f Mon Sep 17 00:00:00 2001 From: ENDERZOMBI102 Date: Thu, 21 Jul 2022 18:36:09 +0200 Subject: [PATCH] simpler and more advanced parsing of declarations --- automate/poetry.lock | 11 ++++++- automate/pyproject.toml | 1 + automate/resources/blobfox.yml | 7 +++-- automate/src/canvas.py | 46 ---------------------------- automate/src/data/__init__.py | 0 automate/src/data/emote.py | 28 +++++++++++++++++ automate/src/data/object.py | 17 +++++++++++ automate/src/data/overwrite.py | 17 +++++++++++ automate/src/data/variantList.py | 52 ++++++++++++++++++++++++++++++++ automate/src/generator.py | 41 +++++++++++++++++++++++++ 10 files changed, 171 insertions(+), 49 deletions(-) delete mode 100644 automate/src/canvas.py create mode 100644 automate/src/data/__init__.py create mode 100644 automate/src/data/emote.py create mode 100644 automate/src/data/object.py create mode 100644 automate/src/data/overwrite.py create mode 100644 automate/src/data/variantList.py create mode 100644 automate/src/generator.py diff --git a/automate/poetry.lock b/automate/poetry.lock index 3e752b7..30e9d84 100644 --- a/automate/poetry.lock +++ b/automate/poetry.lock @@ -119,6 +119,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "typing-extensions" +version = "4.3.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "webencodings" version = "0.5.1" @@ -130,7 +138,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "be5030e81293f50767b18fd51d5f2d7a1ae190e96e4e42546e4645248219e100" +content-hash = "f53bba5be8f79539f2f1e96e0fccc6feaf7553d646a307ea39be9e6d3cefc64c" [metadata.files] cairocffi = [] @@ -186,6 +194,7 @@ tinycss2 = [ {file = "tinycss2-1.1.1.tar.gz", hash = "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf"}, ] types-pyyaml = [] +typing-extensions = [] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, diff --git a/automate/pyproject.toml b/automate/pyproject.toml index 10be895..59e1e2e 100644 --- a/automate/pyproject.toml +++ b/automate/pyproject.toml @@ -9,6 +9,7 @@ python = "^3.10" PyYAML = "^6.0" types-PyYAML = "^6.0.10" CairoSVG = "^2.5.2" +typing-extensions = "^4.3.0" [tool.poetry.dev-dependencies] diff --git a/automate/resources/blobfox.yml b/automate/resources/blobfox.yml index f977b8d..7e792be 100644 --- a/automate/resources/blobfox.yml +++ b/automate/resources/blobfox.yml @@ -1,4 +1,7 @@ -blobfox: +name: 'blobfox' +basedOff: + - null # all variants from 'blob' will be imported in this unit, unless they are already present +variants: - name: 'base' src: '../vector/blobfox.svg' @@ -8,7 +11,7 @@ blobfox: - type: svg src: 'resources/lgbtq_heart.svg' - overwrite: + overwrites: - id: 'eye-left' color: 0xfffffffff remove: true \ No newline at end of file diff --git a/automate/src/canvas.py b/automate/src/canvas.py deleted file mode 100644 index 26c2d59..0000000 --- a/automate/src/canvas.py +++ /dev/null @@ -1,46 +0,0 @@ -from dataclasses import dataclass -from pathlib import Path - -from cairosvg.surface import Surface -from yaml import load - - -@dataclass(frozen=True) -class Object: - type: str - src: Path | None - - -@dataclass(frozen=True) -class Overwrite: - id: str - color: str | None - remove: bool = False - - -@dataclass(frozen=True) -class Emote: - name: str - src: Path | None = None - objects: list[Object] | None = None - overwrite: list[Overwrite] | None = None - - -class Generator: - - def generate( self, declarationFile: Path, outputDir: Path = Path('.') ) -> None: - if not declarationFile.exists(): - raise FileNotFoundError('Declaration file does not exist!') - - if not outputDir.exists(): - outputDir.mkdir() - - data = load( declarationFile.read_text(), None ) - print( data ) - - - - -if __name__ == '__main__': - gen = Generator() - gen.generate( Path('./resources/blobfox.yml'), Path('./run') ) diff --git a/automate/src/data/__init__.py b/automate/src/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/automate/src/data/emote.py b/automate/src/data/emote.py new file mode 100644 index 0000000..e4ce88c --- /dev/null +++ b/automate/src/data/emote.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass +from pathlib import Path +from typing_extensions import Self + +from data.object import Object +from data.overwrite import Overwrite + + +@dataclass(frozen=True) +class Emote: + name: str + origin: str + base: str | None = None + src: Path | None = None + objects: list[Object] = None + overwrites: list[Overwrite] = None + + @classmethod + def load( cls, data: list[dict], origin: str ) -> list[Self]: + return [ + Emote( + origin=origin, + **entry | { + 'overwrites': Overwrite.load( entry.get( 'overwrites', [ ] ) ), + 'objects': Object.load( entry.get( 'objects', [ ] ) ) + } + ) for entry in data + ] diff --git a/automate/src/data/object.py b/automate/src/data/object.py new file mode 100644 index 0000000..1a90785 --- /dev/null +++ b/automate/src/data/object.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass +from pathlib import Path +from typing_extensions import Self + + +@dataclass(frozen=True) +class Object: + type: str + src: Path | None + + @classmethod + def load( cls, data: list[dict] ) -> list[ Self ]: + objects: list[ Object ] = [] + for obj in data or []: + objects += [ Object( **obj ) ] + + return objects diff --git a/automate/src/data/overwrite.py b/automate/src/data/overwrite.py new file mode 100644 index 0000000..00093d7 --- /dev/null +++ b/automate/src/data/overwrite.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass +from typing_extensions import Self + + +@dataclass(frozen=True) +class Overwrite: + id: str + color: str | None + remove: bool = False + + @classmethod + def load( cls, data: list[dict] ) -> list[Self]: + overwrites: list[ Overwrite ] = [ ] + for overwrite in data or [ ]: + overwrites += [ Overwrite( **overwrite ) ] + + return overwrites diff --git a/automate/src/data/variantList.py b/automate/src/data/variantList.py new file mode 100644 index 0000000..b978e5b --- /dev/null +++ b/automate/src/data/variantList.py @@ -0,0 +1,52 @@ +from dataclasses import dataclass +from typing import Final +from collections.abc import Collection, Iterator + +from data.emote import Emote + + +# noinspection PyFinal +@dataclass(frozen=True, slots=True) +class VariantList(Collection[Emote]): + """ An immutable variant list """ + name: Final[ str ] + basedOff: Final[ list[ str ] ] + variants: Final[ tuple[Emote] ] + + def __init__( self, name: str, variants: list[ dict ], basedOff: list[str] | None = None ) -> None: + object.__setattr__( + self, + 'variants', + tuple( Emote.load( variants, name ) ) + ) + object.__setattr__( self, 'basesOff', basedOff or [] ) + object.__setattr__( self, 'name', name ) + + def __iter__( self ) -> Iterator[Emote ]: + return self.variants.__iter__() + + def __contains__( self, item: object ) -> bool: + if isinstance( item, str ): + for elem in self.variants: + if elem.name == item: + return True + return False + return item in self.variants + + def __getitem__( self, item: int | str ) -> Emote: + if isinstance( item, int ): + return self.variants[ item ] + + if isinstance( item, str ): + for elem in self.variants: + if elem.name == item: + return elem + raise KeyError( f'A variant with name "{item}" does not exist' ) + + raise ValueError( f'Invalid __getitem__ input: {item}' ) + + def __len__( self ) -> int: + return len( self.variants ) + + def __repr__( self ) -> str: + return f'VariantList{{name={self.name}, variants={repr(self.variants)}}}' diff --git a/automate/src/generator.py b/automate/src/generator.py new file mode 100644 index 0000000..0fc70ec --- /dev/null +++ b/automate/src/generator.py @@ -0,0 +1,41 @@ +from pathlib import Path + +import yaml +from cairosvg.surface import Surface + + +from data.variantList import VariantList + + +class Generator: + declarations: dict[ str, VariantList ] + surfaces: dict[ str, Surface ] + + def __init__( self, declFile: Path ) -> None: + if not declFile.exists(): + raise FileNotFoundError('Declaration file does not exist!') + + self.recursiveLoad( declFile ) + + def recursiveLoad( self, declFile: Path ) -> None: + variants = VariantList( **yaml.load( declFile.read_text(), yaml.FullLoader ) ) + self.declarations[ variants.name ] = variants + + if variants.basedOff is not None: + self.recursiveLoad( declFile.parent / f'{variants.basedOff}.yml' ) + + def generate( self, outputDir: Path = Path('.') ) -> None: + """ + Generates the images in the given folder + \t + :param outputDir: output directory + """ + if not outputDir.exists(): + outputDir.mkdir() + + for variant in self.variants: + pass + + +if __name__ == '__main__': + Generator( Path('./resources/blobfox.yml') ).generate( Path('./run') )