toodledo 1.3.8 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ == 1.4.0
2
+
3
+ * Added "today", "tomorrow" and "overdue" to commands, thx to afrolov.
4
+
1
5
  == 1.3.8
2
6
 
3
7
  * Rubygems does not allow you to publish the same version, even if yanked. Thanks SO much.
data/README.md CHANGED
@@ -59,6 +59,13 @@ for the client is as follows:
59
59
  #DueDate
60
60
  %Tags
61
61
 
62
+ Additionally, a * _not_ followed immediately by a folder name
63
+ indicates that the task should be starred.
64
+
65
+ For adding tasks, you may specify Priority as either a word:
66
+ top,high,medium,low,negative or as a number: -1,0,1,2,3
67
+
68
+
62
69
  You can encase the symbol with square brackets if there is a space involved:
63
70
 
64
71
  *[Blue Sky]
data/Rakefile CHANGED
@@ -26,6 +26,8 @@ You can also use the client in your shell scripts, or use the API directly
26
26
  as part of a web application. Custom private RSS feed? Want to have the Mac
27
27
  read out your top priority? Input tasks through Quicksilver? Print out
28
28
  tasks with a BetaBrite? It can all happen.
29
+
30
+ Check it out: http://aosekai.net/2011/09/quickly-add-new-task-to-toodledo-with-alfred/
29
31
  EOF
30
32
  gem.homepage = "http://github.com/wsargent/toodledo"
31
33
  gem.authors = ["Will Sargent"]
@@ -18,6 +18,9 @@ require 'toodledo/command_line/add_command'
18
18
  # READ
19
19
  require 'toodledo/command_line/hotlist_command'
20
20
  require 'toodledo/command_line/list_tasks_command'
21
+ require 'toodledo/command_line/list_today_command'
22
+ require 'toodledo/command_line/list_tomorrow_command'
23
+ require 'toodledo/command_line/list_overdue_command'
21
24
  require 'toodledo/command_line/list_tasks_by_context_command'
22
25
  require 'toodledo/command_line/list_folders_command'
23
26
  require 'toodledo/command_line/list_contexts_command'
@@ -333,7 +336,55 @@ module Toodledo
333
336
  print @formatters[:task].format(task)
334
337
  end
335
338
  end
336
-
339
+
340
+ #
341
+ # Print all tasks with the due date in the given time range
342
+ #
343
+ def list_tasks_by_beforeafter(session, before, after)
344
+ params = { :notcomp => true }
345
+ if (before)
346
+ params.merge!({ :before => before.strftime("%Y-%m-%d") })
347
+ end
348
+
349
+ if (after)
350
+ params.merge!({ :after => after.strftime("%Y-%m-%d") })
351
+ end
352
+
353
+ tasks = session.get_tasks(params)
354
+ for task in tasks
355
+ print @formatters[:task].format(task)
356
+ end
357
+ end
358
+
359
+ #
360
+ # Print tasks for today
361
+ #
362
+ def list_today_tasks(session, line)
363
+ tomorrow = Date.today + 1
364
+ yesterday = Date.today - 1
365
+ # show us everything before tomorrow, but after yesterday.
366
+ list_tasks_by_beforeafter(session, tomorrow, yesterday)
367
+ end
368
+
369
+ #
370
+ # Print tasks for tomorrow
371
+ #
372
+ def list_tomorrow_tasks(session, line)
373
+ today = Date.today
374
+ twodaysfromnow = today + 2
375
+ # show us tasks before two days from now, but after today.
376
+ list_tasks_by_beforeafter(session, twodaysfromnow, today)
377
+ end
378
+
379
+ #
380
+ # Print overdue tasks
381
+ #
382
+ def list_overdue_tasks(session, line)
383
+ today = Date.today
384
+ # show us everything before today.
385
+ list_tasks_by_beforeafter(session, today, nil)
386
+ end
387
+
337
388
  #
338
389
  # Prints all active tasks nested by context.
339
390
  #
