notion 1.0.0 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ module NotionAPI
2
+
3
+ # good for just about anything (-:
4
+ class TextBlock < BlockTemplate
5
+ @notion_type = 'text'
6
+ @type = 'text'
7
+
8
+ def type
9
+ NotionAPI::TextBlock.notion_type
10
+ end
11
+
12
+ class << self
13
+ attr_reader :notion_type, :type
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ module NotionAPI
2
+
3
+ # To-Do block: best for checklists and tracking to-dos.
4
+ class TodoBlock < BlockTemplate
5
+ @notion_type = 'to_do'
6
+ @type = 'to_do'
7
+
8
+ def type
9
+ NotionAPI::TodoBlock.notion_type
10
+ end
11
+
12
+ class << self
13
+ attr_reader :notion_type, :type
14
+ end
15
+
16
+ def checked=(checked_value)
17
+ # ! change the checked property of the Todo Block.
18
+ # ! checked_value -> boolean value used to determine whether the block should be checked [yes] or not [no] : ``str``
19
+ # set static variables for request
20
+ cookies = Core.options['cookies']
21
+ headers = Core.options['headers']
22
+ request_url = URLS[:UPDATE_BLOCK]
23
+
24
+ # set unique values for request
25
+ request_id = extract_id(SecureRandom.hex(16))
26
+ transaction_id = extract_id(SecureRandom.hex(16))
27
+ space_id = extract_id(SecureRandom.hex(16))
28
+ request_ids = {
29
+ request_id: request_id,
30
+ transaction_id: transaction_id,
31
+ space_id: space_id
32
+ }
33
+
34
+ if %w[yes no].include?(checked_value.downcase)
35
+ checked_hash = Utils::BlockComponents.checked_todo(@id, checked_value.downcase)
36
+ last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(@parent_id)
37
+ last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
38
+
39
+ operations = [
40
+ checked_hash,
41
+ last_edited_time_parent_hash,
42
+ last_edited_time_child_hash
43
+ ]
44
+ request_body = build_payload(operations, request_ids)
45
+ response = HTTParty.post(
46
+ request_url,
47
+ body: request_body.to_json,
48
+ cookies: cookies,
49
+ headers: headers
50
+ )
51
+ 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}.
52
+ Please try again, and if issues persist open an issue in GitHub."; end
53
+
54
+ true
55
+ else
56
+ false
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,16 @@
1
+ module NotionAPI
2
+
3
+ # Toggle block: best for storing children blocks
4
+ class ToggleBlock < BlockTemplate
5
+ @notion_type = 'toggle'
6
+ @type = 'toggle'
7
+
8
+ def type
9
+ NotionAPI::ToggleBlock.notion_type
10
+ end
11
+
12
+ class << self
13
+ attr_reader :notion_type, :type
14
+ end
15
+ end
16
+ end
@@ -3,9 +3,9 @@
3
3
  module Utils
4
4
  # ! defines utility functions and static variables for this application.
5
5
  URLS = {
6
- GET_BLOCK: 'https://www.notion.so/api/v3/loadPageChunk',
7
- UPDATE_BLOCK: 'https://www.notion.so/api/v3/saveTransactions',
8
- GET_COLLECTION: 'https://www.notion.so/api/v3/queryCollection'
6
+ GET_BLOCK: "https://www.notion.so/api/v3/loadPageChunk",
7
+ UPDATE_BLOCK: "https://www.notion.so/api/v3/saveTransactions",
8
+ GET_COLLECTION: "https://www.notion.so/api/v3/queryCollection",
9
9
  }.freeze
10
10
 
11
11
  class BlockComponents
@@ -15,10 +15,10 @@ module Utils
15
15
  # ! payload for creating a block.
16
16
  # ! block_id -> id of the new block : ``str``
17
17
  # ! block_type -> type of block to create : ``cls``
18
- table = 'block'
18
+ table = "block"
19
19
  path = []
