todoistize-mail 0.0.1
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/.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
|
+
[![wercker status](https://app.wercker.com/status/74b012101b9ef41001e3b4c96691fc65/m "wercker status")](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
|