notion 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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