todoist-ruby 0.1.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7daad29d7cd0d65b9368bd878565885bcd2a6f32
4
- data.tar.gz: b50c774800956866d824b8ec19f65821ccde9a29
2
+ SHA256:
3
+ metadata.gz: d4bf078a206d6401d5e257058da4948f5c07eb4e811d1d5205a4d7d004ae6c8d
4
+ data.tar.gz: e8658818f731cc58b4305eb5f891d6084d80a390d70a6011417f1eb8380ca600
5
5
  SHA512:
6
- metadata.gz: c9bccb4c9920626e43af53b1171f404c91c60813aaf422f77ddcebfd2a19448dad04a4599b8b993c356503c4827dde6b87bf0e0b4b00ef2c73af0d12b82bb1ab
7
- data.tar.gz: 31fa4e9e42d0ed96829fb107ad2323832f70c774f8ae0cccde9d800b5dcab9d0cb09df9999c828b4ed614be0181c7410d762c1a8be54d66c3867afb9cd1ee472
6
+ metadata.gz: 30b7c35ca9477698fec2b2f14e0d2e2a82f47e328aa0387b156c5edc4427136b12300043deccbf9ece739b8579016d10e1d430ba09f20b78f6480fc8917c036d
7
+ data.tar.gz: a8639df99ff2e11c33744f1cb7f21a56a4e395d7997d9690fa1b4098529307d2bea491b9e04a7a9413dbc5c253fd7602ab8011302f3a0b0c1d923093c7dca38a
data/README.md CHANGED
@@ -1,28 +1,28 @@
1
1
  # Todoist Ruby
2
2
 
