notion_ruby_mapping 0.1.2 → 0.2.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Guardfile +1 -1
  3. data/README.md +550 -197
  4. data/env.yml.sample +7 -0
  5. data/lib/notion_ruby_mapping/base.rb +45 -25
  6. data/lib/notion_ruby_mapping/checkbox_property.rb +26 -0
  7. data/lib/notion_ruby_mapping/created_by_property.rb +21 -0
  8. data/lib/notion_ruby_mapping/created_time_property.rb +20 -0
  9. data/lib/notion_ruby_mapping/database.rb +8 -8
  10. data/lib/notion_ruby_mapping/date_base_property.rb +40 -38
  11. data/lib/notion_ruby_mapping/date_property.rb +61 -0
  12. data/lib/notion_ruby_mapping/email_property.rb +30 -1
  13. data/lib/notion_ruby_mapping/files_property.rb +40 -0
  14. data/lib/notion_ruby_mapping/formula_property.rb +18 -0
  15. data/lib/notion_ruby_mapping/last_edited_by_property.rb +21 -0
  16. data/lib/notion_ruby_mapping/last_edited_time_property.rb +20 -0
  17. data/lib/notion_ruby_mapping/list.rb +33 -2
  18. data/lib/notion_ruby_mapping/mention_object.rb +49 -0
  19. data/lib/notion_ruby_mapping/multi_select_property.rb +25 -6
  20. data/lib/notion_ruby_mapping/notion_cache.rb +126 -53
  21. data/lib/notion_ruby_mapping/number_property.rb +13 -8
  22. data/lib/notion_ruby_mapping/page.rb +5 -2
  23. data/lib/notion_ruby_mapping/payload.rb +10 -2
  24. data/lib/notion_ruby_mapping/people_property.rb +38 -0
  25. data/lib/notion_ruby_mapping/phone_number_property.rb +30 -1
  26. data/lib/notion_ruby_mapping/property.rb +79 -41
  27. data/lib/notion_ruby_mapping/property_cache.rb +31 -12
  28. data/lib/notion_ruby_mapping/query.rb +5 -2
  29. data/lib/notion_ruby_mapping/relation_property.rb +37 -0
  30. data/lib/notion_ruby_mapping/rich_text_object.rb +74 -0
  31. data/lib/notion_ruby_mapping/rich_text_property.rb +18 -0
  32. data/lib/notion_ruby_mapping/rollup_property.rb +29 -0
  33. data/lib/notion_ruby_mapping/select_property.rb +12 -6
  34. data/lib/notion_ruby_mapping/text_object.rb +89 -0
  35. data/lib/notion_ruby_mapping/text_property.rb +61 -0
  36. data/lib/notion_ruby_mapping/title_property.rb +18 -0
  37. data/lib/notion_ruby_mapping/url_property.rb +30 -1
  38. data/lib/notion_ruby_mapping/user_object.rb +38 -0
  39. data/lib/notion_ruby_mapping/version.rb +2 -1
  40. data/lib/notion_ruby_mapping.rb +3 -3
  41. data/notion_ruby_mapping.gemspec +3 -1
  42. metadata +40 -7
data/README.md CHANGED
@@ -1,30 +1,69 @@
1
- # NotionRubyMapping
1
+ # notion_ruby_mapping
2
2
 
3
3
  Notion Ruby mapping is currently under development.
4
4
 