20
- command = 'update'
21
- timestamp = DateTime.now.strftime('%Q')
20
+ command = "update"
21
+ timestamp = DateTime.now.strftime("%Q")
22
22
  {
23
23
  id: block_id,
24
24
  table: table,
@@ -29,41 +29,41 @@ module Utils
29
29
  type: block_type,
30
30
  properties: {},
31
31
  created_time: timestamp,
32
- last_edited_time: timestamp
33
- }
32
+ last_edited_time: timestamp,
33
+ },
34
34
  }
35
35
  end
36
36
 
37
37
  def self.title(id, title)
38
38
  # ! payload for updating the title of a block
39
39
  # ! id -> the ID to update the title of : ``str``
40
- table = 'block'
40
+ table = "block"
41
41
  path = %w[properties title]
42
- command = 'set'
42
+ command = "set"
43
43
 
44
44
  {
45
45
  id: id,
46
46
  table: table,
47
47
  path: path,
48
48
  command: command,
49
- args: [[title]]
49
+ args: [[title]],
50
50
  }
51
51
  end
52
52
 
53
53
  def self.last_edited_time(id)
54
54
  # ! payload for updating the last edited time
55
55
  # ! id -> either the block ID or parent ID : ``str``
56
- timestamp = DateTime.now.strftime('%Q')
57
- table = 'block'
58
- path = ['last_edited_time']
59
- command = 'set'
56
+ timestamp = DateTime.now.strftime("%Q")
57
+ table = "block"
58
+ path = ["last_edited_time"]
59
+ command = "set"
60
60
 
61
61
  {
62
62
  table: table,
63
63
  id: id,
64
64
  path: path,
65
65
  command: command,
66
- args: timestamp
66
+ args: timestamp,
67
67
  }
68
68
  end
69
69
 
@@ -71,9 +71,9 @@ module Utils
71
71
  # ! payload for converting a block to a different type.
72
72
  # ! id -> id of the block to convert : ``str``
73
73
  # ! block_class_to_convert_to -> type to convert to block to: ``NotionAPI::<Block_Type>``
74
- table = 'block'
74
+ table = "block"
75
75
  path = []
76
- command = 'update'
76
+ command = "update"
77
77
 
78
78
  {
79
79
  id: id,
@@ -81,8 +81,8 @@ module Utils
81
81
  path: path,
82
82
  command: command,
83
83
  args: {
84
- type: block_class_to_convert_to.notion_type
85
- }
84
+ type: block_class_to_convert_to.notion_type,
85
+ },
86
86
  }
87
87
  end
88
88
 
@@ -90,10 +90,10 @@ module Utils
90
90
  # ! payload for setting a blocks parent ID to 'alive'
91
91
  # ! block_parent_id -> the blocks parent ID : ``str``
92
92
  # ! new_block_id -> the new block ID, who is a child of the parent : ``str``
93
- table = 'block'
93
+ table = "block"
94
94
  path = []
95
- command = 'update'
96
- parent_table = 'block'
95
+ command = "update"
96
+ parent_table = "block"
97
97
  alive = true
98
98
  {
99
99
  id: new_block_id,
@@ -103,17 +103,17 @@ module Utils
103
103
  args: {
104
104
  parent_id: block_parent_id,
105
105
  parent_table: parent_table,
106
- alive: alive
107
- }
106
+ alive: alive,
107
+ },
108
108
  }
109
109
  end
110
110
 
111
111
  def self.set_block_to_dead(block_id)
112
112
  # ! payload for setting a block to dead (alive == true)
113
113
  # ! block_id -> the block ID to 'kill' : ``str``
114
- table = 'block'
114
+ table = "block"
115
115
  path = []
116
- command = 'update'
116
+ command = "update"
117
117
  alive = false
118
118
 
119
119
  {
@@ -122,12 +122,12 @@ module Utils
122
122
  path: path,
123
123
  command: command,
124
124
  args: {
125
- alive: alive
126
- }
125
+ alive: alive,
126
+ },
127
127
  }
128
128
  end
129
129
 
