tdo 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/VERSION +1 -1
  2. data/bin/tdo +5 -5
  3. data/lib/tdo.rb +189 -120
  4. data/tdo.gemspec +2 -2
  5. data/test/test_tdo.rb +28 -21
  6. metadata +3 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/bin/tdo CHANGED
@@ -27,12 +27,12 @@ opts = OptionParser.new do |opts|
27
27
  end
28
28
 
29
29
  opts.on("--summary", "-s", "Summary") do
30
- puts Tdo.task_summary
30
+ puts Tdo.summary
31
31
  exit 0
32
32
  end
33
33
 
34
34
  opts.on("--clear", "-c", "Clear done items") do
35
- Tdo.clear_done
35
+ Tdo.clear
36
36
  exit 0
37
37
  end
38
38
 
@@ -46,9 +46,9 @@ opts.parse!
46
46
 
47
47
 
48
48
  if ARGV.size == 2
49
- Tdo.add_task(ARGV[1], ARGV[0])
49
+ Tdo.add(ARGV[1], ARGV[0])
50
50
  elsif ARGV.size == 1
51
- Tdo.add_task(ARGV[0])
51
+ Tdo.add(ARGV[0])
52
52
  else
53
- puts Tdo.task_summary
53
+ puts Tdo.summary
54
54
  end
data/lib/tdo.rb CHANGED
@@ -1,154 +1,223 @@
1
1
  module Tdo
2
2
 
3
3
  class InvalidGroup < ArgumentError; end
4
-
5
- TODO_FILE = File.expand_path "~/.todo.txt"
6
4
 
7
- # Reads the TODO file
8
- #
9
- # @param [String] group to read tasks from
10
- # @return [String] the tasks
11
- def self.read_tasks( group=nil )
12
- unless group
13
- File.new(TODO_FILE, "r").read
14
- else
15
- t = File.new(TODO_FILE, "r").read
16
- raise InvalidGroup, "'#{group}' is not a valid group name", caller unless self.group?(group)
17
- to_s( to_hash(t)[ group[1..-1] ] )
18
- end
19
- end
5
+ # If using ENV, path must be absolute
6
+ TODO_FILE = ENV['TDO_FILE'] || File.expand_path("~/.todo.txt")
7
+
20
8
 
21
9
  # Gives a summary of remaining tasks
22
10
  #
23
11
  # @return [String] summary of tasks
24
- def self.task_summary
25
- t = to_hash( self.read_tasks )
26
- groups = t.size
12
+ def self.summary
13
+ t = Tasks.new.items
14
+ groups = t.size-1
27
15
  tasks = t.inject(0) {|sum, t| sum += t[1].size}
28
16
  done = t.inject(0) {|sum, t| sum += t[1].delete_if {|i| !i.include? ' #done' }.size}
29
17
  "#{tasks} tasks in #{groups} groups, #{done} done"
30
18
  end
31
19
 
32
- # Allows you to add a new task to the file
33
- #
34
- # @param [String] task to add
35
- # @param [String] group to add the task to
36
- def self.add_task( task, group='@ungrouped' )
37
- if File.exists? TODO_FILE
38
- t = to_hash( self.read_tasks )
39
- else
40
- t = {}
41
- end
42
- if group[0] == "@"
43
- group = group[1..-1]
20
+ # Takes the groups name from a string
21
+ def self.get_group( str )
22
+ if str[0] == '@'
23
+ return str[1..-1]
44
24
  else
45
- raise InvalidGroup, "'#{group}' is not a valid group name", caller
25
+ return str
46
26
  end
47
- t[group] ||= [] # need to create new group if it doesn't exist
48
- t[group] << task.strip
49
-
50
- write_hash t
51
27
  end
52
28
 
53
- # Marks the selected item as done
54
- #
55
- # @param [String, Integer] task to mark as done
56
- # @param [String] group that the task belongs to
57
- def self.mark_done( id, group='@ungrouped' )
58
- if group[0] == "@"
59
- group = group[1..-1]
60
- else
61
- raise InvalidGroup, "'#{group}' is not a valid group name", caller
62
- end
63
29
 
