Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
BasicListEvidenceKeyFilter
from fiftyone_pipeline_engines.engine import Engine
from fiftyone_pipeline_core.aspectproperty_value import AspectPropertyValue
from fiftyone_pipeline_core.jsonbundler import WKT_TYPES

from .clouddata import CloudData

Expand Down Expand Up @@ -133,8 +134,19 @@ def process_internal(self, flowdata):

result = {}

# A shape in well-known text arrives as an object holding the text.
# The property list is keyed by the names the cloud service gives,
# such as Areas, and the response by the same names in lower case.
wkt_keys = {
name.lower() for name, meta in self.properties.items()
if str(meta.get("type", "")).lower() in WKT_TYPES}

for key, value in engineData.items():

if (key.lower() in wkt_keys and isinstance(value, dict)
and list(value) == ["value"]):
value = value["value"]

if key + "nullreason" in engineData:
result[key] = AspectPropertyValue(no_value_message=engineData[key + "nullreason"])
else:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

"""
A WKT value in a response from the remote server is an object with one member,
value, holding the WKT text, and the engine gives the text.
"""

import json
import unittest

from fiftyone_pipeline_cloudrequestengine.cloudengine import CloudEngine
from fiftyone_pipeline_core.elementdata_dictionary import ElementDataDictionary
from fiftyone_pipeline_core.flowelement import FlowElement
from fiftyone_pipeline_core.pipelinebuilder import PipelineBuilder

AREA = "POLYGON((1 2, 3 4, 5 6, 1 2))"


class FakeCloudRequestEngine(FlowElement):

def __init__(self, answer):
super(FakeCloudRequestEngine, self).__init__()
self.datakey = "cloud"
self.answer = answer
# Keyed by the names the cloud service gives, as
# CloudRequestEngine.get_engine_properties keys them.
self.flow_element_properties = {
"ip": {"Areas": {"name": "Areas", "type": "WktString"},
"Name": {"name": "Name", "type": "String"}}}

def process_internal(self, flowdata):
flowdata.set_element_data(ElementDataDictionary(
self, {"cloud": json.dumps(self.answer)}))


def read(answer):
engine = CloudEngine()
engine.datakey = "ip"
pipeline = PipelineBuilder({
"add_javascript_builder": False, "use_setheader_properties": False}) \
.add(FakeCloudRequestEngine(answer)).add(engine).build()
flowdata = pipeline.create_flowdata()
flowdata.process()
pipeline.close()
return flowdata.get("ip")


class CloudEngineWktTests(unittest.TestCase):

def test_the_text_is_taken_out_of_the_object(self):
data = read({"ip": {"areas": {"value": AREA}, "name": "a place"}})
self.assertEqual(AREA, data.get("areas").value())
self.assertEqual("a place", data.get("name").value())

def test_text_that_is_already_plain_is_kept(self):
data = read({"ip": {"areas": AREA, "name": "a place"}})
self.assertEqual(AREA, data.get("areas").value())


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
from .flowelement import FlowElement
from .elementdata_dictionary import ElementDataDictionary

# The property types that hold a shape in well-known text. The JSON holds such
# a value as an object with one member, value, holding the text.
WKT_TYPES = ("wkt", "wktstring", "wkb", "wkbr")

class JSONBundlerElement(FlowElement):

"""!
Expand Down Expand Up @@ -184,6 +188,10 @@ def process_internal(self, flowdata):

continue

if (isinstance(value, str)
and str(propertymeta.get("type", "")).lower() in WKT_TYPES):
value = {"value": value}

output[flow_element.datakey.lower()][propertykey.lower()] = value
if value is None:
output[flow_element.datakey.lower()][propertykey.lower() + "nullreason"] = null_reason
Expand Down
50 changes: 50 additions & 0 deletions pipeline/fiftyone_pipeline_core/tests/test_jsonbundler_wkt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

"""
A WKT value is written to JSON as an object with one member, value, holding
the WKT text, as the value types page of the specification says.
"""

import unittest

from fiftyone_pipeline_core.elementdata_dictionary import ElementDataDictionary
from fiftyone_pipeline_core.flowelement import FlowElement
from fiftyone_pipeline_core.pipelinebuilder import PipelineBuilder

AREA = "POLYGON((1 2, 3 4, 5 6, 1 2))"


class AreasElement(FlowElement):

def __init__(self, type_name):
super(AreasElement, self).__init__()
self.datakey = "areas"
self.properties = {
"areas": {"name": "Areas", "type": type_name},
"name": {"name": "Name", "type": "string"}}

def process_internal(self, flowdata):
flowdata.set_element_data(ElementDataDictionary(
self, {"Areas": AREA, "Name": "a place"}))


def json_of(type_name):
pipeline = PipelineBuilder({}).add(AreasElement(type_name)).build()
flowdata = pipeline.create_flowdata()
flowdata.process()
pipeline.close()
return flowdata.jsonbundler.json["areas"]


class JsonBuilderWktTests(unittest.TestCase):

def test_a_wkt_value_is_an_object_holding_the_text(self):
for type_name in ("WktString", "wkb", "WKBR", "wkt"):
self.assertEqual(
{"value": AREA}, json_of(type_name)["areas"], type_name)

def test_other_values_are_written_as_they_are(self):
self.assertEqual("a place", json_of("WktString")["name"])


if __name__ == "__main__":
unittest.main()
Loading