tudu 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ coverage
@@ -0,0 +1,4 @@
1
+ LineLength:
2
+ Enabled: false
3
+ ClassLength:
4
+ Enabled: false
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in tudu.gemspec
4
3
  gemspec
5
4
  gem "rspec", "~> 2.14.1"
6
5
  gem "thor", "~> 0.18.1"
7
6
  gem "simplecov", "~> 0.8.2"
7
+ gem "highline", "~> 1.6.20"
data/README.md CHANGED
@@ -32,6 +32,29 @@ Or install it yourself as:
32
32
  ┗ Tudufile :in current version, we not use this
33
33
  ~~~
34
34
 
35
+ ## DSL List
36
+ | dsl | mean |
37
+ |:----------- |:------------ |
38
+ | add 'task_name1', 'task_name2' |add tasks to todos |
39
+ | remove 'task_name1', 'task_name2' |remove tasks from [todos, doings, dones] |
40
+ | choose |choose first task from todos to doings |
41
+ | choose 'task_name' |choose task from todos to doings |
42
+ | done |complete task. doings to dones, and first todos to doings |
43
+ | done -p |complete task. doings to dones, and first todos to doings.after show progress |
44
+ | tasks |search all task from [todos, doings, dones] |
45
+ | tasks 'task_name' |search task from [todos, doings, dones] by keyword 'task_name' |
46
+ | tasks 'task_name' -c |search task from [todos, doings, dones] by keyword 'task_name' with categolized view |
47
+ | tasks 'task_name' -c --color |search task from [todos, doings, dones] by keyword 'task_name' with categolized view, colored|
48
+ | todos |search all task from todos |
49
+ | todos 'task_name' |search task from todos by keyword 'task_name' |
50
+ | doings |search all task from doings |
51
+ | doings 'task_name' |search task from doings by keyword 'task_name' |
52
+ | now |alias of doings command |
53
+ | now 'task_name' |alias of doings 'task_name' command |
54
+ | dones |search all task from dones |
55
+ | dones 'task_name' |search task from dones by keyword 'task_name' |
56
+ | progress |show tasks progress |
57
+
35
58
  ## Usage
36
59
  ### init
37
60
  * generate todos,doings,dones emptyfile
@@ -170,17 +193,35 @@ one
170
193
  $ tudu add one two three
171
194
  $ tudu choose one
172
195
  $ tudu done
173
- $tudu tasks -c
196
+ $ tudu tasks -c
174
197
  ========TODOS========
175
198
  three
176
-
177
199
  ========DOINGS========
178
200
  two
201
+ ========DONES========
202
+ one
203
+ ~~~
204
+
205
+ ### tasks show all tasks from [todos, doings, dones] with categorized option and colored option.
206
+ * tudu tasks -c --color
179
207
 
208
+ ~~~
209
+ $ tudu add one two three
210
+ $ tudu choose one
211
+ $ tudu done
212
+ $ tudu tasks -c
213
+ ========TODOS========
214
+ three
215
+ ========DOINGS========
216
+ two
180
217
  ========DONES========
181
218
  one
182
219
  ~~~
183
220
 
221
+ * image sample
222
+
223
+ <img src="./doc_image/colored_tasks.png" />
224
+
184
225
  ### show specific tasks from [todos, doings, dones].
185
226
  * tudu tasks search_word
186
227
 
@@ -252,6 +293,7 @@ if you want to do other operation, edit [todos, doings, dones] directly.
252
293
  it's only plain text, so you can edit freely.
253
294
 
254
295
  ## History
296
+ * version 0.0.5 : add color option to 'tasks'
255
297
  * version 0.0.4 : add 'progress'. add progress option to 'done'.
256
298
  * version 0.0.3 : add categorized option to 'tasks'.
257
299
  * version 0.0.2 : after execute 'done', if there is no todos and doings, display celebration message.
