toggl 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/toggl.rb +34 -26
- data/lib/toggl_cmd/runner.rb +16 -12
- data/lib/toggl_cmd/runner_options.rb +11 -7
- metadata +51 -18
data/lib/toggl.rb
CHANGED
@@ -6,55 +6,59 @@ class Toggl
|
|
6
6
|
include HTTParty
|
7
7
|
base_uri "https://toggl.com"
|
8
8
|
format :json
|
9
|
-
|
9
|
+
|
10
10
|
attr_reader :name, :api_token
|
11
|
-
|
11
|
+
|
12
12
|
def initialize(token, name="toggl-gem", debug=false)
|
13
13
|
self.class.default_params :output => 'json'
|
14
14
|
@api_token = token
|
15
15
|
@name = name
|
16
16
|
self.class.debug_output if debug
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
|
+
def delete_task(task_id)
|
20
|
+
delete 'tasks', task_id
|
21
|
+
end
|
22
|
+
|
19
23
|
def create_task(params={})
|
20
24
|
workspace = params[:workspace] || default_workspace_id
|
21
25
|
project_id = find_project_id(params[:project]) || create_project(params, workspace)
|
22
26
|
params[:billable] = true
|
23
|
-
|
24
|
-
params.merge!({ :created_with => name,
|
25
|
-
:workspace => {:id => workspace},
|
26
|
-
:project => {:id => project_id},
|
27
|
-
:tag_names => [name],
|
28
|
-
:start => start(params[:start]),
|
27
|
+
|
28
|
+
params.merge!({ :created_with => name,
|
29
|
+
:workspace => {:id => workspace},
|
30
|
+
:project => {:id => project_id},
|
31
|
+
:tag_names => [name],
|
32
|
+
:start => start(params[:start]),
|
29
33
|
:duration => duration(params[:duration])})
|
30
|
-
|
34
|
+
|
31
35
|
post 'tasks', {:task => params}
|
32
36
|
end
|
33
|
-
|
37
|
+
|
34
38
|
def create_project(params={}, workspace=nil)
|
35
39
|
workspace ||= default_workspace_id
|
36
|
-
if project = post("projects",
|
37
|
-
:project => {:name => params[:project],
|
38
|
-
:workspace => {:id => workspace},
|
40
|
+
if project = post("projects",
|
41
|
+
:project => {:name => params[:project],
|
42
|
+
:workspace => {:id => workspace},
|
39
43
|
:billable => (params[:billable] || true)})
|
40
44
|
project["id"]
|
41
45
|
end
|
42
46
|
end
|
43
|
-
|
47
|
+
|
44
48
|
def default_workspace_id
|
45
49
|
self.workspaces.first["id"]
|
46
50
|
end
|
47
|
-
|
51
|
+
|
48
52
|
def find_project_id(str)
|
49
53
|
if project = self.projects.find{|project| project["client_project_name"].downcase =~ /#{str}/}
|
50
54
|
project["id"]
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
def duration(str)
|
55
59
|
str ? ChronicDuration.parse(str) : 1800
|
56
60
|
end
|
57
|
-
|
61
|
+
|
58
62
|
def start(value)
|
59
63
|
if value
|
60
64
|
case value
|
@@ -68,31 +72,35 @@ class Toggl
|
|
68
72
|
DateTime.now
|
69
73
|
end
|
70
74
|
end
|
71
|
-
|
75
|
+
|
72
76
|
def workspaces
|
73
77
|
get 'workspaces'
|
74
78
|
end
|
75
|
-
|
79
|
+
|
76
80
|
def tasks(params={})
|
77
81
|
get 'tasks', params
|
78
82
|
end
|
79
|
-
|
83
|
+
|
80
84
|
def projects
|
81
85
|
get 'projects'
|
82
86
|
end
|
83
|
-
|
87
|
+
|
84
88
|
private
|
85
|
-
|
89
|
+
|
86
90
|
def get(resource_name, data={})
|
87
91
|
self.class.get("/api/v1/#{resource_name}.json", :basic_auth => basic_auth, :query => data)
|
88
92
|
end
|
89
|
-
|
93
|
+
|
90
94
|
def post(resource_name, data)
|
91
95
|
self.class.post("/api/v1/#{resource_name}.json", :body => data, :basic_auth => basic_auth)
|
92
96
|
end
|
93
|
-
|
97
|
+
|
98
|
+
def delete(resource_name, id)
|
99
|
+
self.class.delete("/api/v1/#{resource_name}/#{id}.json", :basic_auth => basic_auth)
|
100
|
+
end
|
101
|
+
|
94
102
|
def basic_auth
|
95
103
|
{:username => self.api_token, :password => "api_token"}
|
96
104
|
end
|
97
|
-
|
105
|
+
|
98
106
|
end
|
data/lib/toggl_cmd/runner.rb
CHANGED
@@ -2,36 +2,40 @@ require "optparse"
|
|
2
2
|
require "chronic_duration"
|
3
3
|
|
4
4
|
module TogglCmd
|
5
|
-
|
5
|
+
|
6
6
|
NAME = "toggl-gem"
|
7
7
|
PROJECT_FIELDS = %w(client name)
|
8
|
-
TASK_FIELDS = %w(project description start duration billable)
|
9
|
-
|
8
|
+
TASK_FIELDS = %w(id project description start duration billable)
|
9
|
+
|
10
10
|
class Runner
|
11
|
-
|
11
|
+
|
12
12
|
def self.toggl(args)
|
13
13
|
token = IO.readlines(File.expand_path("~/.toggl")).join.strip
|
14
14
|
options = RunnerOptions.new(args)
|
15
15
|
if options[:tasks]
|
16
16
|
prettify_tasks(Toggl.new(token, NAME).tasks)
|
17
|
-
elsif options[:projects]
|
17
|
+
elsif options[:projects]
|
18
18
|
prettify_projects(Toggl.new(token, NAME).projects)
|
19
|
-
elsif options
|
19
|
+
elsif options[:delete]
|
20
|
+
toggl = Toggl.new(token, NAME)
|
21
|
+
toggl.delete_task(options[:delete])
|
22
|
+
prettify_tasks(toggl.tasks)
|
23
|
+
elsif options.any?
|
20
24
|
prettify_tasks(Toggl.new(token, NAME, options.delete(:debug)).create_task(options))
|
21
25
|
else
|
22
26
|
puts options.opts
|
23
27
|
end
|
24
28
|
end
|
25
|
-
|
29
|
+
|
26
30
|
private
|
27
|
-
|
31
|
+
|
28
32
|
def self.prettify_tasks(values)
|
29
33
|
values = [values] unless values.is_a?(Array)
|
30
|
-
values.each do |value|
|
34
|
+
values.each do |value|
|
31
35
|
value["project"] = value["project"]["name"]
|
32
36
|
value["workspace"] = value["workspace"]["name"]
|
33
37
|
value["duration"] = ChronicDuration.output(value["duration"].to_i, :format => :short)
|
34
|
-
value["start"] =
|
38
|
+
value["start"] = value["start"].strftime("%d/%m/%Y")
|
35
39
|
end
|
36
40
|
values.view(:class => :table, :fields => TASK_FIELDS)
|
37
41
|
end
|
@@ -39,7 +43,7 @@ module TogglCmd
|
|
39
43
|
def self.prettify_projects(values)
|
40
44
|
values.view(:class => :table, :fields => PROJECT_FIELDS)
|
41
45
|
end
|
42
|
-
|
46
|
+
|
43
47
|
end
|
44
48
|
|
45
|
-
end
|
49
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module TogglCmd
|
2
|
-
|
2
|
+
|
3
3
|
class RunnerOptions < Hash
|
4
4
|
attr_reader :opts
|
5
5
|
|
@@ -24,7 +24,7 @@ module TogglCmd
|
|
24
24
|
o.on('-d', '--date DATE', 'When exactly did it happen?') do |date|
|
25
25
|
self[:start] = date
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
o.on('--tasks', 'Show tasks') do |tasks|
|
29
29
|
self[:tasks] = tasks
|
30
30
|
end
|
@@ -32,15 +32,19 @@ module TogglCmd
|
|
32
32
|
o.on('--projects', 'Show projects') do |projects|
|
33
33
|
self[:projects] = projects
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
o.on('--delete TASK_ID', 'Delete tasks with id') do |task_id|
|
37
|
+
self[:delete] = task_id
|
38
|
+
end
|
39
|
+
|
36
40
|
o.on('-v', '--verbose', 'What\'s happening?') do |debug|
|
37
41
|
self[:debug] = debug
|
38
42
|
end
|
39
|
-
|
43
|
+
|
40
44
|
o.on_tail('-h', '--help', 'Display this help and exit') do
|
41
45
|
puts @opts
|
42
46
|
exit
|
43
|
-
end
|
47
|
+
end
|
44
48
|
|
45
49
|
end
|
46
50
|
|
@@ -50,6 +54,6 @@ module TogglCmd
|
|
50
54
|
self[:invalid_argument] = e.message
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
end
|
55
|
-
end
|
59
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toggl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Koen Van der Auwera
|
@@ -9,39 +14,65 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-06-23 00:00:00 +02:00
|
13
18
|
default_executable: toggl
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
21
|
+
name: crack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 1
|
30
|
+
- 7
|
31
|
+
version: 0.1.7
|
17
32
|
type: :runtime
|
18
|
-
|
19
|
-
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: httparty
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
20
38
|
requirements:
|
21
39
|
- - ">="
|
22
40
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 6
|
44
|
+
- 0
|
45
|
+
version: 0.6.0
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
25
48
|
- !ruby/object:Gem::Dependency
|
26
49
|
name: chronic_duration
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
30
52
|
requirements:
|
31
53
|
- - ">="
|
32
54
|
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 9
|
58
|
+
- 0
|
33
59
|
version: 0.9.0
|
34
|
-
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
35
62
|
- !ruby/object:Gem::Dependency
|
36
63
|
name: hirb
|
37
|
-
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
40
66
|
requirements:
|
41
67
|
- - ">="
|
42
68
|
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
- 3
|
72
|
+
- 1
|
43
73
|
version: 0.3.1
|
44
|
-
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
45
76
|
description: Toggl provides a simple REST-style JSON API over standard HTTP - http://www.toggl.com
|
46
77
|
email: koen@atog.be
|
47
78
|
executables:
|
@@ -70,18 +101,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
101
|
requirements:
|
71
102
|
- - ">="
|
72
103
|
- !ruby/object:Gem::Version
|
104
|
+
segments:
|
105
|
+
- 0
|
73
106
|
version: "0"
|
74
|
-
version:
|
75
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
108
|
requirements:
|
77
109
|
- - ">="
|
78
110
|
- !ruby/object:Gem::Version
|
111
|
+
segments:
|
112
|
+
- 0
|
79
113
|
version: "0"
|
80
|
-
version:
|
81
114
|
requirements: []
|
82
115
|
|
83
116
|
rubyforge_project:
|
84
|
-
rubygems_version: 1.3.
|
117
|
+
rubygems_version: 1.3.6
|
85
118
|
signing_key:
|
86
119
|
specification_version: 3
|
87
120
|
summary: Toggl api ruby gem
|