notion_ruby_mapping 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +500 -141
  3. data/env.yml.sample +2 -0
  4. data/examples/change_title.md +26 -0
  5. data/examples/renumbering_pages.md +20 -0
  6. data/examples/set_icon_to_all_icon_unsettled_pages.md +30 -0
  7. data/lib/notion_ruby_mapping/base.rb +130 -73
  8. data/lib/notion_ruby_mapping/checkbox_property.rb +27 -12
  9. data/lib/notion_ruby_mapping/created_by_property.rb +22 -10
  10. data/lib/notion_ruby_mapping/created_time_property.rb +16 -14
  11. data/lib/notion_ruby_mapping/database.rb +78 -8
  12. data/lib/notion_ruby_mapping/date_property.rb +67 -42
  13. data/lib/notion_ruby_mapping/email_property.rb +26 -16
  14. data/lib/notion_ruby_mapping/files_property.rb +40 -24
  15. data/lib/notion_ruby_mapping/formula_property.rb +51 -10
  16. data/lib/notion_ruby_mapping/last_edited_by_property.rb +22 -9
  17. data/lib/notion_ruby_mapping/last_edited_time_property.rb +16 -14
  18. data/lib/notion_ruby_mapping/list.rb +27 -19
  19. data/lib/notion_ruby_mapping/mention_object.rb +26 -1
  20. data/lib/notion_ruby_mapping/multi_select_property.rb +83 -21
  21. data/lib/notion_ruby_mapping/notion_cache.rb +25 -10
  22. data/lib/notion_ruby_mapping/number_property.rb +71 -10
  23. data/lib/notion_ruby_mapping/page.rb +33 -5
  24. data/lib/notion_ruby_mapping/payload.rb +23 -5
  25. data/lib/notion_ruby_mapping/people_property.rb +47 -19
  26. data/lib/notion_ruby_mapping/phone_number_property.rb +26 -15
  27. data/lib/notion_ruby_mapping/property.rb +140 -49
  28. data/lib/notion_ruby_mapping/property_cache.rb +31 -3
  29. data/lib/notion_ruby_mapping/query.rb +10 -0
  30. data/lib/notion_ruby_mapping/relation_property.rb +74 -21
  31. data/lib/notion_ruby_mapping/rich_text_array.rb +81 -0
  32. data/lib/notion_ruby_mapping/rich_text_object.rb +58 -1
  33. data/lib/notion_ruby_mapping/rich_text_property.rb +12 -1
  34. data/lib/notion_ruby_mapping/rollup_property.rb +82 -10
  35. data/lib/notion_ruby_mapping/select_property.rb +88 -13
  36. data/lib/notion_ruby_mapping/text_object.rb +0 -51
  37. data/lib/notion_ruby_mapping/text_property.rb +19 -45
  38. data/lib/notion_ruby_mapping/title_property.rb +12 -1
  39. data/lib/notion_ruby_mapping/url_property.rb +26 -15
  40. data/lib/notion_ruby_mapping/user_object.rb +4 -4
  41. data/lib/notion_ruby_mapping/version.rb +1 -1
  42. data/lib/notion_ruby_mapping.rb +2 -1
  43. data/tools/an +103 -0
  44. metadata +7 -2
data/env.yml.sample CHANGED
@@ -11,3 +11,5 @@ db_second_page: "6601e719a39a460c908e8909467fcccf"
11
11
  db_update_page: "206ffaa277744a99baf593e28730240c"
12
12
  user_hkob: "2200a911-6a96-44bb-bd38-6bfb1e01b9f6"
13
13
  parent1_page: "860753bb6d1f48de96211fa6e0e31f82"
