Skip to content

Commit

Permalink
Merge pull request #43 from ripe-tech/jc/feat-port-query-to-spec
Browse files Browse the repository at this point in the history
feat: port query to spec & other utils
  • Loading branch information
joao-conde authored Jun 8, 2022
2 parents 735caf0 + 414c811 commit 1d26dd2
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added new methods `video` and `video_thumbnail` that return a video and video thumbnail related to a given mode, video name and customization - [ripe-white/#996](https://github.com/ripe-tech/ripe-white/issues/996)
* General order chat methods - [ripe-core/#4702](https://github.com/ripe-tech/ripe-core/issues/4702)
* Order tag methods - [ripe-robin-revamp/#363](https://github.com/ripe-tech/ripe-robin-revamp/issues/363)
* Port `_query_to_spec`, `_unpack_query`, `_parse_extra_s`, `_tuples_to_parts`, `_parts_to_parts_m` from RIPE SDK JS

### Changed

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
url="http://www.platforme.com",
zip_safe=False,
packages=["ripe"],
test_suite="ripe.test",
package_dir={"": os.path.normpath("src")},
install_requires=["appier"],
classifiers=[
Expand Down
121 changes: 121 additions & 0 deletions src/ripe/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,127 @@ class API(
transport_rule.TransportRuleAPI,
availability_rule.AvailabilityRuleAPI,
):
@classmethod
def _query_to_spec(cls, query):
options = cls._unpack_query(query)
brand = options.get("brand", None)
model = options.get("model", None)
variant = options.get("variant", None)
version = options.get("version", None)
description = options.get("description", None)
initials = options.get("initials", None)
engraving = options.get("engraving", None)
gender = options.get("gender", None)
size = options.get("size", None)
meta = options.get("meta", [])
tuples = options.get("p", [])
tuples = tuples if isinstance(tuples, list) else [tuples]
initials_extra = options.get("initials_extra", [])
initials_extra = (
initials_extra if isinstance(initials_extra, list) else [initials_extra]
)
initials_extra = cls._parse_extra_s(initials_extra)
parts = cls._tuples_to_parts(tuples)
parts_m = cls._parts_to_parts_m(parts)
spec = dict(
brand=brand,
model=model,
parts=parts_m,
initials=initials,
engraving=engraving,
initials_extra=initials_extra,
)
if variant:
spec["variant"] = variant
if version:
spec["version"] = version
if description:
spec["description"] = description
if gender:
spec["gender"] = gender
if size:
spec["size"] = size
if meta:
spec["meta"] = cls._normalize_meta(meta)
return spec

@classmethod
def _unpack_query(cls, query):
query = query.strip("?")
parts = appier.split_unescape(query, "&")
options = dict()
for part in parts:
key, value = part.split("=")
if not key in options:
options[key] = value
elif isinstance(options[key], list):
options[key].append(value)
else:
options[key] = [options[key], value]
return options

@classmethod
def _parse_extra_s(cls, extra_s):
extra = dict()
for extra_i in extra_s:
name, initials, engraving = appier.split_unescape(extra_i, ":", 2)
extra[name] = dict(initials=initials, engraving=engraving or None)
return extra

@classmethod
def _tuples_to_parts(cls, tuples):
parts = []
for triplet in tuples:
name, material, color = appier.split_unescape(triplet, ":", 2)
part = dict(name=name, material=material, color=color)
parts.append(part)
return parts

@classmethod
def _parts_to_parts_m(cls, parts):
parts_m = dict()
for part in parts:
name = part["name"]
material = part["material"]
color = part["color"]
parts_m[name] = dict(material=material, color=color)
return parts_m

@classmethod
def _normalize_meta(cls, meta):
meta_d = {}
meta_l = (
[
appier.split_unescape(element, ":", 2)
if element.startswith("$")
else appier.split_unescape(element, ":", 1)
for element in meta
]
if meta
else []
)
for parts in meta_l:
if len(parts) == 2:
parts = None, parts[0], parts[1]
type, key, value = parts
if key in meta_d:
old = meta_d[key]
is_sequence = isinstance(old, (list, tuple))
if not is_sequence:
old = [old]
old.append(value)
value = old
if type == "$list" and not isinstance(value, list):
value = [value]
if type == "$int":
value = int(value)
if type == "$float":
value = float(value)
if type == "$bool":
value = value in ("1", "true", "True")
meta_d[key] = value
return meta_d

def __init__(self, *args, **kwargs):
appier.API.__init__(self, *args, **kwargs)
self.base_url = appier.conf("RIPE_BASE_URL", RIPE_BASE_URL)
Expand Down
2 changes: 2 additions & 0 deletions src/ripe/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
90 changes: 90 additions & 0 deletions src/ripe/test/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

import unittest

import ripe


class APITest(unittest.TestCase):
def test__query_to_spec(self):
result = ripe.API._query_to_spec(
"brand=dummy&model=dummy&locale=en_us&format=webp&initials=AAA&engraving=grey&initials_extra=main:AAA:grey&p=side:leather_dmy:black&p=piping:leather_dmy:black&p=top0_bottom:leather_dmy:black&p=shadow:default:default"
)
self.assertEqual(
result,
dict(
brand="dummy",
model="dummy",
parts=dict(
side=dict(material="leather_dmy", color="black"),
piping=dict(material="leather_dmy", color="black"),
top0_bottom=dict(material="leather_dmy", color="black"),
shadow=dict(material="default", color="default"),
),
initials="AAA",
engraving="grey",
initials_extra=dict(main=dict(engraving="grey", initials="AAA")),
),
)

def test__unpack_query(self):
result = ripe.API._unpack_query(
"brand=dummy&model=dummy&p=sole:rubber:red&p=laces:metal:black"
)
self.assertEqual(
result,
dict(
brand="dummy", model="dummy", p=["sole:rubber:red", "laces:metal:black"]
),
)

result = ripe.API._unpack_query(
"?brand=dummy&model=dummy&p=sole:rubber:red&p=laces:metal:black"
)
self.assertEqual(
result,
dict(
brand="dummy", model="dummy", p=["sole:rubber:red", "laces:metal:black"]
),
)

def test__parse_extra_s(self):
result = ripe.API._parse_extra_s(["name1:aaa:black", "name2:bbb:white"])
self.assertEqual(
result,
dict(
name1=dict(initials="aaa", engraving="black"),
name2=dict(initials="bbb", engraving="white"),
),
)

def test__tuples_to_parts(self):
result = ripe.API._tuples_to_parts(
["sole:rubber:red", "laces:metal:black", "side:rubber:white"]
)
self.assertEqual(
result,
[
dict(name="sole", material="rubber", color="red"),
dict(name="laces", material="metal", color="black"),
dict(name="side", material="rubber", color="white"),
],
)

def test__parts_to_parts_m(self):
result = ripe.API._parts_to_parts_m(
[
dict(name="sole", material="rubber", color="red"),
dict(name="laces", material="metal", color="black"),
dict(name="side", material="rubber", color="white"),
]
)
self.assertEqual(
result,
dict(
sole=dict(material="rubber", color="red"),
laces=dict(material="metal", color="black"),
side=dict(material="rubber", color="white"),
),
)

0 comments on commit 1d26dd2

Please sign in to comment.