notion_ruby_mapping 0.3.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -1237
  3. data/env.yml.sample +0 -13
  4. data/examples/change_title.md +1 -1
  5. data/examples/renumbering_pages.md +3 -3
  6. data/examples/set_icon_to_all_icon_unsettled_pages.md +4 -4
  7. data/lib/notion_ruby_mapping/{base.rb → blocks/base.rb} +163 -92
  8. data/lib/notion_ruby_mapping/blocks/block.rb +145 -0
  9. data/lib/notion_ruby_mapping/blocks/bookmark_block.rb +11 -0
  10. data/lib/notion_ruby_mapping/blocks/breadcrumb_block.rb +19 -0
  11. data/lib/notion_ruby_mapping/blocks/bulleted_list_item_block.rb +11 -0
  12. data/lib/notion_ruby_mapping/blocks/callout_block.rb +82 -0
  13. data/lib/notion_ruby_mapping/blocks/child_base_block.rb +21 -0
  14. data/lib/notion_ruby_mapping/blocks/child_database_block.rb +11 -0
  15. data/lib/notion_ruby_mapping/blocks/child_page_block.rb +11 -0
  16. data/lib/notion_ruby_mapping/blocks/code_block.rb +50 -0
  17. data/lib/notion_ruby_mapping/blocks/column_block.rb +29 -0
  18. data/lib/notion_ruby_mapping/blocks/column_list_block.rb +33 -0
  19. data/lib/notion_ruby_mapping/{database.rb → blocks/database.rb} +41 -8
  20. data/lib/notion_ruby_mapping/blocks/divider_block.rb +19 -0
  21. data/lib/notion_ruby_mapping/blocks/embed_block.rb +11 -0
  22. data/lib/notion_ruby_mapping/blocks/equation_block.rb +43 -0
  23. data/lib/notion_ruby_mapping/blocks/file_base_block.rb +50 -0
  24. data/lib/notion_ruby_mapping/blocks/file_block.rb +11 -0
  25. data/lib/notion_ruby_mapping/blocks/heading1_block.rb +18 -0
  26. data/lib/notion_ruby_mapping/blocks/heading2_block.rb +18 -0
  27. data/lib/notion_ruby_mapping/blocks/heading3_block.rb +18 -0
  28. data/lib/notion_ruby_mapping/blocks/image_block.rb +11 -0
  29. data/lib/notion_ruby_mapping/blocks/link_preview_block.rb +16 -0
  30. data/lib/notion_ruby_mapping/blocks/link_to_page_block.rb +40 -0
  31. data/lib/notion_ruby_mapping/{list.rb → blocks/list.rb} +37 -6
  32. data/lib/notion_ruby_mapping/blocks/numbered_list_item_block.rb +11 -0
  33. data/lib/notion_ruby_mapping/blocks/page.rb +77 -0
  34. data/lib/notion_ruby_mapping/blocks/paragraph_block.rb +11 -0
  35. data/lib/notion_ruby_mapping/{block.rb → blocks/pdf_block.rb} +4 -3
  36. data/lib/notion_ruby_mapping/blocks/quote_block.rb +11 -0
  37. data/lib/notion_ruby_mapping/blocks/synced_block.rb +44 -0
  38. data/lib/notion_ruby_mapping/blocks/table_block.rb +50 -0
  39. data/lib/notion_ruby_mapping/blocks/table_of_contents_block.rb +34 -0
  40. data/lib/notion_ruby_mapping/blocks/table_row_block.rb +34 -0
  41. data/lib/notion_ruby_mapping/blocks/template_block.rb +34 -0
  42. data/lib/notion_ruby_mapping/blocks/text_sub_block_color_base_block.rb +45 -0
  43. data/lib/notion_ruby_mapping/blocks/to_do_block.rb +42 -0
  44. data/lib/notion_ruby_mapping/blocks/toggle_block.rb +11 -0
  45. data/lib/notion_ruby_mapping/blocks/toggle_heading1_block.rb +11 -0
  46. data/lib/notion_ruby_mapping/blocks/toggle_heading2_block.rb +11 -0
  47. data/lib/notion_ruby_mapping/blocks/toggle_heading3_block.rb +11 -0
  48. data/lib/notion_ruby_mapping/blocks/url_base_block.rb +34 -0
  49. data/lib/notion_ruby_mapping/blocks/url_caption_base_block.rb +46 -0
  50. data/lib/notion_ruby_mapping/blocks/video_block.rb +11 -0
  51. data/lib/notion_ruby_mapping/{notion_cache.rb → controllers/notion_cache.rb} +144 -102
  52. data/lib/notion_ruby_mapping/{payload.rb → controllers/payload.rb} +32 -18
  53. data/lib/notion_ruby_mapping/{property_cache.rb → controllers/property_cache.rb} +21 -20
  54. data/lib/notion_ruby_mapping/{query.rb → controllers/query.rb} +27 -19
  55. data/lib/notion_ruby_mapping/{rich_text_array.rb → controllers/rich_text_array.rb} +39 -17
  56. data/lib/notion_ruby_mapping/objects/emoji_object.rb +40 -0
  57. data/lib/notion_ruby_mapping/objects/equation_object.rb +43 -0
  58. data/lib/notion_ruby_mapping/objects/file_object.rb +60 -0
  59. data/lib/notion_ruby_mapping/{mention_object.rb → objects/mention_object.rb} +11 -0
  60. data/lib/notion_ruby_mapping/{rich_text_object.rb → objects/rich_text_object.rb} +12 -4
  61. data/lib/notion_ruby_mapping/{text_object.rb → objects/text_object.rb} +0 -1
  62. data/lib/notion_ruby_mapping/{user_object.rb → objects/user_object.rb} +9 -4
  63. data/lib/notion_ruby_mapping/{checkbox_property.rb → properties/checkbox_property.rb} +3 -0
  64. data/lib/notion_ruby_mapping/{created_by_property.rb → properties/created_by_property.rb} +1 -0
  65. data/lib/notion_ruby_mapping/{created_time_property.rb → properties/created_time_property.rb} +1 -0
  66. data/lib/notion_ruby_mapping/properties/date_base_property.rb +135 -0
  67. data/lib/notion_ruby_mapping/{date_property.rb → properties/date_property.rb} +13 -0
  68. data/lib/notion_ruby_mapping/{email_property.rb → properties/email_property.rb} +2 -2
  69. data/lib/notion_ruby_mapping/{files_property.rb → properties/files_property.rb} +26 -13
  70. data/lib/notion_ruby_mapping/{formula_property.rb → properties/formula_property.rb} +5 -1
  71. data/lib/notion_ruby_mapping/{last_edited_by_property.rb → properties/last_edited_by_property.rb} +1 -0
  72. data/lib/notion_ruby_mapping/{last_edited_time_property.rb → properties/last_edited_time_property.rb} +1 -0
  73. data/lib/notion_ruby_mapping/{multi_property.rb → properties/multi_property.rb} +0 -0
  74. data/lib/notion_ruby_mapping/{multi_select_property.rb → properties/multi_select_property.rb} +4 -3
  75. data/lib/notion_ruby_mapping/{number_property.rb → properties/number_property.rb} +4 -0
  76. data/lib/notion_ruby_mapping/{people_property.rb → properties/people_property.rb} +8 -3
  77. data/lib/notion_ruby_mapping/{phone_number_property.rb → properties/phone_number_property.rb} +4 -1
  78. data/lib/notion_ruby_mapping/{property.rb → properties/property.rb} +33 -0
  79. data/lib/notion_ruby_mapping/{relation_property.rb → properties/relation_property.rb} +30 -10
  80. data/lib/notion_ruby_mapping/{rich_text_property.rb → properties/rich_text_property.rb} +0 -0
  81. data/lib/notion_ruby_mapping/{rollup_property.rb → properties/rollup_property.rb} +7 -0
  82. data/lib/notion_ruby_mapping/{select_property.rb → properties/select_property.rb} +8 -2
  83. data/lib/notion_ruby_mapping/{text_property.rb → properties/text_property.rb} +0 -0
  84. data/lib/notion_ruby_mapping/{title_property.rb → properties/title_property.rb} +0 -0
  85. data/lib/notion_ruby_mapping/{url_property.rb → properties/url_property.rb} +4 -1
  86. data/lib/notion_ruby_mapping/version.rb +1 -1
  87. data/lib/notion_ruby_mapping.rb +21 -7
  88. metadata +82 -40
  89. data/lib/notion_ruby_mapping/date_base_property.rb +0 -75
  90. data/lib/notion_ruby_mapping/page.rb +0 -50
