summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorZack Hobson2009-07-19 13:20:37 -0700
committerZack Hobson2009-07-19 13:20:37 -0700
commit7867896534da18b77f7304232f8db06ed11d583d (patch)
treefe52ab6a404b426889ed581bf63e4f2aabf10194 /lib
parent36510ce224ac6f1594d6fa21977a2f62f5f41e4e (diff)
downloadhcl-7867896534da18b77f7304232f8db06ed11d583d.tar.bz2
use chronic for date parsing, started timer implementation
Diffstat (limited to 'lib')
-rw-r--r--lib/hcl.rb21
-rw-r--r--lib/hcl/day_entry.rb92
2 files changed, 98 insertions, 15 deletions
diff --git a/lib/hcl.rb b/lib/hcl.rb
index 950af8b..fe86443 100644
--- a/lib/hcl.rb
+++ b/lib/hcl.rb
@@ -38,9 +38,10 @@ class HCl
Usage:
hcl show [date]
- hcl add <project> <task> <duration> [msg]
+ hcl tasks
+ hcl add <task> <duration> [msg]
hcl rm [entry_id]
- hcl start <project> <task> [msg]
+ hcl start <task> [msg]
hcl stop [msg]
Examples:
@@ -57,6 +58,19 @@ class HCl
self
end
+ def tasks
+ Task.all.each do |task|
+ # TODO more information and formatting options
+ puts "#{task.id}\t#{task}"
+ end
+ end
+
+ def start *args
+ task = Task.find args.shift
+ puts "Starting timer for #{task}"
+ puts task.start(*args)
+ end
+
def show *args
date = args.empty? ? nil : Chronic.parse(args.join(' '))
total_hours = 0.0
@@ -69,12 +83,11 @@ class HCl
puts "\t#{total_hours}\ttotal"
end
- def not_implemented
+ def not_implemented *args
puts "not yet implemented"
end
# TODO implement the following commands
- alias start not_implemented
alias stop not_implemented
alias add not_implemented
alias rm not_implemented
diff --git a/lib/hcl/day_entry.rb b/lib/hcl/day_entry.rb
index 42afc04..d0f1a13 100644
--- a/lib/hcl/day_entry.rb
+++ b/lib/hcl/day_entry.rb
@@ -29,18 +29,43 @@ class HCl
end
def self.perform action
- client = Curl::Easy.new("https://#{subdomain}.harvestapp.com/#{action}")
- client.headers['Accept'] = 'application/xml'
- client.headers['Content-Type'] = 'application/xml'
- client.http_auth_types = Curl::CURLAUTH_BASIC
- client.userpwd = "#{login}:#{password}"
+ client = session action
if client.http_get
client.body_str
else
raise "failed"
end
end
+
+ def self.send_data action, data
+ client = session action
+ client.multipart_form_post = true
+ data_field = Curl::PostField.file('data','data') { data }
+ if client.http_post data_field
+ client.body_str
+ else
+ raise "failed"
+ end
+ end
+
+ def self.session action
+ client = Curl::Easy.new("https://#{subdomain}.harvestapp.com/#{action}")
+ client.headers['Accept'] = 'application/xml'
+ client.headers['Content-Type'] = 'application/xml'
+ client.http_auth_types = Curl::CURLAUTH_BASIC
+ client.userpwd = "#{login}:#{password}"
+ client
+ #client = Patron::Session.new
+ #client.timeout = 10
+ #client.username = login
+ #client.password = password
+ #if client.get "https://#{subdomain}.harvestapp.com/#{action}"
+ end
+ def id
+ @data[:id]
+ end
+
def method_missing method, *args
if @data.key? method.to_sym
@data[method]
@@ -48,21 +73,66 @@ class HCl
super
end
end
+
+ def self.xml_to_hash elem
+ elem.elements.map { |e| e.name }.inject({}) do |a, f|
+ a[f.to_sym] = elem.elements[f].text if elem.elements[f]
+ a
+ end
+ end
end
+ class Project < TimesheetResource;end
+
+ class Task < TimesheetResource
+ def self.cache_tasks doc
+ tasks = []
+ doc.root.elements.collect('projects/project') do |project_elem|
+ project = Project.new xml_to_hash(project_elem)
+ tasks.concat(project_elem.elements.collect('tasks/task') do |task|
+ new xml_to_hash(task).merge(:project => project)
+ end)
+ end
+ File.open(File.join(ENV['HOME'],'.hcl_tasks'), 'w') do |f|
+ f.write tasks.uniq.to_yaml
+ end
+ end
+
+ def self.all
+ YAML.load File.read(File.join(ENV['HOME'],'.hcl_tasks'))
+ end
+
+ def self.find id
+ all.detect {|t| t.id == id }
+ end
+
+ def to_s
+ "#{project.name} #{name}"
+ end
+
+ def start *args
+ notes = args.join ' '
+ Task.send_data "/daily/add", <<-EOT
+ <request>
+ <notes>#{notes}</notes>
+ <hours></hours>
+ <project_id type="integer">#{project.id}</project_id>
+ <task_id type="integer">#{id}</task_id>
+ <spent_at type="date">#{Date.today}</spent_at>
+ </request>
+ EOT
+ end
+ end
+
class DayEntry < TimesheetResource
# Get the time sheet entries for a given day. If no date is provided
# defaults to today.
def self.all date = nil
url = date.nil? ? 'daily' : "daily/#{date.strftime '%j/%Y'}"
doc = REXML::Document.new perform url
+ Task.cache_tasks doc
doc.root.elements.collect('day_entries/day_entry') do |day|
- new(
- day.elements.map { |e| e.name }.inject({}) do |a, f|
- a[f.to_sym] = day.elements[f].text if day.elements[f]
- a
- end
- )
+ new xml_to_hash(day)
end
end