130
- def self.duplicate(block_type, block_title, block_id, new_block_id, user_notion_id, contents)
130
+ def self.duplicate(block_type, block_title, block_id, new_block_id, user_notion_id, contents, properties, formatting)
131
131
  # ! payload for duplicating a block. Most properties should be
132
132
  # ! inherited from the block class the method is invoked on.
133
133
  # ! block_type -> type of block that is being duplicated : ``cls``
@@ -136,10 +136,10 @@ module Utils
136
136
  # ! new_block_id -> id of new block : ``str``
137
137
  # ! user_notion_id -> ID of notion user : ``str``
138
138
  # ! contents -> The children of the block
139
- timestamp = DateTime.now.strftime('%Q')
140
- table = 'block'
139
+ timestamp = DateTime.now.strftime("%Q")
140
+ table = "block"
141
141
  path = []
142
- command = 'update'
142
+ command = "update"
143
143
 
144
144
  {
145
145
  id: new_block_id,
@@ -150,18 +150,17 @@ module Utils
150
150
  id: new_block_id,
151
151
  version: 10,
152
152
  type: block_type,
153
- properties: {
154
- title: [[block_title]]
155
- },
153
+ properties: properties,
154
+ format: formatting,
156
155
  content: contents, # root-level blocks
157
156
  created_time: timestamp,
158
157
  last_edited_time: timestamp,
159
- created_by_table: 'notion_user',
158
+ created_by_table: "notion_user",
160
159
  created_by_id: user_notion_id,
161
- last_edited_by_table: 'notion_user',
160
+ last_edited_by_table: "notion_user",
162
161
  last_edited_by_id: user_notion_id,
163
- copied_from: block_id
164
- }
162
+ copied_from: block_id,
163
+ },
165
164
  }
166
165
  end
167
166
 
@@ -169,10 +168,10 @@ module Utils
169
168
  # ! payload for adding a parent
170
169
  # ! block_parent_id -> the parent id of the block : ``str``
171
170
  # ! block_id -> the id of the block : ``str``
172
- table = 'block'
171
+ table = "block"
173
172
  path = []
174
- command = 'update'
175
- parent_table = 'block'
173
+ command = "update"
174
+ parent_table = "block"
176
175
  alive = true
177
176
 
178
177
  {
@@ -183,8 +182,8 @@ module Utils
183
182
  args: {
184
183
  parent_id: block_parent_id,
185
184
  parent_table: parent_table,
186
- alive: alive
187
- }
185
+ alive: alive,
186
+ },
188
187
  }
189
188
  end
190
189
 
@@ -196,27 +195,27 @@ module Utils
196
195
  # ! new_block_id -> id of the new block: ``str``
197
196
  # ! target -> the ID of the target block : ``str``
198
197
  # ! command -> the position of the block, before or after, in relation to the target : ``str``
199
- table = 'block'
200
- path = ['content']
198
+ table = "block"
199
+ path = ["content"]
201
200
 
202
- args = if command == 'listAfter'
203
- {
201
+ args = if command == "listAfter"
202
+ {
204
203
  after: target || block_id,
205
- id: new_block_id || block_id
204
+ id: new_block_id || block_id,
206
205
  }
207
- else
208
- {
206
+ else
207
+ {
209
208
  before: target || block_id,
210
- id: new_block_id || block_id
209
+ id: new_block_id || block_id,
211
210
  }
212
- end
211
+ end
213
212
 
214
213
  {
215
214
  table: table,
216
215
  id: block_parent_id, # ID of the parent for the new block. It should be the block that the method is invoked on.
217
216
  path: path,
218
217
  command: command,
219
- args: args
218
+ args: args,
220
219
  }
221
220
  end
222
221
 
@@ -224,17 +223,17 @@ module Utils
224
223
  # ! removes a notion block
225
224
  # ! block_parent_id -> the parent ID of the block to remove : ``str``
226
225
  # ! block_id -> the ID of the block to remove : ``str``
227
- table = 'block'
228
- path = ['content']
229
- command = 'listRemove'
226
+ table = "block"
227
+ path = ["content"]
228
+ command = "listRemove"
230
229
  {
231
230
  table: table,
232
231
  id: block_parent_id, # ID of the parent for the new block. It should be the block that the method is invoked on.
233
232
  path: path,
234
233
  command: command,
235
234
  args: {
236
- id: block_id
237
- }
235
+ id: block_id,
236
+ },
238
237
  }
239
238
  end
240
239
 
@@ -242,17 +241,17 @@ module Utils
242
241
  # ! payload for setting a "checked" value for TodoBlock.
243
242
  # ! block_id -> the ID of the block to remove : ``str``
244
243
  # ! standardized_check_val -> tyes/no value, determines the checked property of the block : ``str``
245
- table = 'block'
246
- path = ['properties']
247
- command = 'update'
244
+ table = "block"
245
+ path = ["properties"]
246
+ command = "update"
248
247
  {
249
248
  id: block_id,
250
249
  table: table,
251
250
  path: path,
252
251
  command: command,
253
252
  args: {
254
- checked: [[standardized_check_val]]
255
- }
253
+ checked: [[standardized_check_val]],
254
+ },
256
255
  }
