toodledo 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ module Toodledo
2
+ module CommandLine
3
+ class ContextFormatter
4
+ def format(context)
5
+ return "<#{context.server_id}> -- @[#{context.name}]"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,79 @@
1
1
 
2
2
  module Toodledo
3
3
  module CommandLine
4
- class DeleteCommand < BaseCommand
4
+
5
+ class DeleteCommand < CmdParse::Command
6
+ def initialize(client)
7
+ super('delete', true)
8
+ self.short_desc = "Deletes a context"
9
+
10
+ self.add_command(DeleteContextCommand.new(client))
11
+ self.add_command(DeleteGoalCommand.new(client))
12
+ self.add_command(DeleteFolderCommand.new(client))
13
+
14
+ self.add_command(DeleteTaskCommand.new(client), true)
15
+ end
16
+
17
+ end
18
+
19
+ class DeleteContextCommand < BaseCommand
20
+ def initialize(client)
21
+ super(client, 'context', false)
22
+ self.short_desc = "Deletes a context"
23
+ end
24
+
25
+ def execute(args)
26
+ Toodledo.begin(client.logger) do |session|
27
+ line = args.join(' ')
28
+ client.delete_context(session, line)
29
+ end
30
+
31
+ return 0
32
+ rescue ItemNotFoundError => e
33
+ puts e.message
34
+ return -1
35
+ end
36
+ end
37
+
38
+ class DeleteFolderCommand < BaseCommand
39
+ def initialize(client)
40
+ super(client, 'folder', false)
41
+ self.short_desc = "Deletes a folder"
42
+ end
43
+
44
+ def execute(args)
45
+ Toodledo.begin(client.logger) do |session|
46
+ line = args.join(' ')
47
+ client.delete_folder(session, line)
48
+ end
49
+
50
+ return 0
51
+ rescue ItemNotFoundError => e
52
+ puts e.message
53
+ return -1
54
+ end
55
+ end
56
+
57
+ class DeleteGoalCommand < BaseCommand
58
+ def initialize(client)
59
+ super(client, 'goal', false)
60
+ self.short_desc = "Deletes a goal"
61
+ end
62
+
63
+ def execute(args)
64
+ Toodledo.begin(client.logger) do |session|
65
+ line = args.join(' ')
66
+ client.delete_goal(session, line)
67
+ end
68
+
69
+ return 0
70
+ rescue ItemNotFoundError => e
71
+ puts e.message
72
+ return -1
73
+ end
74
+ end
75
+
76
+ class DeleteTaskCommand < BaseCommand
5
77
  def initialize(client)
6
78
  super(client, 'delete', false)
7
79
  self.short_desc = "Deletes a task"
@@ -20,5 +92,7 @@ module Toodledo
20
92
  return -1
21
93
  end
22
94
  end
95
+
96
+
23
97
  end
24
98
  end
@@ -0,0 +1,9 @@
1
+ module Toodledo
2
+ module CommandLine
3
+ class FolderFormatter
4
+ def format(folder)
5
+ return "<#{folder.server_id}> -- *[#{folder.name}]"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ require 'toodledo/goal'
2
+
3
+ module Toodledo
4
+ module CommandLine
5
+ class GoalFormatter
6
+ def format(goal)
7
+ msg = "<#{goal.server_id}> -- #{readable_level(goal.level)} ^[#{goal.name}]"
8
+ if (goal.contributes != Goal::NO_GOAL)
9
+ msg += " (Contributes to: ^[#{goal.contributes.name}])"
10
+ end
11
+ return msg
12
+ end
13
+
14
+ def readable_level(level)
15
+ case level
16
+ when Goal::LIFE_LEVEL
17
+ return 'life'
18
+ when Goal::MEDIUM_LEVEL
19
+ return 'medium'
20
+ when Goal::SHORT_LEVEL
21
+ return 'short'
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ require 'toodledo/command_line/parser_helper'
2
+ require 'logger'
3
+
4
+ module Toodledo
5
+
6
+ module CommandLine
7
+ # Runs the interactive client.
8
+ class InteractiveCommand < BaseCommand
9
+
10
+ def initialize(client)
11
+ super(client, 'interactive', false)
12
+ self.short_desc = "Interactive client"
13
+ self.description = "The interactive command line client."
14
+ end
15
+
16
+ def execute(args)
17
+ Toodledo.begin(client.logger) do |session|
18
+ command_loop(session)
19
+ end
20
+ end
21
+
22
+ def command_loop(session)
23
+ loop do
24
+ begin
25
+ input = ask("> ") do |q|
26
+ q.readline = true
27
+ end
28
+
29
+ input.strip!
30
+
31
+ client.execute_command(session, input)
32
+ rescue Toodledo::ItemNotFoundError => infe
33
+ puts "Item not found: #{infe}"
34
+ rescue Toodledo::ServerError => se
35
+ puts "Server Error: #{se}"
36
+ rescue RuntimeError => re
37
+ puts "Error: #{re}"
38
+ end
39
+ end # loop
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ #
3
+ #
4
+
5
+
6
+ module Toodledo
7
+ module CommandLine
8
+
9
+
10
+ #
11
+ # List Folders
12
+ #
13
+ class ListFoldersCommand < BaseCommand
14
+ def initialize(client)
15
+ super(client, 'folders', false)
16
+ self.short_desc = "List folders"
17
+ self.description = "Lists the folders in Toodledo."
18
+ end
19
+
20
+ def execute(args)
21
+
22
+ Toodledo.begin(client.logger) do |session|
23
+ line = args.join(' ')
24
+ return client.list_folders(session, line)
25
+ end
26
+
27
+ return 0
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ #
2
+ #
3
+ #
4
+
5
+
6
+ module Toodledo
7
+ module CommandLine
8
+
9
+ #
10
+ # List Goals
11
+ #
12
+ class ListGoalsCommand < BaseCommand
13
+ def initialize(client)
14
+ super(client, 'goals', false)
15
+ self.short_desc = "List goals"
16
+ self.description = "Lists the goals in Toodledo."
17
+ end
18
+
19
+ def execute(args)
20
+
21
+ Toodledo.begin(client.logger) do |session|
22
+ line = args.join(' ')
23
+ return client.list_goals(session, line)
24
+ end
25
+
26
+ return 0
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -1,14 +1,19 @@
1
1
 
