toggl 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +22 -1
- data/lib/toggl.rb +95 -33
- data/lib/toggl_cmd/runner.rb +6 -5
- data/lib/toggl_cmd/runner_options.rb +2 -2
- metadata +8 -8
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= toggl
|
2
2
|
|
3
|
-
Toggl API wrapper in a Ruby gem
|
3
|
+
Toggl API wrapper in a Ruby gem, this is compatible with v6 of the API
|
4
4
|
|
5
5
|
https://www.toggl.com
|
6
6
|
|
@@ -12,6 +12,27 @@ If you want to create new tasks from the command line, make sure you create ~/.t
|
|
12
12
|
|
13
13
|
run 'toggl' to see all options.
|
14
14
|
|
15
|
+
NOTE: the command line tool is currently broken and needs to be updated for V6 of the API
|
16
|
+
|
17
|
+
== examples
|
18
|
+
|
19
|
+
toggl_interface = Toggl.new(token, "blah")
|
20
|
+
|
21
|
+
toggl_interface.time_entries
|
22
|
+
|
23
|
+
toggl_interface.time_entries({"start_date" => Date.today-1, "end_date" => Date.today})
|
24
|
+
|
25
|
+
toggl_interface.get_time_entry(12345)
|
26
|
+
|
27
|
+
toggl_interface.delete_time_entry(12345)
|
28
|
+
|
29
|
+
entry = toggl_interface.create_time_entry({ "duration" => 900, :start => Time.now, :description => "blabla"})
|
30
|
+
|
31
|
+
toggl_interface.update_time_entry(entry)
|
32
|
+
|
33
|
+
similar methods exist for clients, projects, and tasks, check the source while we work on better documentation
|
34
|
+
|
35
|
+
|
15
36
|
== Copyright
|
16
37
|
|
17
38
|
Copyright (c) 2010 Koen Van der Auwera. See LICENSE for details.
|
data/lib/toggl.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "httparty"
|
3
3
|
require "chronic_duration"
|
4
|
+
require "multi_json"
|
4
5
|
|
5
6
|
class Toggl
|
6
7
|
include HTTParty
|
7
|
-
base_uri "https://toggl.com"
|
8
|
+
base_uri "https://www.toggl.com"
|
8
9
|
format :json
|
10
|
+
headers "Content-Type" => "application/json"
|
9
11
|
|
10
12
|
attr_reader :name, :api_token
|
11
13
|
|
@@ -14,35 +16,12 @@ class Toggl
|
|
14
16
|
@api_token = token
|
15
17
|
@name = name
|
16
18
|
self.class.debug_output if debug
|
19
|
+
auth
|
17
20
|
end
|
18
21
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def create_task(params={})
|
24
|
-
workspace = params[:workspace] || default_workspace_id
|
25
|
-
project_id = find_project_id(params[:project]) || create_project(params, workspace)
|
26
|
-
params[:billable] = true
|
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]),
|
33
|
-
:duration => duration(params[:duration])})
|
34
|
-
|
35
|
-
post 'tasks', {:task => params}
|
36
|
-
end
|
37
|
-
|
38
|
-
def create_project(params={}, workspace=nil)
|
39
|
-
workspace ||= default_workspace_id
|
40
|
-
if project = post("projects",
|
41
|
-
:project => {:name => params[:project],
|
42
|
-
:workspace => {:id => workspace},
|
43
|
-
:billable => (params[:billable] || true)})
|
44
|
-
project["id"]
|
45
|
-
end
|
22
|
+
def auth
|
23
|
+
session_response = get "sessions"
|
24
|
+
self.class.default_cookies.add_cookies(session_response.headers["set-cookie"][0])
|
46
25
|
end
|
47
26
|
|
48
27
|
def default_workspace_id
|
@@ -80,26 +59,109 @@ class Toggl
|
|
80
59
|
get 'workspaces'
|
81
60
|
end
|
82
61
|
|
83
|
-
def
|
84
|
-
get '
|
62
|
+
def time_entries(params={})
|
63
|
+
get 'time_entries', params
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_time_entry(id)
|
67
|
+
get "time_entries/#{id}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_time_entry(params={})
|
71
|
+
workspace = params[:workspace] || default_workspace_id
|
72
|
+
project_id = find_project_id(params[:project]) || create_project(params, workspace)
|
73
|
+
params[:billable] = true
|
74
|
+
params[:start] = Time.now if params[:start].nil?
|
75
|
+
params[:start] = params[:start].iso8601
|
76
|
+
params.merge!({ :created_with => name,
|
77
|
+
:workspace => {:id => workspace},
|
78
|
+
:project => {:id => project_id},
|
79
|
+
:tag_names => [name]})
|
80
|
+
|
81
|
+
post 'time_entries', MultiJson.encode({:time_entry => params})
|
82
|
+
end
|
83
|
+
|
84
|
+
def update_time_entry(params={})
|
85
|
+
put "time_entries/#{params['id']}", MultiJson.encode({:time_entry => params})
|
86
|
+
end
|
87
|
+
|
88
|
+
def delete_time_entry(id)
|
89
|
+
self.class.delete("/api/v6/time_entries/#{id}.json", :basic_auth => basic_auth)
|
90
|
+
end
|
91
|
+
|
92
|
+
def clients
|
93
|
+
get 'clients'
|
94
|
+
end
|
95
|
+
|
96
|
+
def create_client(params={})
|
97
|
+
post "clients", MultiJson.encode({:client => params})
|
98
|
+
end
|
99
|
+
|
100
|
+
def update_client(params={})
|
101
|
+
put "clients/#{params['id']}", MultiJson.encode({:client => params})
|
102
|
+
end
|
103
|
+
|
104
|
+
def delete_client(id)
|
105
|
+
delete "clients/#{id}"
|
85
106
|
end
|
86
107
|
|
87
108
|
def projects
|
88
109
|
get 'projects'
|
89
110
|
end
|
90
111
|
|
112
|
+
def create_project(params={})
|
113
|
+
post "projects", MultiJson.encode({:project => params})
|
114
|
+
end
|
115
|
+
|
116
|
+
def update_project(params={})
|
117
|
+
put "projects/#{params['id']}", MultiJson.encode({:project => params})
|
118
|
+
end
|
119
|
+
|
120
|
+
def create_project_user(params={})
|
121
|
+
post "project_users", MultiJson.encode({:project_user => params})
|
122
|
+
end
|
123
|
+
|
124
|
+
def tasks
|
125
|
+
get 'tasks'
|
126
|
+
end
|
127
|
+
|
128
|
+
def create_task(params={})
|
129
|
+
post "tasks", MultiJson.encode({:task => params})
|
130
|
+
end
|
131
|
+
|
132
|
+
def update_task(params={})
|
133
|
+
put "tasks/#{params['id']}", MultiJson.encode({:task => params})
|
134
|
+
end
|
135
|
+
|
136
|
+
def delete_task(id)
|
137
|
+
delete "tasks/#{id}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def tags
|
141
|
+
get 'tags'
|
142
|
+
end
|
143
|
+
|
91
144
|
private
|
92
145
|
|
93
146
|
def get(resource_name, data={})
|
94
|
-
self.class.get("/api/
|
147
|
+
response = self.class.get("/api/v6/#{resource_name}.json", :basic_auth => basic_auth, :query => data)
|
148
|
+
response['data'].nil? ? response : response['data']
|
95
149
|
end
|
96
150
|
|
97
151
|
def post(resource_name, data)
|
98
|
-
self.class.post("/api/
|
152
|
+
response = self.class.post("/api/v6/#{resource_name}.json", :body => data, :basic_auth => basic_auth,
|
153
|
+
:options => { :headers => {"Content-type" => "application/json"}})
|
154
|
+
response['data'].nil? ? response : response['data']
|
155
|
+
end
|
156
|
+
|
157
|
+
def put(resource_name, data)
|
158
|
+
response = self.class.put("/api/v6/#{resource_name}.json", :body => data, :basic_auth => basic_auth,
|
159
|
+
:options => { :headers => {"Content-type" => "application/json"}})
|
160
|
+
response['data'].nil? ? response : response['data']
|
99
161
|
end
|
100
162
|
|
101
163
|
def delete(resource_name, id)
|
102
|
-
self.class.delete("/api/
|
164
|
+
self.class.delete("/api/v6/#{resource_name}/#{id}.json", :basic_auth => basic_auth)
|
103
165
|
end
|
104
166
|
|
105
167
|
def basic_auth
|
data/lib/toggl_cmd/runner.rb
CHANGED
@@ -12,16 +12,16 @@ module TogglCmd
|
|
12
12
|
def self.toggl(args)
|
13
13
|
token = IO.readlines(File.expand_path("~/.toggl")).join.strip
|
14
14
|
options = RunnerOptions.new(args)
|
15
|
-
if options[:
|
16
|
-
prettify_tasks(Toggl.new(token, NAME).
|
15
|
+
if options[:time_entries]
|
16
|
+
prettify_tasks(Toggl.new(token, NAME).time_entries)
|
17
17
|
elsif options[:projects]
|
18
18
|
prettify_projects(Toggl.new(token, NAME).projects)
|
19
19
|
elsif options[:delete]
|
20
20
|
toggl = Toggl.new(token, NAME)
|
21
|
-
toggl.
|
22
|
-
prettify_tasks(toggl.
|
21
|
+
toggl.delete_time_entry(options[:delete])
|
22
|
+
prettify_tasks(toggl.time_entries)
|
23
23
|
elsif options.any?
|
24
|
-
prettify_tasks(Toggl.new(token, NAME, options.delete(:debug)).
|
24
|
+
prettify_tasks(Toggl.new(token, NAME, options.delete(:debug)).create_time_entry(options))
|
25
25
|
else
|
26
26
|
puts options.opts
|
27
27
|
end
|
@@ -35,6 +35,7 @@ module TogglCmd
|
|
35
35
|
value["project"] = value["project"]["name"]
|
36
36
|
value["workspace"] = value["workspace"]["name"]
|
37
37
|
value["duration"] = ChronicDuration.output(value["duration"].to_i, :format => :short)
|
38
|
+
value["start"] = Time.parse(value["start"])
|
38
39
|
value["start"] = value["start"].strftime("%d/%m/%Y")
|
39
40
|
end
|
40
41
|
values.view(:class => :table, :fields => TASK_FIELDS)
|
@@ -25,8 +25,8 @@ module TogglCmd
|
|
25
25
|
self[:start] = date
|
26
26
|
end
|
27
27
|
|
28
|
-
o.on('--
|
29
|
-
self[:
|
28
|
+
o.on('--time_entries', 'Show time entries') do |time_entries|
|
29
|
+
self[:time_entries] = time_entries
|
30
30
|
end
|
31
31
|
|
32
32
|
o.on('--projects', 'Show projects') do |projects|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toggl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Koen Van der Auwera
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-03-27 00:00:00 +02:00
|
19
19
|
default_executable: toggl
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -103,8 +103,8 @@ homepage: http://github.com/atog/toggl
|
|
103
103
|
licenses: []
|
104
104
|
|
105
105
|
post_install_message:
|
106
|
-
rdoc_options:
|
107
|
-
|
106
|
+
rdoc_options: []
|
107
|
+
|
108
108
|
require_paths:
|
109
109
|
- lib
|
110
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements: []
|
129
129
|
|
130
130
|
rubyforge_project:
|
131
|
-
rubygems_version: 1.
|
131
|
+
rubygems_version: 1.6.2
|
132
132
|
signing_key:
|
133
133
|
specification_version: 3
|
134
134
|
summary: Toggl api ruby gem
|