From 6b7039967da92d70c25e010032fec5ad85a24287 Mon Sep 17 00:00:00 2001 From: Robin Vobruba Date: Fri, 20 Dec 2024 17:36:10 +0100 Subject: [PATCH] Fixes data-classes [fix] --- krawl/project.py | 384 +++++++++++++++++++++++------------------------ 1 file changed, 192 insertions(+), 192 deletions(-) diff --git a/krawl/project.py b/krawl/project.py index 38de75a..46daa93 100644 --- a/krawl/project.py +++ b/krawl/project.py @@ -58,119 +58,6 @@ def from_url(cls, url: str) -> ProjectID: return cls(pu.platform, pu.owner, pu.repo) -@dataclass(slots=True) -class Project: # pylint: disable=too-many-instance-attributes - """Project data model based on - https://github.com/iop-alliance/OpenKnowHow/blob/master/res/sample_data/okh-TEMPLATE.toml. - """ - - # for internal use - meta: Meta = field(default_factory=Meta, init=False, repr=False) - okhv: str = "OKH-LOSHv1.0" - name: str = None - repo: str = None - version: str = None - release: str = None - license: License = None - licensor: str = None - organization: str = None - readme: File = None - contribution_guide: File = None - image: File = None - documentation_language: str = None - technology_readiness_level: str = None - documentation_readiness_level: str = None - attestation: str = None - publication: str = None - function: str = None - standard_compliance: str = None - cpc_patent_class: str = None - tsdc: str = None - bom: File = None - manufacturing_instructions: File = None - user_manual: File = None - part: list[Part] = [] - software: list[Software] = [] - upload_method = None - source = [] - export = [] - specific_api_data = {} - - @classmethod - def from_dict(cls, data: dict) -> Project | None: - if data is None: - return None - project = cls() - project.meta = Meta.from_dict(data.get("__meta", {})) - project.okhv = data.get("okhv", None) - project.name = data.get("name", None) - project.repo = data.get("repo", None) - project.version = data.get("version", None) - project.release = data.get("release", None) - project.license = get_by_id_or_name(data.get("license", None)) - project.licensor = data.get("licensor", None) - project.organization = data.get("organization", None) - project.readme = File.from_dict(data.get("readme")) - project.contribution_guide = File.from_dict(data.get("contribution-guide")) - project.image = File.from_dict(data.get("image")) - project.documentation_language = data.get("documentation-language", None) - project.technology_readiness_level = data.get("technology-readiness-level", None) - project.documentation_readiness_level = data.get("documentation-readiness-level", None) - project.attestation = data.get("attestation", None) - project.publication = data.get("publication", None) - project.function = data.get("function", None) - project.standard_compliance = data.get("standard-compliance", None) - project.cpc_patent_class = data.get("cpc-patent-class", None) - project.tsdc = data.get("tsdc", None) - project.bom = File.from_dict(data.get("bom")) - project.manufacturing_instructions = File.from_dict(data.get("manufacturing-instructions")) - project.user_manual = File.from_dict(data.get("user-manual")) - project.part = [Part.from_dict(p) for p in data.get("part", [])] - project.software = [Software.from_dict(s) for s in data.get("software", [])] - project.specific_api_data = data.get('specific-api-data') - project.upload_method = data.get('upload-method') - return project - - def as_dict(self) -> dict: - # return asdict(self) - return { - "__meta": self.meta.as_dict(), - "okhv": self.okhv, - "name": self.name, - "repo": self.repo, - "version": self.version, - "release": self.release, - "license": str(self.license), - "licensor": self.licensor, - "organization": self.organization, - "readme": self.readme.as_dict() if self.readme is not None else None, - "contribution-guide": self.contribution_guide.as_dict() if self.contribution_guide is not None else None, - "image": self.image.as_dict() if self.image is not None else None, - "documentation-language": self.documentation_language, - "technology-readiness-level": self.technology_readiness_level, - "documentation-readiness-level": self.documentation_readiness_level, - "attestation": self.attestation, - "publication": self.publication, - "function": self.function, - "standard-compliance": self.standard_compliance, - "cpc-patent-class": self.cpc_patent_class, - "tsdc": self.tsdc, - "bom": self.bom.as_dict() if self.bom is not None else None, - "manufacturing-instructions": self.manufacturing_instructions.as_dict() - if self.manufacturing_instructions is not None else None, - "user-manual": self.user_manual.as_dict() if self.user_manual is not None else None, - "part": [p.as_dict() for p in self.part], - "software": [s.as_dict() for s in self.software], - "specific-api-data": self.specific_api_data, - "upload-method": str(self.upload_method) - } - - @property - def id(self) -> ProjectID: - """Generates an ID in form of 'platform/owner/repo/path'""" - return ProjectID(self.meta.source, self.meta.owner, self.meta.repo, self.meta.path) - - @dataclass(slots=True) class Meta: # pylint: disable=too-many-instance-attributes """Metadata for internal use.""" @@ -220,64 +107,54 @@ def as_dict(self) -> dict: @dataclass(slots=True) -class Part: # pylint: disable=too-many-instance-attributes - """Part data model.""" +class File: # pylint: disable=too-many-instance-attributes + """File data model.""" name: str = None - name_clean: str = None - image: File = None - source: File = None - export: list[File] = [] - auxiliary: list[File] = [] + path: Path = None + mime_type: str = None + url: str = None + frozen_url: str = None # frozen URL is bound to a specific version of the file, e.g. a git commit + created_at: datetime = None + last_visited: datetime = None + last_changed: datetime = None license: License = None licensor: str = None - documentation_language: str = None - material: str = None - manufacturing_process: str = None - mass: float = None - outer_dimensions: OuterDimensions = None - tsdc: str = None + + @property + def extension(self): + return self.path.suffix[1:].lower() if self.path else "" @classmethod def from_dict(cls, data: dict) -> Part: if data is None: return None - part = cls() - part.name = data.get("name", None) - part.name_clean = data.get("name_clean", None) - part.image = File.from_dict(data.get("image")) - part.source = File.from_dict(data.get("source")) - part.export = [File.from_dict(e) for e in data.get("export")] - part.auxiliary = [File.from_dict(e) for e in data.get("auxiliary")] - part.documentation_language = data.get("documentation-language", None) - part.material = data.get("material", None) - part.manufacturing_process = data.get("manufacturing-process", None) - part.mass = dict_utils.to_float(data.get("mass")) - outer_dimensions_raw = data.get("outer-dimensions") - part.outer_dimensions = OuterDimensions.from_dict(outer_dimensions_raw) - part.tsdc = data.get("tsdc", None) - part.license = get_by_id_or_name(data.get("license", None)) - part.licensor = data.get("licensor", None) - return part + file = cls() + file.name = data.get("name", None) + file.path = Path(data["path"]) if data.get("path") is not None else None + file.mime_type = data.get("mime-type", None) + file.url = data.get("url", None) + file.frozen_url = data.get("frozen-url", None) + file.created_at = _parse_date(data.get("created-at")) + file.last_visited = _parse_date(data.get("last-visited")) + file.last_changed = _parse_date(data.get("last-changed")) + file.license = get_by_id_or_name(data.get("license", None)) + file.licensor = data.get("licensor", None) + return file def as_dict(self) -> dict: return { "name": self.name, - "name_clean": self.name_clean, - "image": self.image.as_dict() if self.image is not None else None, - "source": self.source.as_dict() if self.source is not None else None, - "export": [e.as_dict() for e in self.export if e is not None], - "auxiliary": [e.as_dict() for e in self.auxiliary if e is not None], - "documentation-language": self.documentation_language, - "material": self.material, - "manufacturing-process": self.manufacturing_process, - "mass": self.mass, - "outer-dimensions": self.outer_dimensions.as_dict() if self.outer_dimensions is not None else None, - "tsdc": self.tsdc, + "path": str(self.path), + "mime-type": self.mime_type, + "url": self.url, + "frozen-url": self.frozen_url, + "created-at": self.created_at.isoformat() if self.created_at is not None else None, + "last-visited": self.last_visited.isoformat() if self.last_visited is not None else None, + "last-changed": self.last_changed.isoformat() if self.last_changed is not None else None, "license": str(self.license), "licensor": self.licensor, } - # return asdict(self) @dataclass(slots=True) @@ -390,64 +267,187 @@ def as_dict(self) -> dict: @dataclass(slots=True) -class File: # pylint: disable=too-many-instance-attributes - """File data model.""" +class User: + """User data model.""" name: str = None - path: Path = None - mime_type: str = None - url: str = None - frozen_url: str = None # frozen URL is bound to a specific version of the file, e.g. a git commit - created_at: datetime = None - last_visited: datetime = None - last_changed: datetime = None + email: str = None + username: str = None + language: str = None + + +@dataclass(slots=True) +class Part: # pylint: disable=too-many-instance-attributes + """Part data model.""" + + name: str = None + name_clean: str = None + image: File = None + source: File = None + export: list[File] = field(default_factory=list) + auxiliary: list[File] = field(default_factory=list) license: License = None licensor: str = None - - @property - def extension(self): - return self.path.suffix[1:].lower() if self.path else "" + documentation_language: str = None + material: str = None + manufacturing_process: str = None + mass: float = None + outer_dimensions: OuterDimensions = None + tsdc: str = None @classmethod def from_dict(cls, data: dict) -> Part: if data is None: return None - file = cls() - file.name = data.get("name", None) - file.path = Path(data["path"]) if data.get("path") is not None else None - file.mime_type = data.get("mime-type", None) - file.url = data.get("url", None) - file.frozen_url = data.get("frozen-url", None) - file.created_at = _parse_date(data.get("created-at")) - file.last_visited = _parse_date(data.get("last-visited")) - file.last_changed = _parse_date(data.get("last-changed")) - file.license = get_by_id_or_name(data.get("license", None)) - file.licensor = data.get("licensor", None) - return file + part = cls() + part.name = data.get("name", None) + part.name_clean = data.get("name_clean", None) + part.image = File.from_dict(data.get("image")) + part.source = File.from_dict(data.get("source")) + part.export = [File.from_dict(e) for e in data.get("export")] + part.auxiliary = [File.from_dict(e) for e in data.get("auxiliary")] + part.documentation_language = data.get("documentation-language", None) + part.material = data.get("material", None) + part.manufacturing_process = data.get("manufacturing-process", None) + part.mass = dict_utils.to_float(data.get("mass")) + outer_dimensions_raw = data.get("outer-dimensions") + part.outer_dimensions = OuterDimensions.from_dict(outer_dimensions_raw) + part.tsdc = data.get("tsdc", None) + part.license = get_by_id_or_name(data.get("license", None)) + part.licensor = data.get("licensor", None) + return part def as_dict(self) -> dict: return { "name": self.name, - "path": str(self.path), - "mime-type": self.mime_type, - "url": self.url, - "frozen-url": self.frozen_url, - "created-at": self.created_at.isoformat() if self.created_at is not None else None, - "last-visited": self.last_visited.isoformat() if self.last_visited is not None else None, - "last-changed": self.last_changed.isoformat() if self.last_changed is not None else None, + "name_clean": self.name_clean, + "image": self.image.as_dict() if self.image is not None else None, + "source": self.source.as_dict() if self.source is not None else None, + "export": [e.as_dict() for e in self.export if e is not None], + "auxiliary": [e.as_dict() for e in self.auxiliary if e is not None], + "documentation-language": self.documentation_language, + "material": self.material, + "manufacturing-process": self.manufacturing_process, + "mass": self.mass, + "outer-dimensions": self.outer_dimensions.as_dict() if self.outer_dimensions is not None else None, + "tsdc": self.tsdc, "license": str(self.license), "licensor": self.licensor, } + # return asdict(self) @dataclass(slots=True) -class User: - """User data model.""" +class Project: # pylint: disable=too-many-instance-attributes + """Project data model based on + https://github.com/iop-alliance/OpenKnowHow/blob/master/res/sample_data/okh-TEMPLATE.toml. + """ + # for internal use + okhv: str = "OKH-LOSHv1.0" name: str = None - email: str = None - username: str = None - language: str = None + repo: str = None + version: str = None + release: str = None + license: License = None + licensor: str = None + organization: str = None + readme: File = None + contribution_guide: File = None + image: File = None + documentation_language: str = None + technology_readiness_level: str = None + documentation_readiness_level: str = None + attestation: str = None + publication: str = None + function: str = None + standard_compliance: str = None + cpc_patent_class: str = None + tsdc: str = None + bom: File = None + manufacturing_instructions: File = None + user_manual: File = None + part: list[Part] = field(default_factory=list) + software: list[Software] = field(default_factory=list) + upload_method = None + source: list[File] = field(default_factory=list) + export: list[File] = field(default_factory=list) + specific_api_data = {} + meta: Meta = field(default_factory=Meta, init=False, repr=False) + + @classmethod + def from_dict(cls, data: dict) -> Project | None: + if data is None: + return None + project = cls() + project.meta = Meta.from_dict(data.get("__meta", {})) + project.okhv = data.get("okhv", None) + project.name = data.get("name", None) + project.repo = data.get("repo", None) + project.version = data.get("version", None) + project.release = data.get("release", None) + project.license = get_by_id_or_name(data.get("license", None)) + project.licensor = data.get("licensor", None) + project.organization = data.get("organization", None) + project.readme = File.from_dict(data.get("readme")) + project.contribution_guide = File.from_dict(data.get("contribution-guide")) + project.image = File.from_dict(data.get("image")) + project.documentation_language = data.get("documentation-language", None) + project.technology_readiness_level = data.get("technology-readiness-level", None) + project.documentation_readiness_level = data.get("documentation-readiness-level", None) + project.attestation = data.get("attestation", None) + project.publication = data.get("publication", None) + project.function = data.get("function", None) + project.standard_compliance = data.get("standard-compliance", None) + project.cpc_patent_class = data.get("cpc-patent-class", None) + project.tsdc = data.get("tsdc", None) + project.bom = File.from_dict(data.get("bom")) + project.manufacturing_instructions = File.from_dict(data.get("manufacturing-instructions")) + project.user_manual = File.from_dict(data.get("user-manual")) + project.part = [Part.from_dict(p) for p in data.get("part", [])] + project.software = [Software.from_dict(s) for s in data.get("software", [])] + project.specific_api_data = data.get('specific-api-data') + project.upload_method = data.get('upload-method') + return project + + def as_dict(self) -> dict: + # return asdict(self) + return { + "__meta": self.meta.as_dict(), + "okhv": self.okhv, + "name": self.name, + "repo": self.repo, + "version": self.version, + "release": self.release, + "license": str(self.license), + "licensor": self.licensor, + "organization": self.organization, + "readme": self.readme.as_dict() if self.readme is not None else None, + "contribution-guide": self.contribution_guide.as_dict() if self.contribution_guide is not None else None, + "image": self.image.as_dict() if self.image is not None else None, + "documentation-language": self.documentation_language, + "technology-readiness-level": self.technology_readiness_level, + "documentation-readiness-level": self.documentation_readiness_level, + "attestation": self.attestation, + "publication": self.publication, + "function": self.function, + "standard-compliance": self.standard_compliance, + "cpc-patent-class": self.cpc_patent_class, + "tsdc": self.tsdc, + "bom": self.bom.as_dict() if self.bom is not None else None, + "manufacturing-instructions": self.manufacturing_instructions.as_dict() + if self.manufacturing_instructions is not None else None, + "user-manual": self.user_manual.as_dict() if self.user_manual is not None else None, + "part": [p.as_dict() for p in self.part], + "software": [s.as_dict() for s in self.software], + "specific-api-data": self.specific_api_data, + "upload-method": str(self.upload_method) + } + + @property + def id(self) -> ProjectID: + """Generates an ID in form of 'platform/owner/repo/path'""" + return ProjectID(self.meta.source, self.meta.owner, self.meta.repo, self.meta.path) def _parse_date(value):