2
2
  module Toodledo
3
3
  module CommandLine
4
- class ListCommand < BaseCommand
4
+
5
+ #
6
+ # Lists the tasks.
7
+ #
8
+ class ListTasksCommand < BaseCommand
5
9
  def initialize(client)
6
- super(client, 'list', false)
10
+ super(client, 'tasks', false)
7
11
  self.short_desc = "List tasks"
8
12
  self.description = "Lists the tasks in Toodledo."
9
13
  end
10
14
 
11
15
  def execute(args)
16
+
12
17
  Toodledo.begin(client.logger) do |session|
13
18
  line = args.join(' ')
14
19
  return client.list_tasks(session, line)
@@ -17,5 +22,7 @@ module Toodledo
17
22
  return 0
18
23
  end
19
24
  end
25
+
26
+
20
27
  end
21
28
  end
@@ -1,18 +1,32 @@
1
+ require 'toodledo/priority'
1
2
 
2
3
  module Toodledo
3
4
 
4
5
  module CommandLine
5
6
 
6
- #
7
+ #
7
8
  # Methods to parse a string and identify it as a Toodledo symbol.
8
- #
9
+ #
9
10
  module ParserHelper
10
-
11
+
11
12
  FOLDER_REGEXP = /\*((\w+)|\[(.*?)\])/
12
13
 
13
- GOAL_REGEXP = /\$((\w+)|\[(.*?)\])/
14
+ GOAL_REGEXP = /\^((\w+)|\[(.*?)\])/
14
15
 
15
16
  CONTEXT_REGEXP = /\@((\w+)|\[(.*?)\])/
17
+
18
+ PRIORITY_REGEXP = /!(top|high|medium|low|negative)/
19
+
20
+ # Note that level must exist at the beginning of the line
21
+ LEVEL_REGEXP = /^(life|medium|short)/
22
+
23
+ # Don't include level regexp
24
+ REGEXP_LIST = [
25
+ FOLDER_REGEXP,
26
+ GOAL_REGEXP,
27
+ CONTEXT_REGEXP,
28
+ PRIORITY_REGEXP
29
+ ]
16
30
 
17
31
  # Parses a context in the format @Context or @[Spaced Context]
18
32
  def parse_context(input)
@@ -28,20 +42,63 @@ module Toodledo
28
42
  return strip_brackets(match_data[1])
29
43
  end
30
44
 
31
- # Parses a goal in the format $Goal or $[Spaced Goal]
45
+ # Parses a goal in the format ^Goal or ^[Spaced Goal]
32
46
  def parse_goal(input)
33
47
  match_data = GOAL_REGEXP.match(input)
34
48
  return match_data if (match_data == nil)
35
49
  return strip_brackets(match_data[1])
36
50
  end
37
51
 
38
- # Returns the bit after we've looked for *Folder, @Context & $Goal
39
- def parse_remainder(line)
52
+ # Parses priority in the format !priority (top, high, medium, low,
53
+ # negative)
54
+ def parse_priority(input)
55
+ match_data = PRIORITY_REGEXP.match(input)
56
+ if (match_data == nil)
57
+ return nil
58
+ end
40
59
 