257
256
  end
258
257
 
@@ -260,9 +259,9 @@ module Utils
260
259
  # ! update the language for a codeblock
261
260
  # ! block_id -> id of the code block
262
261
  # ! coding_language -> language to change the block to.
263
- table = 'block'
264
- path = ['properties']
265
- command = 'update'
262
+ table = "block"
263
+ path = ["properties"]
264
+ command = "update"
266
265
 
267
266
  {
268
267
  id: block_id,
@@ -270,8 +269,16 @@ module Utils
270
269
  path: path,
271
270
  command: command,
272
271
  args: {
273
- language: [[coding_language]]
274
- }
272
+ language: [[coding_language]],
273
+ },
274
+ }
275
+ end
276
+ def self.add_emoji_icon(block_id, icon)
277
+ {
278
+ id: block_id,
279
+ table:"block",
280
+ path:["format","page_icon"],
281
+ command:"set","args": icon
275
282
  }
276
283
  end
277
284
  end
@@ -282,12 +289,12 @@ module Utils
282
289
  # ! new_block_id -> id of the new block
283
290
  # ! collection_id -> ID of the collection.
284
291
  # ! view_ids -> id of the view
285
- table = 'block'
286
- command = 'update'
292
+ table = "block"
293
+ command = "update"
287
294
  path = []
288
- type = 'collection_view'
295
+ type = "collection_view"
289
296
  properties = {}
290
- timestamp = DateTime.now.strftime('%Q')
297
+ timestamp = DateTime.now.strftime("%Q")
291
298
 
292
299
  {
293
300
  id: new_block_id,
@@ -299,12 +306,12 @@ module Utils
299
306
  type: type,
300
307
  collection_id: collection_id,
301
308
  view_ids: [
302
- view_ids
309
+ view_ids,
303
310
  ],
304
311
  properties: properties,
305
312
  created_time: timestamp,
306
- last_edited_time: timestamp
307
- }
313
+ last_edited_time: timestamp,
314
+ },
308
315
  }
309
316
  end
310
317
 
@@ -312,14 +319,14 @@ module Utils
312
319
  # ! payload for setting the collection blocks to alive.
313
320
  # ! new_block_id -> id of the new block
314
321
  # ! collection_id -> ID of the collection.
315
- table = 'block'
322
+ table = "block"
316
323
  path = []
317
- command = 'update'
318
- parent_table = 'collection'
324
+ command = "update"
325
+ parent_table = "collection"
319
326
  alive = true
320
- type = 'page'
327
+ type = "page"
321
328
  properties = {}
322
- timestamp = DateTime.now.strftime('%Q')
329
+ timestamp = DateTime.now.strftime("%Q")
323
330
 
324
331
  {
325
332
  id: new_block_id,
@@ -334,23 +341,22 @@ module Utils
334
341
  alive: alive,
335
342
  properties: properties,
336
343
  created_time: timestamp,
337
- last_edited_time: timestamp
338
- }
344
+ last_edited_time: timestamp,
345
+ },
339
346
  }
