todoistize-mail 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +15 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +7 -0
- data/bin/tize +8 -0
- data/lib/todoistize_mail/cli.rb +152 -0
- data/lib/todoistize_mail/mailer.rb +55 -0
- data/lib/todoistize_mail/todoistize_project.rb +28 -0
- data/lib/todoistize_mail/version.rb +3 -0
- data/lib/todoistize_mail.rb +10 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/todoistize_mail/cli_spec.rb +49 -0
- data/spec/todoistize_mail/mailer_spec.rb +31 -0
- data/spec/todoistize_mail/todoistize_project_spec.rb +62 -0
- data/todoistize-mail.gemspec +19 -0
- data/wercker.yml +31 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 32ded5faf4c7f4bc42d4a0bc774b580a18d53410
|
4
|
+
data.tar.gz: 7f539d393291fef815e3e0fc6d957a9ef8ba49f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4167c40486fcfa380f6ecf0e24cf5701e792585806c9284614fee5d599602ccda15f3f55a7d4c50f787ae61ad02b2b4fb88080a9798f678fad4850a5d3d78bfb
|
7
|
+
data.tar.gz: 4621453932874c11580760b917b7d8bdfa60737fd88ef2cbf3df2e3cff38188e74ecca04a3cc85d5cb82b735d3cfc94776c497f0eb788d6541efc362a4c0e7b7
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'bundler', '~> 1.7'
|
4
|
+
gem 'rake', '~> 10.0'
|
5
|
+
gem 'highline', '~> 1.5'
|
6
|
+
gem 'todoist', git: 'https://github.com/joe-re/todoist.git', tag: '0.0.2'
|
7
|
+
gem 'thor', '~> 0.9'
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem 'rspec'
|
11
|
+
gem 'rspec-its'
|
12
|
+
gem 'guard-rspec'
|
13
|
+
end
|
14
|
+
|
15
|
+
gemspec
|
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 joe-re
|
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,48 @@
|
|
1
|
+
# TodoistizeMail
|
2
|
+
[](https://app.wercker.com/project/bykey/74b012101b9ef41001e3b4c96691fc65)
|
3
|
+
|
4
|
+
todoistize-mail is allow you to integrate your mail into todoist.(required IMAP.)
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'todoistize-mail'
|
10
|
+
```
|
11
|
+
|
12
|
+
### setup
|
13
|
+
```
|
14
|
+
tize setup
|
15
|
+
```
|
16
|
+
|
17
|
+
Then start interactive setup.(make `~/.todoistize.yml`)
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
You type `tize help` and you can look more information.
|
21
|
+
|
22
|
+
### show list tasks of todoist
|
23
|
+
```
|
24
|
+
tize tasks
|
25
|
+
```
|
26
|
+
|
27
|
+
### show list unread mails
|
28
|
+
```
|
29
|
+
tize unread
|
30
|
+
```
|
31
|
+
|
32
|
+
### import your unread mails into todoist
|
33
|
+
```
|
34
|
+
tize todoistize
|
35
|
+
```
|
36
|
+
|
37
|
+
### complete your task and mark read mail
|
38
|
+
```
|
39
|
+
tize done --task-id 11111
|
40
|
+
```
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it ( https://github.com/joe-re/todoistize-mail/fork )
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/tize
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'date'
|
3
|
+
require 'yaml'
|
4
|
+
module TodoistizeMail
|
5
|
+
class Cli < Thor
|
6
|
+
def self.option_todoist_authentication
|
7
|
+
method_option :apikey, type: :string, aliases: '-k', desc: 'todoist apikey'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.option_imap_authentication
|
11
|
+
method_option :host, type: :string, aliases: '-h', desc: 'imap host'
|
12
|
+
method_option :port, type: :numeric, aliases: '-p', desc: 'imap port'
|
13
|
+
method_option :ssl, type: :boolean, aliases: '-s', desc: 'use ssl'
|
14
|
+
method_option :user, type: :string, aliases: '-u', desc: 'mail user'
|
15
|
+
method_option :password, type: :string, aliases: '-P', desc: 'mail password'
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'tasks', 'show your uncompleted tasks'
|
19
|
+
option_todoist_authentication
|
20
|
+
method_option :sort, type: :string, aliases: '-s', default: 'date,pri', desc: 'date: by due_date, pri: by priority'
|
21
|
+
method_option :show, type: :string, aliases: '-w', desc: 'target project name'
|
22
|
+
def tasks
|
23
|
+
Todoist::Base.setup(options(:apikey), true)
|
24
|
+
Todoist::Project.all.each do |p|
|
25
|
+
next if options(:show) && !(p.name =~ /#{options(:show)}/)
|
26
|
+
puts "-- Project: #{p.name} --"
|
27
|
+
puts 'Completed!' if p.tasks.count == 0
|
28
|
+
sort_task(p.tasks).each { |task| print_task task }
|
29
|
+
puts ''
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'unread', 'show your unread mails'
|
34
|
+
option_imap_authentication
|
35
|
+
def unread
|
36
|
+
TodoistizeMail::Mailer.new(options(:host), options(:port), options(:ssl)).login(options(:user), options(:password)) do |mailer|
|
37
|
+
puts mailer.unread_subjects
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'todoistize mail', 'import your unread mails into todoist'
|
42
|
+
option_todoist_authentication
|
43
|
+
option_imap_authentication
|
44
|
+
method_option :project, type: :string, aliases: '-t', desc: 'todoistize project name'
|
45
|
+
def todoistize
|
46
|
+
todoist = TodoistizeMail::TodoistizeProject.new(options(:apikey), options(:project))
|
47
|
+
TodoistizeMail::Mailer.new(options(:host), options(:port), options(:ssl)).login(options(:user), options(:password)) do |mailer|
|
48
|
+
mailer.unread_subjects.each do |subject|
|
49
|
+
if todoist.exist?(subject)
|
50
|
+
puts "already exist: #{subject}"
|
51
|
+
next
|
52
|
+
end
|
53
|
+
todoist.create_task(subject)
|
54
|
+
puts "register: #{subject}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'done', 'complete your task'
|
60
|
+
option_todoist_authentication
|
61
|
+
option_imap_authentication
|
62
|
+
method_option :project, type: :string, aliases: '-t', desc: 'todoistize project name'
|
63
|
+
method_option :task_id, type: :string, aliases: '-id', required: true, desc: 'todoist task id'
|
64
|
+
def done
|
65
|
+
Todoist::Base.setup(options(:apikey), true)
|
66
|
+
task = Todoist::Task.get(options(:task_id)).first
|
67
|
+
if task.nil? || task.checked != 0
|
68
|
+
puts "not found: #{options(:task_id)}"
|
69
|
+
ext 0
|
70
|
+
end
|
71
|
+
todoist = TodoistizeMail::TodoistizeProject.new(options(:apikey), options(:project))
|
72
|
+
mark_read(task) if todoist.todoistize?(task)
|
73
|
+
Todoist::Task.complete(options(:task_id))
|
74
|
+
puts 'done!'
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'setup', 'setup your account'
|
78
|
+
def setup
|
79
|
+
h = HighLine.new
|
80
|
+
if File.file?(File.expand_path(TodoistizeMail::YAML_PATH))
|
81
|
+
return unless h.agree('.todoistize.yml is exist. overrwrite?(yes or no)')
|
82
|
+
end
|
83
|
+
account = {
|
84
|
+
apikey: (h.ask('Enter your todoist apikey:')).to_s,
|
85
|
+
host: (h.ask('Enter your imap host:')).to_s,
|
86
|
+
port: (h.ask('Enter your imap port:')).to_s,
|
87
|
+
ssl: h.agree('Use ssl?(yes or no)'),
|
88
|
+
user: (h.ask('Enter your imap user:')).to_s,
|
89
|
+
password: (h.ask('Enter your imap password:')).to_s,
|
90
|
+
}
|
91
|
+
puts "\nyour account:\n#{YAML.dump(account)}\n"
|
92
|
+
return unless h.agree('Is this correct?(yes or no)')
|
93
|
+
project = h.ask("Enter todoistize project name(In the event it isn't exist, make it):")
|
94
|
+
TodoistizeMail::TodoistizeProject.new(account[:apikey], project)
|
95
|
+
account.merge!(project: project.to_s)
|
96
|
+
File.open(TodoistizeMail::YAML_PATH, 'w') { |file| file.puts YAML.dump(account) }
|
97
|
+
end
|
98
|
+
|
99
|
+
no_commands do
|
100
|
+
def mark_read(task)
|
101
|
+
h = HighLine.new
|
102
|
+
TodoistizeMail::Mailer.new(options(:host), options(:port), options(:ssl)).login(options(:user), options(:password)) do |mailer|
|
103
|
+
return unless mailer.unread?(task.content)
|
104
|
+
return unless h.agree('This task is todoistized. mark read mail too?( yes or no )')
|
105
|
+
mailer.mark_read(task.content) do |target|
|
106
|
+
return unless h.agree("found #{target.count} items: #{task.content}\nyou mark all items to read?( yes or no )") unless target.count == 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class SortableTask
|
112
|
+
attr_accessor :date, :pri, :task
|
113
|
+
include Comparable
|
114
|
+
|
115
|
+
def initialize(task)
|
116
|
+
@task = task
|
117
|
+
@date = task.due_date ? Date.parse(task.due_date) : Date.new(9999, 1, 1)
|
118
|
+
@pri = task.priority
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.create(tasks)
|
122
|
+
tasks.each_with_object([]) { |task, ary| ary << SortableTask.new(task) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def sort_task(tasks)
|
127
|
+
params = options(:sort).split(',').select { |param| SortableTask.method_defined?(param) }
|
128
|
+
sorted = SortableTask.create(tasks).sort_by do |task|
|
129
|
+
params.each_with_object([]) { |param, ary| ary << task.instance_eval(param) }
|
130
|
+
end
|
131
|
+
sorted.each_with_object([]) { |t, ary| ary << t.task }
|
132
|
+
end
|
133
|
+
|
134
|
+
def options(key)
|
135
|
+
yaml = File.file?(File.expand_path(TodoistizeMail::YAML_PATH)) ? YAML.load_file(TodoistizeMail::YAML_PATH) : {}
|
136
|
+
@merged_options ||= yaml.merge(@options)
|
137
|
+
@merged_options[key.to_s] || @merged_options[key.to_sym]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def print_task(task)
|
144
|
+
print "id:#{task.id}".ljust(16)
|
145
|
+
print "pri:#{task.priority}".ljust(7)
|
146
|
+
due_date = task.due_date ? Date.parse(task.due_date).strftime : 'none'
|
147
|
+
print "date:#{due_date}".ljust(17)
|
148
|
+
print "#{task.content}".slice(0..50).ljust(51)
|
149
|
+
print "\n"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'net/imap'
|
2
|
+
require 'kconv'
|
3
|
+
require 'highline'
|
4
|
+
|
5
|
+
module TodoistizeMail
|
6
|
+
class Mailer
|
7
|
+
|
8
|
+
MAILBOX_NAME = 'INBOX'
|
9
|
+
SUBJECT_ATTR = 'BODY[HEADER.FIELDS (SUBJECT)]'
|
10
|
+
def initialize(host, port, usessl)
|
11
|
+
@imap = Net::IMAP.new(host, port, usessl)
|
12
|
+
end
|
13
|
+
|
14
|
+
def login(user, passwd)
|
15
|
+
@imap.login(user, passwd)
|
16
|
+
if block_given?
|
17
|
+
yield self
|
18
|
+
logout
|
19
|
+
end
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def logout
|
24
|
+
@imap.logout
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def unread_subjects
|
29
|
+
unread_list.each_with_object([]) { |(_id, subject), subjects| subjects << subject }
|
30
|
+
end
|
31
|
+
|
32
|
+
def unread?(subject)
|
33
|
+
unread_list.each { |_id, unread_subject| return true if subject =~ /^#{unread_subject}$/ }
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def mark_read(subject)
|
38
|
+
target = unread_list.select { |_k, unread_subject| subject =~ /^#{unread_subject}$/ }
|
39
|
+
return if target.count == 0
|
40
|
+
yield target if block_given?
|
41
|
+
@imap.select(MAILBOX_NAME)
|
42
|
+
target.each { |id, _v| @imap.store(id, '+FLAGS', [:Seen]) }
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def unread_list
|
48
|
+
@imap.examine(MAILBOX_NAME)
|
49
|
+
@imap.search(['UNSEEN']).each_with_object({}) do |id, hash|
|
50
|
+
msg = @imap.fetch(id, [SUBJECT_ATTR]).first
|
51
|
+
hash.merge!(id => msg.attr[SUBJECT_ATTR].toutf8.strip)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module TodoistizeMail
|
2
|
+
class TodoistizeProject
|
3
|
+
def initialize(apikey, project_name)
|
4
|
+
Todoist::Base.setup(apikey, true)
|
5
|
+
project = Todoist::Project.all.select { |p| p.name =~ /^#{project_name}$/ }
|
6
|
+
project = [Todoist::Base.get('/addProject', query: { name: project_name })] if project.count <= 0
|
7
|
+
@project = project.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def uncomplete_tasks
|
11
|
+
@project.tasks
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_task(content)
|
15
|
+
Todoist::Task.create(content, @project)
|
16
|
+
end
|
17
|
+
|
18
|
+
def exist?(content)
|
19
|
+
uncomplete_tasks.each { |task| return true if task.content =~ /^#{content}$/ }
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def todoistize?(task)
|
24
|
+
uncomplete_tasks.each { |t| return true if task.id == t.id }
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'todoist'
|
2
|
+
require 'todoistize_mail/version'
|
3
|
+
require 'todoistize_mail/cli'
|
4
|
+
require 'todoistize_mail/mailer'
|
5
|
+
require 'todoistize_mail/todoistize_project'
|
6
|
+
|
7
|
+
module TodoistizeMail
|
8
|
+
include Todoist
|
9
|
+
YAML_PATH = "#{Dir.home}/.todoistize.yml"
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TodoistizeMail::Cli do
|
4
|
+
describe '#sort_task' do
|
5
|
+
context 'sort by due_date' do
|
6
|
+
let(:task1) { double('task1', due_date: Date.new(2014, 04, 03).strftime, priority: nil) }
|
7
|
+
let(:task2) { double('task2', due_date: Date.new(2014, 04, 02).strftime, priority: nil) }
|
8
|
+
let(:task3) { double('task3', due_date: Date.new(2014, 04, 01).strftime, priority: nil) }
|
9
|
+
let(:tasks) { [task1, task2, task3] }
|
10
|
+
let(:options) { { apikey: 'test_apikey', sort: 'date' } }
|
11
|
+
|
12
|
+
subject { described_class.new([], options).sort_task(tasks) }
|
13
|
+
its(:count) { should eq 3 }
|
14
|
+
it { expect(subject.first).to be task3 }
|
15
|
+
it { expect(subject[1]).to be task2 }
|
16
|
+
it { expect(subject.last).to be task1 }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'sort by priority' do
|
20
|
+
let(:task1) { double('task1', due_date: nil, priority: 3) }
|
21
|
+
let(:task2) { double('task2', due_date: nil, priority: 2) }
|
22
|
+
let(:task3) { double('task3', due_date: nil, priority: 1) }
|
23
|
+
let(:tasks) { [task1, task2, task3] }
|
24
|
+
let(:options) { { apikey: 'test_apikey', sort: 'pri' } }
|
25
|
+
|
26
|
+
subject { described_class.new([], options).sort_task(tasks) }
|
27
|
+
its(:count) { should eq 3 }
|
28
|
+
it { expect(subject.first).to be task3 }
|
29
|
+
it { expect(subject[1]).to be task2 }
|
30
|
+
it { expect(subject.last).to be task1 }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'sort by multi prameter' do
|
34
|
+
context 'first key: pri, second key: date' do
|
35
|
+
let(:task1) { double('task1', due_date: Date.new(2014, 04, 02).strftime, priority: 3) }
|
36
|
+
let(:task2) { double('task2', due_date: Date.new(2014, 04, 01).strftime, priority: 3) }
|
37
|
+
let(:task3) { double('task3', due_date: nil, priority: 1) }
|
38
|
+
let(:tasks) { [task1, task2, task3] }
|
39
|
+
let(:options) { { apikey: 'test_apikey', sort: 'pri,date' } }
|
40
|
+
|
41
|
+
subject { described_class.new([], options).sort_task(tasks) }
|
42
|
+
its(:count) { should eq 3 }
|
43
|
+
it { expect(subject.first).to be task3 }
|
44
|
+
it { expect(subject[1]).to be task2 }
|
45
|
+
it { expect(subject.last).to be task1 }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TodoistizeMail::Mailer do
|
4
|
+
|
5
|
+
let(:host) { 'test.com' }
|
6
|
+
let(:port) { '111' }
|
7
|
+
let(:usessl) { true }
|
8
|
+
|
9
|
+
let(:imap) { double('imap') }
|
10
|
+
before { expect(Net::IMAP).to receive(:new).with(host, port, usessl).and_return(imap) }
|
11
|
+
|
12
|
+
describe '#login' do
|
13
|
+
let(:user) { 'test_user' }
|
14
|
+
let(:passwd) { 'passwd' }
|
15
|
+
before { expect(imap).to receive(:login).with(user, passwd) }
|
16
|
+
subject { described_class.new(host, port, usessl).login(user, passwd) }
|
17
|
+
|
18
|
+
it 'return myself' do
|
19
|
+
expect(subject.instance_of?(described_class)).to be true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#logout' do
|
24
|
+
before { expect(imap).to receive(:logout) }
|
25
|
+
subject { described_class.new(host, port, usessl).logout }
|
26
|
+
|
27
|
+
it 'return myself' do
|
28
|
+
expect(subject.instance_of?(described_class)).to be true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TodoistizeMail::TodoistizeProject do
|
4
|
+
let(:apikey) { 'test_apikey' }
|
5
|
+
let(:test_project_name) { 'test_peoject' }
|
6
|
+
|
7
|
+
before do
|
8
|
+
expect(Todoist::Base).to receive(:setup).with(apikey, true)
|
9
|
+
expect(Todoist::Project).to receive(:all).and_return([project])
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#uncomplete_tasks' do
|
13
|
+
let(:tasks) { %w('test_task1', 'test_task2') }
|
14
|
+
let(:project) { double('test_peoject', name: test_project_name, tasks: tasks) }
|
15
|
+
subject { described_class.new(apikey, test_project_name).uncomplete_tasks }
|
16
|
+
it { should be tasks }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#create_task' do
|
20
|
+
let(:content) { 'content' }
|
21
|
+
let(:project) { double('test_peoject', name: test_project_name) }
|
22
|
+
before { expect(Todoist::Task).to receive(:create).with(content, project).and_return('ok') }
|
23
|
+
subject { described_class.new(apikey, test_project_name).create_task(content) }
|
24
|
+
it { should eq 'ok' }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#exist?' do
|
28
|
+
let(:project) { double('test_peoject', name: test_project_name, tasks: tasks) }
|
29
|
+
|
30
|
+
context 'already exist' do
|
31
|
+
let(:content) { 'content' }
|
32
|
+
let(:tasks) { [double('test_task1', content: content)] }
|
33
|
+
subject { described_class.new(apikey, test_project_name).exist?(content) }
|
34
|
+
it { should eq true }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'not exist' do
|
38
|
+
let(:content) { 'none_content' }
|
39
|
+
let(:tasks) { [double('test_task1', content: 'content')] }
|
40
|
+
subject { described_class.new(apikey, test_project_name).exist?(content) }
|
41
|
+
it { should eq false }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#tosoistize?' do
|
46
|
+
let(:project) { double('test_peoject', name: test_project_name, tasks: tasks) }
|
47
|
+
|
48
|
+
context 'todoistized task' do
|
49
|
+
let(:target_task) { double('target_task', id: 1111) }
|
50
|
+
let(:tasks) { [target_task] }
|
51
|
+
subject { described_class.new(apikey, test_project_name).todoistize?(target_task) }
|
52
|
+
it { should eq true }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'not todoistized task' do
|
56
|
+
let(:target_task) { double('target_task', id: 9999) }
|
57
|
+
let(:tasks) { [double('test_task1', id: 1111)] }
|
58
|
+
subject { described_class.new(apikey, test_project_name).todoistize?(target_task) }
|
59
|
+
it { should eq false }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'todoistize_mail/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'todoistize-mail'
|
8
|
+
spec.version = TodoistizeMail::VERSION
|
9
|
+
spec.authors = ['joe-re']
|
10
|
+
spec.email = ['joe.tialtngo@gmail.com']
|
11
|
+
spec.summary = %q{allow you to integrate your mail into todoist.(required IMAP.)}
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
end
|
data/wercker.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
box: wercker/rvm
|
2
|
+
# Build definition
|
3
|
+
build:
|
4
|
+
# The steps that will be executed on build
|
5
|
+
# See the Ruby section on the wercker devcenter:
|
6
|
+
# http://devcenter.wercker.com/articles/languages/ruby.html
|
7
|
+
steps:
|
8
|
+
# Uncomment this to force RVM to use a specific Ruby version
|
9
|
+
- rvm-use:
|
10
|
+
version: 2.1.5
|
11
|
+
|
12
|
+
- script:
|
13
|
+
name: bundle
|
14
|
+
code: gem install bundler
|
15
|
+
|
16
|
+
# A step that executes `bundle install` command
|
17
|
+
- bundle-install
|
18
|
+
|
19
|
+
# A custom script step, name value is used in the UI
|
20
|
+
# and the code value contains the command that get executed
|
21
|
+
- script:
|
22
|
+
name: echo ruby information
|
23
|
+
code: |
|
24
|
+
echo "ruby version $(ruby --version) running"
|
25
|
+
echo "from location $(which ruby)"
|
26
|
+
echo -p "gem list: $(gem list)"
|
27
|
+
|
28
|
+
# Add more steps here:
|
29
|
+
- script:
|
30
|
+
name: rspec
|
31
|
+
code: bundle exec rspec
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: todoistize-mail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- joe-re
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- joe.tialtngo@gmail.com
|
16
|
+
executables:
|
17
|
+
- tize
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ".gitignore"
|
22
|
+
- ".rspec"
|
23
|
+
- Gemfile
|
24
|
+
- Guardfile
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/tize
|
29
|
+
- lib/todoistize_mail.rb
|
30
|
+
- lib/todoistize_mail/cli.rb
|
31
|
+
- lib/todoistize_mail/mailer.rb
|
32
|
+
- lib/todoistize_mail/todoistize_project.rb
|
33
|
+
- lib/todoistize_mail/version.rb
|
34
|
+
- spec/spec_helper.rb
|
35
|
+
- spec/todoistize_mail/cli_spec.rb
|
36
|
+
- spec/todoistize_mail/mailer_spec.rb
|
37
|
+
- spec/todoistize_mail/todoistize_project_spec.rb
|
38
|
+
- todoistize-mail.gemspec
|
39
|
+
- wercker.yml
|
40
|
+
homepage: ''
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.2.2
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: allow you to integrate your mail into todoist.(required IMAP.)
|
64
|
+
test_files:
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- spec/todoistize_mail/cli_spec.rb
|
67
|
+
- spec/todoistize_mail/mailer_spec.rb
|
68
|
+
- spec/todoistize_mail/todoistize_project_spec.rb
|