@@ -385,7 +436,6 @@ module Toodledo
385
436
  # Lists the contexts.
386
437
  #
387
438
  def list_contexts(session, input)
388
- params = { }
389
439
 
390
440
  contexts = session.get_contexts()
391
441
 
@@ -398,7 +448,6 @@ module Toodledo
398
448
  # Lists the folders.
399
449
  #
400
450
  def list_folders(session, input)
401
- params = { }
402
451
 
403
452
  folders = session.get_folders()
404
453
 
@@ -419,13 +468,14 @@ module Toodledo
419
468
  def add_task(session, line)
420
469
  # TODO Yet again, essentially the same code as list and hotlist; Refactor
421
470
  context = parse_context(line)
471
+ star = parse_star(line) # ctanis
422
472
  folder = parse_folder(line)
423
473
  goal = parse_goal(line)
424
474
  priority = parse_priority(line)
425
475
  date = parse_date(line)
426
476
  tag = parse_tag(line)
427
477
  title = parse_remainder(line)
428
-
478
+
429
479
  params = {}
430
480
  if (priority != nil)
431
481
  params.merge!({ :priority => priority })
@@ -450,6 +500,10 @@ module Toodledo
450
500
  if (tag != nil)
451
501
  params.merge!({ :tag => tag })
452
502
  end
503
+
504
+ if (star) # boolean
505
+ params.merge!({ :star => true })
506
+ end
453
507
 
454
508
  # If we got nothing but 'add' then ask for it explicitly.
455
509
  if (title == nil)
@@ -687,6 +741,9 @@ module Toodledo
687
741
  print "goals Shows all goals"
688
742
  print "contexts Shows all contexts"
689
743
  print "tasks Shows tasks ('tasks *Action @Home')"
744
+ print "today Shows tasks for today"
745
+ print "tomorrow Shows tasks for tomorrow"
746
+ print "overdue Shows overdue tasks"
690
747
  print
691
748
  print "add Adds task ('add *Action @Home Eat breakfast')"
692
749
  print " folder Adds a folder ('add folder MyFolder')"
@@ -764,6 +821,18 @@ module Toodledo
764
821
  line = clean(/^(tasks)/, input)
765
822
  list_tasks(session, line)
766
823
 
824
+ when /^today/
825
+ line = clean(/^(today)/, input)
826
+ list_today_tasks(session, line)
827
+
828
+ when /^tomorrow/
829
+ line = clean(/^(tomorrow)/, input)
830
+ list_tomorrow_tasks(session, line)
831
+
832
+ when /^overdue/
833
+ line = clean(/^(overdue)/, input)
834
+ list_overdue_tasks(session, line)
835
+
767
836
  when /^folders/
768
837
  line = clean(/^folders/, input)
769
838
  list_folders(session,line)
@@ -830,6 +899,11 @@ module Toodledo
830
899
  cmd.add_command(AddTaskCommand.new(self))
831
900
 
832
901
  cmd.add_command(ListTasksCommand.new(self))
902
+
903
+ cmd.add_command(ListTodayCommand.new(self))
904
+ cmd.add_command(ListTomorrowCommand.new(self))
905
+ cmd.add_command(ListOverdueCommand.new(self))
906
+
833
907
  cmd.add_command(ListFoldersCommand.new(self))
834
908
  cmd.add_command(ListGoalsCommand.new(self))
835
909
  cmd.add_command(ListContextsCommand.new(self))
@@ -16,18 +16,21 @@ module Toodledo
16
16
 
17
17
  CONTEXT_REGEXP = /\@((\w+)|\[(.*?)\])/
18
18
 
19
- PRIORITY_REGEXP = /!(top|high|medium|low|negative)/
19
+ PRIORITY_REGEXP = /!(top|high|medium|low|negative|-1|0|1|2|3)/
20
20
 
21
21
  DATE_REGEXP = /\#(([^\[]\S*)|\[(.*?)\])/
22
22
 
