Skip to content
This repository was archived by the owner on Aug 26, 2021. It is now read-only.

Commit 2d23efe

Browse files
committed
Support adding a row from a template
- Change is a fork of jamalex#266 with some changes
1 parent c4e67e5 commit 2d23efe

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

notion/client.py

+60
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from requests.adapters import HTTPAdapter
1010
from requests.packages.urllib3.util.retry import Retry
1111
from getpass import getpass
12+
from time import sleep
1213

1314
from .block import Block, BLOCK_TYPES
1415
from .collection import (
@@ -178,6 +179,29 @@ def get_block(self, url_or_id, force_refresh=False):
178179
block_class = BLOCK_TYPES.get(block.get("type", ""), Block)
179180
return block_class(self, block_id)
180181

182+
def duplicate_block(self, source_block_id, target_block_id, wait_interval=1, wait_tries=10):
183+
"""
184+
Duplicate a block
185+
"""
186+
187+
data = {
188+
"task": {
189+
"eventName": "duplicateBlock",
190+
"request": {
191+
"sourceBlockId": source_block_id,
192+
"targetBlockId": target_block_id,
193+
"appendContentOnly": True,
194+
},
195+
}
196+
}
197+
response = self.post("enqueueTask", data).json()
198+
task_id = response.get("taskId")
199+
200+
if task_id:
201+
self.wait_for_task(task_id, interval=wait_interval, tries=wait_tries)
202+
203+
return True
204+
181205
def get_collection(self, collection_id, force_refresh=False):
182206
"""
183207
Retrieve an instance of Collection that maps to the collection identified by the ID passed in.
@@ -403,6 +427,42 @@ def create_record(self, table, parent, **kwargs):
403427

404428
return record_id
405429

430+
def get_task_status(self, task_id):
431+
"""
432+
Get a status of a single task
433+
"""
434+
data = self.post("getTasks", dict(taskIds=[task_id])).json()
435+
436+
results = data.get("results")
437+
if results is None:
438+
return None
439+
440+
if not results:
441+
# Notion does not know about such a task
442+
print("Invalid task ID.")
443+
return None
444+
445+
try:
446+
task = results.pop()
447+
return task.get("state", None)
448+
except IndexError:
449+
logger.error("There is no task {}".format(results))
450+
return None
451+
452+
def wait_for_task(self, task_id, interval=1, tries=10):
453+
"""
454+
Wait for a task by looping 'tries' times ever 'interval' seconds.
455+
The 'interval' parameter can be used to specify milliseconds using double (e.g 0.75).
456+
"""
457+
for i in range(tries):
458+
state = self.get_task_status(task_id)
459+
if state in ["not_started", "in_progress"]:
460+
sleep(interval)
461+
elif state == "success":
462+
return state
463+
464+
logger.debug("Task takes more time than expected. Specify 'interval' or 'tries' to wait more.")
465+
406466

407467
class Transaction(object):
408468

notion/collection.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,24 @@ def get_schema_property(self, identifier):
197197
return prop
198198
return None
199199

200-
def add_row(self, update_views=True, **kwargs):
200+
def add_row(self, update_views=True, source_block_id=None, source_block=None, **kwargs):
201201
"""
202202
Create a new empty CollectionRowBlock under this collection, and return the instance.
203+
Specify 'source_block' to create a row from a template block.
203204
"""
204205

205206
row_id = self._client.create_record("block", self, type="page")
206207
row = CollectionRowBlock(self._client, row_id)
207208

209+
if source_block:
210+
# The source block can be either an ID or a URL
211+
source_block = self._client.get_block(source_block)
212+
source_block_id = source_block.id
213+
214+
# User wants to create a row from a template
215+
if source_block_id:
216+
self._client.duplicate_block(source_block_id, row_id)
217+
208218
with self._client.as_atomic_transaction():
209219
for key, val in kwargs.items():
210220
setattr(row, key, val)

0 commit comments

Comments
 (0)