From 2fa98f8e988330858eafa73bbd2f44d2b8939903 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Tue, 5 Jan 2021 13:37:48 +0300 Subject: [PATCH 1/6] 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 f8d4a71466de1059de3f8e6c3a5a2bdab214ec70 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 15:44:45 +0300 Subject: [PATCH 2/6] NBOT-14: add ability to update schema collection --- notion/collection.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ notion/smoke_test.py | 14 ++++++++++++ 2 files changed, 67 insertions(+) diff --git a/notion/collection.py b/notion/collection.py index 748cc06..a5e7ed6 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -150,6 +150,26 @@ class Collection(Record): python_to_api=markdown_to_notion, ) cover = field_map("cover") + _schema_types = [ + "number", + "select", + "multi_select", + "date", + "person", + "file", + "checkbox", + "url", + "email", + "phone_number", + "created_time", + "created_by", + "last_edited_time", + "last_edited_by", + "formula", + "rollup", + # "relation" # another contract for this type, requires another db at creation time + ] + @property def templates(self): @@ -159,6 +179,39 @@ def templates(self): self._templates = Templates(parent=self) return self._templates + def update_schema_properties(self, props): + """ + Update current schema with props. + Change the current properties is not supported fow now. The steps to produce such feature: + - find notion scheme property id by name (the original id in collection are random, or base64) + - update current scheme with props found id + """ + schema = dict() + for prop in self.get_schema_properties(): + schema.update({ + prop["id"]: dict( + name=prop["name"], + type=prop["type"] + ) + }) + # check that props has a valid type + for _id, prop in props.items(): + if prop["type"] not in self._schema_types: + logger.error("The type {} is unsupported.".format(prop["type"])) + return + + logger.debug("Update current schema: {} with {}".format(schema, props)) + schema.update(props) + self._client.submit_transaction( + build_operation( + id=self.id, + path=[], + args=dict(schema=schema), + command="update", + table="collection", + ) + ) + def get_schema_properties(self): """ Fetch a flattened list of all properties in the collection's schema. diff --git a/notion/smoke_test.py b/notion/smoke_test.py index d9ff048..aeec8ab 100644 --- a/notion/smoke_test.py +++ b/notion/smoke_test.py @@ -200,6 +200,20 @@ def run_live_smoke_test(token_v2, parent_page_url_or_id): assert row1.some_date.timezone == timezone assert row1.some_date.reminder == reminder + # Test update schema with new props + for type_ in ["number", "select", "multi_select", "date", "person", "file", "checkbox", "url", "email", + "phone_number", "created_time", "created_by", "last_edited_time", "last_edited_by", "formula", + "rollup", + # "relation" # another contract for this type, requires another db at creation time + ]: + cvb.collection.update_schema_properties({ + type_: dict( + name=type_, + type=type_ + ) + }) + assert cvb.collection.get_schema_property(type_) + print( "Check it out and make sure it looks good, then press any key here to delete it..." ) From 0cb4661779034a91c994dfe313ddc2a2aca37f4d Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 17:22:58 +0300 Subject: [PATCH 3/6] NBOT-14: missed text type --- notion/collection.py | 1 + 1 file changed, 1 insertion(+) diff --git a/notion/collection.py b/notion/collection.py index a5e7ed6..25537d7 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -151,6 +151,7 @@ class Collection(Record): ) cover = field_map("cover") _schema_types = [ + "text", "number", "select", "multi_select", From dd0278a6807d43825d4bbc3405aadfce04577efa Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 17:23:43 +0300 Subject: [PATCH 4/6] NBOT-14: missed text type at smoke tests --- notion/smoke_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notion/smoke_test.py b/notion/smoke_test.py index aeec8ab..4e5ef40 100644 --- a/notion/smoke_test.py +++ b/notion/smoke_test.py @@ -203,7 +203,7 @@ def run_live_smoke_test(token_v2, parent_page_url_or_id): # Test update schema with new props for type_ in ["number", "select", "multi_select", "date", "person", "file", "checkbox", "url", "email", "phone_number", "created_time", "created_by", "last_edited_time", "last_edited_by", "formula", - "rollup", + "rollup", "text", # "relation" # another contract for this type, requires another db at creation time ]: cvb.collection.update_schema_properties({ From 132637d64a7d0038f9b30dad3541d68cde35b7e1 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 23:20:55 +0300 Subject: [PATCH 5/6] NBOT-14: use original schema --- notion/collection.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/notion/collection.py b/notion/collection.py index 25537d7..168a582 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -187,14 +187,7 @@ def update_schema_properties(self, props): - find notion scheme property id by name (the original id in collection are random, or base64) - update current scheme with props found id """ - schema = dict() - for prop in self.get_schema_properties(): - schema.update({ - prop["id"]: dict( - name=prop["name"], - type=prop["type"] - ) - }) + schema = self.get("schema") # check that props has a valid type for _id, prop in props.items(): if prop["type"] not in self._schema_types: From 50a5bf2d60608cea236ecb6bbdcfe9afab8bcae1 Mon Sep 17 00:00:00 2001 From: ag0n1k Date: Sun, 7 Feb 2021 23:22:56 +0300 Subject: [PATCH 6/6] NBOT-14: remove doc that is not right --- notion/collection.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/notion/collection.py b/notion/collection.py index 168a582..9d0f757 100644 --- a/notion/collection.py +++ b/notion/collection.py @@ -183,9 +183,6 @@ def templates(self): def update_schema_properties(self, props): """ Update current schema with props. - Change the current properties is not supported fow now. The steps to produce such feature: - - find notion scheme property id by name (the original id in collection are random, or base64) - - update current scheme with props found id """ schema = self.get("schema") # check that props has a valid type