From 2fa98f8e988330858eafa73bbd2f44d2b8939903 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Tue, 5 Jan 2021 13:37:48 +0300 Subject: [PATCH 1/4] AGNKNCS-1: add ability to update and create select attributes --- notion/collection.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/notion/collection.py b/notion/collection.py index e1eb643..faea7a7 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -2,6 +2,7 @@ from copy import deepcopy from datetime import datetime, date from tzlocal import get_localzone +from uuid import uuid1 from .block import Block, PageBlock, Children, CollectionViewBlock from .logger import logger @@ -89,6 +90,33 @@ def to_notion(self): return [["‣", [["d", data]]]] +class NotionSelect(object): + valid_colors = ["default", "gray", "brown", "orange", "yellow", + "green", "blue", "purple", "pink", "red"] + id = None + color = "default" + value = None + + def __init__(self, value, color="default"): + self.id = str(uuid1()) + self.color = self.set_color(color) + self.value = value + + def set_color(self, color): + if color not in self.valid_colors: + if self.color: + return self.color + return "default" + return color + + def to_dict(self): + return { + "id": self.id, + "value": self.value, + "color": self.color + } + + class Collection(Record): """ A "collection" corresponds to what's sometimes called a "database" in the Notion UI. @@ -126,6 +154,20 @@ def get_schema_properties(self): properties.append(prop) return properties + def check_schema_select_options(self, prop, values): + """ + Check and update the prop dict with new values + """ + schema_update = False + current_options = list([p["value"].lower() for p in prop["options"]]) + if not isinstance(values, list): + values = [values] + for v in values: + if v.lower() not in current_options: + schema_update = True + prop["options"].append(NotionSelect(v).to_dict()) + return schema_update, prop + def get_schema_property(self, identifier): """ Look up a property in the collection's schema, by "property id" (generally a 4-char string), @@ -491,6 +533,10 @@ def set_property(self, identifier, val): raise AttributeError( "Object does not have property '{}'".format(identifier) ) + if prop["type"] in ["select"] or prop["type"] in ["multi_select"]: + schema_update, prop = self.collection.check_schema_select_options(prop, val) + if schema_update: + self.collection.set("schema.{}.options".format(prop["id"]), prop["options"]) path, val = self._convert_python_to_notion(val, prop, identifier=identifier) From 94f88e082448e4b2869ba045503c83ee10e7b7c0 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 17:28:19 +0300 Subject: [PATCH 2/4] NBOT-14: handle empty select/multi-select options --- notion/collection.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/notion/collection.py b/notion/collection.py index 748cc06..a61f3a9 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -176,7 +176,12 @@ def check_schema_select_options(self, prop, values): Check and update the prop dict with new values """ schema_update = False - current_options = list([p["value"].lower() for p in prop["options"]]) + current_options = [] + try: + current_options = list([p["value"].lower() for p in prop["options"]]) + except KeyError: + logger.warning("Prop may not have options {}".format(prop)) + prop["options"] = [] if not isinstance(values, list): values = [values] for v in values: From a77d740f0c52206798485b1eef8fd42e32ec045b Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 17:57:22 +0300 Subject: [PATCH 3/4] NBOT-14: added test for empty select/multi-select options --- notion/smoke_test.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/notion/smoke_test.py b/notion/smoke_test.py index d9ff048..6759076 100644 --- a/notion/smoke_test.py +++ b/notion/smoke_test.py @@ -142,6 +142,15 @@ def run_live_smoke_test(token_v2, parent_page_url_or_id): == get_collection_schema()[prop]["options"][0]["id"] ) + # check that insert in empty props works + assert not row2.eselect + row2.eselect = "A" + assert cvb.collection.get("schema.{}.options.0.value".format("eselect")) == "A" + + assert not row2.emselect + row2.emselect = ["A", "B"] + assert cvb.collection.get("schema.{}.options.0.value".format("emselect")) == "A" + # Run a filtered/sorted query using the view's default parameters result = view.default_query().execute() assert row1 == result[0] From e04818e973e42065b47f088504e2afbd05b65683 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 18:48:00 +0300 Subject: [PATCH 4/4] NBOT-14: added test data creation --- notion/smoke_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/notion/smoke_test.py b/notion/smoke_test.py index 6759076..090b792 100644 --- a/notion/smoke_test.py +++ b/notion/smoke_test.py @@ -281,6 +281,14 @@ def get_collection_schema(): }, ], }, + "eselect": { + "name": "eselect", + "type": "select", + }, + "emselect": { + "name": "emselect", + "type": "multi_select", + }, "LL[(": {"name": "Person", "type": "person"}, "4Jv$": {"name": "Estimated value", "type": "number"}, "OBcJ": {"name": "Where to?", "type": "url"},