notion_ruby_mapping 0.1.3 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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 +42 -18
  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 +41 -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 -43
  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).