5
5
  Development note is here. → [Idea note of "notion_ruby_mapping"](https://www.notion.so/hkob/Idea-note-of-notion_ruby_mapping-3b0a3bb3c171438a830f9579d41df501)
6
6
 
7
7
  ## Table of Contents
8
- - [NotionRubyMapping](#notionrubymapping)
9
- - [Installation](#installation)
10
- - [Example code](#example-code)
11
- - [Usage](#usage)
12
- - [Create a New Integration](#create-a-new-integration)
13
- - [Create client](#create-client)
14
- - [Classes](#classes)
15
- - [Base class](#base-class)
16
- - [Database class](#database-class)
17
- - [Query class](#query-class)
18
- - [Page class](#page-class)
19
- - [List class](#list-class)
20
- - [Block class](#block-class)
21
- - [ChangeLog](#changelog)
22
- - [Contributing](#contributing)
23
- - [License](#license)
24
- - [Code of Conduct](#code-of-conduct)
25
- - [Acknowledgements](#acknowledgements)
26
-
27
- ## Installation
8
+
9
+
10
+ <!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
11
+
12
+ <!-- code_chunk_output -->
13
+
14
+ - [notion\_ruby\_mapping](#notion_ruby_mapping)
15
+ - [Table of Contents](#table-of-contents)
16
+ - [1. Installation](#1-installation)
17
+ - [2. Example code](#2-example-code)
18
+ - [2.1 Set icon to all icon unsettled pages](#21-set-icon-to-all-icon-unsettled-pages)
19
+ - [2.2 Renumbering pages](#22-renumbering-pages)
20
+ - [2.3 Change title](#23-change-title)
21
+ - [Pattern 1 (replace existing text partially)](#pattern-1-replace-existing-text-partially)
22
+ - [Pattern 2 (replace all text)](#pattern-2-replace-all-text)
23
+ - [3. Preparation](#3-preparation)
24
+ - [3.1 Create a New Integration](#31-create-a-new-integration)
25
+ - [3.2 Create client](#32-create-client)
26
+ - [4. Usage](#4-usage)
27
+ - [4.1 Page](#41-page)
28
+ - [4.1.1 Retrieve a page](#411-retrieve-a-page)
29
+ - [4.1.2 Update page properties](#412-update-page-properties)
30
+ - [4.1.3 Update other page information](#413-update-other-page-information)
31
+ - [4.1.4 other methods](#414-other-methods)
32
+ - [4.2 Page](#42-page)
33
+ - [4.2.1 Retrieve a database](#421-retrieve-a-database)
34
+ - [4.2.2 Query a database](#422-query-a-database)
35
+ - [4.2.2.1 Complex conditions](#4221-complex-conditions)
36
+ - [4.2.2.2 Sort criteria](#4222-sort-criteria)
37
+ - [4.2.3 Update database](#423-update-database)
38
+ - [4.3 List class](#43-list-class)
39
+ - [4.4 Block class](#44-block-class)
40
+ - [4.5 Property classes](#45-property-classes)
41
+ - [4.5.1 How to obtain Property object](#451-how-to-obtain-property-object)
42
+ - [4.5.2 Query object generator of property objects](#452-query-object-generator-of-property-objects)
43
+ - [4.5.3 create or update values for Page properties](#453-create-or-update-values-for-page-properties)
44
+ - [4.5.3.1 NumberProperty](#4531-numberproperty)
45
+ - [4.5.3.2 SelectProperty](#4532-selectproperty)
46
+ - [4.5.3.3 MultiSelectProperty](#4533-multiselectproperty)
47
+ - [4.5.3.4 DateProperty](#4534-dateproperty)
48
+ - [4.5.3.4 UrlProperty](#4534-urlproperty)
49
+ - [4.5.3.5 EmailProperty](#4535-emailproperty)
50
+ - [4.5.3.6 PhoneNumberProperty](#4536-phonenumberproperty)
51
+ - [4.5.3.7 PeopleProperty](#4537-peopleproperty)
52
+ - [4.5.3.8 TitleProperty, RichTextProperty](#4538-titleproperty-richtextproperty)
53
+ - [4.5.3.9 CheckboxProperty](#4539-checkboxproperty)
54
+ - [4.5.3.10 EmailProperty](#45310-emailproperty)
55
+ - [4.5.3.11 FilesProperty](#45311-filesproperty)
56
+ - [4.5.3.12 RelationProperty](#45312-relationproperty)
57
+ - [6. ChangeLog](#6-changelog)
58
+ - [6. Contributing](#6-contributing)
59
+ - [7. License](#7-license)
60
+ - [8. Code of Conduct](#8-code-of-conduct)
61
+ - [9. Acknowledgements](#9-acknowledgements)
62
+
63
+ <!-- /code_chunk_output -->
64
+
65
+
66
+ ## 1. Installation
28
67
 
29
68
  Add this line to your application's Gemfile:
30
69
 
@@ -34,15 +73,22 @@ gem 'notion_ruby_mapping'
34
73
 
35
74
  And then execute:
36
75
 
37
- $ bundle install
76
+ ```shell
77
+ bundle install
78
+ ```
38
79
 
39
80
  Or install it yourself as:
40
81
 
41
- $ gem install notion_ruby_mapping
82
+ ```shell
83
+ gem install notion_ruby_mapping
84
+ ```
85
+
86
+ ## 2. Example code
42
87
 
43
- ## Example code
88
+ ### 2.1 Set icon to all icon unsettled pages
44
89
 
45
90
  The following code sets a "💿" icon on all unset pages in the database.
91
+
46
92
  ```Ruby
47
93
  require "notion_ruby_mapping"
48
94
 
@@ -53,7 +99,8 @@ database_id = ENV["DATABASE_ID"]
53
99
 
54
100
  NotionCache.instance.create_client token
55
101
 
56
- Database.query(database_id).each do |page|
102
+ db = Database.new id: database_id
103
+ db.query_database.each do |page|
57
104
  p page.set_icon(emoji: "💿").id unless page.icon
58
105
  end
59
106
  ```
@@ -62,158 +109,195 @@ end
62
109
  |---|---|
63
110
  |![Before execution](images/pre_set_icon.png)|![After execution](images/post_set_icon.png)|
64
111
 
112
+ ### 2.2 Renumbering pages
113
+
65
114
  The following code sets serial numbers to the pages whose title is not empty in ascending order of titles.
115
+
66
116
  ```Ruby
67
- tp = RichTextProperty.new("TextTitle")
68
- Database.query(database_id, tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |page, index|
117
+ db = Database.new id: database_id, assign: [RichTextProperty, "TextTitle"]
118
+ tp = db.properties["TextTitle"]
119
+ query = tp.filter_is_not_empty.ascending(tp)
120
+ db.query_database(tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |page, index|
69
121
  page.properties["NumberTitle"].number = index
70
122
  page.update
71
123
  end
72
124
  ```
125
+
73
126
  | After execution |
74
127
  |-----------------------------------------------|
75
128
  | ![After exuecution](images/serial_number.png) |
76
129
 
77
- ## Usage
130
+ ### 2.3 Change title
78
131
 
79
- ### Create a New Integration
132
+ The following code update the page title.
133
+
134
+ #### Pattern 1 (replace existing text partially)
135
+
136
+ ```Ruby
137
+ page = Page.find page_id # API access
138
+ print page.title # -> ABC\nDEF
139
+ tp = page.properties["Title"]
140
+ tp[1].text = "GHI"
141
+ page.update # API access
142
+ print page.title # -> ABC\nGHI
143
+ ```
144
+
145
+ #### Pattern 2 (replace all text)
146
+
147
+ ```Ruby
148
+ page = Page.new id: page_id, assign: [TitleProperty, "Title"]
149
+ tp = page.properties["Title"]
150
+ tp << TextObject.new("JKL")
151
+ page.update # API access
152
+ print page.title # -> JKL
153
+ ```
154
+
155
+ ## 3. Preparation
156
+
157
+ ### 3.1 Create a New Integration
80
158
 
81
159
  Please check [Notion documentation](https://developers.notion.com/docs#getting-started).
82
160
 
83
- ### Create client
161
+ ### 3.2 Create client
162
+
163
+ Please create a client (notion-ruby-client) before you use the following class.
84
164
 
85
165
  ```Ruby
86
166
  NotionCache.instance.create_client ENV["NOTION_API_TOKEN"]
87
167
  ```
88
- Please create a client (notion-ruby-client) before you use the following class.
89
168
 
90
- ### Classes
169
+ ## 4. Usage
170
+
171
+ ### 4.1 Page
172
+
173
+ #### 4.1.1 Retrieve a page
174
+
175
+ `Page.find(id)` creates a Page object with `retrieving page API`.
176
+ The created object has page information generated from the JSON response.
177
+
178
+ ```Ruby
179
+ page = Page.find "c01166c6-13ae-45cb-b968-18b4ef2f5a77" # Notion API call
180
+ ```
181
+
182
+ `Page.new(id)` creates a Page object without the Notion API.
183
+ Since Page.new does not acquire property information, so you need to assign yourself.
184
+
185
+ ```Ruby
186
+ # Assign some properties for update manually
187
+ # The argument of assign keyword is Array with the multiple pairs of PropertyClass and Property name
188
+ page = Page.new id: "c01166c6-13ae-45cb-b968-18b4ef2f5a77",
189
+ assign: [TitleProperty, "Title", NumberProperty, "NumberTitle"]
190
+ ```
191
+
192
+ #### 4.1.2 Update page properties
91
193
 
92
- #### Base class (Abstract class for Database / Page / Block / List)
194
+ Page properties with values can be obtained from the retrieved page using `find`.
195
+ On the other hand, Page properties without values can be obtained from the property assigned page.
93
196
 
94
- - Set icon (only Database / Page)
197
+ ```Ruby
198
+ tp = page.properties["Title"] # TitleProperty
199
+ np = page.properties["Number"] # NumberProperty
200
+ ```
201
+
202
+ Each property object can change values using corresponded methods.
203
+ After changing value, `will_update` flag of the property object also set to true.
204
+ These methods are explained in the section of each property object class.
95
205
 
96
206
  ```Ruby
207
+ to = tp[1] # TitleProperty has Array of TextObject
208
+ to.text = "ABC" # TextObject can set text by ".text="
209
+ # or tp[1].text = "ABC"
210
+
211
+ np.number = 3.14159
212
+ ```
213
+
214
+ After update some properties, `page.update` method sends `update page API` and replace the page information using the response of API.
215
+
216
+ ```Ruby
217
+ page.update # Notion API call
218
+ ```
219
+
220
+ #### 4.1.3 Update other page information
221
+
222
+ `page.set_icon` can change the page icon using emoji or external url.
223
+
224
+ ```Ruby
225
+ # both methods call Notion API
97
226
  obj.set_icon emoji: "💿" # set emoji
98
227
  obj.set_icon url: "https://cdn.profile-image.st-hatena.com/users/hkob/profile.png" # set external url
99
228
  ```
100
229
 
101
- - Get values and properties
230
+ #### 4.1.4 other methods
231
+
232
+ - `page.title` returns plain_text string of `Title`.
233
+ - `page.icon` returns JSON hash for the page icon.
234
+ - `page[key]` returns a hash or an array object except "properties".
235
+
236
+ ### 4.2 Page
237
+
238
+ #### 4.2.1 Retrieve a database
239
+
240
+ `Database.find(id)` creates a Database object with `retrieving database API`.
241
+ The created object has database information generated from the JSON response.
102
242
 
103
243
  ```Ruby
104
- obj.icon # obtain icon json
105
- obj["icon"] # same as obj.icon
106
- obj.properties["NumberTitle"]
244
+ db = Database.find("c37a2c66-e3aa-4a0d-a447-73de3b80c253") # Notion API call
107
245
  ```
108
246
 
109
- #### Database class
247
+ `Database.new(id)` creates a Database object without the Notion API.
248
+ Since Database.new does not acquire property information, so you need to assign yourself.
110
249
 
111
- - Retrieve a database
112
250
  ```Ruby
113
- db = Database.find("c37a2c66-e3aa-4a0d-a447-73de3b80c253")
251
+ # assign some properties for update manually
252
+ db = Database.new id: "c37a2c66-e3aa-4a0d-a447-73de3b80c253",
253
+ assign: [TitleProperty, "Title", NumberProperty, "NumberTitle"]
114
254
  ```
115
- - Query a database
116
255
 
117
- Gets a List object of Page objects contained in the database.
256
+ #### 4.2.2 Query a database
257
+
258
+ `db.query_database` obtains a List object with Page objects contained in the database.
118
259
  You can obtain filtered and ordered pages using Query object.
260
+
119
261
  ```Ruby
120
- Database.query("c37a2c66-e3aa-4a0d-a447-73de3b80c253") # retrieves all pages
121
- Database.query("c37a2c66-e3aa-4a0d-a447-73de3b80c253", query) # retrieves using query
262
+ # query_database method calls Notion API
263
+ db.query_database # retrieves all pages (no filter, no sort)
264
+ db.query_database query # retrieves using query
122
265
  ```
123
266
 
124
- #### Query class and related *Property class
267
+ The query object can be generated from the Property objects included in the database object.
268
+ The Property object can be obtained from the retrieved or assigned database object like as the Page object.
269
+
270
+ `filter_xxxx` methods of the property objects generates a query object.
271
+ These methods are explained in the section of each property object class.
125
272
 
126
- Query object can be generated from the following Property objects.
127
- For example, in order to obtain the pages whose title starts with "A" and ordered by ascending,
128
- the following code can be used.
129
273
  ```Ruby
130
- tp = TitleProperty.new "Title"
274
+ tp = db.properties["Title"]
131
275
  query = tp.filter_starts_with("A").ascending(tp)
132
- pages = Database.query database_id, query
276
+ pages = db.query_database query
133
277
  ```
134
278
 
135
- The following methods for the Property objects generate a query object.
136
- - TitleProperty, RichTextProperty, UrlProperty, EmailProperty, PhoneNumberProperty
137
- - filter_equals(value)
138
- - filter_does_not_equal(value)
139
- - filter_contains(value)
140
- - filter_does_not_contain(value)
141
- - filter_starts_with(value)
142
- - filter_ends_with(value)
143
- - filter_is_empty
144
- - filter_is_not_empty
145
- - NumberProperty
146
- - filter_equals(value)
147
- - filter_does_not_equal(value)
148
- - filter_greater_than(value)
149
- - filter_less_than(value)
150
- - filter_greater_than_or_equal_to(value)
151
- - filter_less_than_or_equal_to(value)
152
- - filter_is_empty
153
- - filter_is_not_empty
154
- - CheckboxProperty
155
- - filter_equals(value)
156
- - filter_does_not_equal(value)
157
- - SelectProperty
158
- - filter_equals(value)
159
- - filter_does_not_equal(value)
160
- - filter_is_empty
161
- - filter_is_not_empty
162
- - MultiSelectProperty, PeopleProperty, CreatedByProperty, LastEditedByProperty
163
- - filter_contains(value)
164
- - filter_does_not_contain(value)
165
- - filter_is_empty
166
- - filter_is_not_empty
167
- - DateProperty, CreatedTimeProperty, LastEditedTimeProperty
168
- - filter_equals(value(Date / Time / DateTime / String))
169
- - filter_does_not_equal(value(Date / Time / DateTime / String))
170
- - filter_before(value(Date / Time / DateTime / String))
171
- - filter_after(value(Date / Time / DateTime / String))
172
- - filter_on_or_before(value(Date / Time / DateTime / String))
173
- - filter_on_or_after(value(Date / Time / DateTime / String))
174
- - filter_past_week
175
- - filter_past_month
176
- - filter_past_year
177
- - filter_next_week
178
- - filter_next_month
179
- - filter_next_year
180
- - FilesProperty
181
- - filter_is_empty
182
- - filter_is_not_empty
183
- - FormulaProperty
184
- - filter_equals(value(Date / Time / DateTime / String))
185
- - filter_does_not_equal(value(Date / Time / DateTime / String))
186
- - filter_before(value(Date / Time / DateTime / String))
187
- - filter_after(value(Date / Time / DateTime / String))
188
- - filter_on_or_before(value(Date / Time / DateTime / String))
189
- - filter_on_or_after(value(Date / Time / DateTime / String))
190
- - filter_past_week
191
- - filter_past_month
192
- - filter_past_year
193
- - filter_next_week
194
- - filter_next_month
195
- - filter_next_year
196
- - filter_contains(value)
197
- - filter_does_not_contain(value)
198
- - filter_starts_with(value)
199
- - filter_ends_with(value)
200
- - filter_greater_than(value)
201
- - filter_less_than(value)
202
- - filter_greater_than_or_equal_to(value)
203
- - filter_less_than_or_equal_to(value)
204
- - filter_is_empty
205
- - filter_is_not_empty
279
+ ##### 4.2.2.1 Complex conditions
280
+
281
+ Complex filters can be generated `and` / `or` methods of the Query object.
282
+ Here are some sample scripts and the json parameters created from them.
206
283
 
207
- Complex filters can be generated `and` / `or` methods.
208
284
  ```Ruby
209
- # Prepare sample properties
210
- tp = TitleProperty.new "tp"
211
- np = NumberProperty.new "np"
212
- cp = CheckboxProperty.new "cp"
213
- letp = LastEditedTimeProperty.new "letp"
285
+ # Prepare some sample properties
286
+ db = Database.new id: "sample database id",
287
+ assign: [
288
+ TitleProperty, "tp",
289
+ NumberProperty, "np",
290
+ CheckboxProperty, "cp",
291
+ LastEditedTimeProperty, "letp",
292
+ ]
293
+ properties = db.properties # PropertyCache object
294
+ # PropertyCache object can receive [] or values_at methods.
295
+ # `values_at` method is useful when retrieving multiple properties at once.
296
+ (tp, np, cp, letp) = properties.values_at "tp", "np", "cp", "letp"
214
297
  ```
215
298
 
216
- - (A and B) filter
299
+ - query1: (A and B) filter
300
+
217
301
  ```Ruby
218
302
  query1 = tp.filter_starts_with("start")
219
303
  .and(np.filter_greater_than(100))
@@ -233,7 +317,8 @@ query1 = tp.filter_starts_with("start")
233
317
  }
234
318
  ```
235
319
 
236
- - (A and B and C) filter
320
+ - query2: (A and B and C) filter
321
+
237
322
  ```Ruby
238
323
  query2 = tp.filter_starts_with("start")
239
324
  .and(np.filter_greater_than(100))
@@ -258,7 +343,8 @@ query2 = tp.filter_starts_with("start")
258
343
  }
259
344
  ```
260
345
 
261
- - (A or B) filter
346
+ - query3: (A or B) filter
347
+
262
348
  ```Ruby
263
349
  query3 = tp.filter_starts_with("start")
264
350
  .or(np.filter_greater_than(100))
@@ -278,7 +364,8 @@ query3 = tp.filter_starts_with("start")
278
364
  }
279
365
  ```
280
366
 
281
- - (A or B or C) filter
367
+ - query4: (A or B or C) filter
368
+
282
369
  ```Ruby
283
370
  query4 = tp.filter_starts_with("start")
284
371
  .or(np.filter_greater_than(100))
@@ -303,7 +390,8 @@ query4 = tp.filter_starts_with("start")
303
390
  }
304
391
  ```
305
392
 
306
- - ((A and B) or C) filter
393
+ - query5: ((A and B) or C) filter
394
+
307
395
  ```Ruby
308
396
  query5 = tp.filter_starts_with("start")
309
397
  .and(np.filter_greater_than(100))
@@ -332,7 +420,8 @@ query5 = tp.filter_starts_with("start")
332
420
  }
333
421
  ```
334
422
 
335
- - ((A or B) and C) filter
423
+ - query6: ((A or B) and C) filter
424
+
336
425
  ```Ruby
337
426
  query6 = tp.filter_starts_with("start")
338
427
  .or(np.filter_greater_than(100))
@@ -361,7 +450,8 @@ query6 = tp.filter_starts_with("start")
361
450
  }
362
451
  ```
363
452
 
364
- - ((A and B) or (C and D)) filter
453
+ - query7: ((A and B) or (C and D)) filter
454
+
365
455
  ```Ruby
366
456
  query7 = np.filter_greater_than(100).and(np.filter_less_than(200))
367
457
  .or(np.filter_greater_than(300).and(np.filter_less_than(400)))
@@ -397,7 +487,13 @@ query7 = np.filter_greater_than(100).and(np.filter_less_than(200))
397
487
  }
398
488
  ```
399
489
 
400
- - sort criteria
490
+ ##### 4.2.2.2 Sort criteria
491
+
492
+ Sort criteria can be appended to an existing query object.
493
+ If you don't use the previous filters, you can generate by `Query.new`.
494
+
495
+ - sort criteria only
496
+
401
497
  ```Ruby
402
498
  query8 = Query.new.ascending tp
403
499
  query9 = Query.new.ascending letp
@@ -425,6 +521,7 @@ query12 = Query.new.ascending(tp).descending letp
425
521
  ```
426
522
 
427
523
  - filter with sort
524
+
428
525
  ```Ruby
429
526
  query13 = tp.filter_starts_with("A").ascending(tp)
430
527
 
@@ -435,116 +532,372 @@ query13 = tp.filter_starts_with("A").ascending(tp)
435
532
  [{"property" => "tp", "direction" => "ascending"}]
436
533
  ```
437
534
 
438
- #### Page class
535
+ #### 4.2.3 Update database
536
+
537
+ === under construction ===
538
+
539
+ ### 4.3 List class
540
+
541
+ `db.query_database` and other API list results returns a List object.
542
+ The list object is an Enumerable object, so usually combines with `.each` method.
439
543
 
440
- - Retrieve a page
441
544
  ```Ruby
442
- page = Page.find("c01166c6-13ae-45cb-b968-18b4ef2f5a77")
545
+ db.query_database(query).each do |page|
546
+ # exec some methods for a page object
547
+ end
443
548
  ```
444
549
 
445
- - Update values and properties
550
+ Notion API returns only the first page-size objects.
551
+ The default page-size of this library is 100.
552
+ Since the above `.each` method is supported for paging, it will automatically execute API call that obtain the following 100 objects when you used the first 100 objects.
553
+ Users do not have to worry about paging.
554
+
555
+ ### 4.4 Block class
446
556
 
447
- Page properties can update in the following three ways.
557
+ === under construction ===
558
+
559
+ ### 4.5 Property classes
560
+
561
+ #### 4.5.1 How to obtain Property object
562
+
563
+ There are the following 17 XXXProperty classes corresponding to Notion databases.
564
+
565
+ 1. TitleProperty
566
+ 2. RichTextProperty
567
+ 3. UrlProperty
568
+ 4. EmailProperty
569
+ 5. PhoneNumberProperty
570
+ 6. NumberProperty
571
+ 7. CheckboxProperty
572
+ 8. SelectProperty
573
+ 9. MultiSelectProperty
574
+ 10. PeopleProperty
575
+ 11. CreatedByProperty
576
+ 12. LastEditedByProperty
577
+ 13. DateProperty
578
+ 14. CreatedTimeProperty
579
+ 15. LastEditedTimeProperty
580
+ 16. FilesProperty
581
+ 17. FormulaProperty
582
+
583
+ They are child classes of a `Property` class and generated from Page or Database objects.
448
584
 
449
- 1. update the property directory (fastest: one API call only)
450
585
  ```Ruby
451
- page = Page.new id: page_id
452
- np = NumberProperty.new "NumberTitle", number: 3.14
453
- page.add_property_for_update np
454
- page.update # update page API call
455
- print page
586
+ page = Page.new page_id, assign: [XXXProperty, "property_name"]
587
+ # or
588
+ page = Page.find page_id
589
+
590
+ xp = page.properties["property_name"]
591
+ # or
592
+ xp, yp = page.properties.values_at "xp_name", "yp_name"
456
593
  ```
457
594
 
458
- 2. update the loaded page (easy but slow: two API call)
595
+ #### 4.5.2 Query object generator of property objects
596
+
597
+ The following methods for the Property objects generate a query object.
598
+
599
+ - TitleProperty, RichTextProperty, UrlProperty, EmailProperty, PhoneNumberProperty
600
+ - filter_equals(value)
601
+ - filter_does_not_equal(value)
602
+ - filter_contains(value)
603
+ - filter_does_not_contain(value)
604
+ - filter_starts_with(value)
605
+ - filter_ends_with(value)
606
+ - filter_is_empty
607
+ - filter_is_not_empty
608
+ - NumberProperty
609
+ - filter_equals(value)
610
+ - filter_does_not_equal(value)
611
+ - filter_greater_than(value)
612
+ - filter_less_than(value)
613
+ - filter_greater_than_or_equal_to(value)
614
+ - filter_less_than_or_equal_to(value)
615
+ - filter_is_empty
616
+ - filter_is_not_empty
617
+ - CheckboxProperty
618
+ - filter_equals(value)
619
+ - filter_does_not_equal(value)
620
+ - SelectProperty
621
+ - filter_equals(value)
622
+ - filter_does_not_equal(value)
623
+ - filter_is_empty
624
+ - filter_is_not_empty
625
+ - MultiSelectProperty, PeopleProperty, CreatedByProperty, LastEditedByProperty
626
+ - filter_contains(value)
627
+ - filter_does_not_contain(value)
628
+ - filter_is_empty
629
+ - filter_is_not_empty
630
+ - DateProperty, CreatedTimeProperty, LastEditedTimeProperty
631
+ - filter_equals(value(Date / Time / DateTime / String))
632
+ - filter_does_not_equal(value(Date / Time / DateTime / String))
633
+ - filter_before(value(Date / Time / DateTime / String))
634
+ - filter_after(value(Date / Time / DateTime / String))
635
+ - filter_on_or_before(value(Date / Time / DateTime / String))
636
+ - filter_on_or_after(value(Date / Time / DateTime / String))
637
+ - filter_past_week
638
+ - filter_past_month
639
+ - filter_past_year
640
+ - filter_next_week
641
+ - filter_next_month
642
+ - filter_next_year
643
+ - FilesProperty
644
+ - filter_is_empty
645
+ - filter_is_not_empty
646
+ - FormulaProperty
647
+ - filter_equals(value(Date / Time / DateTime / String))
648
+ - filter_does_not_equal(value(Date / Time / DateTime / String))
649
+ - filter_before(value(Date / Time / DateTime / String))
650
+ - filter_after(value(Date / Time / DateTime / String))
651
+ - filter_on_or_before(value(Date / Time / DateTime / String))
652
+ - filter_on_or_after(value(Date / Time / DateTime / String))
653
+ - filter_past_week
654
+ - filter_past_month
655
+ - filter_past_year
656
+ - filter_next_week
657
+ - filter_next_month
658
+ - filter_next_year
659
+ - filter_contains(value)
660
+ - filter_does_not_contain(value)
661
+ - filter_starts_with(value)
662
+ - filter_ends_with(value)
663
+ - filter_greater_than(value)
664
+ - filter_less_than(value)
665
+ - filter_greater_than_or_equal_to(value)
666
+ - filter_less_than_or_equal_to(value)
667
+ - filter_is_empty
668
+ - filter_is_not_empty
669
+
670
+ #### 4.5.3 create or update values for Page properties
671
+
672
+ Retrieving Page object has XXXProperties with values.
673
+ On the other hand, Assigned Page object has also XXXProperties, but they don't have any information for pages.
674
+
675
+ XXXProperties can change property values by setter methods.
676
+ Since the setter method is different for each class, it will be explained separately.
677
+
678
+ ##### 4.5.3.1 NumberProperty
679
+
680
+ NumberProperty can set a number by `.number=`.
681
+
459
682
  ```Ruby
460
- page = Page.find first_page_id # retrieve page API call
461
- page.properties["NumberTitle"].number = 2022
462
- page.update # update page API call
463
- print page
683
+ np = page.properties["NumberTitle"]
684
+ np.number = 3.14
685
+ p np.property_values_json
686
+ # Result => => {"np"=>{"number"=>3.14, "type"=>"number"}}
464
687
  ```
465
688
 
466
- 3. update the unloaded page using autoload (easy but slow: two API call)
689
+ ##### 4.5.3.2 SelectProperty
690
+
691
+ NumberProperty can set a select name by `.select=`.
692
+
467
693
  ```Ruby
468
- page = Page.new id: first_page_id
469
- page.properties["NumberTitle"].number = 12345 # retrieve page API call (autoload)
470
- page.update # update page API call
471
- print page
694
+ sp = page.properties["SelectTitle"]
695
+ sp.select = "Select 2"
696
+ p sp.property_values_json
697
+ # Result => {"sp"=>{"type"=>"select", "select"=>{"name"=>"Select 2"}}}
472
698
  ```
473
699
 
474
- - Retrieve block children (List object)
700
+ ##### 4.5.3.3 MultiSelectProperty
701
+
702
+ MultiSelectProperty can set a select value or Array of select values by `.multi_select=`.
703
+
475
704
  ```Ruby
476
- children = page.children
705
+ msp = page.properties["MultiSelectTitle"]
706
+ msp.multi_select = "MS2"
707
+ p msp.property_values_json
708
+ # Result => {"msp"=>{"type"=>"multi_select", "multi_select"=>[{"name"=>"MS2"}]}}
709
+
710
+ msp.multi_select = %w[MS2 MS1]
711
+ p msp.property_values_json
712
+ # Result => {"msp"=>{"type"=>"multi_select", "multi_select"=>[{"name"=>"MS2"}, {"name"=>"MS1"}]}}
477
713
  ```
478
714
 
479
- #### List class
715
+ ##### 4.5.3.4 DateProperty
716
+
717
+ DateProperty can set a start_date or end_date by `.start_date=` or `end_date=`.
718
+ Date, Time, DateTime or String object can be used to the argument.
480
719
 
481
- - access for each components
482
720
  ```Ruby
483
- list.each do |obj| # obj's class is Page or Block
484
- # do something
485
- end
721
+ dp = page.properties["DateTitle"]
722
+ dp.start_date = Date.new(2022, 2, 22)
723
+ p dp.property_values_json
724
+ # Result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-22", "end"=>nil, "time_zone"=>nil}}}
725
+
726
+ dp.start_date = Time.new(2022, 2, 22, 1, 23, 45, "+09:00")
727
+ p dp.property_values_json
728
+ # Result =>{"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-22T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
729
+
730
+ dp.start_date = DateTime.new(2022, 2, 23, 1, 23, 45, "+09:00")
731
+ p dp.property_values_json
732
+ # Result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-23T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
733
+
734
+ dp.start_date = Date.new(2022, 2, 20)
735
+ dp.end_date = Date.new(2022, 2, 22)
736
+ p dp.property_values_json
737
+ # Result => => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-20", "end"=>"2022-02-22", "time_zone"=>nil}}}
738
+
739
+ dp.start_date = Time.new(2022, 2, 21, 1, 23, 45, "+09:00")
740
+ dp.end_date = Time.new(2022, 2, 22, 1, 23, 45, "+09:00")
741
+ p dp.property_values_json
742
+ # Result => {"start" => "2022-02-21T01:23:45+09:00", "end" => "2022-02-22T01:23:45+09:00"}
743
+
744
+ dp.start_date = DateTime.new(2022, 2, 21, 1, 23, 45, "+09:00")
745
+ dp.end_date = DateTime.new(2022, 2, 22, 1, 23, 45, "+09:00")
746
+ p dp.property_values_json
747
+ # result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-21T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
748
+ ```
749
+
750
+ ##### 4.5.3.4 UrlProperty
751
+
752
+ UrlProperty can set a url by `.url=`.
753
+
754
+ ```Ruby
755
+ up = page.properties["UrlTitle"]
756
+ up.url = "https://www.google.com/"
757
+ p up.property_values_json
758
+ # result => {"up"=>{"url"=>"https://www.google.com/", "type"=>"url"}}
486
759
  ```
487
760
 
488
- #### Block class
761
+ ##### 4.5.3.5 EmailProperty
762
+
763
+ EmailProperty can set an email by `.email=`.
764
+
765
+ ```Ruby
766
+ ep = page.properties["MailTitle"]
767
+ ep.email = "https://www.google.com/"
768
+ p ep.property_values_json
769
+ # result => {"ep"=>{"email"=>"hkobhkob@gmail.com", "type"=>"email"}}
770
+ ```
489
771
 
490
- Not implemented
772
+ ##### 4.5.3.6 PhoneNumberProperty
491
773
 
492
- #### NumberProperty class
774
+ PhoneNumberProperty can set an phone number by `.phone_number=`.
493
775
 
494
- - constructor
495
776
  ```Ruby
496
- np = NumberProperty.new "np", number: 123
777
+ pp = page.properties["TelTitle"]
778
+ pp.phone_number = "xx-xxxx-xxxx"
779
+ p pp.property_values_json
780
+ # result => {"pp"=>{"phone_number"=>"xx-xxxx-xxxx", "type"=>"phone_number"}}
497
781
  ```
498
782
 
499
- - set value
783
+ ##### 4.5.3.7 PeopleProperty
784
+
785
+ PeopleProperty can set an people by `.people=`.
786
+ PeopleProperty can set a user_id/UserObject value or Array of user_id/UserObject values by `.people=`.
787
+
500
788
  ```Ruby
501
- np.number = 456 # number <- 456 and will_update <- true
789
+ pp = page.properties["UserTitle"]
790
+ pp.people = "user_id1"
791
+ p pp.property_values_json
792
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id1"}]}}
793
+
794
+ pp.people = UserObject.new json: user1_json
795
+ p pp.property_values_json
796
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id1_from_json"}]}}
502
797
  ```
503
798
 
504
- - create json
505
799
  ```Ruby
506
- np.create_json # {"number" => 456}
800
+ pp.people = %w[user_id2 user_id3]
801
+ p pp.property_values_json
802
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id2"}, {"object"=>"user", "id"=>"user_id3"}]}}
803
+
804
+ u2 = UserObject.new(json: user2_json)
805
+ u3 = UserObject.new(json: user3_json)
806
+ pp.people = [u2, u3]
807
+ p pp.property_values_json
808
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id2_from_json"}, {"object"=>"user", "id"=>"user_id3_from_json"}]}}
507
809
  ```
508
810
 
509
- #### SelectProperty class
811
+ ##### 4.5.3.8 TitleProperty, RichTextProperty
812
+
813
+ TextProperty's subclasses (TitleProperty, RichTextProperty) have an array of TextObject objects.
814
+ `[]` method returns an existing TextObject.
815
+ The obtained TextObject can be set text by `.text=`.
816
+
817
+ ```Ruby
818
+ pp = page.properties["Title"]
819
+ tp[0].text = "ABC\n"
820
+ p tp.property_values_json
821
+ # result => {"tp"=>{"type"=>"title", "title"=>[{"type"=>"text", "text"=>{"content"=>"ABC\n", "link"=>nil}, "plain_text"=>"ABC\n", "href"=>nil}]}}
822
+ ```
510
823
 
511
- - constructor
824
+ `<<` method appends a new TextObject or a String.
512
825
  ```Ruby
513
- sp = SelectProperty.new "sp", select: "Select 1"
826
+ to = TextObject.new "DEF"
827
+ to.bold = true
828
+ to.italic = true
829
+ to.strikethrough = true
830
+ to.underline = true
831
+ to.code = true
832
+ to.color = "default"
833
+ tp << to
834
+ p tp.property_values_json
835
+ # result => {"tp"=>{"type"=>"title","title"=>[{"type"=>"text","text"=>{"content"=>"ABC\n","link"=>nil},"plain_text"=>"ABC\n","href"=>nil},{"type"=>"text","text"=>{"content"=>"DEF","link"=>nil},"plain_text"=>"DEF","href"=>nil,"annotations"=>{"bold"=>true,"italic"=>true,"strikethrough"=>true,"underline"=>true,"code"=>true,"color"=>"default"}}]}}
514
836
  ```
515
837
 
516
- - set value
838
+ `delete_at(index)` method remove a TextObject at index.
517
839
  ```Ruby
518
- sp.select = "Select 2" # select <- "Select 2" and will_update <- true
840
+ tp.delete_at 1
841
+ tp << "GHI"
842
+ p tp.property_values_json
843
+ # result => {"tp"=>{"type"=>"title", "title"=>[{"type"=>"text", "text"=>{"content"=>"ABC\n", "link"=>nil}, "plain_text"=>"ABC\n", "href"=>nil}, {"type"=>"text", "text"=>{"content"=>"DEF", "link"=>nil}, "plain_text"=>"DEF", "href"=>nil, "annotations"=>{"bold"=>true, "italic"=>true, "strikethrough"=>true, "underline"=>true, "code"=>true, "color"=>"default"}}, {"type"=>"text", "text"=>{"content"=>"GHI", "link"=>nil}, "plain_text"=>"GHI", "href"=>nil}]}}
519
844
  ```
520
845
 
521
- - create json
846
+ ##### 4.5.3.9 CheckboxProperty
847
+
848
+ PeopleProperty can set a boolean value by `.checkbox=`.
522
849
  ```Ruby
523
- sp.create_json # {"select" => {"name" => "Select 2"}}
850
+ cp = page.properties["CheckboxTitle"]
851
+ cp.checkbox = true
852
+ p cp.property_values_json
853
+ # result => {"cp"=>{"checkbox"=>true, "type"=>"checkbox"}}
524
854
  ```
525
855
 
526
- #### MultiSelectProperty class
856
+ ##### 4.5.3.10 EmailProperty
527
857
 
528
- - constructor
858
+ EmailProperty can set an email address by `.email=`.
529
859
  ```Ruby
530
- msp1 = MultiSelectProperty.new "msp1", multi_select: "MS1" # Single value
531
- msp2 = MultiSelectProperty.new "msp2", multi_select: %w[MS1 MS2] # Multi values
860
+ ep = page.properties["MailTitle"]
861
+ ep.email = "hkobhkob@gmail.com"
862
+ p ep.property_values_json
863
+ # result => {"ep"=>{"email"=>"hkobhkob@gmail.com", "type"=>"email"}}
532
864
  ```
533
865
 
534
- - set value
866
+ ##### 4.5.3.11 FilesProperty
867
+
868
+ FilesProperty can set an external url or Array of external urls by `.files=`.
869
+
535
870
  ```Ruby
536
- msp1.multi_select = %w[MS2 MS1] # multi_select <- ["MS1", "MS2"] and will_update <- true
537
- msp2.select = "MS2" # multi_select <- "MS2" and will_update <- true
871
+ fp = page.properties["FilesTitle"]
872
+ fp.files = "F1"
873
+ p fp.property_values_json
874
+ # Result => {"fp"=>{"files"=>[{"name"=>"F1", "type"=>"external", "external"=>{"url"=>"F1"}}], "type"=>"files"}}
875
+
876
+ fp.files = %w[F2 F3]
877
+ p fp.property_values_json
878
+ # Result => {"fp"=>{"files"=>[{"name"=>"F2", "type"=>"external", "external"=>{"url"=>"F2"}}, {"name"=>"F3", "type"=>"external", "external"=>{"url"=>"F3"}}], "type"=>"files"}}
538
879
  ```
539
880
 
540
- - create json
881
+ ##### 4.5.3.12 RelationProperty
882
+
883
+ RelationProperty can set an relation's page_id or Array of relation's page_ids by `.relation=`.
884
+
541
885
  ```Ruby
542
- msp1.create_json # {"multi_select" => [{"name" => "MS2"}, {"name" => "MS1"}]}
543
- msp2.create_json # {"multi_select" => [{"name" => "MS2"}]}
886
+ rp = page.properties["RelationTitle"]
887
+ rp.relation = "R1"
888
+ p rp.property_values_json
889
+ # Result => {"rp"=>{"type"=>"relation", "relation"=>[{"id"=>"R1"}]}}
890
+
891
+ rp.relation = %w[R2 R3]
892
+ p rp.property_values_json
893
+ # Result => {"rp"=>{"type"=>"relation", "relation"=>[{"id"=>"R2"}, {"id"=>"R3"}]}}
544
894
  ```
545
895
 
546
- ## ChangeLog
547
896
 
897
+ ## 6. ChangeLog
898
+
899
+ - 2022/3/14 Exclude notion-ruby-client, update Property values, update for Notion-Version 2022-02-22
900
+ - 2022/2/25 add_property_for_update -> assign_property, update README.md
548
901
  - 2022/2/20 add support for MultiSelectProperty
549
902
  - 2022/2/19 add support for SelectProperty
550
903
  - 2022/2/17 added Page#properties, Page#add_property_for_update, Page#update
@@ -554,18 +907,18 @@ msp2.create_json # {"multi_select" => [{"name" => "MS2"}]}
554
907
  - 2022/2/13 added Page#set_icon
555
908
  - 2022/2/13 First commit
556
909
 
557
- ## Contributing
910
+ ## 6. Contributing
558
911
 
559
- Bug reports and pull requests are welcome on GitHub at https://github.com/hkob/notion_ruby_mapping. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
912
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/hkob/notion_ruby_mapping>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
560
913
 
561
- ## License
914
+ ## 7. License
562
915
 
563
916
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
564
917
 
565
- ## Code of Conduct
918
+ ## 8. Code of Conduct
566
919
 
567
920
  Everyone interacting in the NotionRubyMapping project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
568
921
 
569
- ## Acknowledgements
922
+ ## 9. Acknowledgements
570
923
 
571
- The code depends on [notion-ruby-client](https://github.com/orbit-love/notion-ruby-client).
924
+ The code depends on [notion-ruby-client](https://github.com/orbit-love/notion-ruby-client).