23
23
  TAGS_REGEXP = /\%((\w+)|\[(.*?)\])/
24
24
 
25
+ STAR_REGEXP = /\*\s+|\*$/
26
+
25
27
  # Note that level must exist at the beginning of the line
26
28
  LEVEL_REGEXP = /^(life|medium|short)/
27
29
 
28
30
  # Don't include level regexp
29
31
  REGEXP_LIST = [
30
32
  FOLDER_REGEXP,
33
+ STAR_REGEXP,
31
34
  GOAL_REGEXP,
32
35
  CONTEXT_REGEXP,
33
36
  PRIORITY_REGEXP,
@@ -92,6 +95,17 @@ module Toodledo
92
95
  return Toodledo::Priority::LOW
93
96
  when 'negative'
94
97
  return Toodledo::Priority::NEGATIVE
98
+ when '-1'
99
+ return Toodledo::Priority::NEGATIVE
100
+ when '0'
101
+ return Toodledo::Priority::LOW
102
+ when '1'
103
+ return Toodledo::Priority::MEDIUM
104
+ when '2'
105
+ return Toodledo::Priority::HIGH
106
+ when '3'
107
+ return Toodledo::Priority::TOP
108
+
95
109
  else
96
110
  return nil
97
111
  end
@@ -116,7 +130,17 @@ module Toodledo
116
130
  end
117
131
  end
118
132
 
119
- # Returns the bit after we've looked for *Folder, @Context & ^Goal
133
+ def parse_star(input)
134
+ match_data = STAR_REGEXP.match(input)
135
+ if (match_data == nil)
136
+ return false
137
+ else
138
+ return true
139
+ end
140
+ end
141
+
142
+
143
+ # Returns the bit after we've looked for *Folder, @Context & ^Goal & star
120
144
  def parse_remainder(line)
121
145
  input = line
122
146
 
@@ -129,6 +153,7 @@ module Toodledo
129
153
 
130
154
  return input
131
155
  end
156
+
132
157
 
133
158
  # Strips a string of [ and ] characters
134
159
  def strip_brackets(inword)
@@ -2,8 +2,8 @@
2
2
  module Toodledo
3
3
  module Version
4
4
  MAJOR = 1
5
- MINOR = 3
6
- PATCH = 8
5
+ MINOR = 4
6
+ PATCH = 0
7
7
 
8
8
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
9
9
  end
@@ -158,4 +158,80 @@ class ParserHelperTest < Test::Unit::TestCase
158
158
  assert_equal(Goal::SHORT_LEVEL, level, 'level not found')
159
159
  end
160
160
 
161
- end
161
+ def test_find_star()
162
+ input = '* this is a starred task'
163
+ star = parse_star(input)
164
+ folder = parse_folder(input)
165
+ assert_equal(star, true)
166
+ assert_equal(folder, nil)
167
+ end
168
+
169
+ def test_find_star2()
170
+ input = 'this is also a starred task *'
171
+ star = parse_star(input)
172
+ folder = parse_folder(input)
173
+ assert_equal(star, true)
174
+ assert_equal(folder, nil)
175
+ end
176
+
177
+ def test_find_star3()
178
+ input = 'this is not a starred task *foo'
179
+ star = parse_star(input)
180
+ folder = parse_folder(input)
181
+ assert_equal(star, false)
182
+ assert_equal(folder, "foo")
183
+ end
184
+
185
+ def test_find_star4()
186
+ input = '* but this is not a starred task *foo'
187
+ star = parse_star(input)
188
+ folder = parse_folder(input)
189
+ assert_equal(star, true)
190
+ assert_equal(folder, "foo")
191
+ end
192
+
193
+ def test_find_priority_with_numbers1
194
+ input = "!3 I AM VERY IMPORTANT!"
195
+
196
+ priority = parse_priority(input)
197
+
198
+ assert(priority == Priority::TOP, "Value not found")
199
+ end
200
+
201
+ def test_find_priority_with_numbers2
202
+ input = "I AM QUITE IMPORTANT! !2"
203
+
204
+ priority = parse_priority(input)
205
+
206
+ assert(priority == Priority::HIGH, "Value not found")
207
+ end
208
+
209
+ def test_find_priority_with_numbers3
210
+ input = "!1 I AM KINDA IMPORTANT!"
211
+
212
+ priority = parse_priority(input)
213
+
214
+ assert(priority == Priority::MEDIUM, "Value not found")
215
+ end
216
+
217
+
218
+ def test_find_priority_with_numbers4
219
+ input = "!0 I AM NOT VERY IMPORTANT!"
220
+
221
+ priority = parse_priority(input)
222
+
223
+ assert(priority == Priority::LOW, "Value not found")
224
+ end
225
+
226
+
227
+ def test_find_priority_with_numbers5
228
+ input = "!-1 I AM MAXIMALLY UNIMPORTANT!"
229
+
230
+ priority = parse_priority(input)
231
+
232
+ assert(priority == Priority::NEGATIVE, "Value not found")
233
+ end
234
+
235
+
236
+
237
+ end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{toodledo}
8
- s.version = "1.3.8"
8
+ s.version = "1.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Will Sargent}]
metadata CHANGED
@@ -1,85 +1,92 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: toodledo
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 3
9
- - 8
10
- version: 1.3.8
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Will Sargent
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-06-28 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-06-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: cmdparse
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: highline
36
23
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
38
25
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: highline
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
46
38
  type: :runtime
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: flexmock
50
39
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
52
41
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: flexmock
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
60
54
  type: :development
61
- version_requirements: *id003
62
- description: |
63
- This is a Ruby API and client for http://toodledo.com, a task management
64
- website. It implements all of the calls from Toodledo's developer API, and
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: ! 'This is a Ruby API and client for http://toodledo.com, a task management
63
+
64
+ website. It implements all of the calls from Toodledo''s developer API, and
65
+
65
66
  provides a nice wrapper around the functionality.
66
-
67
+
68
+
67
69
  The client allows you to work with Toodledo from the command line. It will
70
+
68
71
  work in either interactive or command line mode.
69
-
72
+
73
+
70
74
  You can also use the client in your shell scripts, or use the API directly
75
+
71
76
  as part of a web application. Custom private RSS feed? Want to have the Mac
77
+
72
78
  read out your top priority? Input tasks through Quicksilver? Print out
79
+
73
80
  tasks with a BetaBrite? It can all happen.
74
81
 
82
+ '
75
83
  email: will.sargent@gmail.com
76
- executables:
84
+ executables:
77
85
  - toodledo
78
86
  extensions: []
79
-
80
- extra_rdoc_files:
87
+ extra_rdoc_files:
81
88
  - README.md
82
- files:
89
+ files:
83
90
  - History.txt
84
91
  - README.md
85
92
  - Rakefile
@@ -124,36 +131,26 @@ files:
124
131
  - toodledo.gemspec
125
132
  homepage: http://github.com/wsargent/toodledo
126
133
  licenses: []
127
-
128
134
  post_install_message:
129
135
  rdoc_options: []
130
-
131
- require_paths:
136
+ require_paths:
132
137
  - lib
133
- required_ruby_version: !ruby/object:Gem::Requirement
138
+ required_ruby_version: !ruby/object:Gem::Requirement
134
139
  none: false
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- hash: 3
139
- segments:
140
- - 0
141
- version: "0"
142
- required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
145
  none: false
144
- requirements:
145
- - - ">="
146
- - !ruby/object:Gem::Version
147
- hash: 3
148
- segments:
149
- - 0
150
- version: "0"
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
151
150
  requirements: []
152
-
153
151
  rubyforge_project:
154
- rubygems_version: 1.8.5
152
+ rubygems_version: 1.8.23
155
153
  signing_key:
156
154
  specification_version: 3
157
155
  summary: A command line client and API to Toodledo
158
156
  test_files: []
159
-