diff options
| -rw-r--r-- | lib/hcl.rb | 21 | ||||
| -rw-r--r-- | lib/hcl/day_entry.rb | 92 | 
2 files changed, 98 insertions, 15 deletions
@@ -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  | 