14
+ parent_database: "1d6b1040a9fb48d99a3d041429816e9f"
15
+ created_database: "c7697137d49f49c2bbcdd6a665c4f921"
@@ -0,0 +1,26 @@
1
+ # Change title
2
+
3
+ The following code update the page title.
4
+
5
+ #### Pattern 1 (replace existing text partially)
6
+
7
+ ```Ruby
8
+ page = Page.find page_id # API access
9
+ print page.title # -> ABC\nDEF
10
+ tp = page.properties["Title"]
11
+ tp[1].text = "GHI"
12
+ page.save # API access
13
+ print page.title # -> ABC\nGHI
14
+ ```
15
+
16
+ #### Pattern 2 (replace all text)
17
+
18
+ ```Ruby
19
+ page = Page.new id: page_id, assign: [TitleProperty, "Title"]
20
+ tp = page.properties["Title"]
21
+ tp << TextObject.new("JKL")
22
+ page.save # API access
23
+ print page.title # -> JKL
24
+ ```
25
+ ---
26
+ [Return to README.md](../README.md#2-example-code)
@@ -0,0 +1,20 @@
1
+ # Renumbering pages
2
+
3
+ The following code sets serial numbers to the pages whose title is not empty in ascending order of titles.
4
+
5
+ ```Ruby
6
+ db = Database.new id: database_id, assign: [RichTextProperty, "TextTitle"]
7
+ tp = db.properties["TextTitle"]
8
+ query = tp.filter_is_not_empty.ascending(tp)
9
+ db.query_database(tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |page, index|
10
+ page.properties["NumberTitle"].number = index
11
+ page.save
12
+ end
13
+ ```
14
+
15
+ | After execution |
16
+ |-----------------------------------------------|
17
+ | ![After exuecution](../images/serial_number.png) |
18
+
19
+ ---
20
+ [Return to README.md](../README.md#2-example-code)
@@ -0,0 +1,30 @@
1
+ # Set icon to all icon unsettled pages
2
+
3
+ The following code sets a "💿" icon on all unset pages in the database.
4
+
5
+ ```Ruby
6
+ require "notion_ruby_mapping"
7
+
8
+ include NotionRubyMapping
9
+
10
+ token = ENV["NOTION_API_TOKEN"]
11
+ database_id = ENV["DATABASE_ID"]
12
+
13
+ NotionCache.instance.create_client token
14
+
15
+ db = Database.new id: database_id
16
+ db.query_database.each do |page|
17
+ unless page.icon
18
+ page.set_icon(emoji: "💿")
19
+ page.save
20
+ p page.id
21
+ end
22
+ end
23
+ ```
24
+
25
+ |Before execution|After execution|
26
+ |---|---|
27
+ |![Before execution](../images/pre_set_icon.png)|![After execution](../images/post_set_icon.png)|
28
+
29
+ ---
30
+ [Return to README.md](../README.md#2-example-code)
@@ -3,41 +3,65 @@
3
3
  module NotionRubyMapping
4
4
  # Notion Base object (Parent of Page / Database / List)
5
5
  class Base
6
+ #### Public announced methods
7
+
6
8
  # @param [Hash, nil] json
7
9
  # @param [String, nil] id
8
10
  # @param [Array<Property, Class, String>] assign
9
- def initialize(json: nil, id: nil, assign: [])
11
+ def initialize(json: nil, id: nil, assign: [], parent: nil)
10
12
  @nc = NotionCache.instance
11
13
  @json = json
12
14
  @id = @nc.hex_id(id || json && @json["id"])
13
- raise StandardError, "Unknown id" if !is_a?(List) && @id.nil?
15
+ @new_record = true unless parent.nil?
16
+ raise StandardError, "Unknown id" if !is_a?(List) && @id.nil? && parent.nil?
14
17
 
15
- @payload = nil
18
+ @payload = Payload.new(parent && {"parent" => parent})
16
19
  @property_cache = nil
20
+ @created_time = nil
21
+ @last_edited_time = nil
17
22
  assign.each_slice(2) { |(klass, key)| assign_property(klass, key) }
18
23
  end
19
24
  attr_reader :json, :id
20
25
 
21
- # @param [Hash, Notion::Messages] json
22
- # @return [NotionRubyMapping::Base]
23
- def self.create_from_json(json)
24
- case json["object"]
25
- when "page"
26
- Page.new json: json
27
- when "database"
28
- Database.new json: json
29
- when "list"
30
- List.new json: json
31
- when "block"
32
- Block.new json: json
26
+ # @param [String] key
27
+ # @return [NotionRubyMapping::PropertyCache, Hash] obtained Page value or PropertyCache
28
+ def [](key)
29
+ unless @json
30
+ raise StandardError, "Unknown id" if @id.nil?
31
+
32
+ reload
33
+ end
34
+ case key
35
+ when "properties"
36
+ properties
33
37
  else
34
- raise StandardError, json.inspect
38
+ @json[key]
35
39
  end
36
40
  end
37
41
 
38
- # @return [NotionRubyMapping::Payload] get or created Payload object
39
- def payload
40
- @payload ||= Payload.new
42
+ # @return [NotionRubyMapping::CreatedTimeProperty]
43
+ def created_time
44
+ @created_time ||= CreatedTimeProperty.new("title")
45
+ end
46
+
47
+ # @return [TrueClass, FalseClass] true if Database object
48
+ def database?
49
+ is_a? Database
50
+ end
51
+
52
+ # @return [Hash, nil] obtained Hash
53
+ def icon
54
+ self["icon"]
55
+ end
56
+
57
+ # @return [Boolean] true if new record
58
+ def new_record?
59
+ @new_record
60
+ end
61
+
62
+ # @return [TrueClass, FalseClass] true if Page object
63
+ def page?
64
+ is_a? Page
41
65
  end
42
66
 
43
67
  # @return [NotionRubyMapping::PropertyCache] get or created PropertyCache object
@@ -48,25 +72,68 @@ module NotionRubyMapping
48
72
 
49
73
  reload
50
74
  end
51
- @property_cache = PropertyCache.new json_properties
75
+ @property_cache = PropertyCache.new json_properties, base_type: database? ? :database : :page
52
76
  end
53
77
  @property_cache
54
78
  end
55
79
 
80
+ # @return [NotionRubyMapping::Base, String]
81
+ def save(dry_run: false)
82
+ if dry_run
83
+ @new_record ? create(dry_run: true) : update(dry_run: true)
84
+ else
85
+ @new_record ? create : update
86
+ @property_cache.clear_will_update
87
+ @payload.clear
88
+ self
89
+ end
90
+ end
91
+
92
+ # @param [String] emoji
93
+ # @param [String] url
94
+ # @return [NotionRubyMapping::Base]
95
+ def set_icon(emoji: nil, url: nil)
96
+ @payload.set_icon(emoji: emoji, url: url) if page? || database?
97
+ self
98
+ end
99
+
56
100
  # @return [String] title
57
101
  def title
58
102
  properties.select { |p| p.is_a? TitleProperty }.map(&:full_text).join ""
59
103
  end
60
104
 
61
- # @return [NotionRubyMapping::Base] reloaded self
62
- def reload
63
- update_json reload_json
64
- self
105
+ ### Not public announced methods
106
+
107
+ # @param [Hash, Notion::Messages] json
108
+ # @return [NotionRubyMapping::Base]
109
+ def self.create_from_json(json)
110
+ case json["object"]
111
+ when "page"
112
+ Page.new json: json
113
+ when "database"
114
+ Database.new json: json
115
+ when "list"
116
+ List.new json: json
117
+ when "block"
118
+ Block.new json: json
119
+ else
120
+ raise StandardError, json.inspect
121
+ end
65
122
  end
66
123
 
67
- # @return [Hash] json properties
68
- def json_properties
69
- @json && @json["properties"]
124
+ # @param [NotionRubyMapping::Property] klass
125
+ # @param [String] title
126
+ # @return [NotionRubyMapping::Property] generated property
127
+ def assign_property(klass, title)
128
+ @property_cache ||= PropertyCache.new({}, base_type: database? ? :database : :page)
129
+
130
+ property = if database?
131
+ klass.new(title, will_update: new_record?, base_type: :database)
132
+ else
133
+ klass.new(title, will_update: true, base_type: :page)
134
+ end
135
+ @property_cache.add_property property
136
+ property
70
137
  end
71
138
 
72
139
  # @return [NotionRubyMapping::List]
@@ -74,75 +141,65 @@ module NotionRubyMapping
74
141
  @children ||= @nc.block_children(id)
75
142
  end
76
143
 
77
- # @param [Hash] json
78
- # @return [NotionRubyMapping::Base]
79
- def update_json(json)
80
- raise StandardError, json.inspect unless json["object"] != "error" && @json.nil? || @json["type"] == json["type"]
144
+ # @return [Hash] created json for update page
145
+ def property_values_json
146
+ @payload.property_values_json @property_cache
147
+ end
81
148
 
82
- @json = json
83
- @id = @nc.hex_id(@json["id"])
84
- restore_from_json
149
+ # @return [NotionRubyMapping::Base] reloaded self
150
+ def reload
151
+ update_json reload_json
85
152
  self
86
153
  end
87
154
 
155
+ # @return [NotionRubyMapping::Base]
88
156
  def restore_from_json
89
- payload.clear
90
157
  return if (ps = @json["properties"]).nil?
91
158
 
92
159
  properties.json = json_properties
93
- return unless is_a? Page
160
+ return unless is_a?(Page) || is_a?(Database)
94
161
 
95
162
  ps.each do |key, json|
96
163
  properties[key].update_from_json json
97
164
  end
165
+ self
98
166
  end
99
167
 
100
- # @param [String] emoji
101
- # @param [String] url
168
+ # @param [Hash] json
102
169
  # @return [NotionRubyMapping::Base]
103
- def set_icon(emoji: nil, url: nil)
104
- if is_a?(Page) || is_a?(Database)
105
- payload.set_icon(emoji: emoji, url: url)
106
- update
107
- end
170
+ def update_json(json)
171
+ raise StandardError, json.inspect unless json["object"] != "error" && @json.nil? || @json["type"] == json["type"]
172
+
173
+ @json = json
174
+ @id = @nc.hex_id(@json["id"])
175
+ restore_from_json
108
176
  self
109
177
  end
110
178
 
111
- # @param [String] key
112
- # @return [NotionRubyMapping::PropertyCache, Hash] obtained Page value or PropertyCache
113
- def [](key)
114
- unless @json
115
- raise StandardError, "Unknown id" if @id.nil?
116
-
117
- reload
118
- end
119
- case key
120
- when "properties"
121
- properties
122
- else
123
- @json[key]
124
- end
179
+ # protected
180
+ # @return [Hash] json properties
181
+ def json_properties
182
+ @json && @json["properties"]
125
183
  end
126
184
 
127
- # @return [Hash, nil] obtained Hash
128
- def icon
129
- self["icon"]
185
+ # @param [Object] method
186
+ # @param [Object] path
187
+ # @param [nil] json
188
+ def self.dry_run_script(method, path, json = nil)
189
+ shell = [
190
+ "#!/bin/sh\ncurl #{method == :get ? "" : "-X #{method.to_s.upcase}"} 'https://api.notion.com/#{path}'",
191
+ " -H 'Notion-Version: 2022-02-22'",
192
+ " -H 'Authorization: Bearer '\"$NOTION_API_KEY\"''"
193
+ ]
194
+ shell << " -H 'Content-Type: application/json'" unless path == :get
195
+ shell << " --data '#{JSON.generate json}'" if json
196
+ shell.join("\\ \n")
130
197
  end
131
198
 
132
- # @param [Property, Class] klass
133
- # @param [String] title
134
- # @return [Property] generated property
135
- def assign_property(klass, title)
136
- @property_cache ||= PropertyCache.new {}
137
-
138
- property = klass.new(title, will_update: true)
139
- @property_cache.add_property property
140
- property
141
- end
199
+ protected
142
200
 
143
- # @return [Hash] created json
144
- def property_values_json
145
- payload.property_values_json @property_cache&.property_values_json
201
+ def dry_run_script(method, path, json_method)
202
+ self.class.dry_run_script method, path, send(json_method)
146
203
  end
147
204
  end
148
205
  end
@@ -6,30 +6,45 @@ module NotionRubyMapping
6
6
  include EqualsDoesNotEqual
7
7
  TYPE = "checkbox"
8
8
 
9
- # @param [String] name Property name
10
- # @param [Boolean] checkbox Number value (optional)
11
- def initialize(name, will_update: false, checkbox: false)
12
- super name, will_update: will_update
13
- @checkbox = checkbox
9
+ ### Public announced methods
10
+
11
+ ## Common methods
12
+
13
+ # @return [Boolean, Hash]
14
+ def checkbox
15
+ @json
14
16
  end
15
- attr_reader :checkbox
17
+
18
+ ## Page property only methods
16
19
 
17
20
  # @param [Boolean] flag
18
21
  # @return [TrueClass, FalseClass] settled value
19
22
  def checkbox=(flag)
20
23
  @will_update = true
21
- @checkbox = flag
24
+ @json = flag
22
25
  end
23
26
 
24
- # @param [Hash] json
25
- def update_from_json(json)
26
- @will_update = false
27
- @checkbox = json["checkbox"]
27
+ ### Not public announced methods
28
+
29
+ ## Common methods
30
+
31
+ # @param [String] name Property name
32
+ # @param [Boolean, Hash] json
33
+ def initialize(name, will_update: false, base_type: :page, json: nil)
34
+ super name, will_update: will_update, base_type: base_type
35
+ @json = if database?
36
+ json || {}
37
+ else
38
+ json || false
39
+ end
28
40
  end
29
41
 
42
+ ## Page property only methods
43
+
30
44
  # @return [Hash]
31
45
  def property_values_json
32
- {@name => {"checkbox" => @checkbox, "type" => "checkbox"}}
46
+ assert_page_property __method__
47
+ {@name => {"checkbox" => @json, "type" => "checkbox"}}
33
48
  end
34
49
  end
35
50
  end
@@ -5,24 +5,36 @@ module NotionRubyMapping
5
5
  class CreatedByProperty < MultiProperty
6
6
  TYPE = "created_by"
7
7
 
8
+ ### Public announced methods
9
+
10
+ ## Common methods
11
+
12
+ # @return [NotionRubyMapping::UserObject, Hash]
13
+ def created_by
14
+ @json
15
+ end
16
+
17
+ ### Not public announced methods
18
+
19
+ ## Common methods
20
+
8
21
  # @param [String] name Property name
9
22
  # @param [String] user_id user_id (optional)
10
23
  # @param [Hash] json json (optional)
11
- def initialize(name, json: nil, user_id: nil)
12
- super name, will_update: false
13
- @user = UserObject.new user_id: user_id, json: json
24
+ def initialize(name, will_update: false, base_type: :page, json: nil, user_id: nil)
25
+ super name, will_update: will_update, base_type: base_type
26
+ @json = if database?
27
+ json || {}
28
+ else
29
+ UserObject.new user_id: user_id, json: json
30
+ end
14
31
  end
15
- attr_reader :user
16
32
 
17
33
  # @param [Hash] json
18
34
  def update_from_json(json)
19
35
  @will_update = false
20
- @user = UserObject.new json: json["created_by"]
21
- end
22
-
23
- # @return [Hash] {} created_time cannot be updated
24
- def property_values_json
25
- {}
36
+ cb = json["created_by"]
37
+ @json = database? ? cb : UserObject.new(json: cb)
26
38
  end
27
39
  end
28
40
  end
@@ -5,23 +5,25 @@ module NotionRubyMapping
5
5
  class CreatedTimeProperty < DateBaseProperty
6
6
  TYPE = "created_time"
7
7
 
8
- # @param [String] name Property name
9
- # @param [String] created_time created_time value (optional)
10
- def initialize(name, created_time: nil)
11
- super name, will_update: false
12
- @created_time = created_time
13
- end
14
- attr_reader :created_time
8
+ ### Public announced methods
9
+
10
+ ## Common methods
15
11
 
16
- # @param [Hash] json
17
- def update_from_json(json)
18
- @will_update = false
19
- @created_time = json["created_time"]
12
+ # @return [Date, Hash]
13
+ def created_time
14
+ @json
20
15
  end
21
16
 
22
- # @return [Hash] {} created_time cannot be updated
23
- def property_values_json
24
- {}
17
+ ### Not public announced methods
18
+
19
+ ## Common methods
20
+
21
+ # @param [String] name Property name
22
+ # @param [String] json created_time value (optional)
23
+ def initialize(name, will_update: false, base_type: :page, json: nil)
24
+ super name, will_update: will_update, base_type: base_type
25
+ @json = json
26
+ @json ||= {} if database?
25
27
  end
26
28
  end
27
29
  end
@@ -3,26 +3,96 @@
3
3
  module NotionRubyMapping
4
4
  # Notion database
5
5
  class Database < Base
6
- def self.find(id)
7
- NotionCache.instance.database id
6
+ ### Public announced methods
7
+
8
+ # @param [String] id
9
+ # @return [NotionRubyMapping::Database, String]
10
+ def self.find(id, dry_run: false)
11
+ nc = NotionCache.instance
12
+ if dry_run
13
+ dry_run_script :get, nc.database_path(id)
14
+ else
15
+ nc.database id
16
+ end
8
17
  end
9
18
 
10
- # @param [NotionRubyMapping::Query] query object
11
- def query_database(query = Query.new)
12
- response = @nc.database_query @id, query
13
- List.new json: response, database: self, query: query
19
+ # @return [NotionRubyMapping::Property]
20
+ # @param [Class] klass
21
+ # @param [String] title
22
+ def add_property(klass, title)
23
+ prop = assign_property klass, title
24
+ yield prop if block_given?
25
+ @payload.merge_property prop.property_schema_json
26
+ prop.clear_will_update
27
+ prop
14
28
  end
15
29
 
30
+ # @param [Array<Property, Class, String>] assign
16
31
  # @return [NotionRubyMapping::Base]
17
- def update
18
- update_json @nc.update_database_request(@id, property_values_json)
32
+ def create_child_page(*assign)
33
+ Page.new assign: assign, parent: {"database_id" => @id}
34
+ end
35
+
36
+ # @return [NotionRubyMapping::RichTextArray]
37
+ def database_title
38
+ @database_title ||= RichTextArray.new "title", json: (self["title"]), will_update: new_record?
39
+ end
40
+
41
+ def property_schema_json
42
+ @payload.property_schema_json @property_cache, database_title
43
+ end
44
+
45
+ # @return [Hash] created json for update database
46
+ def property_values_json
47
+ @payload.property_values_json @property_cache, database_title
48
+ end
49
+
50
+ # @param [NotionRubyMapping::Query] query object
51
+ # @return [NotionRubyMapping::List, String]
52
+ def query_database(query = Query.new, dry_run: false)
53
+ if dry_run
54
+ Base.dry_run_script :post, @nc.query_database_path(@id), query.query_json
55
+ else
56
+ response = @nc.database_query @id, query
57
+ List.new json: response, database: self, query: query
58
+ end
59
+ end
60
+
61
+ # @param [Array] names
62
+ # @return [Array<NotionRubyMapping::Property>]
63
+ def remove_properties(*names)
64
+ names.map { |n| properties[n] }.each(&:remove)
65
+ end
66
+
67
+ # @return [Hash] created json for update database
68
+ def update_property_schema_json
69
+ @payload.update_property_schema_json @property_cache, database_title
19
70
  end
20
71
 
21
72
  protected
22
73
 
74
+ def create(dry_run: false)
75
+ if dry_run
76
+ dry_run_script :post, @nc.databases_path, :property_schema_json
77
+ else
78
+ json = @nc.create_database_request(property_schema_json)
79
+ @new_record = false
80
+ update_json json
81
+ end
82
+ end
83
+
23
84
  # @return [Hash]
24
85
  def reload_json
25
86
  @nc.database_request @id
26
87
  end
88
+
89
+ # @return [NotionRubyMapping::Base, String]
90
+ def update(dry_run: false)
91
+ if dry_run
92
+ dry_run_script :patch, @nc.database_path(@id), :update_property_schema_json
93
+ else
94
+ update_json @nc.update_database_request(@id, update_property_schema_json)
95
+ end
96
+ end
27
97
  end
28
98
  end