notion 1.0.4 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -13
- data/lib/notion_api/core.rb +63 -6
- data/lib/notion_api/notion_types/collection_view_blocks.rb +343 -229
- data/lib/notion_api/notion_types/template.rb +9 -1
- data/lib/notion_api/utils.rb +145 -56
- data/lib/notion_api/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 761cf6b775c714eb4b8eb65710baf3407eaa6061d717b18e59510a048c0edf7f
|
4
|
+
data.tar.gz: 7f3ba657e798d7e9a24b0aa77ee098462fdb164f958309fdc12ca39d54b78231
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 281bc33e957a074c02bf2866e526aa866d2f75945f7c9dbf9ec0a41a5ac7b5795fe2cedf429e8b2e6220b16550d2bf8c9c7107832672bf4915124fb8c9dae167
|
7
|
+
data.tar.gz: f02fde242ad8ebfeef9edc3c1850270a8d1459a93b1fafd83ec88eae323ca4dba0ae07bacfc9ef38e053012e81c71b2690c7fe6b68d88e31ca7898e3a4592df7
|
data/README.md
CHANGED
@@ -8,18 +8,23 @@
|
|
8
8
|
- Check out the [Gem](https://rubygems.org/gems/notion)!
|
9
9
|
|
10
10
|
## Table of Contents
|
11
|
-
- [
|
12
|
-
|
13
|
-
- [
|
14
|
-
- [
|
15
|
-
|
16
|
-
|
17
|
-
- [
|
18
|
-
|
19
|
-
|
20
|
-
- [Creating New
|
21
|
-
- [
|
22
|
-
|
11
|
+
- [Unofficial Notion Client for Ruby.](#unofficial-notion-client-for-ruby)
|
12
|
+
- [Table of Contents](#table-of-contents)
|
13
|
+
- [Getting Started](#getting-started)
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Retrieving a Page](#retrieving-a-page)
|
16
|
+
- [Retrieving a CollectionView Page](#retrieving-a-collectionview-page)
|
17
|
+
- [Retrieving a Block within the Page](#retrieving-a-block-within-the-page)
|
18
|
+
- [Get a Block](#get-a-block)
|
19
|
+
- [Get a Collection View](#get-a-collection-view)
|
20
|
+
- [Creating New Blocks](#creating-new-blocks)
|
21
|
+
- [Create a block whose parent is the page](#create-a-block-whose-parent-is-the-page)
|
22
|
+
- [Create a block whose parent is another block](#create-a-block-whose-parent-is-another-block)
|
23
|
+
- [Creating New Collections](#creating-new-collections)
|
24
|
+
- [Updating Collection View Cells](#updating-collection-view-cells)
|
25
|
+
- [Troubleshooting](#troubleshooting)
|
26
|
+
- [No results returned when attempting to get a page](#no-results-returned-when-attempting-to-get-a-page)
|
27
|
+
- [Retrieve a full-page Collection View](#retrieve-a-full-page-collection-view)
|
23
28
|
|
24
29
|
## Getting Started
|
25
30
|
### Installation
|
@@ -60,6 +65,8 @@ The following attributes can be read from any block class instance:
|
|
60
65
|
To update the title of the page:
|
61
66
|
![Update the title of a page](https://github.com/danmurphy1217/notion-ruby/blob/master/gifs/change_title.gif)
|
62
67
|
|
68
|
+
## Retrieving a CollectionView Page
|
69
|
+
This is achieved by passing the ID of the Collection View to the `get_page` method. Currently, the full URL of a Collection View Page is not supported (next up on the features list!). Once you retrieve the Collection View Page, all of the methods exposed to a normal Collection View instance are available (such as `.rows`, `.row(<row_id>)`, and all else outlined in [Updating a Collection](#updating-collection-view-cells)).
|
63
70
|
## Retrieving a Block within the Page
|
64
71
|
Now that you have retrieved a Notion Page, you have full access to the blocks on that page. You can retrieve a specific block or collection view, retrieve all children IDs (array of children IDs), or retrieve all children (array of children class instances).
|
65
72
|
|
@@ -268,6 +275,28 @@ The first argument passed to `create_collection` determines which type of collec
|
|
268
275
|
4. timeline
|
269
276
|
5. gallery
|
270
277
|
|
278
|
+
## Updating Collection View Cells
|
279
|
+
When you retrieve a `CollectionViewRow` instance with `.row(<row_id>)` or a list of `CollectionViewRow` instances with `.rows`, a handful of methods are created. Each row instance has access attributes that represent the properties in the Notion Collection View. So, let's say we are working with the following Notion Collection View:
|
280
|
+
| emoji | description | category | aliases | tags | unicode_version | ios_version |
|
281
|
+
|-------|--------------|---------------------|---------|---------|-----------------|-------------|
|
282
|
+
| 😉 | "winking face" | "Smileys & Emotion" | "wink" | "flirt" | "6.0" | "6.0" |
|
283
|
+
|
284
|
+
If you wanted to update the unicode and ios versions, you could use the following code:
|
285
|
+
```ruby
|
286
|
+
>>> collection_view = @page.get_collection("1234567") # the ID of the collection block is 1234567
|
287
|
+
>>> rows = collection_view.rows
|
288
|
+
>>> row[0].unicode_version = "updated version here!"
|
289
|
+
>>> row[0].ios_version = "I was updated too!"
|
290
|
+
```
|
291
|
+
Now, your Collection View will look like this:
|
292
|
+
| emoji | description | category | aliases | tags | unicode_version | ios_version |
|
293
|
+
|-------|--------------|---------------------|---------|---------|-----------------|-------------|
|
294
|
+
| 😉 | "winking face" | "Smileys & Emotion" | "wink" | "flirt" | "updated version here!" | "I was updated too!" |
|
295
|
+
|
296
|
+
You can also add new rows with the `.add_row({<data!>})` method and add new properties with the `.add_property("name_of_property", "type_of_property")` method.
|
297
|
+
|
298
|
+
**One important thing to be aware of:**
|
299
|
+
When adding a row with `.add_row`, the hash of data passed must be in the same order as it appears in your Notion Collection View.
|
271
300
|
## Troubleshooting
|
272
301
|
### No results returned when attempting to get a page
|
273
302
|
If an empty hash is returned when you attempt to retrieve a Notion page, you'll need to include the `x-notion-active-user-header` when instantiating the Notion Client.
|
@@ -280,4 +309,13 @@ From here, you can instantiate the Notion Client with the following code:
|
|
280
309
|
"<insert_x_notion_active_user_header_here>"
|
281
310
|
)
|
282
311
|
```
|
283
|
-
|
312
|
+
### Retrieve a full-page Collection View
|
313
|
+
A full-page collection view must have a URL that follows the below pattern:
|
314
|
+
https://www.notion.so/danmurphy/[page-id]?v=[view-id]
|
315
|
+
Then, it can be retrieved with the following code:
|
316
|
+
```ruby
|
317
|
+
>>> @client = NotionAPI::Client.new(
|
318
|
+
"<insert_v2_token_here>"
|
319
|
+
)
|
320
|
+
>>> @client.get_page(https://www.notion.so/danmurphy/[page-id]?v=[view-id])
|
321
|
+
```
|
data/lib/notion_api/core.rb
CHANGED
@@ -54,8 +54,14 @@ module NotionAPI
|
|
54
54
|
collection_id = extract_collection_id(block_id, jsonified_record_response)
|
55
55
|
block_title = extract_collection_title(clean_id, collection_id, jsonified_record_response)
|
56
56
|
view_id = extract_view_ids(block_id, jsonified_record_response)[0]
|
57
|
-
|
58
|
-
|
57
|
+
schema = extract_collection_schema(collection_id, view_id, jsonified_record_response)
|
58
|
+
column_mappings = schema.keys
|
59
|
+
column_names = column_mappings.map { |mapping| schema[mapping]['name']}
|
60
|
+
|
61
|
+
collection_view_page = CollectionViewPage.new(block_id, block_title, block_parent_id, collection_id, view_id)
|
62
|
+
collection_view_page.instance_variable_set(:@column_names, column_names)
|
63
|
+
CollectionView.class_eval{attr_reader :column_names}
|
64
|
+
collection_view_page
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
@@ -229,20 +235,71 @@ module NotionAPI
|
|
229
235
|
# ! parse and clean the URL or ID object provided.
|
230
236
|
# ! url_or_id -> the block ID or URL : ``str``
|
231
237
|
http_or_https = url_or_id.match(/^(http|https)/) # true if http or https in url_or_id...
|
238
|
+
collection_view_match = url_or_id.match(/(\?v=)/)
|
239
|
+
|
232
240
|
if (url_or_id.length == 36) && ((url_or_id.split('-').length == 5) && !http_or_https)
|
233
241
|
# passes if url_or_id is perfectly formatted already...
|
234
242
|
url_or_id
|
235
|
-
elsif (http_or_https && (url_or_id.split('-').last.length == 32)) || (!http_or_https && (url_or_id.length == 32))
|
243
|
+
elsif (http_or_https && (url_or_id.split('-').last.length == 32)) || (!http_or_https && (url_or_id.length == 32)) || (collection_view_match)
|
236
244
|
# passes if either:
|
237
245
|
# 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
|
238
246
|
# 2. a URL is not passed and the ID length is 32 [aka unformatted]
|
239
247
|
pattern = [8, 13, 18, 23]
|
240
|
-
|
241
|
-
|
242
|
-
|
248
|
+
if collection_view_match
|
249
|
+
id_without_view = url_or_id.split('?')[0]
|
250
|
+
clean_id = id_without_view.split('/').last
|
251
|
+
pattern.each { |index| clean_id.insert(index, '-') }
|
252
|
+
clean_id
|
253
|
+
else
|
254
|
+
id = url_or_id.split('-').last
|
255
|
+
pattern.each { |index| id.insert(index, '-') }
|
256
|
+
id
|
257
|
+
end
|
243
258
|
else
|
244
259
|
raise ArgumentError, 'Expected a Notion page URL or a page ID. Please consult the documentation for further information.'
|
245
260
|
end
|
246
261
|
end
|
262
|
+
|
263
|
+
def extract_collection_schema(collection_id, view_id, response = {})
|
264
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
265
|
+
# ! collection_id -> the collection ID : ``str``
|
266
|
+
# ! view_id -> the view ID : ``str``
|
267
|
+
cookies = Core.options['cookies']
|
268
|
+
headers = Core.options['headers']
|
269
|
+
|
270
|
+
if response.empty?
|
271
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
272
|
+
|
273
|
+
request_url = URLS[:GET_COLLECTION]
|
274
|
+
response = HTTParty.post(
|
275
|
+
request_url,
|
276
|
+
body: query_collection_hash.to_json,
|
277
|
+
cookies: cookies,
|
278
|
+
headers: headers
|
279
|
+
)
|
280
|
+
response['recordMap']['collection'][collection_id]['value']['schema']
|
281
|
+
else
|
282
|
+
response['collection'][collection_id]['value']['schema']
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def extract_collection_data(collection_id, view_id)
|
287
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
288
|
+
# ! collection_id -> the collection ID : ``str``
|
289
|
+
# ! view_id -> the view ID : ``str``
|
290
|
+
cookies = Core.options['cookies']
|
291
|
+
headers = Core.options['headers']
|
292
|
+
|
293
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
294
|
+
|
295
|
+
request_url = URLS[:GET_COLLECTION]
|
296
|
+
response = HTTParty.post(
|
297
|
+
request_url,
|
298
|
+
body: query_collection_hash.to_json,
|
299
|
+
cookies: cookies,
|
300
|
+
headers: headers
|
301
|
+
)
|
302
|
+
response['recordMap']
|
303
|
+
end
|
247
304
|
end
|
248
305
|
end
|
@@ -1,243 +1,357 @@
|
|
1
1
|
module NotionAPI
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
2
|
+
# collection views such as tables and timelines.
|
3
|
+
class CollectionView < Core
|
4
|
+
attr_reader :id, :title, :parent_id, :collection_id, :view_id
|
5
|
+
|
6
|
+
@notion_type = "collection_view"
|
7
|
+
@type = "collection_view"
|
8
|
+
|
9
|
+
def type
|
10
|
+
NotionAPI::CollectionView.notion_type
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_reader :notion_type, :type
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(id, title, parent_id, collection_id, view_id)
|
18
|
+
@id = id
|
19
|
+
@title = title
|
20
|
+
@parent_id = parent_id
|
21
|
+
@collection_id = collection_id
|
22
|
+
@view_id = view_id
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_row(data)
|
26
|
+
# ! add new row to Collection View table.
|
27
|
+
# ! data -> data to add to table : ``hash``
|
28
|
+
|
29
|
+
cookies = Core.options["cookies"]
|
30
|
+
headers = Core.options["headers"]
|
31
|
+
|
32
|
+
request_id = extract_id(SecureRandom.hex(16))
|
33
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
34
|
+
space_id = extract_id(SecureRandom.hex(16))
|
35
|
+
new_block_id = extract_id(SecureRandom.hex(16))
|
36
|
+
collection_data = extract_collection_data(collection_id, view_id)
|
37
|
+
last_row_id = collection_data["collection_view"][@view_id]["value"]["page_sort"][-1]
|
38
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
39
|
+
keys = schema.keys
|
40
|
+
col_map = {}
|
41
|
+
keys.map { |key| col_map[schema[key]["name"]] = key }
|
42
|
+
|
43
|
+
request_ids = {
|
44
|
+
request_id: request_id,
|
45
|
+
transaction_id: transaction_id,
|
46
|
+
space_id: space_id,
|
47
|
+
}
|
48
|
+
|
49
|
+
instantiate_row = Utils::CollectionViewComponents.add_new_row(new_block_id)
|
50
|
+
set_block_alive = Utils::CollectionViewComponents.set_collection_blocks_alive(new_block_id, @collection_id)
|
51
|
+
new_block_edited_time = Utils::BlockComponents.last_edited_time(new_block_id)
|
52
|
+
page_sort = Utils::BlockComponents.row_location_add(last_row_id, new_block_id, @view_id)
|
53
|
+
|
54
|
+
operations = [
|
55
|
+
instantiate_row,
|
56
|
+
set_block_alive,
|
57
|
+
new_block_edited_time,
|
58
|
+
page_sort,
|
59
|
+
]
|
60
|
+
|
61
|
+
data.keys.each_with_index do |col_name, j|
|
62
|
+
unless col_map.keys.include?(col_name.to_s); raise ArgumentError, "Column '#{col_name.to_s}' does not exist." end
|
63
|
+
if %q[select multi_select].include?(schema[col_map[col_name.to_s]]["type"])
|
64
|
+
options = schema[col_map[col_name.to_s]]["options"].nil? ? [] : schema[col_map[col_name.to_s]]["options"].map { |option| option["value"] }
|
65
|
+
multi_select_multi_options = data[col_name].split(",")
|
66
|
+
multi_select_multi_options.each do |option|
|
67
|
+
if !options.include?(option.strip)
|
68
|
+
create_new_option = Utils::CollectionViewComponents.add_new_option(col_map[col_name.to_s], option.strip, @collection_id)
|
69
|
+
operations.push(create_new_option)
|
70
|
+
end
|
71
|
+
end
|
62
72
|
end
|
63
|
-
|
64
|
-
|
65
|
-
request_body = build_payload(operations, request_ids)
|
66
|
-
response = HTTParty.post(
|
67
|
-
request_url,
|
68
|
-
body: request_body.to_json,
|
69
|
-
cookies: cookies,
|
70
|
-
headers: headers
|
71
|
-
)
|
72
|
-
|
73
|
-
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
74
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
75
|
-
|
76
|
-
NotionAPI::CollectionViewRow.new(new_block_id, @parent_id, @collection_id, @view_id)
|
73
|
+
child_component = Utils::CollectionViewComponents.insert_data(new_block_id, col_map[col_name.to_s], data[col_name], schema[col_map[col_name.to_s]]["type"])
|
74
|
+
operations.push(child_component)
|
77
75
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
# create updated schema
|
97
|
-
schema = extract_collection_schema(@collection_id, @view_id)
|
98
|
-
schema[name] = {
|
99
|
-
name: name,
|
100
|
-
type: type
|
101
|
-
}
|
102
|
-
new_schema = {
|
103
|
-
schema: schema
|
104
|
-
}
|
105
|
-
|
106
|
-
add_collection_property = Utils::CollectionViewComponents.add_collection_property(@collection_id, new_schema)
|
107
|
-
|
108
|
-
operations = [
|
109
|
-
add_collection_property
|
110
|
-
]
|
111
|
-
|
112
|
-
request_url = URLS[:UPDATE_BLOCK]
|
113
|
-
request_body = build_payload(operations, request_ids)
|
114
|
-
response = HTTParty.post(
|
115
|
-
request_url,
|
116
|
-
body: request_body.to_json,
|
117
|
-
cookies: cookies,
|
118
|
-
headers: headers
|
119
|
-
)
|
120
|
-
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
121
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
122
|
-
|
123
|
-
true
|
76
|
+
|
77
|
+
request_url = URLS[:UPDATE_BLOCK]
|
78
|
+
request_body = build_payload(operations, request_ids)
|
79
|
+
response = HTTParty.post(
|
80
|
+
request_url,
|
81
|
+
body: request_body.to_json,
|
82
|
+
cookies: cookies,
|
83
|
+
headers: headers,
|
84
|
+
)
|
85
|
+
|
86
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
87
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
88
|
+
|
89
|
+
collection_row = NotionAPI::CollectionViewRow.new(new_block_id, @parent_id, @collection_id, @view_id)
|
90
|
+
|
91
|
+
properties = {}
|
92
|
+
data.keys.each do |col|
|
93
|
+
properties[col_map[col.to_s]] = [[data[col]]]
|
124
94
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
95
|
+
|
96
|
+
collection_data["block"][collection_row.id] = {"role"=>"editor", "value"=>{"id"=> collection_row.id, "version"=>12, "type"=>"page", "properties"=> properties, "created_time"=>1607253360000, "last_edited_time"=>1607253360000, "parent_id"=>"dde513c6-2428-4a5d-a830-7a67fdbf6b48", "parent_table"=>"collection", "alive"=>true, "created_by_table"=>"notion_user", "created_by_id"=>"0c5f02f3-495d-4b73-b1c5-9f6fe03a8c26", "last_edited_by_table"=>"notion_user", "last_edited_by_id"=>"0c5f02f3-495d-4b73-b1c5-9f6fe03a8c26", "shard_id"=>955090, "space_id"=>"f687f7de-7f4c-4a86-b109-941a8dae92d2"}}
|
97
|
+
row_data = collection_data["block"][collection_row.id]
|
98
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
99
|
+
|
100
|
+
collection_row
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_property(name, type)
|
104
|
+
# ! add a property (column) to the table.
|
105
|
+
# ! name -> name of the property : ``str``
|
106
|
+
# ! type -> type of the property : ``str``
|
107
|
+
cookies = Core.options["cookies"]
|
108
|
+
headers = Core.options["headers"]
|
109
|
+
|
110
|
+
request_id = extract_id(SecureRandom.hex(16))
|
111
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
112
|
+
space_id = extract_id(SecureRandom.hex(16))
|
113
|
+
|
114
|
+
request_ids = {
|
115
|
+
request_id: request_id,
|
116
|
+
transaction_id: transaction_id,
|
117
|
+
space_id: space_id,
|
118
|
+
}
|
119
|
+
|
120
|
+
# create updated schema
|
121
|
+
schema = extract_collection_schema(@collection_id, @view_id)
|
122
|
+
schema[name] = {
|
123
|
+
name: name,
|
124
|
+
type: type,
|
125
|
+
}
|
126
|
+
new_schema = {
|
127
|
+
schema: schema,
|
128
|
+
}
|
129
|
+
|
130
|
+
add_collection_property = Utils::CollectionViewComponents.add_collection_property(@collection_id, new_schema)
|
131
|
+
|
132
|
+
operations = [
|
133
|
+
add_collection_property,
|
134
|
+
]
|
135
|
+
|
136
|
+
request_url = URLS[:UPDATE_BLOCK]
|
137
|
+
request_body = build_payload(operations, request_ids)
|
138
|
+
response = HTTParty.post(
|
139
|
+
request_url,
|
140
|
+
body: request_body.to_json,
|
141
|
+
cookies: cookies,
|
142
|
+
headers: headers,
|
143
|
+
)
|
144
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
145
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
146
|
+
|
147
|
+
true
|
148
|
+
end
|
149
|
+
|
150
|
+
def row(row_id)
|
151
|
+
# ! retrieve a row from a CollectionView Table.
|
152
|
+
# ! row_id -> the ID for the row to retrieve: ``str``
|
153
|
+
clean_id = extract_id(row_id)
|
154
|
+
|
155
|
+
request_body = {
|
156
|
+
pageId: clean_id,
|
157
|
+
chunkNumber: 0,
|
158
|
+
limit: 100,
|
159
|
+
verticalColumns: false,
|
160
|
+
}
|
161
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
162
|
+
|
163
|
+
i = 0
|
164
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
165
|
+
return {} if i >= 10
|
166
|
+
|
137
167
|
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
138
|
-
|
139
|
-
keys = schema.keys
|
140
|
-
column_names = keys.map { |key| schema[key]['name'] }
|
141
|
-
i = 0
|
142
|
-
while jsonified_record_response.empty? || jsonified_record_response['block'].empty?
|
143
|
-
return {} if i >= 10
|
144
|
-
|
145
|
-
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
146
|
-
i += 1
|
147
|
-
end
|
148
|
-
row_jsonified_response = jsonified_record_response['block'][clean_id]['value']['properties']
|
149
|
-
row_data = {}
|
150
|
-
keys.each_with_index { |key, idx| row_data[column_names[idx]] = row_jsonified_response[key] ? row_jsonified_response[key].flatten : [] }
|
151
|
-
row_data
|
168
|
+
i += 1
|
152
169
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
170
|
+
|
171
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
172
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
173
|
+
column_mappings = schema.keys
|
174
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
175
|
+
|
176
|
+
collection_row = CollectionViewRow.new(row_id, @parent_id, @collection_id, @view_id)
|
177
|
+
collection_row.instance_variable_set(:@column_names, column_names)
|
178
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
179
|
+
|
180
|
+
row_data = collection_data["block"][collection_row.id]
|
181
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
182
|
+
|
183
|
+
collection_row
|
184
|
+
end
|
185
|
+
|
186
|
+
def row_ids
|
187
|
+
# ! retrieve all Collection View table rows.
|
188
|
+
clean_id = extract_id(@id)
|
189
|
+
|
190
|
+
request_body = {
|
191
|
+
pageId: clean_id,
|
192
|
+
chunkNumber: 0,
|
193
|
+
limit: 100,
|
194
|
+
verticalColumns: false,
|
195
|
+
}
|
196
|
+
|
197
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
198
|
+
i = 0
|
199
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
200
|
+
return {} if i >= 10
|
201
|
+
|
165
202
|
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
166
|
-
i
|
167
|
-
while jsonified_record_response.empty? || jsonified_record_response['block'].empty?
|
168
|
-
return {} if i >= 10
|
169
|
-
|
170
|
-
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
171
|
-
i += 1
|
172
|
-
end
|
173
|
-
|
174
|
-
jsonified_record_response['collection_view'][@view_id]['value']['page_sort']
|
175
|
-
end
|
176
|
-
|
177
|
-
def rows
|
178
|
-
# ! returns all rows as instantiated class instances.
|
179
|
-
row_id_array = row_ids
|
180
|
-
parent_id = @parent_id
|
181
|
-
collection_id = @collection_id
|
182
|
-
view_id = @view_id
|
183
|
-
|
184
|
-
row_id_array.map { |row_id| NotionAPI::CollectionViewRow.new(row_id, parent_id, collection_id, view_id) }
|
185
|
-
end
|
186
|
-
|
187
|
-
private
|
188
|
-
|
189
|
-
def extract_collection_schema(collection_id, view_id)
|
190
|
-
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
191
|
-
# ! collection_id -> the collection ID : ``str``
|
192
|
-
# ! view_id -> the view ID : ``str``
|
193
|
-
cookies = Core.options['cookies']
|
194
|
-
headers = Core.options['headers']
|
195
|
-
|
196
|
-
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
197
|
-
|
198
|
-
request_url = URLS[:GET_COLLECTION]
|
199
|
-
response = HTTParty.post(
|
200
|
-
request_url,
|
201
|
-
body: query_collection_hash.to_json,
|
202
|
-
cookies: cookies,
|
203
|
-
headers: headers
|
204
|
-
)
|
205
|
-
response['recordMap']['collection'][collection_id]['value']['schema']
|
203
|
+
i += 1
|
206
204
|
end
|
205
|
+
|
206
|
+
jsonified_record_response["collection_view"][@view_id]["value"]["page_sort"]
|
207
207
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
208
|
+
|
209
|
+
def rows
|
210
|
+
# ! returns all rows as instantiated class instances.
|
211
|
+
row_id_array = row_ids
|
212
|
+
parent_id = @parent_id
|
213
|
+
collection_id = @collection_id
|
214
|
+
view_id = @view_id
|
215
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
216
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
217
|
+
column_mappings = schema.keys
|
218
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
219
|
+
|
220
|
+
row_instances = row_id_array.map { |row_id| NotionAPI::CollectionViewRow.new(row_id, parent_id, collection_id, view_id) }
|
221
|
+
clean_row_instances = row_instances.filter { |row| collection_data["block"][row.id] }
|
222
|
+
clean_row_instances.each { |row| row.instance_variable_set(:@column_names, column_names) }
|
223
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
224
|
+
|
225
|
+
clean_row_instances.each do |collection_row|
|
226
|
+
row_data = collection_data["block"][collection_row.id]
|
227
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
226
228
|
end
|
229
|
+
clean_row_instances
|
227
230
|
end
|
228
231
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
232
|
+
def create_singleton_methods_and_instance_variables(row, row_data)
|
233
|
+
# ! creates singleton methods for each property in a CollectionView.
|
234
|
+
# ! row -> the block ID of the 'row' to retrieve: ``str``
|
235
|
+
# ! row_data -> the data corresponding to that row, should be key-value pairs where the keys are the columns: ``hash``
|
236
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
237
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
238
|
+
column_mappings = schema.keys
|
239
|
+
column_hash = {}
|
240
|
+
column_names = column_mappings.map { |mapping| column_hash[mapping] = schema[mapping]["name"].downcase }
|
241
|
+
|
242
|
+
column_hash.keys.each_with_index do |column, i|
|
243
|
+
# loop over the column names...
|
244
|
+
# set instance variables for each column, allowing the dev to 'read' the column value
|
245
|
+
cleaned_column = column_hash[column].split(" ").join("_").downcase.to_sym
|
246
|
+
|
247
|
+
# p row_data["value"]["properties"][column_mappings[i]], !(row_data["value"]["properties"][column] or row_data["value"]["properties"][column_mappings[i]])
|
248
|
+
if row_data["value"]["properties"].nil? or row_data["value"]["properties"][column].nil?
|
249
|
+
value = ""
|
250
|
+
else
|
251
|
+
value = row_data["value"]["properties"][column][0][0]
|
252
|
+
if ["‣"].include?(value.to_s)
|
253
|
+
value = row_data["value"]["properties"][column][0][1].flatten[-1]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
row.instance_variable_set("@#{cleaned_column}", value)
|
258
|
+
CollectionViewRow.class_eval { attr_reader cleaned_column }
|
259
|
+
# then, define singleton methods for each column that are used to update the table cell
|
260
|
+
row.define_singleton_method("#{cleaned_column}=") do |new_value|
|
261
|
+
# neat way to get the name of the currently invoked method...
|
262
|
+
parsed_method = __method__.to_s[0...-1].split("_").join(" ")
|
263
|
+
cookies = Core.options["cookies"]
|
264
|
+
headers = Core.options["headers"]
|
265
|
+
|
266
|
+
p new_value, column_hash.key(parsed_method), column_names, schema
|
267
|
+
|
268
|
+
request_id = extract_id(SecureRandom.hex(16))
|
269
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
270
|
+
space_id = extract_id(SecureRandom.hex(16))
|
271
|
+
|
272
|
+
request_ids = {
|
273
|
+
request_id: request_id,
|
274
|
+
transaction_id: transaction_id,
|
275
|
+
space_id: space_id,
|
276
|
+
}
|
277
|
+
|
278
|
+
update_property_value_hash = Utils::CollectionViewComponents.update_property_value(@id, column_hash.key(parsed_method), new_value)
|
279
|
+
|
280
|
+
operations = [
|
281
|
+
update_property_value_hash,
|
282
|
+
]
|
283
|
+
|
284
|
+
if %q[select multi_select].include?(schema[column_hash.key(parsed_method)]["type"])
|
285
|
+
p "ENTERED THE ABYSS"
|
286
|
+
options = schema[column_hash.key(parsed_method)]["options"].nil? ? [] : schema[column_hash.key(parsed_method)]["options"].map { |option| option["value"] }
|
287
|
+
multi_select_multi_options = new_value.split(",")
|
288
|
+
multi_select_multi_options.each do |option|
|
289
|
+
if !options.include?(option.strip)
|
290
|
+
create_new_option = Utils::CollectionViewComponents.add_new_option(column_hash.key(parsed_method), option.strip, @collection_id)
|
291
|
+
operations.push(create_new_option)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
request_url = URLS[:UPDATE_BLOCK]
|
297
|
+
request_body = build_payload(operations, request_ids)
|
298
|
+
response = HTTParty.post(
|
299
|
+
request_url,
|
300
|
+
body: request_body.to_json,
|
301
|
+
cookies: cookies,
|
302
|
+
headers: headers,
|
303
|
+
)
|
304
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
305
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
306
|
+
|
307
|
+
# set the instance variable to the updated value!
|
308
|
+
_ = row.instance_variable_set("@#{__method__.to_s[0...-1]}", new_value)
|
309
|
+
row
|
310
|
+
end
|
239
311
|
end
|
240
|
-
|
241
|
-
attr_reader :parent_id, :id
|
242
312
|
end
|
243
|
-
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# class that represents each row in a CollectionView
|
316
|
+
class CollectionViewRow < Core
|
317
|
+
@notion_type = "table_row"
|
318
|
+
@type = "table_row"
|
319
|
+
|
320
|
+
def type
|
321
|
+
NotionAPI::CollectionViewRow.notion_type
|
322
|
+
end
|
323
|
+
|
324
|
+
def inspect
|
325
|
+
"CollectionViewRow - id: #{self.id} - parent id: #{self.parent_id}"
|
326
|
+
end
|
327
|
+
|
328
|
+
class << self
|
329
|
+
attr_reader :notion_type, :type, :parent_id
|
330
|
+
end
|
331
|
+
|
332
|
+
attr_reader :parent_id, :id
|
333
|
+
|
334
|
+
def initialize(id, parent_id, collection_id, view_id)
|
335
|
+
@id = id
|
336
|
+
@parent_id = parent_id
|
337
|
+
@collection_id = collection_id
|
338
|
+
@view_id = view_id
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# class that represents a CollectionViewPage, inheriting all properties from CollectionView
|
343
|
+
class CollectionViewPage < CollectionView
|
344
|
+
@notion_type = "collection_view_page"
|
345
|
+
@type = "collection_view_page"
|
346
|
+
|
347
|
+
def type
|
348
|
+
NotionAPI::CollectionViewRow.notion_type
|
349
|
+
end
|
350
|
+
|
351
|
+
class << self
|
352
|
+
attr_reader :notion_type, :type, :parent_id
|
353
|
+
end
|
354
|
+
|
355
|
+
attr_reader :parent_id, :id
|
356
|
+
end
|
357
|
+
end
|
@@ -304,7 +304,15 @@ module NotionAPI
|
|
304
304
|
block_collection_id = extract_collection_id(clean_id, jsonified_record_response)
|
305
305
|
block_view_id = extract_view_ids(clean_id, jsonified_record_response)
|
306
306
|
collection_title = extract_collection_title(clean_id, block_collection_id, jsonified_record_response)
|
307
|
-
|
307
|
+
|
308
|
+
block = block_class.new(clean_id, collection_title, block_parent_id, block_collection_id, block_view_id.join)
|
309
|
+
schema = extract_collection_schema(block_collection_id, block_view_id[0])
|
310
|
+
column_mappings = schema.keys
|
311
|
+
column_names = column_mappings.map { |mapping| schema[mapping]['name']}
|
312
|
+
block.instance_variable_set(:@column_names, column_names)
|
313
|
+
CollectionView.class_eval{attr_reader :column_names}
|
314
|
+
|
315
|
+
block
|
308
316
|
else
|
309
317
|
block_title = extract_title(clean_id, jsonified_record_response)
|
310
318
|
block_class.new(clean_id, block_title, block_parent_id)
|
data/lib/notion_api/utils.rb
CHANGED
@@ -200,14 +200,14 @@ module Utils
|
|
200
200
|
|
201
201
|
args = if command == "listAfter"
|
202
202
|
{
|
203
|
-
|
204
|
-
|
205
|
-
|
203
|
+
after: target || block_id,
|
204
|
+
id: new_block_id || block_id,
|
205
|
+
}
|
206
206
|
else
|
207
207
|
{
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
before: target || block_id,
|
209
|
+
id: new_block_id || block_id,
|
210
|
+
}
|
211
211
|
end
|
212
212
|
|
213
213
|
{
|
@@ -219,6 +219,21 @@ module Utils
|
|
219
219
|
}
|
220
220
|
end
|
221
221
|
|
222
|
+
def self.row_location_add(last_row_id, block_id, view_id)
|
223
|
+
{
|
224
|
+
"table": "collection_view",
|
225
|
+
"id": view_id,
|
226
|
+
"path": [
|
227
|
+
"page_sort"
|
228
|
+
],
|
229
|
+
"command": "listAfter",
|
230
|
+
"args": {
|
231
|
+
"after": last_row_id,
|
232
|
+
"id": block_id
|
233
|
+
}
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
222
237
|
def self.block_location_remove(block_parent_id, block_id)
|
223
238
|
# ! removes a notion block
|
224
239
|
# ! block_parent_id -> the parent ID of the block to remove : ``str``
|
@@ -276,9 +291,9 @@ module Utils
|
|
276
291
|
def self.add_emoji_icon(block_id, icon)
|
277
292
|
{
|
278
293
|
id: block_id,
|
279
|
-
table:"block",
|
280
|
-
path:["format","page_icon"],
|
281
|
-
command:"set","args": icon
|
294
|
+
table: "block",
|
295
|
+
path: ["format", "page_icon"],
|
296
|
+
command: "set", "args": icon,
|
282
297
|
}
|
283
298
|
end
|
284
299
|
end
|
@@ -383,14 +398,14 @@ module Utils
|
|
383
398
|
# ! new_block_id -> id of the new block
|
384
399
|
# ! data -> json data to insert into table.
|
385
400
|
col_names = data[0].keys
|
386
|
-
data_mappings = {Integer => "number", String => "text", Array => "text", Float => "number", Date => "date"}
|
401
|
+
data_mappings = { Integer => "number", String => "text", Array => "text", Float => "number", Date => "date" }
|
387
402
|
exceptions = [ArgumentError, TypeError]
|
388
403
|
data_types = col_names.map do |name|
|
389
404
|
# TODO: this is a little hacky... should probably think about a better way or add a requirement for user input to match a certain criteria.
|
390
|
-
begin
|
405
|
+
begin
|
391
406
|
DateTime.parse(data[0][name]) ? data_mappings[Date] : nil
|
392
407
|
rescue *exceptions
|
393
|
-
data_mappings[data[0][name].class]
|
408
|
+
data_mappings[data[0][name].class]
|
394
409
|
end
|
395
410
|
end
|
396
411
|
|
@@ -403,18 +418,18 @@ module Utils
|
|
403
418
|
end
|
404
419
|
end
|
405
420
|
return {
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
421
|
+
id: collection_id,
|
422
|
+
table: "collection",
|
423
|
+
path: [],
|
424
|
+
command: "update",
|
425
|
+
args: {
|
426
|
+
id: collection_id,
|
427
|
+
schema: schema_conf,
|
428
|
+
parent_id: new_block_id,
|
429
|
+
parent_table: "block",
|
430
|
+
alive: true,
|
431
|
+
},
|
432
|
+
}, data_types
|
418
433
|
end
|
419
434
|
|
420
435
|
def self.set_collection_title(collection_title, collection_id)
|
@@ -440,6 +455,11 @@ module Utils
|
|
440
455
|
# ! column -> the name of the column to insert data into.
|
441
456
|
# ! value -> the value to insert into the column.
|
442
457
|
# ! mapping -> the column data type.
|
458
|
+
simple_mappings = ["title", "text", "phone_number", "email", "url", "number", "checkbox", "select", "multi_select"]
|
459
|
+
datetime_mappings = ["date"]
|
460
|
+
media_mappings = ["file"]
|
461
|
+
person_mappings = ["person"]
|
462
|
+
|
443
463
|
table = "block"
|
444
464
|
path = [
|
445
465
|
"properties",
|
@@ -447,12 +467,50 @@ module Utils
|
|
447
467
|
]
|
448
468
|
command = "set"
|
449
469
|
|
470
|
+
if simple_mappings.include?(mapping)
|
471
|
+
args = [[value]]
|
472
|
+
elsif media_mappings.include?(mapping)
|
473
|
+
args = [[value, [["a", value]]]]
|
474
|
+
elsif datetime_mappings.include?(mapping)
|
475
|
+
args = [["‣", [["d", { "type": "date", "start_date": value }]]]]
|
476
|
+
elsif person_mappings.include?(mapping)
|
477
|
+
args = [["‣",
|
478
|
+
[["u", value]]
|
479
|
+
]]
|
480
|
+
else
|
481
|
+
raise SchemaTypeError, "Invalid property type: #{mapping}"
|
482
|
+
end
|
483
|
+
|
450
484
|
{
|
451
|
-
id: block_id,
|
452
485
|
table: table,
|
486
|
+
id: block_id,
|
487
|
+
command: command,
|
453
488
|
path: path,
|
489
|
+
args: args,
|
490
|
+
}
|
491
|
+
end
|
492
|
+
|
493
|
+
def self.add_new_option(column, value, collection_id)
|
494
|
+
table = "collection"
|
495
|
+
path = ["schema", column, "options"]
|
496
|
+
command = "keyedObjectListAfter"
|
497
|
+
colors = ["default", "gray", "brown", "orange", "yellow", "green", "blue", "purple", "pink", "red"]
|
498
|
+
random_color = colors[rand(0...colors.length)]
|
499
|
+
|
500
|
+
args = {
|
501
|
+
"value": {
|
502
|
+
"id": SecureRandom.hex(16),
|
503
|
+
"value": value,
|
504
|
+
"color": random_color
|
505
|
+
}
|
506
|
+
}
|
507
|
+
|
508
|
+
{
|
509
|
+
table: table,
|
510
|
+
id: collection_id,
|
454
511
|
command: command,
|
455
|
-
|
512
|
+
path: path,
|
513
|
+
args: args,
|
456
514
|
}
|
457
515
|
end
|
458
516
|
|
@@ -505,45 +563,45 @@ module Utils
|
|
505
563
|
args["format"] = {
|
506
564
|
"table_properties" => [
|
507
565
|
{
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
566
|
+
"property" => "title",
|
567
|
+
"visible" => true,
|
568
|
+
"width" => 280,
|
569
|
+
},
|
512
570
|
{
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
571
|
+
"property" => "aliases",
|
572
|
+
"visible" => true,
|
573
|
+
"width" => 200,
|
574
|
+
},
|
517
575
|
{
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
576
|
+
"property" => "category",
|
577
|
+
"visible" => true,
|
578
|
+
"width" => 200,
|
579
|
+
},
|
522
580
|
{
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
581
|
+
"property" => "description",
|
582
|
+
"visible" => true,
|
583
|
+
"width" => 200,
|
584
|
+
},
|
527
585
|
{
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
586
|
+
"property" => "ios_version",
|
587
|
+
"visible" => true,
|
588
|
+
"width" => 200,
|
589
|
+
},
|
590
|
+
{
|
591
|
+
"property" => "tags",
|
592
|
+
"visible" => true,
|
593
|
+
"width" => 200,
|
594
|
+
},
|
532
595
|
{
|
533
|
-
"property" => "tags",
|
534
|
-
"visible" => true,
|
535
|
-
"width" => 200,
|
536
|
-
},
|
537
|
-
{
|
538
596
|
"property" => "phone",
|
539
597
|
"visible" => true,
|
540
598
|
"width" => 200,
|
541
599
|
},
|
542
600
|
{
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
601
|
+
"property" => "unicode_version",
|
602
|
+
"visible" => true,
|
603
|
+
"width" => 200,
|
604
|
+
},
|
547
605
|
],
|
548
606
|
}
|
549
607
|
{
|
@@ -554,6 +612,37 @@ module Utils
|
|
554
612
|
args: args,
|
555
613
|
}
|
556
614
|
end
|
615
|
+
|
616
|
+
def self.update_property_value(page_id, column_name, new_value)
|
617
|
+
# ! update the specified column_name to new_value
|
618
|
+
# ! page_id -> the ID of the page: ``str``
|
619
|
+
# ! column_name -> the name of the column ["property"] to update: ``str``
|
620
|
+
# ! new_value -> the new value to assign to that column ["property"]: ``str``
|
621
|
+
table = "block"
|
622
|
+
path = [
|
623
|
+
"properties",
|
624
|
+
column_name,
|
625
|
+
]
|
626
|
+
command = "set"
|
627
|
+
args = [[
|
628
|
+
new_value,
|
629
|
+
]]
|
630
|
+
|
631
|
+
{
|
632
|
+
id: page_id,
|
633
|
+
table: table,
|
634
|
+
path: path,
|
635
|
+
command: command,
|
636
|
+
args: args,
|
637
|
+
}
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
class SchemaTypeError < StandardError
|
642
|
+
def initialize(msg="Custom exception that is raised when an invalid property type is passed as a mapping.", exception_type="schema_type")
|
643
|
+
@exception_type = exception_type
|
644
|
+
super(msg)
|
645
|
+
end
|
557
646
|
end
|
558
647
|
|
559
648
|
def build_payload(operations, request_ids)
|
@@ -576,4 +665,4 @@ module Utils
|
|
576
665
|
}
|
577
666
|
payload
|
578
667
|
end
|
579
|
-
end
|
668
|
+
end
|
data/lib/notion_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Murphy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|