data/env.yml.sample CHANGED
@@ -1,15 +1,2 @@
1
1
  ---
2
2
  notion_token: "secret_XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
3
- top_page: "c01166c613ae45cbb96818b4ef2f5a77"
4
- unpermitted_page: "4a6eb31244204fecb488da11f3caf871"
5
- database: "c37a2c66e3aa4a0da44773de3b80c253"
6
- unpermitted_database: "668d797c76fa49349b05ad288df2d136"
7
- h1block: "0250fb6d600142eca4c74efb8794fc6b"
8
- unpermitted_block: "0c940186ab704351bb342d16f0635d49"
9
- db_first_page: "dcdc805c85fa4155a55c20fc28771af7"
10
- db_second_page: "6601e719a39a460c908e8909467fcccf"
11
- db_update_page: "206ffaa277744a99baf593e28730240c"
12
- user_hkob: "2200a911-6a96-44bb-bd38-6bfb1e01b9f6"
13
- parent1_page: "860753bb6d1f48de96211fa6e0e31f82"
14
- parent_database: "1d6b1040a9fb48d99a3d041429816e9f"
15
- created_database: "c7697137d49f49c2bbcdd6a665c4f921"
@@ -23,4 +23,4 @@ page.save # API access
23
23
  print page.title # -> JKL