data/bin/tudu CHANGED
@@ -1,79 +1,80 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'tudu/version'
5
- require 'tudu_core'
6
- require "thor"
7
-
8
- module Tudu
9
- #= Tudu CLI
10
- class CLI < Thor
11
- class_option :help, :type => :boolean, :aliases => '-h', :desc => 'help message.'
12
- class_option :version, :type => :boolean, :desc => 'version'
13
-
14
- desc "init", "generate todos,doings,dones files"
15
- def init
16
- Tudu::Core.new.init
17
- end
18
-
19
- desc "add", "add tasks to todos file"
20
- def add(*args)
21
- puts args
22
- Tudu::Core.new.add *args
23
- end
24
-
25
- desc "remove", "remove tasks from todos,doings,dones file"
26
- def remove(*args)
27
- Tudu::Core.new.remove *args
28
- end
29
-
30
- desc "choose", "choose tasks from todos to doings file"
31
- def choose(*args)
32
- Tudu::Core.new.choose args.first
33
- end
34
-
35
- desc "done", "done tasks from doings to dones file. and choose task from todos's top task to doings"
36
- option :progress, :type => :boolean, :aliases => '-p', :desc => "display tasks progress"
37
- def done
38
- Tudu::Core.new.done
39
- progress if options[:progress]
40
- end
41
-
42
- desc "tasks", "search tasks from todos,doings,dones file. no args => get all tasks. set search word args, you get hit tasks"
43
- option :category, :type => :boolean, :aliases => '-c', :desc => "display categorized tasks"
44
- def tasks(*args)
45
- puts Tudu::Core.new.tasks args.first, options
46
- end
47
-
48
- desc "todos", "search tasks from todos file. no args => get all tasks. set search word args, you get hit tasks"
49
- def todos(*args)
50
- puts Tudu::Core.new.todos args.first
51
- end
52
-
53
- desc "doings", "search tasks from doings file. no args => get all tasks. set search word args, you get hit tasks"
54
- def doings(*args)
55
- puts Tudu::Core.new.doings args.first
56
- end
57
-
58
- desc "now", "search tasks from doings file. no args => get all tasks. set search word args, you get hit tasks"
59
- def now(*args)
60
- puts Tudu::Core.new.now args.first
61
- end
62
-
63
- desc "dones", "search tasks from dones file. no args => get all tasks. set search word args, you get hit tasks"
64
- def dones(*args)
65
- puts Tudu::Core.new.dones args.first
66
- end
67
-
68
- desc "progress", "display tasks progress"
69
- def progress
70
- puts Tudu::Core.new.progress
71
- end
72
-
73
- desc "version", "version"
74
- def version
75
- p Tudu::VERSION
76
- end
77
- end
78
- end
79
- Tudu::CLI.start(ARGV)
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'tudu/version'
5
+ require 'tudu_core'
6
+ require 'thor'
7
+
8
+ module Tudu
9
+ # = Tudu CLI
10
+ class CLI < Thor
11
+ class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
12
+ class_option :version, type: :boolean, desc: 'version'
13
+
14
+ desc 'init', 'generate todos,doings,dones files'
15
+ def init
16
+ Tudu::Core.new.init
17
+ end
18
+
19
+ desc 'add', 'add tasks to todos file'
20
+ def add(*args)
21
+ puts args
22
+ Tudu::Core.new.add(*args)
23
+ end
24
+
25
+ desc 'remove', 'remove tasks from todos,doings,dones file'
26
+ def remove(*args)
27
+ Tudu::Core.new.remove(*args)
28
+ end
29
+
30
+ desc 'choose', 'choose tasks from todos to doings file'
31
+ def choose(*args)
32
+ Tudu::Core.new.choose args.first
33
+ end
34
+
35
+ desc 'done', "done tasks from doings to dones file. and choose task from todos's top task to doings"
36
+ option :progress, type: :boolean, aliases: '-p', desc: 'display tasks progress'
37
+ def done
38
+ Tudu::Core.new.done
39
+ progress if options[:progress]
40
+ end
41
+
42
+ desc 'tasks', 'search tasks from todos,doings,dones file. no args => get all tasks. set search word args, you get hit tasks'
43
+ option :category, type: :boolean, aliases: '-c', desc: 'display categorized tasks'
44
+ option :color, type: :boolean, aliases: '-co', desc: 'display colored tasks'
45
+ def tasks(*args)
46
+ puts Tudu::Core.new.tasks args.first, options
47
+ end
48
+
49
+ desc 'todos', 'search tasks from todos file. no args => get all tasks. set search word args, you get hit tasks'
50
+ def todos(*args)
51
+ puts Tudu::Core.new.todos args.first
52
+ end
53
+
54
+ desc 'doings', 'search tasks from doings file. no args => get all tasks. set search word args, you get hit tasks'
55
+ def doings(*args)
56
+ puts Tudu::Core.new.doings args.first
57
+ end
58
+
59
+ desc 'now', 'search tasks from doings file. no args => get all tasks. set search word args, you get hit tasks'
60
+ def now(*args)
61
+ puts Tudu::Core.new.now args.first
62
+ end
63
+
64
+ desc 'dones', 'search tasks from dones file. no args => get all tasks. set search word args, you get hit tasks'
65
+ def dones(*args)
66
+ puts Tudu::Core.new.dones args.first
67
+ end
68
+
69
+ desc 'progress', 'display tasks progress'
70
+ def progress
71
+ puts Tudu::Core.new.progress
72
+ end
73
+
74
+ desc 'version', 'version'
75
+ def version
76
+ p Tudu::VERSION
77
+ end
78
+ end
79
+ end
80
+ Tudu::CLI.start(ARGV)
@@ -1,304 +1,319 @@
1
- # encoding: utf-8
2
-
3
- module Tudu
4
- #= Tudu::Tasks
5
- class Tasks
6
- #== Tudufile key
7
- TUDU_FILE_KEY = :tudufile
8
- #== todo key
9
- TUDU_TODO_KEY = :todo
10
- #== doing key
11
- TUDU_DOING_KEY = :doing
12
- #== done key
13
- TUDU_DONE_KEY = :done
14
- #== file's key
15
- TUDU_KEYS = [TUDU_FILE_KEY, TUDU_TODO_KEY, TUDU_DOING_KEY, TUDU_DONE_KEY]
16
-
17
- #== Tudufile file name
18
- TUDU_FILE = "Tudufile"
19
- #== Tudufile file name
20
- TUDU_DIR = "tudu"
21
- #== todo file name
22
- TUDU_TODOS_FILE = "todos"
23
- #== todo file path
24
- TUDU_TODOS_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_TODOS_FILE}"
25
- #== doing file name
26
- TUDU_DOINGS_FILE = "doings"
27
- #== doing file path
28
- TUDU_DOINGS_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_DOINGS_FILE}"
29
- #== done file name
30
- TUDU_DONES_FILE = "dones"
31
- #== done file path
32
- TUDU_DONES_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_DONES_FILE}"
33
- #== file names
34
- INIT_FILES = {
35
- TUDU_FILE_KEY => TUDU_FILE,
36
- TUDU_TODO_KEY => TUDU_TODOS_FILE,
37
- TUDU_DOING_KEY => TUDU_DOINGS_FILE,
38
- TUDU_DONE_KEY => TUDU_DONES_FILE
39
- }
40
- #== task file names
41
- TASK_FILES = {
42
- TUDU_TODO_KEY => TUDU_TODOS_FILE,
43
- TUDU_DOING_KEY => TUDU_DOINGS_FILE,
44
- TUDU_DONE_KEY => TUDU_DONES_FILE
45
- }
46
-
47
- #== Tudufile file template
48
- TUDU_FILE_TEMPLATE =<<-EOS
49
- # encoding: utf-8
50
-
51
- # !!!!!!! in tudu ver 0.0.1 this file not using !!!!!!!
52
-
53
- # if you want to use notification, set target type. default => :none
54
- # you can set :none, :mail
55
- # target_type :mail
56
-
57
- # if you want to use notification, set targets. default => []
58
- # if you choose target_type none, you must not set targets.
59
- # if you choose mail, you must set target email addresses.
60
- # targets ["target1@abcdefg", "target2@abcdefg"]
61
- EOS
62
-
63
- #== todo file template
64
- TUDU_TODOS_FILE_TEMPLATE = ""
65
- #== doing file template
66
- TUDU_DOINGS_FILE_TEMPLATE = ""
67
- #== done file template
68
- TUDU_DONES_FILE_TEMPLATE = ""
69
-
70
- #== template files
71
- INIT_FILES_TEMPLATE = {
72
- TUDU_FILE_KEY => TUDU_FILE_TEMPLATE,
73
- TUDU_TODO_KEY => TUDU_TODOS_FILE_TEMPLATE,
74
- TUDU_DOING_KEY => TUDU_DOINGS_FILE_TEMPLATE,
75
- TUDU_DONE_KEY => TUDU_DONES_FILE_TEMPLATE
76
- }
77
-
78
- #== task type [todo, doing, done]
79
- attr_accessor :type
80
- #== task name [uniq]
81
- attr_accessor :name
82
-
83
- class << self
84
- #== add task to todos
85
- #=== Params
86
- #- task_names : add task name list
87
- def add(*task_names)
88
- task_names.each do |task_name|
89
- if find_tasks(task_name)
90
- puts "#{task_name} is already exists.";
91
- next
92
- end
93
- File.open(TUDU_TODOS_FILE_PATH, "a:UTF-8") {|f|f.puts task_name}
94
- puts "complete add todo '#{task_name}' to tudu/todos"
95
- end
96
- end
97
-
98
- #== remove task to todo
99
- #=== Params
100
- #- task_names : remove task name list
101
- def remove(*task_names)
102
- task_names.each do |task_name|
103
- can_find = false
104
- TASK_FILES.each_value do |rf|
105
- tasks = get_tasks_from_file(rf)
106
- next unless has_task?(tasks, task_name)
107
- remove_task(tasks, task_name, "./#{TUDU_DIR}/#{rf}")
108
- can_find = true
109
- break
110
- end
111
- puts "no such todo '#{task_name}'" unless can_find
112
- end
113
- end
114
-
115
- #== choose todo => doing task
116
- #=== Params
117
- #- task_name : target task name
118
- def choose(task_name)
119
- if get_todos.size == 0
120
- puts "todos is empty."
121
- return
122
- end
123
- if get_doings.size > 0
124
- puts "before choose, you must done current doings."
125
- return
126
- end
127
- task_name = get_first_todo_name_if_nil_or_empty task_name
128
- task = find_tasks(task_name)
129
- if task.nil?
130
- puts "#{task_name} not exists"
131
- return
132
- end
133
- unless task.todo?
134
- puts "#{task_name} is not exists in todos. #{task_name} in #{task.type}"
135
- return
136
- end
137
- remove task_name
138
- File.open(TUDU_DOINGS_FILE_PATH, "w:UTF-8") {|f|f.puts task_name}
139
- puts "complete add doings '#{task_name}'"
140
- end
141
-
142
- #== doing to done
143
- #- if doings size == 0, nothing todo.
144
- #- after move doing to done, next todo move to doing.
145
- def done
146
- return unless doings_to_dones
147
- todos_to_doings
148
- end
149
-
150
- #== get todos type tasks.
151
- #=== Returns
152
- # return Array[Tasks]
153
- def get_todos
154
- get_tasks(TUDU_TODOS_FILE)
155
- end
156
-
157
- #== get doings type tasks.
158
- #=== Returns
159
- # return Array[Tasks]
160
- def get_doings
161
- get_tasks(TUDU_DOINGS_FILE)
162
- end
163
-
164
- #== get dones type tasks.
165
- #=== Returns
166
- # return Array[Tasks]
167
- def get_dones
168
- get_tasks(TUDU_DONES_FILE)
169
- end
170
-
171
- #== get each type tasks.
172
- #=== Params
173
- #- type : task type.if use nil, you can get all types task.
174
- #=== Returns
175
- # return Array[Tasks]
176
- def get_tasks(type = nil)
177
- type.nil? ? get_all_tasks : get_each_tasks(type)
178
- end
179
-
180
- #== get each type tasks from file.
181
- #=== Params
182
- #- type : task type.
183
- #=== Returns
184
- # return Array[String]
185
- def get_tasks_from_file(file_name)
186
- File.read("./#{TUDU_DIR}/#{file_name}").split("\n")
187
- end
188
-
189
- #== filter tasklist by search_word.
190
- #=== Params
191
- #- tasks : task list.
192
- #- search_word : filtering word.
193
- #=== Returns
194
- # return filterd task list
195
- def filter_tasks(tasks, search_word)
196
- return tasks if search_word.nil?
197
- tasks.select {|task|task.name.match /.*#{search_word}.*/}
198
- end
199
-
200
- #== find task from all tasks.
201
- #=== Params
202
- #- task_name : task name.
203
- #=== Returns
204
- # return task
205
- def find_tasks(task_name)
206
- tasks = get_tasks
207
- tasks.select {|task|task.name == task_name}.first
208
- end
209
-
210
- #== display tasks progress
211
- #=== Returns
212
- # return progress
213
- def progress
214
- total_count = get_tasks.size
215
- dones_count = get_dones.size
216
- percent = total_count == 0 ? 0 : (dones_count.to_f / total_count.to_f * 100).round
217
- prefix = "#{dones_count}/#{total_count}|"
218
- done_bar = "="*(percent/10)
219
- rest_bar = " "*(10-(percent/10))
220
- progress_bar = "#{done_bar}>#{rest_bar}"
221
- sufix = "|#{percent}%"
222
- "#{prefix}#{progress_bar}#{sufix}"
223
- end
224
-
225
- private
226
- def get_first_todo_name_if_nil_or_empty(task_name)
227
- (task_name.nil? || task_name.empty?) ? get_todos.first.name : task_name
228
- end
229
-
230
- def get_each_tasks(type)
231
- tasks = []
232
- get_tasks_from_file(type).each {|task|tasks << Tasks.new(type, task)}
233
- tasks
234
- end
235
-
236
- def get_all_tasks
237
- tasks = []
238
- TASK_FILES.each_value {|each_type|tasks += get_each_tasks(each_type)}
239
- tasks
240
- end
241
-
242
- def has_task?(tasks, task_name)
243
- tasks.include? task_name
244
- end
245
-
246
- def remove_task(tasks, task_name, file_path)
247
- tasks.delete(task_name)
248
- contents = tasks.size == 0 ? "" : tasks.join("\n") + "\n"
249
- File.open(file_path, "w:UTF-8") {|wf|wf.print contents}
250
- puts "complete remove todo '#{task_name}' from #{file_path}"
251
- end
252
-
253
- def doings_to_dones
254
- _doings = get_doings
255
- if _doings.size == 0
256
- puts "there is no doing task.before done, you must choose task."
257
- return false
258
- end
259
- File.open(TUDU_DOINGS_FILE_PATH, "w:UTF-8") {|f|f.print ""}
260
- File.open(TUDU_DONES_FILE_PATH, "a:UTF-8") {|f|f.puts _doings.first.name}
261
- true
262
- end
263
-
264
- def todos_to_doings
265
- _todos = get_todos
266
- if _todos.size == 0
267
- puts "All Tasks Finish!!" if get_doings.size == 0
268
- return
269
- end
270
-
271
- deleted_todos = _todos.dup
272
- deleted_todos.delete_at 0
273
- File.open(TUDU_TODOS_FILE_PATH, "w:UTF-8") do |f|
274
- deleted_todos.each {|task|f.puts task.name}
275
- end
276
- File.open(TUDU_DOINGS_FILE_PATH, "w:UTF-8") {|f|f.puts _todos.first.name}
277
- end
278
- end
279
-
280
- #== init task with setting task type and task name.
281
- def initialize(type, name)
282
- @type, @name = type, name
283
- end
284
-
285
- def todo?
286
- @type == "todos"
287
- end
288
-
289
- def doing?
290
- @type == "doings"
291
- end
292
-
293
- def done?
294
- @type == "dones"
295
- end
296
-
297
- def ==(other)
298
- if self.name == other.name
299
- return true if self.type == other.type
300
- end
301
- false
302
- end
303
- end
304
- end
1
+ # encoding: utf-8
2
+
3
+ module Tudu
4
+ # = Tudu::Tasks
5
+ class Tasks
6
+ # == Tudufile key
7
+ TUDU_FILE_KEY = :tudufile
8
+ # == todo key
9
+ TUDU_TODO_KEY = :todo
10
+ # == doing key
11
+ TUDU_DOING_KEY = :doing
12
+ # == done key
13
+ TUDU_DONE_KEY = :done
14
+ # == file's key
15
+ TUDU_KEYS = [TUDU_FILE_KEY, TUDU_TODO_KEY, TUDU_DOING_KEY, TUDU_DONE_KEY]
16
+
17
+ # == Tudufile file name
18
+ TUDU_FILE = 'Tudufile'
19
+ # == Tudufile file name
20
+ TUDU_DIR = 'tudu'
21
+ # == todo file name
22
+ TUDU_TODOS_FILE = 'todos'
23
+ # == todo file path
24
+ TUDU_TODOS_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_TODOS_FILE}"
25
+ # == doing file name
26
+ TUDU_DOINGS_FILE = 'doings'
27
+ # == doing file path
28
+ TUDU_DOINGS_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_DOINGS_FILE}"
29
+ # == done file name
30
+ TUDU_DONES_FILE = 'dones'
31
+ # == done file path
32
+ TUDU_DONES_FILE_PATH = "./#{TUDU_DIR}/#{TUDU_DONES_FILE}"
33
+ # == file names
34
+ INIT_FILES = {
35
+ TUDU_FILE_KEY => TUDU_FILE,
36
+ TUDU_TODO_KEY => TUDU_TODOS_FILE,
37
+ TUDU_DOING_KEY => TUDU_DOINGS_FILE,
38
+ TUDU_DONE_KEY => TUDU_DONES_FILE
39
+ }
40
+ # == task file names
41
+ TASK_FILES = {
42
+ TUDU_TODO_KEY => TUDU_TODOS_FILE,
43
+ TUDU_DOING_KEY => TUDU_DOINGS_FILE,
44
+ TUDU_DONE_KEY => TUDU_DONES_FILE
45
+ }
46
+
47
+ # == Tudufile file template
48
+ TUDU_FILE_TEMPLATE = <<-EOS
49
+ # encoding: utf-8
50
+
51
+ # !!!!!!! in tudu ver 0.0.1 this file not using !!!!!!!
52
+
53
+ # if you want to use notification, set target type. default => :none
54
+ # you can set :none, :mail
55
+ # target_type :mail
56
+
57
+ # if you want to use notification, set targets. default => []
58
+ # if you choose target_type none, you must not set targets.
59
+ # if you choose mail, you must set target email addresses.
60
+ # targets ["target1@abcdefg", "target2@abcdefg"]
61
+ EOS
62
+
63
+ # == todo file template
64
+ TUDU_TODOS_FILE_TEMPLATE = ''
65
+ # == doing file template
66
+ TUDU_DOINGS_FILE_TEMPLATE = ''
67
+ # == done file template
68
+ TUDU_DONES_FILE_TEMPLATE = ''
69
+
70
+ # == template files
71
+ INIT_FILES_TEMPLATE = {
72
+ TUDU_FILE_KEY => TUDU_FILE_TEMPLATE,
73
+ TUDU_TODO_KEY => TUDU_TODOS_FILE_TEMPLATE,
74
+ TUDU_DOING_KEY => TUDU_DOINGS_FILE_TEMPLATE,
75
+ TUDU_DONE_KEY => TUDU_DONES_FILE_TEMPLATE
76
+ }
77
+
78
+ # == task type [todo, doing, done]
79
+ attr_accessor :type
80
+ # == task name [uniq]
81
+ attr_accessor :name
82
+
83
+ class << self
84
+ # == add task to todos
85
+ # === Params
86
+ #- task_names : add task name list
87
+ def add(*task_names)
88
+ task_names.each do |task_name|
89
+ if find_tasks(task_name)
90
+ puts "#{task_name} is already exists."
91
+ next
92
+ end
93
+ File.open(TUDU_TODOS_FILE_PATH, 'a:UTF-8') { |f|f.puts task_name }
94
+ puts "complete add todo '#{task_name}' to tudu/todos"
95
+ end
96
+ end
97
+
98
+ # == remove task to todo
99
+ # === Params
100
+ #- task_names : remove task name list
101
+ def remove(*task_names)
102
+ task_names.each { |task_name|remove_each_task(task_name) }
103
+ end
104
+
105
+ # == choose todo => doing task
106
+ # === Params
107
+ #- task_name : target task name
108
+ def choose(task_name)
109
+ return if when_choose_no_todos?
110
+ return unless when_choose_no_doings?
111
+ task_name = get_first_todo_name_if_nil_or_empty task_name
112
+ task = find_tasks(task_name)
113
+ return if when_choose_no_task?(task, task_name)
114
+ return unless when_choose_type_is_todo?(task, task_name)
115
+ remove task_name
116
+ File.open(TUDU_DOINGS_FILE_PATH, 'w:UTF-8') { |f|f.puts task_name }
117
+ puts "complete add doings '#{task_name}'"
118
+ end
119
+
120
+ # == doing to done
121
+ #- if doings size == 0, nothing todo.
122
+ #- after move doing to done, next todo move to doing.
123
+ def done
124
+ return unless doings_to_dones
125
+ todos_to_doings
126
+ end
127
+
128
+ # == get todos type tasks.
129
+ # === Returns
130
+ # return Array[Tasks]
131
+ def get_todos
132
+ get_tasks(TUDU_TODOS_FILE)
133
+ end
134
+
135
+ # == get doings type tasks.
136
+ # === Returns
137
+ # return Array[Tasks]
138
+ def get_doings
139
+ get_tasks(TUDU_DOINGS_FILE)
140
+ end
141
+
142
+ # == get dones type tasks.
143
+ # === Returns
144
+ # return Array[Tasks]
145
+ def get_dones
146
+ get_tasks(TUDU_DONES_FILE)
147
+ end
148
+
149
+ # == get each type tasks.
150
+ # === Params
151
+ #- type : task type.if use nil, you can get all types task.
152
+ # === Returns
153
+ # return Array[Tasks]
154
+ def get_tasks(type = nil)
155
+ type.nil? ? get_all_tasks : get_each_tasks(type)
156
+ end
157
+
158
+ # == get each type tasks from file.
159
+ # === Params
160
+ #- type : task type.
161
+ # === Returns
162
+ # return Array[String]
163
+ def get_tasks_from_file(file_name)
164
+ File.read("./#{TUDU_DIR}/#{file_name}").split("\n")
165
+ end
166
+
167
+ # == filter tasklist by search_word.
168
+ # === Params
169
+ #- tasks : task list.
170
+ #- search_word : filtering word.
171
+ # === Returns
172
+ # return filterd task list
173
+ def filter_tasks(tasks, search_word)
174
+ return tasks if search_word.nil?
175
+ tasks.select { |task|task.name.match /.*#{search_word}.*/ }
176
+ end
177
+
178
+ # == find task from all tasks.
179
+ # === Params
180
+ #- task_name : task name.
181
+ # === Returns
182
+ # return task
183
+ def find_tasks(task_name)
184
+ tasks = get_tasks
185
+ tasks.select { |task|task.name == task_name }.first
186
+ end
187
+
188
+ # == display tasks progress
189
+ # === Returns
190
+ # return progress
191
+ def progress
192
+ total_count = get_tasks.size
193
+ dones_count = get_dones.size
194
+ percent = total_count == 0 ? 0 : (dones_count.to_f / total_count.to_f * 100).round
195
+ prefix = "#{dones_count}/#{total_count}|"
196
+ done_bar = '=' * (percent / 10)
197
+ rest_bar = ' ' * (10 - (percent / 10))
198
+ progress_bar = "#{done_bar}>#{rest_bar}"
199
+ sufix = "|#{percent}%"
200
+ "#{prefix}#{progress_bar}#{sufix}"
201
+ end
202
+
203
+ private
204
+
205
+ def get_first_todo_name_if_nil_or_empty(task_name)
206
+ task_name.nil? || task_name.empty? ? get_todos.first.name : task_name
207
+ end
208
+
209
+ def get_each_tasks(type)
210
+ tasks = []
211
+ get_tasks_from_file(type).each { |task|tasks << Tasks.new(type, task) }
212
+ tasks
213
+ end
214
+
215
+ def get_all_tasks
216
+ tasks = []
217
+ TASK_FILES.each_value { |each_type|tasks += get_each_tasks(each_type) }
218
+ tasks
219
+ end
220
+
221
+ def has_task?(tasks, task_name)
222
+ tasks.include? task_name
223
+ end
224
+
225
+ def remove_each_task(task_name)
226
+ can_find = false
227
+ TASK_FILES.each_value do |rf|
228
+ tasks = get_tasks_from_file(rf)
229
+ next unless has_task?(tasks, task_name)
230
+ remove_task(tasks, task_name, "./#{TUDU_DIR}/#{rf}")
231
+ can_find = true
232
+ break
233
+ end
234
+ puts "no such todo '#{task_name}'" unless can_find
235
+ end
236
+
237
+ def remove_task(tasks, task_name, file_path)
238
+ tasks.delete(task_name)
239
+ contents = tasks.size == 0 ? '' : tasks.join("\n") + "\n"
240
+ File.open(file_path, 'w:UTF-8') { |wf|wf.print contents }
241
+ puts "complete remove todo '#{task_name}' from #{file_path}"
242
+ end
243
+
244
+ def when_choose_no_todos?
245
+ return false unless get_todos.size == 0
246
+ puts 'todos is empty.'
247
+ true
248
+ end
249
+
250
+ def when_choose_no_doings?
251
+ return true if get_doings.size == 0
252
+ puts 'todos is empty.'
253
+ false
254
+ end
255
+
256
+ def when_choose_no_task?(task, task_name)
257
+ return true if task.nil?
258
+ puts "#{task_name} not exists"
259
+ false
260
+ end
261
+
262
+ def when_choose_type_is_todo?(task, task_name)
263
+ return true if task.todo?
264
+ puts "#{task_name} is not exists in todos. #{task_name} in #{task.type}"
265
+ false
266
+ end
267
+
268
+ def doings_to_dones
269
+ _doings = get_doings
270
+ if _doings.size == 0
271
+ puts 'there is no doing task.before done, you must choose task.'
272
+ return false
273
+ end
274
+ File.open(TUDU_DOINGS_FILE_PATH, 'w:UTF-8') { |f|f.print '' }
275
+ File.open(TUDU_DONES_FILE_PATH, 'a:UTF-8') { |f|f.puts _doings.first.name }
276
+ true
277
+ end
278
+
279
+ def todos_to_doings
280
+ _todos = get_todos
281
+ return if finish?(_todos)
282
+ deleted_todos = _todos.dup
283
+ deleted_todos.delete_at 0
284
+ File.open(TUDU_TODOS_FILE_PATH, 'w:UTF-8') do |f|
285
+ deleted_todos.each { |task|f.puts task.name }
286
+ end
287
+ File.open(TUDU_DOINGS_FILE_PATH, 'w:UTF-8') { |f|f.puts _todos.first.name }
288
+ end
289
+
290
+ def finish?(_todos)
291
+ return false unless _todos.size == 0
292
+ puts 'All Tasks Finish!!' if get_doings.size == 0
293
+ true
294
+ end
295
+ end
296
+
297
+ # == init task with setting task type and task name.
298
+ def initialize(type, name)
299
+ @type, @name = type, name
300
+ end
301
+
302
+ def todo?
303
+ @type == 'todos'
304
+ end
305
+
306
+ def doing?
307
+ @type == 'doings'
308
+ end
309
+
310
+ def done?
311
+ @type == 'dones'
312
+ end
313
+
314
+ def ==(other)
315
+ return true if name == other.name && type == other.type
316
+ false
317
+ end
318
+ end
319
+ end