3
- This is an unofficial client library that interfaces with the [Todoist API](https://developer.todoist.com/).
3
+ This is an unofficial client library that interfaces with the [Todoist API](https://developer.todoist.com/sync/v8/).
4
4
 
5
5
  ## What's implemented
6
6
 
7
- ### sync API
7
+ ### Sync API
8
8
 
9
9
  The "sync" API is almost fully implemented with the exception of collaboration features.
10
10
 
11
- * [Projects](https://developer.todoist.com/#projects)
12
- * [Templates](https://developer.todoist.com/#templates)
13
- * [Items](https://developer.todoist.com/#items)
14
- * [Labels](https://developer.todoist.com/#labels)
15
- * [Notes](https://developer.todoist.com/#notes)
16
- * [Filters](https://developer.todoist.com/#filters)
17
- * [Reminders](https://developer.todoist.com/#reminders)
11
+ * [Projects](https://developer.todoist.com/sync/v8/#projects)
12
+ * [Templates](https://developer.todoist.com/sync/v8/#templates)
13
+ * [Items](https://developer.todoist.com/sync/v8/#items)
14
+ * [Labels](https://developer.todoist.com/sync/v8/#labels)
15
+ * [Notes](https://developer.todoist.com/sync/v8/#notes)
16
+ * [Filters](https://developer.todoist.com/sync/v8/#filters)
17
+ * [Reminders](https://developer.todoist.com/sync/v8/#reminders)
18
18
 
19
19
  ### Other APIs
20
20
 
21
- * [Miscellaneous](https://developer.todoist.com/#miscellaneous)
22
- * [Quick](https://developer.todoist.com/#quick)
23
- * [Activity](https://developer.todoist.com/#activity)
24
- * [Uploads](https://developer.todoist.com/#uploads)
25
- * [Backups](https://developer.todoist.com/#backups)
21
+ * [Miscellaneous](https://developer.todoist.com/sync/v8/#miscellaneous)
22
+ * [Quick](https://developer.todoist.com/sync/v8/#quick)
23
+ * [Activity](https://developer.todoist.com/sync/v8/#activity)
24
+ * [Uploads](https://developer.todoist.com/sync/v8/#uploads)
25
+ * [Backups](https://developer.todoist.com/sync/v8/#backups)
26
26
 
27
27
  In addition to the above mentioned APIs, there is also an implementation of the "query" method call provided (with limitations documented).
28
28
 
@@ -30,10 +30,10 @@ In addition to the above mentioned APIs, there is also an implementation of the
30
30
 
31
31
  Generally speaking collaboration features are not supported through this API but contributions are welcome and encouraged primarily due to testing limitations and the requirement to have multiple accounts. This includes:
32
32
 
33
- * [Emails](https://developer.todoist.com/#emails)
34
- * [User](https://developer.todoist.com/#user)
35
- * [Sharing](https://developer.todoist.com/#sharing)
36
- * [Live notifications](https://developer.todoist.com/#live-notifications)
33
+ * [Emails](https://developer.todoist.com/sync/v8/#emails)
34
+ * [User](https://developer.todoist.com/sync/v8/#user)
35
+ * [Sharing](https://developer.todoist.com/sync/v8/#sharing)
36
+ * [Live notifications](https://developer.todoist.com/sync/v8/#live-notifications)
37
37
 
38
38
  ## Installation
39
39
 
@@ -62,68 +62,61 @@ Or install it yourself as:
62
62
  This section provides some simple scenarios to get started. To use the library make sure you include the library as follows:
63
63
 
64
64
  ```ruby
65
- require todoist
65
+ require 'todoist'
66
66
  ```
67
67
 
68
68
  ### Logging in and setting tokens
69
69
 
70
- Before you make any API calls, you **must** login. The library supports two methods:
70
+ Before you make any API calls, you **must** create a client using one of two methods. The library supports two methods:
71
71
 
72
72
  #### Email and password
73
73
 
74
74
  ```ruby
75
- user_manager = Todoist::Misc::User.new
76
- user = user_manager.login("hello@example.com", "123")
77
- user.email
78
- => "hello@example.com"
75
+ @client = Todoist::Client.create_client_by_login("hello@example.com", "123")
79
76
  ```
80
77
 
81
- Upon calling the login method, an object is returned implemented through an [OpenStruct](http://ruby-doc.org/stdlib-2.0.0/libdoc/ostruct/rdoc/OpenStruct.html) that represents a variety of fields that may be useful to you.
82
-
83
78
  #### Token
84
79
 
85
- New tokens can be generated at the [Todoist App Management portal](https://developer.todoist.com/appconsole.html). Once a token has been acquired simply set it as so:
80
+ New tokens can be generated at the [Todoist App Management portal](https://developer.todoist.com/appconsole.html) or [General API token](https://todoist.com/prefs/integrations). Once a token has been acquired you can create a client by calling:
86
81
 
87
82
  ```ruby
88
- Todoist::Config.token = "my token"
83
+ @client = Todoist::Client.create_client_by_token("my token")
89
84
  ```
90
85
 
91
- ### Using the sync API
92
-
93
- The Todoist sync API enables you to mimic how the actual Todoist client retrieves information. Among other nuances, the sync API minimizes network traffic by batching a series of calls together. It supports dependencies between as-yet-created objects through temporary IDs.
86
+ ### Using the API
94
87
 
95
- Because of the way the API is designed, it is likely your application will need to use some combination of the sync api along with the other, lighterweight methods also provided.
88
+ The Todoist API enables you to mimic how the actual Todoist client retrieves information. Among other nuances, the "sync" API minimizes network traffic by batching a series of calls together. It supports dependencies between as-yet-created objects through temporary IDs. In addition to the sync API, Todoist also has several other methods that are lighterweight. For many light use cases, the lightweight methods will suffice but for more complex cases you will likely need to use both approaches.
96
89
 
97
- Managers provides in the sync API all exist in the module ```Todoist::Sync```.
90
+ All APIs can be accessed through the client. In general, the naming convention to access the service is ```[api_type]_[api]```.
98
91
 
99
92
  There are two ways to force a sync in the API:
100
93
 
101
- 1. ```manager_object.collection```: Calling collection forces the library to sync with the Todoist server to retrieve the latest. This method stores an internal in-memory copy of the result for incremental syncs but the caller should store a copy of the result in its own variable for query purposes.
102
- 2. ```Todoist::Util::CommandSynchronizer.sync```: Calling this method forcibly syncs the side-effects that have been queued.
94
+ 1. ```collection```: Calling collection forces the library to sync with the Todoist server to retrieve the latest. This method stores an internal in-memory copy of the result for incremental syncs but the caller should store a copy of the result in its own variable for query purposes. The following call syncs all items and returns a collection of the items: ```@client.sync_items.collection```.
95
+ 2. ```sync```: Calling the sync method on the client object forces a sync which can be called like ```@client.sync```
103
96
 
104
- When objects are called using the ```manager.object.add``` methods, a shallow object is created with a temporary id accessible by sending an ```id``` message. Once any of the above synchronization methods are called above, the ids are updated via a callback with their actual ids so they can be used in subsequent calls.
97
+ When objects are called using the ```add``` methods, a shallow object is created with a temporary id accessible by sending an ```id``` message. Once any of the above synchronization methods are called above, the ids are updated via a callback with their actual ids so they can be used in subsequent calls.
105
98
 
106
- #### Creating an item
99
+ #### Creating an item
107
100
 
108
- ```ruby
109
- update_item = @item_manager.add({content: "Item3"})
101
+ ```ruby
102
+ update_item = @client.sync_items.add({content: "Item3"})
110
103
  ## At this time update_item has a temporary id
111
104
 
112
105
  update_item.priority = 2
113
- result = @item_manager.update(update_item)
106
+ result = @client.sync_items.update(update_item)
114
107
  # Up until this point update_item has not been created yet
115
108
 
116
- items_list = @item_manager.collection
109
+ items_list = @client.sync_items.collection
117
110
  # Update item is created and a query is issued to sync up the existing items. The actual id of the newly created item is updated and so now update_item should have the actual id.
118
111
 
119
112
  queried_object = items_list[update_item.id]
120
113
  # update_item remains a shallow value object. To fully inflate the object, you will need to retrieve the item from the list. At this point, queried_object has a fully inflated copy of the object
121
114
 
122
- @item_manager.delete([update_item])
115
+ @client.sync_items.delete([update_item])
123
116
  # As is the case with other side-effects, issuing the call does not send the request immediately.
124
117
 
125
- Todoist::Util::CommandSynchronizer.sync
126
- # Manually calling sync deletes the item
118
+ @client.sync
119
+ # Manually calling sync deletes the item
127
120
  ```
128
121
 
129
122
  For more detailed examples, please review the unit tests located in the ```spec``` directory.
@@ -135,8 +128,7 @@ The rest of the APIs are available in the ```Todoist::Misc``` module. For light
135
128
  #### Creating an item using the "quick" API
136
129
 
137
130
  ```ruby
138
- @misc_quick_manager = Todoist::Misc::Quick.new
139
- item = @misc_quick_manager.add_item("Test quick add content today")
131
+ item = @client.misc_quick.add_item("Test quick add content today")
140
132
  # Unlike the sync API the item is already created after this method call and fully inflated
141
133
  ```
142
134
  ### Rate limiting
@@ -155,7 +147,7 @@ The library provides two defenses against this.
155
147
  If an ```HTTP 429 Too Many Requests``` is received, the library can wait for a period of time and then retry with an exponential backoff. To configure this parameter:
156
148
 
157
149
  ```ruby
158
- Todoist::Util::Config.retry_time = 40
150
+ Todoist::Config.retry_time = 40
159
151
  # Default is 20s, adds a 40s delay
160
152
  ```
161
153
 
@@ -164,7 +156,7 @@ Todoist::Util::Config.retry_time = 40
164
156
  To set an artifical delay between sync requests:
165
157
 
166
158
  ```ruby
167
- Todoist::Util::Config.delay_between_requests = 2
159
+ Todoist::Config.delay_between_requests = 2
168
160
  # Default is 0, adds a 2s delay
169
161
  ```
170
162
 
@@ -190,9 +182,62 @@ rake spec:clean["misc_items"]
190
182
 
191
183
  Once tests pass cleanly, subsquent runs that do not change the network requests run quickly since no network calls are made and in fact ```rake``` can be run with no issues.
192
184
 
193
- ## Version History
194
185
 
195
- * 0.1.3: Changed Todoist::Sync managers so that the update method uses a hash instead of an OpenStruct. The OpenStruct creates errors when an OpenStruct passed from a previous call is used. The hash helps the caller make fewer mistakes.
186
+ ## Migration
187
+
188
+ ### Migrating from 1.x to 2.x
189
+
190
+ 2.x was a major rewrite of the library that avoids using classes as Singletons. In addition, in 2.x the client facing interfaces have been greatly simplified.
191
+
192
+ ### Authentication
193
+
194
+ Instead of:
195
+ ```
196
+ Todoist::Config.token = "my token"
197
+ ```
198
+
199
+ Use:
200
+
201
+ ```
202
+ @client = Todoist::Client.create_client_by_token("my token")
203
+ ```
204
+
205
+ ### Calling Services
206
+
207
+ Instead of:
208
+
209
+ ```
210
+ @manager = Todoist::Sync::Items.new
211
+ @manager.collection
212
+ ```
213
+
214
+ Use:
215
+ ```
216
+ @client.sync_items.collection
217
+ ```
218
+
219
+ ### Synchronization
220
+
221
+ Instead of:
222
+
223
+ ```
224
+ Todoist::Util::CommandSynchronizer.sync
225
+ ```
226
+
227
+ Use:
228
+
229
+ ```
230
+ @client.sync
231
+ ```
232
+
233
+
234
+ ## Version History
235
+ * 0.2.5: Fix for Extra params aren't sent when creating a item when using the misc add_item method. (Thank you to @juliend2)
236
+ * 0.2.4: Numerous bug fixes to address v7 to v8 changes that go beyond just an endpoint change. Passing all specs.
237
+ * 0.2.3: Updated to v8 endpoints
238
+ * 0.2.2: For some code paths, it seems OpenSSL does not get loaded. Added require 'openssl' to network helper
239
+ * 0.2.1: Major refactoring of library to support implementations that require multi-user support in a concurrent environment (e.g. Rails app). The previous implementation relied heavily on class singletons. Internally, the code has been cleaned up significantly. Due to the scale of changes, 0.2.1 is not compatible 0.1.x versions of the library.
240
+ * 0.1.3: Changed ```Todoist::Sync``` managers so that the update method uses a hash instead of an OpenStruct. The OpenStruct creates errors when an OpenStruct passed from a previous call is used. The hash helps the caller make fewer mistakes.
196
241
  * 0.1.2: Renamed method ```Todoist::Util::ParseHelper.make_objects_as_array``` to ```Todoist::Util::ParseHelper.make_objects_as_hash``` to reflect the fact that it was actually returning hashes. Added the aforementioned deleted method to return arrays and finally altered ```Todoist::Misc::Completed``` to return objects as arrays instead of hashes due to the fact that recurring completed items were being de-duped unintentionally and data was being lost as a result.
197
242
  * 0.1.1: Initial release.
198
243
 
@@ -204,4 +249,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/h6y3/t
204
249
  ## License
205
250
 
206
251
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
207
-
@@ -1,6 +1,10 @@
1
1
  require "todoist/version"
2
+ require "todoist/config"
2
3
  require "todoist/util/api_helper"
3
4
  require "todoist/util/network_helper"
5
+ require "todoist/service"
6
+ require "todoist/client"
7
+
4
8
  require "todoist/sync/items"
5
9
  require "todoist/sync/labels"
6
10
  require "todoist/sync/projects"
@@ -15,8 +19,6 @@ require "todoist/misc/items"
15
19
  require "todoist/misc/quick"
16
20
  require "todoist/misc/activity"
17
21
  require "todoist/misc/backups"
18
- require "todoist/misc/user"
19
- require "todoist/misc/query"
20
22
 
21
23
  module Todoist
22
24
 
@@ -0,0 +1,119 @@
1
+ module Todoist
2
+ class Client
3
+
4
+ def self.create_client_by_token(token)
5
+ client = Client.new
6
+ client.token = token
7
+ client
8
+ end
9
+
10
+ # TODO: Need to write a unit test for this
11
+ def self.create_client_by_login(email, password)
12
+ client = Client.new
13
+ result = client.api_helper.get_response(Config::TODOIST_USER_LOGIN_COMMAND, {email: email, password: password}, false)
14
+ user = Todoist::Util::ParseHelper.make_object(result)
15
+ client.token = user.token
16
+ client
17
+ end
18
+
19
+ def token=(token)
20
+ @token = token.chomp
21
+ end
22
+
23
+ def token
24
+ @token
25
+ end
26
+
27
+ def sync
28
+ @api_helper.sync
29
+ end
30
+
31
+ def misc_activity
32
+ @misc_activity = Todoist::Misc::Activity.new(self) unless @misc_activity
33
+ @misc_activity
34
+ end
35
+
36
+ def misc_backups
37
+ @misc_backups = Todoist::Misc::Backups.new(self) unless @misc_backups
38
+ @misc_backups
39
+ end
40
+
41
+ def misc_completed
42
+ @misc_completed = Todoist::Misc::Completed.new(self) unless @misc_completed
43
+ @misc_completed
44
+ end
45
+
46
+ def misc_items
47
+ @misc_items = Todoist::Misc::Items.new(self) unless @misc_items
48
+ @misc_items
49
+ end
50
+
51
+ def misc_projects
52
+ @misc_projects = Todoist::Misc::Projects.new(self) unless @misc_projects
53
+ @misc_projects
54
+ end
55
+
56
+ def misc_query
57
+ @misc_query = Todoist::Misc::Query.new(self) unless @misc_query
58
+ @misc_query
59
+ end
60
+
61
+ def misc_quick
62
+ @misc_quick = Todoist::Misc::Quick.new(self) unless @misc_quick
63
+ @misc_quick
64
+ end
65
+
66
+ def misc_templates
67
+ @misc_templates = Todoist::Misc::Templates.new(self) unless @misc_templates
68
+ @misc_templates
69
+ end
70
+
71
+ def misc_uploads
72
+ @misc_uploads = Todoist::Misc::Uploads.new(self) unless @misc_uploads
73
+ @misc_uploads
74
+ end
75
+
76
+ def sync_filters
77
+ @sync_filters = Todoist::Sync::Filters.new(self) unless @sync_filters
78
+ @sync_filters
79
+ end
80
+
81
+ def sync_items
82
+ @sync_items = Todoist::Sync::Items.new(self) unless @sync_items
83
+ @sync_items
84
+ end
85
+
86
+ def sync_labels
87
+ @sync_labels = Todoist::Sync::Labels.new(self) unless @sync_labels
88
+ @sync_labels
89
+ end
90
+
91
+ def sync_notes
92
+ @sync_notes = Todoist::Sync::Notes.new(self) unless @sync_notes
93
+ @sync_notes
94
+ end
95
+
96
+ def sync_projects
97
+ @sync_projects = Todoist::Sync::Projects.new(self) unless @sync_projects
98
+ @sync_projects
99
+ end
100
+
101
+ def sync_reminders
102
+ @sync_reminders = Todoist::Sync::Reminders.new(self) unless @sync_reminders
103
+ @sync_reminders
104
+ end
105
+
106
+ def api_helper
107
+ @api_helper
108
+ end
109
+
110
+ protected
111
+
112
+ def initialize
113
+ @api_helper = Todoist::Util::ApiHelper.new(self)
114
+ end
115
+
116
+
117
+
118
+ end
119
+ end
@@ -0,0 +1,64 @@
1
+ module Todoist
2
+ class Config
3
+ TODOIST_API_URL = "https://api.todoist.com/sync/v8"
4
+
5
+ # List of commands supported
6
+ @@command_list = [
7
+ TODOIST_SYNC_COMMAND = "/sync",
8
+ TODOIST_TEMPLATES_IMPORT_INTO_PROJECT_COMMAND = "/templates/import_into_project",
9
+ TODOIST_TEMPLATES_EXPORT_AS_FILE_COMMAND = "/templates/export_as_file",
10
+ TODOIST_TEMPLATES_EXPORT_AS_URL_COMMAND = "/templates/export_as_url",
11
+ TODOIST_UPLOADS_ADD_COMMAND = "/uploads/add",
12
+ TODOIST_UPLOADS_GET_COMMAND = "/uploads/get",
13
+ TODOIST_UPLOADS_DELETE_COMMAND = "/uploads/delete",
14
+ TODOIST_COMPLETED_GET_STATS_COMMAND = "/completed/get_stats",
15
+ TODOIST_COMPLETED_GET_ALL_COMMAND = "/completed/get_all",
16
+ TODOIST_PROJECTS_GET_ARCHIVED_COMMAND = "/projects/get_archived",
17
+ TODOIST_PROJECTS_GET_COMMAND = "/projects/get",
18
+ TODOIST_PROJECTS_GET_DATA_COMMAND = "/projects/get_data",
19
+ TODOIST_ITEMS_ADD_COMMAND = "/items/add",
20
+ TODOIST_ITEMS_GET_COMMAND = "/items/get",
21
+ TODOIST_QUICK_ADD_COMMAND = "/quick/add",
22
+ TODOIST_ACTIVITY_GET_COMMAND = "/activity/get",
23
+ TODOIST_BACKUPS_GET_COMMAND = "/backups/get",
24
+ TODOIST_USER_LOGIN_COMMAND = "/user/login"
25
+ ]
26
+
27
+ # Map of commands to URIs
28
+ @@uri = nil
29
+
30
+ # Artificial delay between requests to avoid API throttling
31
+ @@delay_between_requests = 0
32
+
33
+ # Should API throttling happen (HTTP Error 429), retry_time between requests
34
+ # with exponential backoff
35
+ @@retry_time = 20
36
+
37
+ def self.retry_time=(retry_time)
38
+ @@retry_time = retry_time
39
+ end
40
+
41
+ def self.retry_time
42
+ @@retry_time
43
+ end
44
+
45
+ def self.delay_between_requests=(delay_between_requests)
46
+ @@delay_between_requests = delay_between_requests
47
+ end
48
+
49
+ def self.delay_between_requests
50
+ @@delay_between_requests
51
+ end
52
+
53
+ def self.getURI
54
+ if @@uri == nil
55
+ @@uri = {}
56
+ @@command_list.each do |command|
57
+ @@uri[command] = URI.parse(TODOIST_API_URL + command)
58
+ end
59
+ end
60
+ return @@uri
61
+ end
62
+
63
+ end
64
+ end