Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

V6 #3

Merged
merged 3 commits into from Mar 27, 2012
Jump to file or symbol
Failed to load files and symbols.
+125 −41
Split
View
@@ -1,6 +1,6 @@
= toggl
-Toggl API wrapper in a Ruby gem
+Toggl API wrapper in a Ruby gem, this is compatible with v6 of the API
https://www.toggl.com
@@ -12,6 +12,27 @@ If you want to create new tasks from the command line, make sure you create ~/.t
run 'toggl' to see all options.
+NOTE: the command line tool is currently broken and needs to be updated for V6 of the API
+
+== examples
+
+ toggl_interface = Toggl.new(token, "blah")
+
+ toggl_interface.time_entries
+
+ toggl_interface.time_entries({"start_date" => Date.today-1, "end_date" => Date.today})
+
+ toggl_interface.get_time_entry(12345)
+
+ toggl_interface.delete_time_entry(12345)
+
+ entry = toggl_interface.create_time_entry({ "duration" => 900, :start => Time.now, :description => "blabla"})
+
+ toggl_interface.update_time_entry(entry)
+
+similar methods exist for clients, projects, and tasks, check the source while we work on better documentation
+
+
== Copyright
Copyright (c) 2010 Koen Van der Auwera. See LICENSE for details.
View
@@ -1,11 +1,13 @@
require "rubygems"
require "httparty"
require "chronic_duration"
+require "multi_json"
class Toggl
include HTTParty
- base_uri "https://toggl.com"
+ base_uri "https://www.toggl.com"
format :json
+ headers "Content-Type" => "application/json"
attr_reader :name, :api_token
@@ -14,35 +16,12 @@ def initialize(token, name="toggl-gem", debug=false)
@api_token = token
@name = name
self.class.debug_output if debug
+ auth
end
- def delete_task(task_id)
- delete 'tasks', task_id
- end
-
- def create_task(params={})
- workspace = params[:workspace] || default_workspace_id
- project_id = find_project_id(params[:project]) || create_project(params, workspace)
- params[:billable] = true
-
- params.merge!({ :created_with => name,
- :workspace => {:id => workspace},
- :project => {:id => project_id},
- :tag_names => [name],
- :start => start(params[:start]),
- :duration => duration(params[:duration])})
-
- post 'tasks', {:task => params}
- end
-
- def create_project(params={}, workspace=nil)
- workspace ||= default_workspace_id
- if project = post("projects",
- :project => {:name => params[:project],
- :workspace => {:id => workspace},
- :billable => (params[:billable] || true)})
- project["id"]
- end
+ def auth
+ session_response = get "sessions"
+ self.class.default_cookies.add_cookies(session_response.headers["set-cookie"][0])
end
def default_workspace_id
@@ -80,26 +59,109 @@ def workspaces
get 'workspaces'
end
- def tasks(params={})
- get 'tasks', params
+ def time_entries(params={})
+ get 'time_entries', params
+ end
+
+ def get_time_entry(id)
+ get "time_entries/#{id}"
+ end
+
+ def create_time_entry(params={})
+ workspace = params[:workspace] || default_workspace_id
+ project_id = find_project_id(params[:project]) || create_project(params, workspace)
+ params[:billable] = true
+ params[:start] = Time.now if params[:start].nil?
+ params[:start] = params[:start].iso8601
+ params.merge!({ :created_with => name,
+ :workspace => {:id => workspace},
+ :project => {:id => project_id},
+ :tag_names => [name]})
+
+ post 'time_entries', MultiJson.encode({:time_entry => params})
+ end
+
+ def update_time_entry(params={})
+ put "time_entries/#{params['id']}", MultiJson.encode({:time_entry => params})
+ end
+
+ def delete_time_entry(id)
+ self.class.delete("/api/v6/time_entries/#{id}.json", :basic_auth => basic_auth)
+ end
+
+ def clients
+ get 'clients'
+ end
+
+ def create_client(params={})
+ post "clients", MultiJson.encode({:client => params})
+ end
+
+ def update_client(params={})
+ put "clients/#{params['id']}", MultiJson.encode({:client => params})
+ end
+
+ def delete_client(id)
+ delete "clients/#{id}"
end
def projects
get 'projects'
end
+ def create_project(params={})
+ post "projects", MultiJson.encode({:project => params})
+ end
+
+ def update_project(params={})
+ put "projects/#{params['id']}", MultiJson.encode({:project => params})
+ end
+
+ def create_project_user(params={})
+ post "project_users", MultiJson.encode({:project_user => params})
+ end
+
+ def tasks
+ get 'tasks'
+ end
+
+ def create_task(params={})
+ post "tasks", MultiJson.encode({:task => params})
+ end
+
+ def update_task(params={})
+ put "tasks/#{params['id']}", MultiJson.encode({:task => params})
+ end
+
+ def delete_task(id)
+ delete "tasks/#{id}"
+ end
+
+ def tags
+ get 'tags'
+ end
+
private
def get(resource_name, data={})
- self.class.get("/api/v1/#{resource_name}.json", :basic_auth => basic_auth, :query => data)
+ response = self.class.get("/api/v6/#{resource_name}.json", :basic_auth => basic_auth, :query => data)
+ response['data'].nil? ? response : response['data']
end
def post(resource_name, data)
- self.class.post("/api/v1/#{resource_name}.json", :body => data, :basic_auth => basic_auth)
+ response = self.class.post("/api/v6/#{resource_name}.json", :body => data, :basic_auth => basic_auth,
+ :options => { :headers => {"Content-type" => "application/json"}})
+ response['data'].nil? ? response : response['data']
+ end
+
+ def put(resource_name, data)
+ response = self.class.put("/api/v6/#{resource_name}.json", :body => data, :basic_auth => basic_auth,
+ :options => { :headers => {"Content-type" => "application/json"}})
+ response['data'].nil? ? response : response['data']
end
def delete(resource_name, id)
- self.class.delete("/api/v1/#{resource_name}/#{id}.json", :basic_auth => basic_auth)
+ self.class.delete("/api/v6/#{resource_name}/#{id}.json", :basic_auth => basic_auth)
end
def basic_auth
View
@@ -12,16 +12,16 @@ class Runner
def self.toggl(args)
token = IO.readlines(File.expand_path("~/.toggl")).join.strip
options = RunnerOptions.new(args)
- if options[:tasks]
- prettify_tasks(Toggl.new(token, NAME).tasks)
+ if options[:time_entries]
+ prettify_tasks(Toggl.new(token, NAME).time_entries)
elsif options[:projects]
prettify_projects(Toggl.new(token, NAME).projects)
elsif options[:delete]
toggl = Toggl.new(token, NAME)
- toggl.delete_task(options[:delete])
- prettify_tasks(toggl.tasks)
+ toggl.delete_time_entry(options[:delete])
+ prettify_tasks(toggl.time_entries)
elsif options.any?
- prettify_tasks(Toggl.new(token, NAME, options.delete(:debug)).create_task(options))
+ prettify_tasks(Toggl.new(token, NAME, options.delete(:debug)).create_time_entry(options))
else
puts options.opts
end
@@ -35,6 +35,7 @@ def self.prettify_tasks(values)
value["project"] = value["project"]["name"]
value["workspace"] = value["workspace"]["name"]
value["duration"] = ChronicDuration.output(value["duration"].to_i, :format => :short)
+ value["start"] = Time.parse(value["start"])
value["start"] = value["start"].strftime("%d/%m/%Y")
end
values.view(:class => :table, :fields => TASK_FIELDS)
@@ -25,8 +25,8 @@ def initialize(args)
self[:start] = date
end
- o.on('--tasks', 'Show tasks') do |tasks|
- self[:tasks] = tasks
+ o.on('--time_entries', 'Show time entries') do |time_entries|
+ self[:time_entries] = time_entries
end
o.on('--projects', 'Show projects') do |projects|