64
- t = to_hash( self.read_tasks )
65
- if id.is_a? String
66
- t[group].each_with_index do |task, i|
67
- if task.include? id
68
- t[group][i] += ' #done'
30
+
31
+ class Tasks
32
+
33
+ attr_accessor :items
34
+
35
+ # Creates a new Tasks object and loads in the TODO_FILE
36
+ def initialize
37
+ @items = {'ungrouped' => []}
38
+ self.read
39
+ end
40
+
41
+ # Reads TODO_FILE and converts it to a hash
42
+ def read
43
+ t = File.new(TODO_FILE, "r").read
44
+ _group = ''
45
+ t.split("\n").each do |l|
46
+ if l[0] == '-'
47
+ @items['ungrouped'] << l[1..-1].strip
48
+ elsif l[0] == '@'
49
+ _group = l[1..-1].strip
50
+ @items[_group] = []
51
+ elsif l[0..1] == ' -'
52
+ @items[_group] << l[2..-1].strip
69
53
  end
70
54
  end
71
- elsif id.is_a? Integer
72
- t[group][id] += ' #done'
73
55
  end
74
- write_hash t
75
- end
76
-
77
-
78
- # Deletes all items which have been marked done
79
- #
80
- # @return [Integer] number of tasks cleared
81
- def self.clear_done
82
- t = to_hash( self.read_tasks )
83
- r = 0
84
- t.each do |group, tasks|
85
- s = tasks.size
86
- r += tasks.delete_if {|i| i.include? ' #done' }.size - s
56
+
57
+ # Adds the task to the list
58
+ #
59
+ # @param [String] task to add
60
+ # @param [String] group to add the task to
61
+ # @return [Boolean] whether the task has been added successfully
62
+ def add(task, group=nil)
63
+ if group.nil?
64
+ group = 'ungrouped'
65
+ else
66
+ group = Tdo.get_group(group)
67
+ end
68
+
69
+ if self.find(task, group)
70
+ false
71
+ else
72
+ @items[group] ||= []
73
+ @items[group] << task.strip
74
+ self.write
75
+ true
76
+ end
77
+ end
78
+
79
+ # Marks the selected item as done
80
+ #
81
+ # @param [String, Integer] task to mark as done
82
+ # @param [String] group that the task belongs to
83
+ def mark_done(id, group=nil)
84
+ unless group.nil?
85
+ group = Tdo.get_group(group)
86
+ self.group?(group)
87
+ end
88
+
89
+ if id.is_a? Integer
90
+ if group
91
+ @items[group][id] += ' #done'
92
+ else
93
+ # should really count across groups, another time!
94
+ @items['ungrouped'][id] += ' #done'
95
+ end
96
+ elsif id.is_a? String
97
+ if group
98
+ @items[group].collect! { |t|
99
+ t.include?(id) ? t += ' #done' : t
100
+ }
101
+ else
102
+ # should test in every group as above
103
+ @items['ungrouped'].collect! { |t|
104
+ t.include?(id) ? t += ' #done' : t
105
+ }
106
+ end
107
+ else
108
+ # error
109
+ return false
110
+ end
111
+ self.write
112
+ true
113
+ end
114
+
115
+ # Deletes all tasks marked as done
116
+ #
117
+ # @return [Integer] number of tasks cleared
118
+ def clear
119
+ r = 0
120
+ @items.each do |g, ts|
121
+ s = ts.size
122
+ ts.delete_if {|i| i.include?(' #done') }
123
+ r += s - ts.size
124
+ end
125
+ @items.delete_if {|g, ts| ts == [] }
126
+ self.write
127
+ r
128
+ end
129
+
130
+ # Finds tasks which contain the string to look for
131
+ #
132
+ # @param [String] arg string to look for
133
+ # @param [String] group to look within
134
+ # @return [Array] found tasks
135
+ # @todo find within group
136
+ def find(str, group=nil)
137
+ r = []
138
+ @items.each do |g, ts|
139
+ ts.each do |t|
140
+ r << t if t.include?(str)
141
+ end
142
+ end
143
+ if r == []
144
+ false
145
+ else
146
+ r
147
+ end
148
+ end
149
+
150
+ # Converts the tasks to a string which can then be written to a file
151
+ #
152
+ # @param [String] group
153
+ # @return [String] string representation of tasks
154
+ def to_s(group=nil)
155
+ r = ''
156
+ if group
157
+ self.group?(group)
158
+ group = Tdo.get_group(group)
159
+ @items[group].each do |t|
160
+ r += "- #{t}\n"
161
+ end
162
+ else
163
+ @items.each do |g, ts|
164
+ if g == 'ungrouped'
165
+ ts.each do |t|
166
+ r += "- #{t}\n"
167
+ end
168
+ else
169
+ r += "\n@#{g}\n"
170
+ ts.each do |t|
171
+ r += " - #{t}\n"
172
+ end
173
+ end
174
+ end
175
+ end
176
+ r
177
+ end
178
+
179
+ # Writes the tasks to a file
180
+ def write
181
+ File.open(TODO_FILE, "w") {|f| f.write( self.to_s )}
182
+ end
183
+
184
+ # Tests whether the group exists
185
+ #
186
+ # @param [String] group name
187
+ # @return [Boolean] whether the group exists
188
+ def group?( name )
189
+ if self.items.has_key?( Tdo.get_group(name) )
190
+ true
191
+ else
192
+ raise InvalidGroup, "'#{name}' is not a valid group name", caller
193
+ end
87
194
  end