60
+ p = match_data[1]
61
+ case p
62
+ when 'top'
63
+ return Toodledo::Priority::TOP
64
+ when 'high'
65
+ return Toodledo::Priority::HIGH
66
+ when 'medium'
67
+ return Toodledo::Priority::MEDIUM
68
+ when 'low'
69
+ return Toodledo::Priority::LOW
70
+ when 'negative'
71
+ return Toodledo::Priority::NEGATIVE
72
+ else
73
+ return nil
74
+ end
75
+ end
76
+
77
+ def parse_level(input)
78
+ match_data = LEVEL_REGEXP.match(input)
79
+ if (match_data == nil)
80
+ return nil
81
+ end
82
+
83
+ p = match_data[1]
84
+ case p
85
+ when 'life'
86
+ return Toodledo::Goal::LIFE_LEVEL
87
+ when 'medium'
88
+ return Toodledo::Goal::MEDIUM_LEVEL
89
+ when 'short'
90
+ return Toodledo::Goal::SHORT_LEVEL
91
+ else
92
+ return nil
93
+ end
94
+ end
95
+
96
+ # Returns the bit after we've looked for *Folder, @Context & ^Goal
97
+ def parse_remainder(line)
41
98
  input = line
42
99
 
43
100
  # Strip out anything that isn't folder, goal or context.
44
- for regexp in [ FOLDER_REGEXP, GOAL_REGEXP, CONTEXT_REGEXP]
101
+ for regexp in REGEXP_LIST
45
102
  input = input.sub(regexp, '')
46
103
  end
47
104
 
@@ -0,0 +1,31 @@
1
+ require 'toodledo/command_line/parser_helper'
2
+ require 'logger'
3
+
4
+ module Toodledo
5
+
6
+ module CommandLine
7
+ # Runs the stdin client.
8
+ class StdinCommand < BaseCommand
9
+
10
+ def initialize(client)
11
+ super(client, 'stdin', false)
12
+ self.short_desc = "Takes standard input"
13
+ self.description = "Useful for pipes and redirected files"
14
+ end
15
+
16
+ def execute(args)
17
+ Toodledo.begin(client.logger) do |session|
18
+ $stdin.each do |line|
19
+ line.strip!
20
+
21
+ if (line == nil || line.empty?)
22
+ return 0
23
+ end
24
+
25
+ client.execute_command(session, line)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,102 @@
1
+
2
+ module Toodledo
3
+ module CommandLine
4
+ class TaskFormatter
5
+
6
+ # Formats the task for a command line.
7
+ def format(task)
8
+ fancyp = '!' + readable_priority(task.priority)
9
+
10
+ msg = "<#{task.server_id}> -- #{fancyp}"
11
+
12
+ if (task.folder != Folder::NO_FOLDER)
13
+ msg += " *[#{task.folder.name}]"
14
+ end
15
+
16
+ if (task.context != Context::NO_CONTEXT)
17
+ msg += " @[#{task.context.name}]"
18
+ end
19
+
20
+ if (task.goal != Goal::NO_GOAL)
21
+ msg += " ^[#{task.goal.name}]"
22
+ end
23
+
24
+ if (task.repeat != Repeat::NONE)
25
+ msg += " repeat[#{readable_repeat(task.repeat)}]"
26
+ end
27
+
28
+ if (task.duedate != nil)
29
+ fmt = '%m/%d/%Y %I:%M %p'
30
+ msg += " \#[#{task.duedatemodifier}#{task.duedate.strftime(fmt)}]"
31
+ end
32
+
33
+ if (task.tag != nil)
34
+ msg += " tag[#{task.tag}]"
35
+ end
36
+
37
+ if (task.parent_id != nil)
38
+ msg += " parent[#{task.parent_id}]"
39
+ end
40
+
41
+ if (task.length != nil)
42
+ msg += " length[#{task.length}]"
43
+ end
44
+
45
+ if (task.timer != nil)
46
+ msg += " timer[#{task.timer}]"
47
+ end
48
+
49
+ # Use the highline color library
50
+ msg += " #{task.title}"
51
+
52
+ if (task.note != nil)
53
+ msg += "\n #{task.note}"
54
+ end
55
+
56
+ return msg
57
+ end
58
+
59
+ def readable_priority(priority)
60
+ case priority
61
+ when Priority::TOP
62
+ return 'top'
63
+ when Priority::HIGH
64
+ return 'high'
65
+ when Priority::MEDIUM
66
+ return 'medium'
67
+ when Priority::LOW
68
+ return 'low'
69
+ when Priority::NEGATIVE
70
+ return 'negative'
71
+ else
72
+ return ''
73
+ end
74
+ end
75
+
76
+ def readable_repeat(repeat)
77
+ case repeat
78
+ when Repeat::NONE
79
+ ''
80
+ when Repeat::WEEKLY
81
+ "weekly"
82
+ when Repeat::MONTHLY
83
+ "monthly"
84
+ when Repeat::YEARLY
85
+ "yearly"
86
+ when Repeat::DAILY
87
+ "daily"
88
+ when Repeat::BIWEEKLY
89
+ "biweekly"
90
+ when Repeat::BIMONTHLY
91
+ "bimonthly"
92
+ when Repeat::SEMIANNUALLY
93
+ "semiannually"
94
+ when Repeat::QUARTERLY
95
+ "quarterly"
96
+ else
97
+ ''
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end