340
347
  end
341
348
 
342
- def self.set_view_config(new_block_id, view_id, children_ids)
349
+ def self.set_view_config(collection_type, new_block_id, view_id, children_ids)
343
350
  # ! payload for setting the configurations of the view.
344
351
  # ! new_block_id -> id of the new block
345
352
  # ! view_id -> id of the view
346
353
  # ! children_ids -> IDs for the children of the collection.
347
- table = 'collection_view'
354
+ table = "collection_view"
348
355
  path = []
349
- command = 'update'
356
+ command = "update"
350
357
  version = 0
351
- type = 'table'
352
- name = 'Default View'
353
- parent_table = 'block'
358
+ name = "Default View"
359
+ parent_table = "block"
354
360
  alive = true
355
361
 
356
362
  {
@@ -361,13 +367,13 @@ module Utils
361
367
  args: {
362
368
  id: view_id,
363
369
  version: version,
364
- type: type,
370
+ type: collection_type,
365
371
  name: name,
366
372
  page_sort: children_ids,
367
373
  parent_id: new_block_id,
368
374
  parent_table: parent_table,
369
- alive: alive
370
- }
375
+ alive: alive,
376
+ },
371
377
  }
372
378
  end
373
379
 
@@ -377,75 +383,86 @@ module Utils
377
383
  # ! new_block_id -> id of the new block
378
384
  # ! data -> json data to insert into table.
379
385
  col_names = data[0].keys
386
+ data_mappings = {Integer => "number", String => "text", Array => "text", Float => "number", Date => "date"}
387
+ exceptions = [ArgumentError, TypeError]
388
+ data_types = col_names.map do |name|
389
+ # 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
391
+ DateTime.parse(data[0][name]) ? data_mappings[Date] : nil
392
+ rescue *exceptions
393
+ data_mappings[data[0][name].class]
394
+ end
395
+ end
380
396
 
381
397
  schema_conf = {}
382
398
  col_names.each_with_index do |_name, i|
383
399
  if i.zero?
384
- schema_conf[:title] = { name: col_names[i], type: 'title' }
400
+ schema_conf[:title] = { name: col_names[i], type: "title" }
385
401
  else
386
- schema_conf[col_names[i]] = { name: col_names[i], type: 'text' }
402
+ schema_conf[col_names[i]] = { name: col_names[i], type: data_types[i] }
387
403
  end
388
404
  end
389
- {
405
+ return {
390
406
  id: collection_id,
391
- table: 'collection',
407
+ table: "collection",
392
408
  path: [],
393
- command: 'update',
409
+ command: "update",
394
410
  args: {
395
411
  id: collection_id,
396
412
  schema: schema_conf,
397
413
  parent_id: new_block_id,
398
- parent_table: 'block',
399
- alive: true
400
- }
401
- }
414
+ parent_table: "block",
415
+ alive: true,
416
+ },
417
+ }, data_types
402
418
  end
403
419
 
404
420
  def self.set_collection_title(collection_title, collection_id)
405
421
  # ! payload for setting the title of the collection.
406
422
  # ! collection_title -> title of the collection.
407
423
  # ! collection_id -> ID of the collection.
408
- table = 'collection'
409
- path = ['name']
410
- command = 'set'
424
+ table = "collection"
425
+ path = ["name"]
426
+ command = "set"
411
427
 
412
428
  {
413
429
  id: collection_id,
414
430
  table: table,
415
431
  path: path,
416
432
  command: command,
417
- args: [[collection_title]]
433
+ args: [[collection_title]],
418
434
  }
419
435
  end
420
436
 
421
- def self.insert_data(block_id, column, value)
437
+ def self.insert_data(block_id, column, value, mapping)
422
438
  # ! payload for inserting data into the table.
423
439
  # ! block_id -> the ID of the block : ``str``
424
440
  # ! column -> the name of the column to insert data into.
425
441
  # ! value -> the value to insert into the column.