88
- t.delete_if {|k, v| v == [] }
89
- write_hash t
90
- r
195
+
196
+ # Override default insepct
197
+ def inspect
198
+ "#<Tdo::Tasks>"
199
+ end
200
+
91
201
  end
92
202
 
93
- # Converts the given hash to a string and writes to the TODO_FILE
203
+ ##
204
+ # These are a group of methods to make it easy to use the above class
94
205
  #
95
- # @param [Hash] tasks hash to write
96
- def self.write_hash( hash )
97
- File.open(TODO_FILE, "w") {|f| f.write( to_s(hash) )}
206
+ def self.read_tasks(group=nil)
207
+ Tdo::Tasks.new.to_s(group)
98
208
  end
99
209
 
100
-
101
- # Tests whether the group exists
102
- #
103
- # @param [String] group name
104
- # @return [Boolean] whether the group exists
105
- def self.group?( name )
106
- t = to_hash( self.read_tasks )
107
- t.has_key?(name[1..-1])
210
+ def self.mark_done(id, group=nil)
211
+ Tdo::Tasks.new.mark_done(id, group)
108
212
  end
109
213
 
110
- # Converts the string read from the file to a hash so it can easily be used
111
- #
112
- # @param [String] read file string
113
- # @return [Hash] the string as a hash
114
- def self.to_hash( s )
115
- r = {'ungrouped' => []}
116
- last_group ||= ''
117
- s.split("\n").each do |l|
118
- if l[0] == '@'
119
- last_group = l[1..-1].strip
120
- r[last_group] = []
121
- elsif l[1] == '-'
122
- r[last_group] << l[2..-1].strip
123
- elsif l[0] == '-'
124
- r['ungrouped'] << l[1..-1].strip
125
- end
126
- end
127
- r
214
+ def self.clear
215
+ Tdo::Tasks.new.clear
128
216
  end
129
217
 
130
- # Converts the given hash to a string which can then be written to a file
131
- #
132
- # @param [Hash] hash of todo tasks
133
- # @return [String] string representation of hash
134
- def self.to_s( hash )
135
- if !hash.is_a? Hash
136
- hash = {'ungrouped' => hash}
137
- end
138
- r = ""
139
- hash.each do |group, tasks|
140
- if group == 'ungrouped'
141
- tasks.each do |task|
142
- r += "- #{task}\n"
143
- end
144
- else
145
- r += "\n@#{group}\n"
146
- tasks.each do |task|
147
- r += " - #{task}\n"
148
- end
149
- end
150
- end
151
- r
218
+ def self.add(task, group=nil)
219
+ Tdo::Tasks.new.add(task, group)
152
220
  end
221
+
153
222
 
