ruby-todoist-api 0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.kick +18 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +45 -0
- data/Rakefile +2 -0
- data/lib/todoist.rb +27 -0
- data/lib/todoist/client.rb +94 -0
- data/lib/todoist/command.rb +24 -0
- data/lib/todoist/error.rb +0 -0
- data/lib/todoist/filter.rb +16 -0
- data/lib/todoist/item.rb +54 -0
- data/lib/todoist/label.rb +15 -0
- data/lib/todoist/note.rb +19 -0
- data/lib/todoist/project.rb +32 -0
- data/lib/todoist/query.rb +47 -0
- data/lib/todoist/queue.rb +39 -0
- data/lib/todoist/reminder.rb +16 -0
- data/lib/todoist/request.rb +37 -0
- data/lib/todoist/resource.rb +73 -0
- data/lib/todoist/service/base_service.rb +77 -0
- data/lib/todoist/service/filter.rb +9 -0
- data/lib/todoist/service/item.rb +24 -0
- data/lib/todoist/service/label.rb +9 -0
- data/lib/todoist/service/note.rb +9 -0
- data/lib/todoist/service/project.rb +9 -0
- data/lib/todoist/service/reminder.rb +9 -0
- data/lib/todoist/user.rb +10 -0
- data/lib/todoist/version.rb +3 -0
- data/ruby-todoist-api.gemspec +22 -0
- data/spec/lib/todoist/client_spec.rb +58 -0
- data/spec/lib/todoist/filter_spec.rb +19 -0
- data/spec/lib/todoist/item_spec.rb +39 -0
- data/spec/lib/todoist/label_spec.rb +12 -0
- data/spec/lib/todoist/note_spec.rb +12 -0
- data/spec/lib/todoist/project_spec.rb +12 -0
- data/spec/lib/todoist/query_spec.rb +26 -0
- data/spec/lib/todoist/reminder_spec.rb +12 -0
- data/spec/lib/todoist/service/filter_spec.rb +33 -0
- data/spec/lib/todoist/service/item_spec.rb +46 -0
- data/spec/lib/todoist/service/label_spec.rb +33 -0
- data/spec/lib/todoist/service/note_spec.rb +33 -0
- data/spec/lib/todoist/service/project_spec.rb +33 -0
- data/spec/lib/todoist/service/reminder_spec.rb +33 -0
- data/spec/lib/todoist_spec.rb +7 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/json_response_helper.rb +17 -0
- data/spec/support/responses/filter.json +9 -0
- data/spec/support/responses/item.json +25 -0
- data/spec/support/responses/label.json +8 -0
- data/spec/support/responses/note.json +18 -0
- data/spec/support/responses/project.json +14 -0
- data/spec/support/responses/query.json +88 -0
- data/spec/support/responses/reminder.json +9 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2b507fa8fca73baa2ead62502e01e13594845643
|
4
|
+
data.tar.gz: 247941d5ae67bb886031300163bf8dde9d03d786
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 15b90aaed52b0088af9d8b646fefd58ea3600d2722dd6347b9c7ac3976d2fb66ce1205c7a991e01d8698deef38154d951b0c436090abdcae715b5234f696b195
|
7
|
+
data.tar.gz: b0ac8033d9612ad994ca382a83452df7d6801cac805d437527a2c5620849b7fea047f89d6d2fea1c183cb31fe15a34fd18b327538bbea0fdf486a1395812f42c
|
data/.gitignore
ADDED
data/.kick
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
process do |file, flags|
|
5
|
+
test_files = Set.new
|
6
|
+
case file
|
7
|
+
when %r(^spec/.*_spec.rb$)
|
8
|
+
test_files << file
|
9
|
+
when %r(^lib/(.*).rb)
|
10
|
+
test_files << 'spec/lib/' + $1 + '_spec.rb'
|
11
|
+
when %r(^spec/helpers/expected)
|
12
|
+
test_files.merge Dir['spec/helpers/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
test_files = test_files.select { |filename| File.exist?(filename) }
|
15
|
+
unless test_files.empty?
|
16
|
+
watcher.execute("bundle exec rspec --fail-fast #{test_files.to_a.join(' ')}")
|
17
|
+
end
|
18
|
+
end
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Maarten van Vliet
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/maartenvanvliet/ruby-todoist-api.svg)](https://travis-ci.org/maartenvanvliet/ruby-todoist-api)
|
2
|
+
|
3
|
+
# Todoist::Api
|
4
|
+
|
5
|
+
Gem to wrap the Todoist Api v6 as described on https://developer.todoist.com/
|
6
|
+
|
7
|
+
*Note:* Until a more complete coverage of the all Todoist features is achieved the api is unstable and no semantic versioning will be applied.
|
8
|
+
|
9
|
+
## Goals
|
10
|
+
|
11
|
+
* To provide an easy to use, well tested, wrapper for the Todoist Api
|
12
|
+
* Use a minimal set of dependencies apart from the Ruby standard library (exception for development dependencies, although also bare minimum).
|
13
|
+
* Ruby 2.1 and up
|
14
|
+
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'todoist-api', git: 'https://github.com/maartenvanvliet/ruby-todoist-api', branch: 'master', require: 'todoist'
|
22
|
+
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle install
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
todoist = Todoist::Client.new(todoist_token)
|
32
|
+
todoist.items.create(content: 'Some new todo')
|
33
|
+
todoist.process!
|
34
|
+
|
35
|
+
## Future
|
36
|
+
|
37
|
+
Possible spinoff would be a gem to do provide a CLI interface to Todoist.
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
1. Fork it ( https://github.com/maartenvanvliet/ruby-todoist-api/fork )
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
45
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/todoist.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Todoist; end
|
5
|
+
|
6
|
+
require 'todoist/client'
|
7
|
+
require 'todoist/command'
|
8
|
+
require 'todoist/resource'
|
9
|
+
require 'todoist/error'
|
10
|
+
require 'todoist/filter'
|
11
|
+
require 'todoist/item'
|
12
|
+
require 'todoist/label'
|
13
|
+
require 'todoist/note'
|
14
|
+
require 'todoist/project'
|
15
|
+
require 'todoist/query'
|
16
|
+
require 'todoist/queue'
|
17
|
+
require 'todoist/user'
|
18
|
+
require 'todoist/reminder'
|
19
|
+
require 'todoist/request'
|
20
|
+
require 'todoist/service/base_service'
|
21
|
+
require 'todoist/service/filter'
|
22
|
+
require 'todoist/service/item'
|
23
|
+
require 'todoist/service/label'
|
24
|
+
require 'todoist/service/note'
|
25
|
+
require 'todoist/service/project'
|
26
|
+
require 'todoist/service/reminder'
|
27
|
+
require 'todoist/version'
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Client
|
3
|
+
attr_reader :token, :queue, :_last_response
|
4
|
+
attr_writer :seq_no, :seq_no_global
|
5
|
+
attr_accessor :errors
|
6
|
+
|
7
|
+
SUCCES_STATUS_CODE = 200
|
8
|
+
|
9
|
+
def initialize(token)
|
10
|
+
@token = token
|
11
|
+
end
|
12
|
+
|
13
|
+
def base_url
|
14
|
+
"https://todoist.com"
|
15
|
+
end
|
16
|
+
|
17
|
+
def filters
|
18
|
+
@filters ||= Service::Filter.new(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def items
|
22
|
+
@items ||= Service::Item.new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def labels
|
26
|
+
@labels ||= Service::Label.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def notes
|
30
|
+
@notes ||= Service::Note.new(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def projects
|
34
|
+
@projects ||= Service::Project.new(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def reminders
|
38
|
+
@reminders ||= Service::Reminder.new(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def query
|
42
|
+
@query ||= Query.new(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def queue
|
46
|
+
@queue ||= Queue.new(self)
|
47
|
+
end
|
48
|
+
|
49
|
+
def seq_no
|
50
|
+
@seq_no ||= 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def seq_no_global
|
54
|
+
@seq_no_global ||= 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def logger
|
58
|
+
@logger ||= Logger.new($stdout).tap do |log|
|
59
|
+
log.progname = 'todoist-api'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def post(path, payload)
|
64
|
+
post_request = Request.post(path, payload.merge(token: token))
|
65
|
+
|
66
|
+
response = @_last_response = post_request.execute(base_url)
|
67
|
+
|
68
|
+
if response.code.to_i != SUCCES_STATUS_CODE
|
69
|
+
self.errors = JSON.parse(@_last_response.body.to_s)
|
70
|
+
return false
|
71
|
+
else
|
72
|
+
parsed_response = JSON.parse(response.body)
|
73
|
+
|
74
|
+
self.seq_no_global = parsed_response['seq_no_global'] if parsed_response.is_a?(Hash) && parsed_response['seq_no_global']
|
75
|
+
|
76
|
+
parsed_response
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def process!
|
81
|
+
queue.process!
|
82
|
+
end
|
83
|
+
|
84
|
+
def process_queue
|
85
|
+
logger.warn 'Deprecated process_queue'
|
86
|
+
queue.process!
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_to_queue(command)
|
90
|
+
logger.warn 'Deprecated process_queue'
|
91
|
+
queue.add(command)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Command
|
3
|
+
attr_accessor :type, :object, :temp_id, :uuid
|
4
|
+
|
5
|
+
def initialize(type, object, temp_id = nil, uuid = nil)
|
6
|
+
@type = type
|
7
|
+
@object = object
|
8
|
+
@temp_id = object.temp_id
|
9
|
+
@uuid = uuid || SecureRandom.uuid
|
10
|
+
end
|
11
|
+
|
12
|
+
def arguments
|
13
|
+
object.to_submittable_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
{
|
18
|
+
type: type,
|
19
|
+
uuid: uuid,
|
20
|
+
args: object.to_submittable_hash
|
21
|
+
}.merge(temp_id ? { temp_id: temp_id} : {})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
File without changes
|
data/lib/todoist/item.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Item
|
3
|
+
include Todoist::Resource
|
4
|
+
extend Todoist::Resource::ClassMethods
|
5
|
+
|
6
|
+
define_attributes %w(
|
7
|
+
id
|
8
|
+
user_id
|
9
|
+
project_id
|
10
|
+
content
|
11
|
+
date_string
|
12
|
+
date_lang
|
13
|
+
priority
|
14
|
+
indent
|
15
|
+
item_order
|
16
|
+
day_order
|
17
|
+
collapsed
|
18
|
+
children
|
19
|
+
labels
|
20
|
+
assigned_by_uid
|
21
|
+
responsible_uid
|
22
|
+
checked
|
23
|
+
in_history
|
24
|
+
is_deleted
|
25
|
+
is_archived
|
26
|
+
sync_id
|
27
|
+
due_date_utc
|
28
|
+
due_date
|
29
|
+
date_added
|
30
|
+
postpone_count
|
31
|
+
complete_count
|
32
|
+
mm_offset
|
33
|
+
seq_no
|
34
|
+
has_notifications
|
35
|
+
)
|
36
|
+
|
37
|
+
define_read_only_attributes %w(
|
38
|
+
has_notifications
|
39
|
+
postpone_count
|
40
|
+
complete_count
|
41
|
+
mm_offset
|
42
|
+
seq_no
|
43
|
+
)
|
44
|
+
|
45
|
+
def project=(project)
|
46
|
+
self.project_id = project.to_hash['id']
|
47
|
+
end
|
48
|
+
|
49
|
+
def user=(user)
|
50
|
+
self.user_id = user.to_hash['id']
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
data/lib/todoist/note.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Note
|
3
|
+
include Todoist::Resource
|
4
|
+
extend Todoist::Resource::ClassMethods
|
5
|
+
|
6
|
+
define_attributes %w(
|
7
|
+
id
|
8
|
+
item_id
|
9
|
+
posted_uid
|
10
|
+
project_id
|
11
|
+
content
|
12
|
+
is_deleted
|
13
|
+
is_archived
|
14
|
+
file_attachment
|
15
|
+
uids_to_notify
|
16
|
+
posted
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Project
|
3
|
+
include Todoist::Resource
|
4
|
+
extend Todoist::Resource::ClassMethods
|
5
|
+
|
6
|
+
define_attributes %w(
|
7
|
+
id
|
8
|
+
user_id
|
9
|
+
name
|
10
|
+
color
|
11
|
+
indent
|
12
|
+
item_order
|
13
|
+
collapsed
|
14
|
+
shared
|
15
|
+
is_deleted
|
16
|
+
is_archived
|
17
|
+
archived_date
|
18
|
+
archived_timestamp
|
19
|
+
inbox_project
|
20
|
+
)
|
21
|
+
|
22
|
+
define_read_only_attributes %w(
|
23
|
+
inbox_project
|
24
|
+
)
|
25
|
+
|
26
|
+
def items
|
27
|
+
@items ||= Service::Item.new(client)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Todoist
|
2
|
+
class Result
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def initialize(result)
|
8
|
+
@query = result['query']
|
9
|
+
@data = result['data']
|
10
|
+
end
|
11
|
+
|
12
|
+
def each(&block)
|
13
|
+
data.each do |object|
|
14
|
+
block.call(Todoist::Item.new(object))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def size
|
19
|
+
data.size
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class Query
|
25
|
+
def initialize(client)
|
26
|
+
@client = client
|
27
|
+
end
|
28
|
+
|
29
|
+
def query_path
|
30
|
+
'/API/v6/query'
|
31
|
+
end
|
32
|
+
|
33
|
+
def search(queries)
|
34
|
+
if queries.is_a?(String)
|
35
|
+
queries = [queries]
|
36
|
+
end
|
37
|
+
|
38
|
+
parsed_response = @client.post(query_path, { queries: queries.to_json})
|
39
|
+
|
40
|
+
result_set = parsed_response.inject({}) do |results, query|
|
41
|
+
results[query['query']] = Todoist::Result.new(query)
|
42
|
+
results
|
43
|
+
end
|
44
|
+
result_set
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|