From ae7c4bc14dee23e88f5890e836b7daca127c5aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= Date: Thu, 6 Oct 2022 16:39:40 +0200 Subject: [PATCH 1/2] add host aplication implementation from sharp --- specklepy/api/host_applications.py | 114 +++++++++++++++++++++++++++++ tests/test_host_applications.py | 13 ++++ 2 files changed, 127 insertions(+) create mode 100644 specklepy/api/host_applications.py create mode 100644 tests/test_host_applications.py diff --git a/specklepy/api/host_applications.py b/specklepy/api/host_applications.py new file mode 100644 index 00000000..360f9387 --- /dev/null +++ b/specklepy/api/host_applications.py @@ -0,0 +1,114 @@ +from enum import Enum +from dataclasses import dataclass +from unicodedata import name + + +class HostAppVersion(Enum): + v = "v" + v6 = "v6" + v7 = "v7" + v2019 = "v2019" + v2020 = "v2020" + v2021 = "v2021" + v2022 = "v2022" + v2023 = "v2023" + v2024 = "v2024" + v2025 = "v2025" + vSandbox = "vSandbox" + vRevit = "vRevit" + vRevit2021 = "vRevit2021" + vRevit2022 = "vRevit2022" + vRevit2023 = "vRevit2023" + vRevit2024 = "vRevit2024" + vRevit2025 = "vRevit2025" + v25 = "v25" + v26 = "v26" + + def __repr__(self) -> str: + return self.value + + def __str__(self) -> str: + return self.value + + +@dataclass +class HostApplication: + name: str + slug: str + + def get_version(self, version: HostAppVersion) -> str: + return f"{name.replace(' ', '')}{str(version).strip('v')}" + +RHINO = HostApplication("Rhino", "rhino") +GRASSHOPPER = HostApplication("Grasshopper", "grasshopper") +REVIT = HostApplication("Revit", "revit") +DYNAMO = HostApplication("Dynamo", "dynamo") +UNITY = HostApplication("Unity", "unity") +GSA = HostApplication("GSA", "gsa") +CIVIL = HostApplication("Civil 3D", "civil3d") +AUTOCAD = HostApplication("AutoCAD", "autocad") +MICROSTATION = HostApplication("MicroStation", "microstation") +OPENROADS = HostApplication("OpenRoads", "openroads") +OPENRAIL = HostApplication("OpenRail", "openrail") +OPENBUILDINGS = HostApplication("OpenBuildings", "openbuildings") +ETABS = HostApplication("ETABS", "etabs") +SAP2000 = HostApplication("SAP2000", "sap2000") +CSIBRIDGE = HostApplication("CSIBridge", "csibridge") +SAFE = HostApplication("SAFE", "safe") +TEKLASTRUCTURES = HostApplication("Tekla Structures", "teklastructures") +DXF = HostApplication("DXF Converter", "dxf") +EXCEL = HostApplication("Excel", "excel") +UNREAL = HostApplication("Unreal", "unreal") +POWERBI = HostApplication("Power BI", "powerbi") +BLENDER = HostApplication("Blender", "blender") +QGIS = HostApplication("QGIS", "qgis") +ARCGIS = HostApplication("ArcGIS", "arcgis") +SKETCHUP = HostApplication("SketchUp", "sketchup") +ARCHICAD = HostApplication("Archicad", "archicad") +TOPSOLID = HostApplication("TopSolid", "topsolid") +PYTHON = HostApplication("Python", "python") +NET = HostApplication(".NET", "net") +OTHER = HostApplication("Other", "other") + +_app_name_host_app_mapping = { + "dynamo": DYNAMO, + "revit": REVIT, + "autocad": AUTOCAD, + "civil": CIVIL, + "rhino": RHINO, + "grasshopper": GRASSHOPPER, + "unity": UNITY, + "gsa": GSA, + "microstation": MICROSTATION, + "openroads": OPENROADS, + "openrail": OPENRAIL, + "openbuildings": OPENBUILDINGS, + "etabs": ETABS, + "sap": SAP2000, + "csibridge": CSIBRIDGE, + "safe": SAFE, + "teklastructures": TEKLASTRUCTURES, + "dxf": DXF, + "excel": EXCEL, + "unreal": UNREAL, + "powerbi": POWERBI, + "blender": BLENDER, + "qgis": QGIS, + "arcgis": ARCGIS, + "sketchup": SKETCHUP, + "archicad": ARCHICAD, + "topsolid": TOPSOLID, + "python": PYTHON, + "net": NET +} + +def get_host_app_from_string(app_name: str) -> HostApplication: + app_name = app_name.lower().replace(" ", "") + for partial_app_name, host_app in _app_name_host_app_mapping.items(): + if (partial_app_name in app_name): + return host_app + return HostApplication(app_name, app_name) + + +if __name__ == "__main__": + print(HostAppVersion.v) diff --git a/tests/test_host_applications.py b/tests/test_host_applications.py new file mode 100644 index 00000000..8167a9af --- /dev/null +++ b/tests/test_host_applications.py @@ -0,0 +1,13 @@ +import pytest +from specklepy.api.host_applications import get_host_app_from_string, _app_name_host_app_mapping + +def test_get_host_app_from_string_returns_fallback_app(): + not_existing_app_name = "gmail" + host_app = get_host_app_from_string(not_existing_app_name) + assert host_app.name == not_existing_app_name + assert host_app.slug == not_existing_app_name + +@pytest.mark.parametrize("app_name", _app_name_host_app_mapping.keys()) +def test_get_host_app_from_string_matches_for_predefined_apps(app_name) -> None: + host_app = get_host_app_from_string(app_name) + assert app_name in host_app.slug.lower() \ No newline at end of file From 459bd0901f062becaf0b7e8799b16fed7d38befa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= Date: Thu, 6 Oct 2022 16:40:03 +0200 Subject: [PATCH 2/2] add untracked receive operations for connector side tracking --- specklepy/api/operations.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/specklepy/api/operations.py b/specklepy/api/operations.py index 212c12ff..6e447db3 100644 --- a/specklepy/api/operations.py +++ b/specklepy/api/operations.py @@ -2,7 +2,6 @@ from specklepy.logging import metrics from specklepy.objects.base import Base from specklepy.transports.sqlite import SQLiteTransport -from specklepy.transports.server import ServerTransport from specklepy.logging.exceptions import SpeckleException from specklepy.transports.abstract_transport import AbstractTransport from specklepy.serialization.base_object_serializer import BaseObjectSerializer @@ -53,6 +52,16 @@ def receive( remote_transport: AbstractTransport = None, local_transport: AbstractTransport = None, ) -> Base: + metrics.track(metrics.RECEIVE, getattr(remote_transport, "account", None)) + return _untracked_receive(obj_id, remote_transport, local_transport) + + +def _untracked_receive( + obj_id: str, + remote_transport: AbstractTransport = None, + local_transport: AbstractTransport = None, +) -> Base: + """Receives an object from a transport. Arguments: @@ -64,13 +73,12 @@ def receive( Returns: Base -- the base object """ - metrics.track(metrics.RECEIVE, getattr(remote_transport, "account", None)) if not local_transport: local_transport = SQLiteTransport() serializer = BaseObjectSerializer(read_transport=local_transport) - # try local transport first. if the parent is there, we assume all the children are there and continue with deserialisation using the local transport + # try local transport first. if the parent is there, we assume all the children are there and continue with deserialization using the local transport obj_string = local_transport.get_object(obj_id) if obj_string: return serializer.read_json(obj_string=obj_string) @@ -124,3 +132,6 @@ def deserialize(obj_string: str, read_transport: AbstractTransport = None) -> Ba serializer = BaseObjectSerializer(read_transport=read_transport) return serializer.read_json(obj_string=obj_string) + + +__all__ = [receive.__name__, send.__name__, serialize.__name__, deserialize.__name__]