426
- table = 'block'
442
+ # ! mapping -> the column data type.
443
+ table = "block"
427
444
  path = [
428
- 'properties',
429
- column
445
+ "properties",
446
+ column,
430
447
  ]
431
- command = 'set'
448
+ command = "set"
432
449
 
433
450
  {
434
451
  id: block_id,
435
452
  table: table,
436
453
  path: path,
437
454
  command: command,
438
- args: [[value]]
455
+ args: mapping == "date" ? [["‣",[["d",{"type": "date","start_date": value}]]]] : [[value]],
439
456
  }
440
457
  end
441
458
 
442
459
  def self.add_new_row(new_block_id)
443
460
  # ! payload for adding a new row to the table.
444
461
  # ! new_block_id -> the ID of the new row : ``str``
445
- table = 'block'
462
+ table = "block"
446
463
  path = []
447
- command = 'set'
448
- type = 'page'
464
+ command = "set"
465
+ type = "page"
449
466
 
450
467
  {
451
468
  id: new_block_id,
@@ -455,29 +472,29 @@ module Utils
455
472
  args: {
456
473
  type: type,
457
474
  id: new_block_id,
458
- version: 1
459
- }
475
+ version: 1,
476
+ },
460
477
  }
461
478
  end
462
479
 
463
- def self.query_collection(collection_id, view_id, search_query = '')
480
+ def self.query_collection(collection_id, view_id, search_query = "")
464
481
  # ! payload for querying the table for data.
465
482
  # ! collection_id -> the collection ID : ``str``
466
483
  # ! view_id -> the view ID : ``str``
467
484
  # ! search_query -> the query for searching the table : ``str``
468
485
  query = {}
469
486
  loader = {
470
- type: 'table',
487
+ type: "table",
471
488
  limit: 100,
472
489
  searchQuery: search_query,
473
- loadContentCover: true
490
+ loadContentCover: true,
474
491
  }
475
492
 
476
493
  {
477
494
  collectionId: collection_id,
478
495
  collectionViewId: view_id,
479
496
  query: query,
480
- loader: loader
497
+ loader: loader,
481
498
  }
482
499
  end
483
500
 
@@ -485,11 +502,79 @@ module Utils
485
502
  # ! payload for adding a column to the table.
486
503
  # ! collection_id -> the collection ID : ``str``
487
504
  # ! args -> the definition of the column : ``str``
505
+ args["format"] = {
506
+ "table_properties" => [
507
+ {
508
+ "property" => "title",
509
+ "visible" => true,
510
+ "width" => 280,
511
+ },
512
+ {
513
+ "property" => "aliases",
514
+ "visible" => true,
515
+ "width" => 200,
516
+ },
517
+ {
518
+ "property" => "category",
519
+ "visible" => true,
520
+ "width" => 200,
521
+ },
522
+ {
523
+ "property" => "description",
524
+ "visible" => true,
525
+ "width" => 200,
526
+ },
527
+ {
528
+ "property" => "ios_version",
529
+ "visible" => true,
530
+ "width" => 200,
531
+ },
532
+ {
533
+ "property" => "tags",
534
+ "visible" => true,
535
+ "width" => 200,
536
+ },
537
+ {
538
+ "property" => "phone",
539
+ "visible" => true,
540
+ "width" => 200,
541
+ },
542
+ {
543
+ "property" => "unicode_version",
544
+ "visible" => true,
545
+ "width" => 200,
546
+ }
547
+ ],
548
+ }
488
549
  {
489
550
  id: collection_id,
490
- table: 'collection',
551
+ table: "collection",
491
552
  path: [],
492
- command: 'update',
553
+ command: "update",
554
+ args: args,
555
+ }
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,
493
578
  args: args
494
579
  }
495
580
  end
@@ -509,9 +594,9 @@ module Utils
509
594
  id: transaction_id,
510
595
  shardId: 955_090,
511
596
  spaceId: space_id,
512
- operations: operations
513
- }
514
- ]
597
+ operations: operations,
598
+ },
599
+ ],
515
600
  }
516
601
  payload
517
602
  end