154
223
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tdo}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joshua Hawxwell"]
12
- s.date = %q{2010-06-26}
12
+ s.date = %q{2010-07-01}
13
13
  s.default_executable = %q{tdo}
14
14
  s.description = %q{Tdo is a simple ruby app to add, edit and read your todo list. It stores the list at ~/.todo.txt}
15
15
  s.email = %q{m@hawx.me}
@@ -1,63 +1,70 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestTdo < Test::Unit::TestCase
4
-
4
+
5
5
  should "read tasks" do
6
6
  clear_todo
7
- assert_equal Tdo.read_tasks, file_text
7
+ t = Tdo::Tasks.new
8
+ assert_equal t.to_s, file_text
8
9
  end
9
10
 
10
11
  should "read tasks from specific group" do
11
12
  clear_todo
12
- assert_equal Tdo.read_tasks('@home'), "- Another group\n"
13
+ assert_equal "- Another group\n", Tdo::Tasks.new.to_s('@home')
13
14
  end
14
15
 
15
16
  should "add new task" do
16
17
  clear_todo
17
- b = Tdo.read_tasks
18
- Tdo.add_task("Pick up milk")
19
-
20
- assert_equal Tdo.read_tasks.size, b.size + " - Pick up milk".size
18
+ t = Tdo::Tasks.new
19
+ b = t.to_s
20
+ t.add("Pick up milk")
21
+
22
+ assert_equal b.size + " - Pick up milk".size, t.to_s.size
21
23
  end
22
24
 
23
25
  should "add new task to group" do
24
26
  clear_todo
25
- Tdo.add_task('Pick up milk', '@test')
27
+ t = Tdo::Tasks.new
28
+ t.add('Pick up milk', '@test')
26
29
 
27
- assert_equal Tdo.read_tasks('@test').size, " - Pick up milk".size
30
+ assert_equal " - Pick up milk".size, t.to_s('@test').size
28
31
  end
29
32
 
30
33
  should "mark task as done" do
31
34
  clear_todo
32
- b = Tdo.read_tasks('@ungrouped').strip
33
- Tdo.mark_done('A task', '@ungrouped')
35
+ t = Tdo::Tasks.new
36
+ b = t.to_s('@ungrouped').strip
37
+ t.mark_done('A task', '@ungrouped')
34
38
 
35
- assert_equal Tdo.read_tasks('@ungrouped'), b + " #done\n"
39
+ assert_equal b + " #done\n", t.to_s('@ungrouped')
36
40
  end
37
41
 
38
42
  should "mark task at index as done" do
39
43
  clear_todo
40
- b = Tdo.read_tasks( '@ungrouped').strip
41
- Tdo.mark_done(0, '@ungrouped')
44
+ t = Tdo::Tasks.new
45
+ b = t.to_s('@ungrouped').strip
46
+ t.mark_done(0, '@ungrouped')
42
47
 
43
- assert_equal Tdo.read_tasks('@ungrouped'), b + " #done\n"
48
+ assert_equal b + " #done\n", t.to_s('@ungrouped')
44
49
  end
45
50
 
46
51
  should "remove all tasks marked done" do
47
52
  clear_todo
48
- Tdo.clear_done
53
+ t = Tdo::Tasks.new
54
+ t.clear
49
55
 
50
- assert_equal Tdo.read_tasks('@group'), "- Another task\n"
56
+ assert_equal "- Another task\n", t.to_s('@group')
51
57
  end
52
58
 
53
59
  should "remove group when all tasks are cleared" do
54
60
  clear_todo
55
- Tdo.mark_done(0, '@home')
56
- Tdo.clear_done
61
+ t = Tdo::Tasks.new
62
+ t.mark_done(0, '@home')
63
+ t.clear
57
64
 
58
65
  assert_raise Tdo::InvalidGroup do
59
- Tdo.read_tasks('@home')
66
+ t.to_s('@home')
60
67
  end
61
68
  end
62
-
69
+
63
70
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joshua Hawxwell
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-26 00:00:00 +01:00
17
+ date: 2010-07-01 00:00:00 +01:00
18
18
  default_executable: tdo
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency