notion 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -13
- data/lib/notion_api/core.rb +50 -2
- data/lib/notion_api/notion_types/collection_view_blocks.rb +303 -231
- data/lib/notion_api/notion_types/template.rb +9 -1
- data/lib/notion_api/utils.rb +24 -0
- 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: 529d9a75b50731156f263184b27628a2ee6b0b0cd798e3f3b44e5ea3f7106c60
|
4
|
+
data.tar.gz: eb5b69ebe9b9d34215d6da17e8c2999761e9242b2618afaaa6583ee09691c65d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09ec6f516f22fac9f2b9c7c2efc3df164f83a745414cb18f092a6df939625435a77883712b86e100d7062536b189ddd8115145a52528cd5cc81767029f3bd250'
|
7
|
+
data.tar.gz: b643a46d9682d2ebb612c0d0c37454344f0f9abb580c1cf258887bc7a242afdc22af155c78b87434a00c38a048b206351ad453477d5c914393b1ff4ac68aeb97
|
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,9 @@ 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
|
+
Currently, either a "normal" Page URL or the Page Block ID is accepted to the `get_page` method. Therefore, if you pass the full URL to the CV Table, it will raise an error:
|
314
|
+
```text
|
315
|
+
the URL or ID passed to the get_page method must be that of a Page Block.
|
316
|
+
```
|
317
|
+
To avoid this, you must pass only the ID of the full-page collection-view to the `get_page` method. This is next up on the features list, so passing the full URL will be supported soon:smile:
|
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
|
|
@@ -244,5 +250,47 @@ module NotionAPI
|
|
244
250
|
raise ArgumentError, 'Expected a Notion page URL or a page ID. Please consult the documentation for further information.'
|
245
251
|
end
|
246
252
|
end
|
253
|
+
|
254
|
+
def extract_collection_schema(collection_id, view_id, response = {})
|
255
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
256
|
+
# ! collection_id -> the collection ID : ``str``
|
257
|
+
# ! view_id -> the view ID : ``str``
|
258
|
+
cookies = Core.options['cookies']
|
259
|
+
headers = Core.options['headers']
|
260
|
+
|
261
|
+
if response.empty?
|
262
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
263
|
+
|
264
|
+
request_url = URLS[:GET_COLLECTION]
|
265
|
+
response = HTTParty.post(
|
266
|
+
request_url,
|
267
|
+
body: query_collection_hash.to_json,
|
268
|
+
cookies: cookies,
|
269
|
+
headers: headers
|
270
|
+
)
|
271
|
+
response['recordMap']['collection'][collection_id]['value']['schema']
|
272
|
+
else
|
273
|
+
response['collection'][collection_id]['value']['schema']
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def extract_collection_data(collection_id, view_id)
|
278
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
279
|
+
# ! collection_id -> the collection ID : ``str``
|
280
|
+
# ! view_id -> the view ID : ``str``
|
281
|
+
cookies = Core.options['cookies']
|
282
|
+
headers = Core.options['headers']
|
283
|
+
|
284
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
285
|
+
|
286
|
+
request_url = URLS[:GET_COLLECTION]
|
287
|
+
response = HTTParty.post(
|
288
|
+
request_url,
|
289
|
+
body: query_collection_hash.to_json,
|
290
|
+
cookies: cookies,
|
291
|
+
headers: headers
|
292
|
+
)
|
293
|
+
response['recordMap']
|
294
|
+
end
|
247
295
|
end
|
248
296
|
end
|
@@ -1,243 +1,315 @@
|
|
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
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
request_url = URLS[:UPDATE_BLOCK]
|
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)
|
77
|
-
end
|
78
|
-
|
79
|
-
def add_property(name, type)
|
80
|
-
# ! add a property (column) to the table.
|
81
|
-
# ! name -> name of the property : ``str``
|
82
|
-
# ! type -> type of the property : ``str``
|
83
|
-
cookies = Core.options['cookies']
|
84
|
-
headers = Core.options['headers']
|
85
|
-
|
86
|
-
request_id = extract_id(SecureRandom.hex(16))
|
87
|
-
transaction_id = extract_id(SecureRandom.hex(16))
|
88
|
-
space_id = extract_id(SecureRandom.hex(16))
|
89
|
-
|
90
|
-
request_ids = {
|
91
|
-
request_id: request_id,
|
92
|
-
transaction_id: transaction_id,
|
93
|
-
space_id: space_id
|
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
|
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
|
+
schema = extract_collection_schema(@collection_id, @view_id)
|
37
|
+
keys = schema.keys
|
38
|
+
col_map = {}
|
39
|
+
keys.map { |key| col_map[schema[key]["name"]] = key }
|
40
|
+
|
41
|
+
request_ids = {
|
42
|
+
request_id: request_id,
|
43
|
+
transaction_id: transaction_id,
|
44
|
+
space_id: space_id,
|
45
|
+
}
|
46
|
+
|
47
|
+
instantiate_row = Utils::CollectionViewComponents.add_new_row(new_block_id)
|
48
|
+
set_block_alive = Utils::CollectionViewComponents.set_collection_blocks_alive(new_block_id, @collection_id)
|
49
|
+
new_block_edited_time = Utils::BlockComponents.last_edited_time(new_block_id)
|
50
|
+
parent_edited_time = Utils::BlockComponents.last_edited_time(@parent_id)
|
51
|
+
|
52
|
+
operations = [
|
53
|
+
instantiate_row,
|
54
|
+
set_block_alive,
|
55
|
+
new_block_edited_time,
|
56
|
+
parent_edited_time,
|
57
|
+
]
|
58
|
+
|
59
|
+
data.keys.each_with_index do |col_name, j|
|
60
|
+
child_component = Utils::CollectionViewComponents.insert_data(new_block_id, j.zero? ? "title" : col_map[col_name], data[col_name], j.zero? ? schema["title"]["type"] : schema[col_map[col_name]]["type"])
|
61
|
+
operations.push(child_component)
|
124
62
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
63
|
+
|
64
|
+
request_url = URLS[:UPDATE_BLOCK]
|
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)
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_property(name, type)
|
80
|
+
# ! add a property (column) to the table.
|
81
|
+
# ! name -> name of the property : ``str``
|
82
|
+
# ! type -> type of the property : ``str``
|
83
|
+
cookies = Core.options["cookies"]
|
84
|
+
headers = Core.options["headers"]
|
85
|
+
|
86
|
+
request_id = extract_id(SecureRandom.hex(16))
|
87
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
88
|
+
space_id = extract_id(SecureRandom.hex(16))
|
89
|
+
|
90
|
+
request_ids = {
|
91
|
+
request_id: request_id,
|
92
|
+
transaction_id: transaction_id,
|
93
|
+
space_id: space_id,
|
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
|
124
|
+
end
|
125
|
+
|
126
|
+
def row(row_id)
|
127
|
+
# ! retrieve a row from a CollectionView Table.
|
128
|
+
# ! row_id -> the ID for the row to retrieve: ``str``
|
129
|
+
clean_id = extract_id(row_id)
|
130
|
+
|
131
|
+
request_body = {
|
132
|
+
pageId: clean_id,
|
133
|
+
chunkNumber: 0,
|
134
|
+
limit: 100,
|
135
|
+
verticalColumns: false,
|
136
|
+
}
|
137
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
138
|
+
|
139
|
+
i = 0
|
140
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
141
|
+
return {} if i >= 10
|
142
|
+
|
137
143
|
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
|
144
|
+
i += 1
|
152
145
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
146
|
+
|
147
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
148
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
149
|
+
column_mappings = schema.keys
|
150
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
151
|
+
|
152
|
+
collection_row = CollectionViewRow.new(row_id, @parent_id, @collection_id, @view_id)
|
153
|
+
collection_row.instance_variable_set(:@column_names, column_names)
|
154
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
155
|
+
|
156
|
+
row_data = collection_data["block"][collection_row.id]
|
157
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
158
|
+
|
159
|
+
collection_row
|
160
|
+
end
|
161
|
+
|
162
|
+
def row_ids
|
163
|
+
# ! retrieve all Collection View table rows.
|
164
|
+
clean_id = extract_id(@id)
|
165
|
+
|
166
|
+
request_body = {
|
167
|
+
pageId: clean_id,
|
168
|
+
chunkNumber: 0,
|
169
|
+
limit: 100,
|
170
|
+
verticalColumns: false,
|
171
|
+
}
|
172
|
+
|
173
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
174
|
+
i = 0
|
175
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
176
|
+
return {} if i >= 10
|
177
|
+
|
165
178
|
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']
|
179
|
+
i += 1
|
206
180
|
end
|
181
|
+
|
182
|
+
jsonified_record_response["collection_view"][@view_id]["value"]["page_sort"]
|
207
183
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
184
|
+
|
185
|
+
def rows
|
186
|
+
# ! returns all rows as instantiated class instances.
|
187
|
+
row_id_array = row_ids
|
188
|
+
parent_id = @parent_id
|
189
|
+
collection_id = @collection_id
|
190
|
+
view_id = @view_id
|
191
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
192
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
193
|
+
column_mappings = schema.keys
|
194
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
195
|
+
|
196
|
+
row_instances = row_id_array.map { |row_id| NotionAPI::CollectionViewRow.new(row_id, parent_id, collection_id, view_id) }
|
197
|
+
clean_row_instances = row_instances.filter { |row| collection_data["block"][row.id] }
|
198
|
+
clean_row_instances.each { |row| row.instance_variable_set(:@column_names, column_names) }
|
199
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
200
|
+
|
201
|
+
clean_row_instances.each do |collection_row|
|
202
|
+
row_data = collection_data["block"][collection_row.id]
|
203
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
226
204
|
end
|
205
|
+
clean_row_instances
|
227
206
|
end
|
207
|
+
def create_singleton_methods_and_instance_variables(row, row_data)
|
208
|
+
# ! creates singleton methods for each property in a CollectionView.
|
209
|
+
# ! row -> the block ID of the 'row' to retrieve: ``str``
|
210
|
+
# ! row_data -> the data corresponding to that row, should be key-value pairs where the keys are the columns: ``hash``
|
211
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
212
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
213
|
+
column_mappings = schema.keys
|
214
|
+
column_hash = {}
|
215
|
+
column_names = column_mappings.map { |mapping| column_hash[mapping] = schema[mapping]["name"].downcase }
|
216
|
+
|
217
|
+
column_hash.keys.each_with_index do |column, i|
|
218
|
+
# loop over the column names...
|
219
|
+
# set instance variables for each column, allowing the dev to 'read' the column value
|
220
|
+
cleaned_column = column_hash[column].split(" ").join("_").downcase.to_sym
|
228
221
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
222
|
+
# p row_data["value"]["properties"][column_mappings[i]], !(row_data["value"]["properties"][column] or row_data["value"]["properties"][column_mappings[i]])
|
223
|
+
if row_data["value"]["properties"].nil? or row_data["value"]["properties"][column].nil?
|
224
|
+
value = ""
|
225
|
+
else
|
226
|
+
value = row_data["value"]["properties"][column][0][0]
|
227
|
+
end
|
228
|
+
|
229
|
+
row.instance_variable_set("@#{cleaned_column}", value)
|
230
|
+
CollectionViewRow.class_eval { attr_reader cleaned_column }
|
231
|
+
# then, define singleton methods for each column that are used to update the table cell
|
232
|
+
row.define_singleton_method("#{cleaned_column}=") do |new_value|
|
233
|
+
# neat way to get the name of the currently invoked method...
|
234
|
+
parsed_method = __method__.to_s[0...-1].split("_").join(" ")
|
235
|
+
cookies = Core.options["cookies"]
|
236
|
+
headers = Core.options["headers"]
|
237
|
+
|
238
|
+
request_id = extract_id(SecureRandom.hex(16))
|
239
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
240
|
+
space_id = extract_id(SecureRandom.hex(16))
|
241
|
+
|
242
|
+
request_ids = {
|
243
|
+
request_id: request_id,
|
244
|
+
transaction_id: transaction_id,
|
245
|
+
space_id: space_id,
|
246
|
+
}
|
247
|
+
|
248
|
+
update_property_value = Utils::CollectionViewComponents.update_property_value(@id, column_hash.key(parsed_method), new_value)
|
249
|
+
|
250
|
+
operations = [
|
251
|
+
update_property_value,
|
252
|
+
]
|
253
|
+
|
254
|
+
request_url = URLS[:UPDATE_BLOCK]
|
255
|
+
request_body = build_payload(operations, request_ids)
|
256
|
+
response = HTTParty.post(
|
257
|
+
request_url,
|
258
|
+
body: request_body.to_json,
|
259
|
+
cookies: cookies,
|
260
|
+
headers: headers,
|
261
|
+
)
|
262
|
+
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}.
|
263
|
+
Please try again, and if issues persist open an issue in GitHub.";end
|
264
|
+
|
265
|
+
# set the instance variable to the updated value!
|
266
|
+
_ = row.instance_variable_set("@#{__method__.to_s[0...-1]}", new_value)
|
267
|
+
row
|
268
|
+
end
|
239
269
|
end
|
240
|
-
|
241
|
-
attr_reader :parent_id, :id
|
242
270
|
end
|
243
|
-
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# class that represents each row in a CollectionView
|
274
|
+
class CollectionViewRow < Core
|
275
|
+
@notion_type = "table_row"
|
276
|
+
@type = "table_row"
|
277
|
+
|
278
|
+
def type
|
279
|
+
NotionAPI::CollectionViewRow.notion_type
|
280
|
+
end
|
281
|
+
|
282
|
+
def inspect
|
283
|
+
"CollectionViewRow - id: #{self.id} - parent id: #{self.parent_id}"
|
284
|
+
end
|
285
|
+
|
286
|
+
class << self
|
287
|
+
attr_reader :notion_type, :type, :parent_id
|
288
|
+
end
|
289
|
+
|
290
|
+
attr_reader :parent_id, :id
|
291
|
+
|
292
|
+
def initialize(id, parent_id, collection_id, view_id)
|
293
|
+
@id = id
|
294
|
+
@parent_id = parent_id
|
295
|
+
@collection_id = collection_id
|
296
|
+
@view_id = view_id
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# class that represents a CollectionViewPage, inheriting all properties from CollectionView
|
301
|
+
class CollectionViewPage < CollectionView
|
302
|
+
@notion_type = "collection_view_page"
|
303
|
+
@type = "collection_view_page"
|
304
|
+
|
305
|
+
def type
|
306
|
+
NotionAPI::CollectionViewRow.notion_type
|
307
|
+
end
|
308
|
+
|
309
|
+
class << self
|
310
|
+
attr_reader :notion_type, :type, :parent_id
|
311
|
+
end
|
312
|
+
|
313
|
+
attr_reader :parent_id, :id
|
314
|
+
end
|
315
|
+
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
@@ -554,6 +554,30 @@ module Utils
|
|
554
554
|
args: args,
|
555
555
|
}
|
556
556
|
end
|
557
|
+
|
558
|
+
def self.update_property_value(page_id, column_name, new_value)
|
559
|
+
# ! update the specified column_name to new_value
|
560
|
+
# ! page_id -> the ID of the page: ``str``
|
561
|
+
# ! column_name -> the name of the column ["property"] to update: ``str``
|
562
|
+
# ! new_value -> the new value to assign to that column ["property"]: ``str``
|
563
|
+
table = "block"
|
564
|
+
path = [
|
565
|
+
"properties",
|
566
|
+
column_name
|
567
|
+
]
|
568
|
+
command = "set"
|
569
|
+
args = [[
|
570
|
+
new_value
|
571
|
+
]]
|
572
|
+
|
573
|
+
{
|
574
|
+
id: page_id,
|
575
|
+
table: table,
|
576
|
+
path: path,
|
577
|
+
command: command,
|
578
|
+
args: args
|
579
|
+
}
|
580
|
+
end
|
557
581
|
end
|
558
582
|
|
559
583
|
def build_payload(operations, request_ids)
|
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.0.
|
4
|
+
version: 1.0.5
|
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-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|