24
24
  ```
25
25
  ---
26
- [Return to README.md](../README.md#2-example-code)
26
+ [Return to README.md](../README.md)
@@ -12,9 +12,9 @@ db.query_database(tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |p
12
12
  end
13
13
  ```
14
14
 
15
- | After execution |
16
- |-----------------------------------------------|
15
+ | After execution |
16
+ |--------------------------------------------------|
17
17
  | ![After exuecution](../images/serial_number.png) |
18
18
 
19
19
  ---
20
- [Return to README.md](../README.md#2-example-code)
20
+ [Return to README.md](../README.md)
@@ -22,9 +22,9 @@ db.query_database.each do |page|
22
22
  end
23
23
  ```
24
24
 
25
- |Before execution|After execution|
26
- |---|---|
27
- |![Before execution](../images/pre_set_icon.png)|![After execution](../images/post_set_icon.png)|
25
+ | Before execution | After execution |
26
+ |-------------------------------------------------|-------------------------------------------------|
27
+ | ![Before execution](../images/pre_set_icon.png) | ![After execution](../images/post_set_icon.png) |
28
28
 
29
29
  ---
30
- [Return to README.md](../README.md#2-example-code)
30
+ [Return to README.md](../README.md)
@@ -2,20 +2,21 @@
2
2
 
3
3
  module NotionRubyMapping
4
4
  # Notion Base object (Parent of Page / Database / List)
5
+ # The Public API method has a link to the API references.
5
6
  class Base
6
- #### Public announced methods
7
-
8
7
  # @param [Hash, nil] json
9
8
  # @param [String, nil] id
10
9
  # @param [Array<Property, Class, String>] assign
11
10
  def initialize(json: nil, id: nil, assign: [], parent: nil)
12
11
  @nc = NotionCache.instance
13
12
  @json = json
14
- @id = @nc.hex_id(id || json && @json["id"])
13
+ @id = @nc.hex_id(id || @json && @json["id"])
14
+ @archived = @json && @json["archived"]
15
+ @has_children = @json && @json["has_children"]
15
16
  @new_record = true unless parent.nil?
16
- raise StandardError, "Unknown id" if !is_a?(List) && @id.nil? && parent.nil?
17
+ raise StandardError, "Unknown id" if !is_a?(List) && !is_a?(Block) && @id.nil? && parent.nil?
17
18
 
18
- @payload = Payload.new(parent && {"parent" => parent})
19
+ @payload = Payload.new(!is_a?(Block) && parent && {"parent" => parent})
19
20
  @property_cache = nil
20
21
  @created_time = nil
21
22
  @last_edited_time = nil
@@ -26,9 +27,40 @@ module NotionRubyMapping
26
27
  end
27
28
  attr_reader :json, :id
28
29
 
30
+ # @param [Hash, Notion::Messages] json
31
+ # @return [NotionRubyMapping::Base]
32
+ def self.create_from_json(json)
33
+ case json["object"]
34
+ when "page"
35
+ Page.new json: json
36
+ when "database"
37
+ Database.new json: json
38
+ when "list"
39
+ List.new json: json
40
+ when "block"
41
+ Block.decode_block json
42
+ else
43
+ raise StandardError, json.inspect
44
+ end
45
+ end
46
+
47
+ # @param [Object] method
48
+ # @param [Object] path
49
+ # @param [nil] json
50
+ def self.dry_run_script(method, path, json = nil)
51
+ shell = [
52
+ "#!/bin/sh\ncurl #{method == :get ? "" : "-X #{method.to_s.upcase}"} 'https://api.notion.com/#{path}'",
53
+ " -H 'Notion-Version: 2022-02-22'",
54
+ " -H 'Authorization: Bearer '\"$NOTION_API_KEY\"''",
55
+ ]
56
+ shell << " -H 'Content-Type: application/json'" if %i[post patch].include?(method)
57
+ shell << " --data '#{JSON.generate json}'" if json
58
+ shell.join(" \\\n")
59
+ end
60
+
29
61
  # @param [String] key
30
62
  # @return [NotionRubyMapping::PropertyCache, Hash] obtained Page value or PropertyCache
31
- def [](key)
63
+ def get(key)
32
64
  unless @json
33
65
  raise StandardError, "Unknown id" if @id.nil?
34
66
 
@@ -42,9 +74,85 @@ module NotionRubyMapping
42
74
  end
43
75
  end
44
76
 
77
+ # @param [Array<Block>] blocks
78
+ # @param [Boolean] dry_run
79
+ # @return [NotionRubyMapping::Block, String]
80
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#44bbf83d852c419485c5efe9fe1558fb
81
+ # @see https://www.notion.so/hkob/Block-689ad4cbff50404d8a1baf67b6d6d78d#2c47f7fedae543cf8566389ba1677132
82
+ def append_block_children(*blocks, dry_run: false)
83
+ raise StandardError, "This block can have no children." unless page? || (block? && can_have_children)
84
+
85
+ only_one = blocks.length == 1
86
+ json = {
87
+ "children" => Array(blocks).map do |block|
88
+ assert_parent_children_pair block
89
+ block.block_json
90
+ end,
91
+ }
92
+ if dry_run
93
+ path = @nc.append_block_children_page_path(id)
94
+ self.class.dry_run_script :patch, path, json
95
+ else
96
+ response = @nc.append_block_children_request @id, json
97
+ raise StandardError, response unless response["results"]
98
+
99
+ answers = response["results"].map { |sub_json| Block.new json: sub_json }
100
+ only_one ? answers.first : answers
101
+ end
102
+ end
103
+
104
+ # @param [NotionRubyMapping::Block] block
105
+ def assert_parent_children_pair(block)
106
+ raise StandardError, "the argument is not a block." unless block.block?
107
+
108
+ raise StandardError, "#{type} cannot have children." if block? && !@can_have_children
109
+
110
+ return if block.can_append
111
+
112
+ bt = block.type
113
+ raise StandardError, "Internal file block can not append." if bt == "file"
114
+
115
+ raise StandardError, "Column block can only append column_list block" unless bt == "column" &&
116
+ block? && type == "column_list"
117
+ end
118
+
119
+ # @param [NotionRubyMapping::Property] klass
120
+ # @param [String] title
121
+ # @return [NotionRubyMapping::Property] generated property
122
+ def assign_property(klass, title)
123
+ @property_cache ||= PropertyCache.new({}, base_type: database? ? :database : :page)
124
+ property = if database?
125
+ klass.new(title, will_update: new_record?, base_type: :database)
126
+ else
127
+ klass.new(title, will_update: true, base_type: :page)
128
+ end
129
+ @property_cache.add_property property
130
+ property
131
+ end
132
+
133
+ # @return [TrueClass, FalseClass] true if Block object
134
+ def block?
135
+ is_a? Block
136
+ end
137
+
138
+ # @param [NotionRubyMapping::Query] query
139
+ # @param [Boolean] dry_run
140
+ # @return [NotionRubyMapping::List, String]
141
+ def children(query = Query.new, dry_run: false)
142
+ if dry_run
143
+ path = @nc.block_children_page_path(id) + query.query_string
144
+ self.class.dry_run_script :get, path
145
+ elsif @children
146
+ @children
147
+ else
148
+ response = @nc.block_children_request @id, query.query_string
149
+ @children = List.new json: response, parent: self, query: query
150
+ end
151
+ end
152
+
45
153
  # @return [NotionRubyMapping::CreatedTimeProperty]
46
154
  def created_time
47
- @created_time ||= CreatedTimeProperty.new("__timestamp__")
155
+ @created_time ||= CreatedTimeProperty.new("__timestamp__", json: self["created_time"])
48
156
  end
49
157
 
50
158
  # @return [TrueClass, FalseClass] true if Database object
@@ -53,16 +161,28 @@ module NotionRubyMapping
53
161
  end
54
162
 
55
163
  # @return [Hash, nil] obtained Hash
164
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#e13d526bd709451e9b06fd32e8d07fcd
56
165
  def icon
57
166
  self["icon"]
58
167
  end
59
168
 
169
+ # @return [String (frozen)]
170
+ def inspect
171
+ "#{self.class.name}-#{@id}"
172
+ end
173
+
174
+ # @return [Hash] json properties
175
+ def json_properties
176
+ @json && @json["properties"]
177
+ end
178
+
60
179
  # @return [NotionRubyMapping::LastEditedTimeProperty]
61
180
  def last_edited_time
62
- @last_edited_time ||= LastEditedTimeProperty.new("__timestamp__")
181
+ @last_edited_time ||= LastEditedTimeProperty.new("__timestamp__", json: self["last_edited_time"])
63
182
  end
64
183
 
65
184
  # @return [Boolean] true if new record
185
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#307af6e40d3840c59f8a82513a572d51
66
186
  def new_record?
67
187
  @new_record
68
188
  end
@@ -73,6 +193,7 @@ module NotionRubyMapping
73
193
  end
74
194
 
75
195
  # @return [NotionRubyMapping::PropertyCache] get or created PropertyCache object
196
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#8f0b28e09dd74e2a9ff06126c48d64d4
76
197
  def properties
77
198
  unless @property_cache
78
199
  unless @json
@@ -85,70 +206,6 @@ module NotionRubyMapping
85
206
  @property_cache
86
207
  end
87
208
 
88
- # @return [NotionRubyMapping::Base, String]
89
- def save(dry_run: false)
90
- if dry_run
91
- @new_record ? create(dry_run: true) : update(dry_run: true)
92
- else
93
- @new_record ? create : update
94
- @property_cache.clear_will_update
95
- @payload.clear
96
- self
97
- end
98
- end
99
-
100
- # @param [String] emoji
101
- # @param [String] url
102
- # @return [NotionRubyMapping::Base]
103
- def set_icon(emoji: nil, url: nil)
104
- @payload.set_icon(emoji: emoji, url: url) if page? || database?
105
- self
106
- end
107
-
108
- # @return [String] title
109
- def title
110
- properties.select { |p| p.is_a? TitleProperty }.map(&:full_text).join ""
111
- end
112
-
113
- ### Not public announced methods
114
-
115
- # @param [Hash, Notion::Messages] json
116
- # @return [NotionRubyMapping::Base]
117
- def self.create_from_json(json)
118
- case json["object"]
119
- when "page"
120
- Page.new json: json
121
- when "database"
122
- Database.new json: json
123
- when "list"
124
- List.new json: json
125
- when "block"
126
- Block.new json: json
127
- else
128
- raise StandardError, json.inspect
129
- end
130
- end
131
-
132
- # @param [NotionRubyMapping::Property] klass
133
- # @param [String] title
134
- # @return [NotionRubyMapping::Property] generated property
135
- def assign_property(klass, title)
136
- @property_cache ||= PropertyCache.new({}, base_type: database? ? :database : :page)
137
-
138
- property = if database?
139
- klass.new(title, will_update: new_record?, base_type: :database)
140
- else
141
- klass.new(title, will_update: true, base_type: :page)
142
- end
143
- @property_cache.add_property property
144
- property
145
- end
146
-
147
- # @return [NotionRubyMapping::List]
148
- def children
149
- @children ||= @nc.block_children(id)
150
- end
151
-
152
209
  # @return [Hash] created json for update page
153
210
  def property_values_json
154
211
  @payload.property_values_json @property_cache
@@ -173,10 +230,42 @@ module NotionRubyMapping
173
230
  self
174
231
  end
175
232
 
233
+ # @param [Boolean] dry_run
234
+ # @return [NotionRubyMapping::Base, String]
235
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#277085c8439841c798a4b94eae9a7326
236
+ def save(dry_run: false)
237
+ if dry_run
238
+ @new_record ? create(dry_run: true) : update(dry_run: true)
239
+ else
240
+ @new_record ? create : update
241
+ @property_cache.clear_will_update unless block?
242
+ @payload.clear
243
+ self
244
+ end
245
+ end
246
+
247
+ # @param [String] emoji
248
+ # @param [String] url
249
+ # @return [NotionRubyMapping::Base]
250
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#62eea67af7824496820c6bb903503540
251
+ # @see https://www.notion.so/hkob/Page-d359650e3ca94424af8359a24147b9a0#e13d526bd709451e9b06fd32e8d07fcd
252
+ def set_icon(emoji: nil, url: nil)
253
+ @payload.set_icon(emoji: emoji, url: url) if page? || database?
254
+ self
255
+ end
256
+
257
+ # @return [FalseClass] return false except block
258
+ def synced_block_original?
259
+ false
260
+ end
261
+
176
262
  # @param [Hash] json
177
263
  # @return [NotionRubyMapping::Base]
178
264
  def update_json(json)
179
- raise StandardError, json.inspect unless json["object"] != "error" && (@json.nil? || @json["type"] == json["type"])
265
+ unless json["object"] != "error" && (@json.nil? || @json["type"] == json["type"])
266
+ raise StandardError,
267
+ json.inspect
268
+ end
180
269
 
181
270
  @json = json
182
271
  @id = @nc.hex_id(@json["id"])
@@ -184,25 +273,7 @@ module NotionRubyMapping
184
273
  self
185
274
  end
186
275
 
187
- # protected
188
- # @return [Hash] json properties
189
- def json_properties
190
- @json && @json["properties"]
191
- end
192
-
193
- # @param [Object] method
194
- # @param [Object] path
195
- # @param [nil] json
196
- def self.dry_run_script(method, path, json = nil)
197
- shell = [
198
- "#!/bin/sh\ncurl #{method == :get ? "" : "-X #{method.to_s.upcase}"} 'https://api.notion.com/#{path}'",
199
- " -H 'Notion-Version: 2022-02-22'",
200
- " -H 'Authorization: Bearer '\"$NOTION_API_KEY\"''",
201
- ]
202
- shell << " -H 'Content-Type: application/json'" unless path == :get
203
- shell << " --data '#{JSON.generate json}'" if json
204
- shell.join(" \\\n")
205
- end
276
+ ### Not public announced methods
206
277
 
207
278
  protected
208
279
 
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class Block < Base
6
+ ### Public announced methods
7
+
8
+ # @see https://www.notion.so/hkob/BreadcrumbBlock-3d0905b858524cdd8c868f80fd5d089a#d3b517be0c4b4825bed98206ce3ef41a
9
+ # @see https://www.notion.so/hkob/DividerBlock-d943b964dc4d4eff8f1d24ee0684e29e#f0ac8179c9a044bf95b87de1eb338413
10
+ def initialize(json: nil, id: nil, parent: nil)
11
+ super
12
+ @can_have_children = false
13
+ @can_append = true
14
+ end
15
+ attr_reader :can_have_children, :can_append, :type, :rich_text_array, :url, :caption, :color, :language
16
+
17
+ def self.type2class(type, has_children = false)
18
+ @type2class ||= {
19
+ false => {
20
+ "bookmark" => BookmarkBlock,
21
+ "breadcrumb" => BreadcrumbBlock,
22
+ "bulleted_list_item" => BulletedListItemBlock,
23
+ "callout" => CalloutBlock,
24
+ "child_database" => ChildDatabaseBlock,
25
+ "child_page" => ChildPageBlock,
26
+ "code" => CodeBlock,
27
+ "column" => ColumnBlock,
28
+ "column_list" => ColumnListBlock,
29
+ "divider" => DividerBlock,
30
+ "embed" => EmbedBlock,
31
+ "equation" => EquationBlock,
32
+ "file" => FileBlock,
33
+ "heading_1" => Heading1Block,
34
+ "heading_2" => Heading2Block,
35
+ "heading_3" => Heading3Block,
36
+ "image" => ImageBlock,
37
+ "link_preview" => LinkPreviewBlock,
38
+ "link_to_page" => LinkToPageBlock,
39
+ "numbered_list_item" => NumberedListItemBlock,
40
+ "paragraph" => ParagraphBlock,
41
+ "pdf" => PdfBlock,
42
+ "quote" => QuoteBlock,
43
+ "synced_block" => SyncedBlock,
44
+ "table" => TableBlock,
45
+ "table_row" => TableRowBlock,
46
+ "table_of_contents" => TableOfContentsBlock,
47
+ "template" => TemplateBlock,
48
+ "to_do" => ToDoBlock,
49
+ "toggle" => ToggleBlock,
50
+ "video" => VideoBlock,
51
+ },
52
+ true => {
53
+ "heading_1" => ToggleHeading1Block,
54
+ "heading_2" => ToggleHeading2Block,
55
+ "heading_3" => ToggleHeading3Block,
56
+ }
57
+ }
58
+ @klass = @type2class[has_children][type] || @type2class[false][type] || Block
59
+ end
60
+
61
+ def self.decode_block(json)
62
+ type2class(json["type"], json["has_children"]).new json: json
63
+ end
64
+
65
+ # @see https://www.notion.so/hkob/Block-689ad4cbff50404d8a1baf67b6d6d78d#298916c7c379424682f39ff09ee38544
66
+ # @param [String] id
67
+ # @return [NotionRubyMapping::Block]
68
+ def self.find(id, dry_run: false)
69
+ nc = NotionCache.instance
70
+ if dry_run
71
+ Base.dry_run_script :get, nc.block_path(id)
72
+ else
73
+ nc.block id
74
+ end
75
+ end
76
+
77
+ # @param [Boolean] not_update false when update
78
+ # @return [Hash{String (frozen)->Hash}]
79
+ def block_json(not_update: true)
80
+ ans = {"type" => type}
81
+ ans["object"] = "block"
82
+ ans["archived"] = true if @archived
83
+ ans
84
+ end
85
+
86
+ # @return [Hash{String (frozen)->Array<Hash{String (frozen)->Hash}>}]
87
+ def children_block_json
88
+ {"children" => [block_json]}
89
+ end
90
+
91
+ # @return [NotionRubyMapping::RichTextArray]
92
+ def decode_block_caption
93
+ @caption = RichTextArray.new "caption", json: @json[type]["caption"]
94
+ end
95
+
96
+ # @return [String]
97
+ def decode_color
98
+ @color = @json[type]["color"]
99
+ end
100
+
101
+ # @return [NotionRubyMapping::RichTextArray]
102
+ def decode_block_rich_text_array
103
+ @rich_text_array = RichTextArray.new "rich_text", json: @json[type]["rich_text"]
104
+ end
105
+
106
+ # @param [Boolean] dry_run
107
+ # @return [NotionRubyMapping::Base, String]
108
+ def destroy(dry_run: false)
109
+ if dry_run
110
+ Base.dry_run_script :delete, @nc.block_path(@id)
111
+ else
112
+ @nc.destroy_block id
113
+ end
114
+ end
115
+
116
+ # @return [NotionRubyMapping::Base, String]
117
+ def update(dry_run: false)
118
+ if dry_run
119
+ dry_run_script :patch, @nc.block_path(@id), :update_block_json
120
+ else
121
+ update_json @nc.update_block_request(@id, update_block_json)
122
+ end
123
+ end
124
+
125
+ # @return [Hash]
126
+ def update_block_json
127
+ @payload.update_block_json type, block_json(not_update: false)
128
+ end
129
+
130
+ protected
131
+
132
+ def add_sub_blocks(sub_blocks)
133
+ @sub_blocks = Array(sub_blocks) if sub_blocks
134
+ @can_have_children = true
135
+ end
136
+
137
+ # @param [String] type
138
+ # @param [String] color
139
+ def rich_text_array_and_color(type, text_info, color = "default")
140
+ @rich_text_array = RichTextArray.rich_text_array type, text_info
141
+ @color = color
142
+ self
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class BookmarkBlock < UrlCaptionBaseBlock
6
+ # @return [String (frozen)]
7
+ def type
8
+ "bookmark"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class BreadcrumbBlock < Block
6
+ # @return [String (frozen)]
7
+ def type
8
+ "breadcrumb"
9
+ end
10
+
11
+ # @param [Boolean] not_update false when update
12
+ # @return [Hash{String (frozen)->Hash}]
13
+ def block_json(not_update: true)
14
+ ans = super
15
+ ans[type] = {}
16
+ ans
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class BulletedListItemBlock < TextSubBlockColorBaseBlock
6
+ # @return [String (frozen)]
7
+ def type
8
+ "bulleted_list_item"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class CalloutBlock < Block
6
+ # @param [RichTextArray, String, Array<String>, RichTextObject, Array<RichTextObject>] text_info
7
+ # @param [String] emoji
8
+ # @param [String] file_url
9
+ # @param [String] color
10
+ # @param [NotionRubyMapping::Block, Array<NotionRubyMapping::Block>, nil] sub_blocks
11
+ def initialize(text_info = nil, emoji: nil, file_url: nil, sub_blocks: nil, color: "default", json: nil, id: nil,
12
+ parent: nil)
13
+ super(json: json, id: id, parent: parent)
14
+ if @json
15
+ decode_block_rich_text_array
16
+ decode_color
17
+ else
18
+ rich_text_array_and_color "rich_text", text_info, color
19
+ @emoji = EmojiObject.emoji_object emoji if emoji
20
+ @file_object = FileObject.file_object file_url if file_url
21
+ add_sub_blocks sub_blocks
22
+ end
23
+ @can_have_children = true
24
+ end
25
+
26
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#db689d47cbcc44359a5ade17ca754cdd
27
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#4314e4d50617485f8d0fc3505c5b3e9b
28
+ attr_reader :color, :rich_text_array
29
+
30
+ # @param [Boolean] not_update false when update
31
+ # @return [Hash{String (frozen)->Hash}]
32
+ def block_json(not_update: true)
33
+ ans = super
34
+ ans[type] = @rich_text_array.update_property_schema_json not_update
35
+ ans[type]["color"] = @color
36
+ ans[type]["icon"] = @emoji.property_values_json if @emoji
37
+ ans[type]["icon"] = @file_object.property_values_json if @file_object
38
+ ans[type]["children"] = @sub_blocks.map(&:block_json) if @sub_blocks
39
+ ans
40
+ end
41
+
42
+ # @param [String] new_color
43
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#b3598e385c2d4a23ada506441a7f0f32
44
+ def color=(new_color)
45
+ @color = new_color
46
+ @payload.add_update_block_key "color"
47
+ end
48
+
49
+ # @return [String, nil]
50
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#611496b7fd96499882fad138ef248b04
51
+ def emoji
52
+ @emoji&.emoji
53
+ end
54
+
55
+ # @param [String] emoji
56
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#0bd030c398184f94b819358830c2e26d
57
+ def emoji=(emoji)
58
+ @emoji = EmojiObject.emoji_object emoji
59
+ @file_object = nil
60
+ @payload.add_update_block_key "icon"
61
+ end
62
+
63
+ # @return [String]
64
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#57a8fc88f2ee49f7963942ad30cbca04
65
+ def file_url
66
+ @file_object&.url
67
+ end
68
+
69
+ # @param [String] url
70
+ # @see https://www.notion.so/hkob/CalloutBlock-0eb8b64bea664bc89fad706a866a6e26#041dd676bbfb442699229486fd30370a
71
+ def file_url=(url)
72
+ @file_object = FileObject.file_object url
73
+ @emoji = nil
74
+ @payload.add_update_block_key "icon"
75
+ end
76
+
77
+ # @return [String (frozen)]
78
+ def type
79
+ "callout"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class ChildBaseBlock < Block
6
+ def initialize(json: nil, id: nil, parent: nil)
7
+ super
8
+ @title = @json[type]["title"]
9
+ @can_append = false
10
+ @can_append = false
11
+ end
12
+
13
+ # @param [Boolean] not_update false when update
14
+ # @return [Hash{String (frozen)->Hash}]
15
+ def block_json(not_update: true)
16
+ ans = super
17
+ ans[type] = {"title" => @title}
18
+ ans
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionRubyMapping
4
+ # Notion block
5
+ class ChildDatabaseBlock < ChildBaseBlock
6
+ # @return [String (frozen)]
7
+ def type
8
+ "child_database"
9
+ end
10
+ end
11
+ end