ruby_desk 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +4 -0
- data/VERSION +1 -1
- data/lib/ruby_desk/connector.rb +29 -9
- data/lib/ruby_desk/provider.rb +3 -5
- data/lib/ruby_desk/snapshot.rb +2 -6
- data/lib/ruby_desk/team_room.rb +4 -5
- data/lib/ruby_desk/time_report.rb +7 -4
- data/lib/ruby_desk.rb +10 -0
- data/test/test_ruby_desk.rb +27 -24
- data/test/timereport_error.json +2 -0
- metadata +3 -2
    
        data/README.rdoc
    CHANGED
    
    | @@ -2,6 +2,10 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            A gem built by BadrIT (www.badrit.com) that works as an interface for oDesk APIs. It can be used for both desktop and web applications
         | 
| 4 4 |  | 
| 5 | 
            +
            == Using RubyDesk with Rails
         | 
| 6 | 
            +
            If you want to use oDesk APIs with Rails applications you may better use ror_desk.
         | 
| 7 | 
            +
            ror_desk is a plugin built on Ruby Desk and makes it much easier to use with Rails.
         | 
| 8 | 
            +
             | 
| 5 9 | 
             
            == Example
         | 
| 6 10 | 
             
            Initialize with your api key
         | 
| 7 11 | 
             
              rd = RubyDesk::Connector.new(api_key, api_secret)
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.5.0
         | 
    
        data/lib/ruby_desk/connector.rb
    CHANGED
    
    | @@ -2,6 +2,8 @@ require 'digest/md5' | |
| 2 2 | 
             
            require 'uri'
         | 
| 3 3 | 
             
            require 'net/http'
         | 
| 4 4 | 
             
            require 'net/https'
         | 
| 5 | 
            +
            require 'rexml/document'
         | 
| 6 | 
            +
            require 'json'
         | 
| 5 7 |  | 
| 6 8 | 
             
            module RubyDesk
         | 
| 7 9 | 
             
              class Connector
         | 
| @@ -22,6 +24,7 @@ module RubyDesk | |
| 22 24 |  | 
| 23 25 | 
             
                # Sign the given parameters and returns the signature
         | 
| 24 26 | 
             
                def sign(params)
         | 
| 27 | 
            +
                  RubyDesk.logger.info "Params to sign: #{params.inspect}"
         | 
| 25 28 | 
             
                  # sort parameters by its names (keys)
         | 
| 26 29 | 
             
                  sorted_params = params.sort { |a, b| a.to_s <=> b.to_s}
         | 
| 27 30 |  | 
| @@ -65,6 +68,10 @@ module RubyDesk | |
| 65 68 | 
             
                    'Content-Type' => 'application/x-www-form-urlencoded'
         | 
| 66 69 | 
             
                  }
         | 
| 67 70 |  | 
| 71 | 
            +
                  RubyDesk.logger.info "URL: #{api_call[:url]}"
         | 
| 72 | 
            +
                  RubyDesk.logger.info "method: #{api_call[:method]}"
         | 
| 73 | 
            +
                  RubyDesk.logger.info "Params: #{data}"
         | 
| 74 | 
            +
             | 
| 68 75 | 
             
                  case api_call[:method]
         | 
| 69 76 | 
             
                    when :get, 'get' then
         | 
| 70 77 | 
             
                      resp, data = http.request(Net::HTTP::Get.new(url.path+"?"+data, headers))
         | 
| @@ -74,13 +81,29 @@ module RubyDesk | |
| 74 81 | 
             
                      resp, data = http.request(Net::HTTP::Delete.new(url.path, headers), data)
         | 
| 75 82 | 
             
                  end
         | 
| 76 83 |  | 
| 77 | 
            -
                   | 
| 84 | 
            +
                  RubyDesk.logger.info "Response code: #{resp.code}"
         | 
| 85 | 
            +
                  RubyDesk.logger.info "Returned data: #{data}"
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  case resp.code
         | 
| 88 | 
            +
                    when "200" then return data
         | 
| 89 | 
            +
                    when "401" then raise RubyDesk::UnauthorizedError, data
         | 
| 90 | 
            +
                    when "500" then raise RubyDesk::ServerError, data
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 78 93 | 
             
                end
         | 
| 79 94 |  | 
| 80 95 | 
             
                # Prepares an API call with the given arguments then invokes it and returns its body
         | 
| 81 96 | 
             
                def prepare_and_invoke_api_call(path, options = {})
         | 
| 82 97 | 
             
                  api_call = prepare_api_call(path, options)
         | 
| 83 | 
            -
                  invoke_api_call(api_call)
         | 
| 98 | 
            +
                  data = invoke_api_call(api_call)
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  parsed_data = case options[:format]
         | 
| 101 | 
            +
                    when 'json' then JSON.parse(data)
         | 
| 102 | 
            +
                    when 'xml' then REXML::Document.new(data)
         | 
| 103 | 
            +
                    else JSON.parse(data) rescue REXML::Document.new(data) rescue data
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
                  RubyDesk.logger.info "Parsed data: #{parsed_data.inspect}"
         | 
| 106 | 
            +
                  return parsed_data
         | 
| 84 107 | 
             
                end
         | 
| 85 108 |  | 
| 86 109 | 
             
                # Returns the URL that authenticates the application for the current user
         | 
| @@ -107,10 +130,9 @@ module RubyDesk | |
| 107 130 | 
             
                #  Return Data
         | 
| 108 131 | 
             
                #    * token
         | 
| 109 132 | 
             
                def get_token
         | 
| 110 | 
            -
                   | 
| 133 | 
            +
                  json = prepare_and_invoke_api_call 'auth/v1/keys/tokens',
         | 
| 111 134 | 
             
                      :params=>{:frob=>@frob, :api_key=>@api_key}, :method=>:post,
         | 
| 112 135 | 
             
                      :auth=>false
         | 
| 113 | 
            -
                  json = JSON.parse(response)
         | 
| 114 136 | 
             
                  @api_token = json['token']
         | 
| 115 137 | 
             
                end
         | 
| 116 138 |  | 
| @@ -123,9 +145,8 @@ module RubyDesk | |
| 123 145 | 
             
                #    * frob
         | 
| 124 146 |  | 
| 125 147 | 
             
                def get_frob
         | 
| 126 | 
            -
                   | 
| 148 | 
            +
                  json = prepare_and_invoke_api_call 'auth/v1/keys/frobs',
         | 
| 127 149 | 
             
                    :params=>{:api_key=>@api_key}, :method=>:post, :auth=>false
         | 
| 128 | 
            -
                  json = JSON.parse(response)
         | 
| 129 150 | 
             
                  @frob = json['frob']
         | 
| 130 151 | 
             
                end
         | 
| 131 152 |  | 
| @@ -140,9 +161,8 @@ module RubyDesk | |
| 140 161 | 
             
                #
         | 
| 141 162 | 
             
                #      * token
         | 
| 142 163 | 
             
                def check_token
         | 
| 143 | 
            -
                  prepare_and_invoke_api_call 'auth/v1/keys/token', :method=>:get
         | 
| 144 | 
            -
                   | 
| 145 | 
            -
                  # TODO what to make with results?
         | 
| 164 | 
            +
                  json = prepare_and_invoke_api_call 'auth/v1/keys/token', :method=>:get
         | 
| 165 | 
            +
                  # TODO what to do with results?
         | 
| 146 166 | 
             
                  return json
         | 
| 147 167 | 
             
                end
         | 
| 148 168 |  | 
    
        data/lib/ruby_desk/provider.rb
    CHANGED
    
    | @@ -116,11 +116,10 @@ class RubyDesk::Provider < RubyDesk::OdeskEntity | |
| 116 116 | 
             
                  if options.respond_to? :to_str
         | 
| 117 117 | 
             
                    return search(connector, :q=>options.to_str)
         | 
| 118 118 | 
             
                  end
         | 
| 119 | 
            -
                   | 
| 119 | 
            +
                  json = connector.prepare_and_invoke_api_call(
         | 
| 120 120 | 
             
                    'profiles/v1/search/providers', :method=>:get,
         | 
| 121 121 | 
             
                    :auth=>false, :sign=>false)
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                  json = JSON.parse(response)
         | 
| 122 | 
            +
             | 
| 124 123 | 
             
                  providers = []
         | 
| 125 124 | 
             
                  [json['providers']['provider']].flatten.each do |provider|
         | 
| 126 125 | 
             
                    providers << self.new(provider)
         | 
| @@ -130,9 +129,8 @@ class RubyDesk::Provider < RubyDesk::OdeskEntity | |
| 130 129 |  | 
| 131 130 | 
             
                def get_profile(connector, id, options={})
         | 
| 132 131 | 
             
                  brief = options.delete :brief || false
         | 
| 133 | 
            -
                   | 
| 132 | 
            +
                  json = connector.prepare_and_invoke_api_call(
         | 
| 134 133 | 
             
                    "profiles/v1/providers/#{id}" + (brief ? "/brief" : ""), :method=>:get)
         | 
| 135 | 
            -
                  json = JSON.parse(response)
         | 
| 136 134 | 
             
                  return self.new(json['profile'])
         | 
| 137 135 | 
             
                end
         | 
| 138 136 | 
             
              end
         | 
    
        data/lib/ruby_desk/snapshot.rb
    CHANGED
    
    | @@ -9,10 +9,9 @@ class RubyDesk::Snapshot < RubyDesk::OdeskEntity | |
| 9 9 | 
             
              attribute :user, :class=>RubyDesk::User
         | 
| 10 10 |  | 
| 11 11 | 
             
              def self.work_diary(connector, company_id, user_id, date = nil, timezone = "mine")
         | 
| 12 | 
            -
                 | 
| 12 | 
            +
                json = connector.prepare_and_invoke_api_call(
         | 
| 13 13 | 
             
                  "team/v1/workdiaries/#{company_id}/#{user_id}" + (date ? "/"+date : ""),
         | 
| 14 14 | 
             
                    :params=>{:timezone=>timezone}, :method=>:get)
         | 
| 15 | 
            -
                json = JSON.parse(response)
         | 
| 16 15 |  | 
| 17 16 | 
             
                return nil unless json['snapshots']['snapshot']
         | 
| 18 17 | 
             
                [json['snapshots']['snapshot']].flatten.map do |snapshot|
         | 
| @@ -28,13 +27,10 @@ class RubyDesk::Snapshot < RubyDesk::OdeskEntity | |
| 28 27 | 
             
                  when Array then timestamp.map{|t| t.strftime("%Y%m%d")}.join(";")
         | 
| 29 28 | 
             
                end
         | 
| 30 29 | 
             
                # Invoke API call
         | 
| 31 | 
            -
                 | 
| 30 | 
            +
                json = connector.prepare_and_invoke_api_call(
         | 
| 32 31 | 
             
                  "team/v1/workdiaries/#{company_id}/#{user_id}" +
         | 
| 33 32 | 
             
                  (timestamp_param ? "/#{timestamp_param}" : ""), :method=>:get)
         | 
| 34 33 |  | 
| 35 | 
            -
                # Parse result in json format
         | 
| 36 | 
            -
                json = JSON.parse(response)
         | 
| 37 | 
            -
             | 
| 38 34 | 
             
                # Generate ruby objects for each snapshot
         | 
| 39 35 | 
             
                [json['snapshot']].flatten.map do |snapshot|
         | 
| 40 36 | 
             
                  self.new(snapshot)
         | 
    
        data/lib/ruby_desk/team_room.rb
    CHANGED
    
    | @@ -4,10 +4,9 @@ class RubyDesk::TeamRoom | |
| 4 4 |  | 
| 5 5 | 
             
              class << self
         | 
| 6 6 | 
             
                def get_teamrooms(connector)
         | 
| 7 | 
            -
                   | 
| 7 | 
            +
                  json = connector.prepare_and_invoke_api_call 'team/v1/teamrooms',
         | 
| 8 8 | 
             
                      :method=>:get
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                  json = JSON.parse(response)
         | 
| 9 | 
            +
             | 
| 11 10 | 
             
                  team_rooms = []
         | 
| 12 11 | 
             
                  [json['teamrooms']['teamroom']].flatten.each do |teamroom|
         | 
| 13 12 | 
             
                    # Append this TeamRoom to array
         | 
| @@ -28,9 +27,9 @@ class RubyDesk::TeamRoom | |
| 28 27 | 
             
              end
         | 
| 29 28 |  | 
| 30 29 | 
             
              def snapshot(connector, online='now')
         | 
| 31 | 
            -
                 | 
| 30 | 
            +
                json = connector.prepare_and_invoke_api_call "team/v1/teamrooms/#{self.id}",
         | 
| 32 31 | 
             
                  :params=>{:online=>online}, :method=>:get
         | 
| 33 | 
            -
             | 
| 32 | 
            +
             | 
| 34 33 | 
             
                RubyDesk::Snapshot.new(json['teamroom']['snapshot'])
         | 
| 35 34 | 
             
              end
         | 
| 36 35 |  | 
| @@ -54,11 +54,12 @@ class RubyDesk::TimeReport | |
| 54 54 | 
             
                call_url << "/hours" if options[:hours]
         | 
| 55 55 |  | 
| 56 56 | 
             
                gds_query = build_query(options)
         | 
| 57 | 
            -
                 | 
| 57 | 
            +
                json = connector.prepare_and_invoke_api_call(call_url, :method=>:get,
         | 
| 58 58 | 
             
                  :base_url=>RubyDesk::Connector::ODESK_GDS_URL, :format=>nil,
         | 
| 59 59 | 
             
                  :params=>{:tq=>URI.escape(gds_query," ,%&=./"), :tqx=>"out:json"})
         | 
| 60 60 |  | 
| 61 | 
            -
                json  | 
| 61 | 
            +
                raise RubyDesk::Error, json['errors'].inspect if json['status'] == "error"
         | 
| 62 | 
            +
             | 
| 62 63 | 
             
                columns = [json['table']['cols']].flatten
         | 
| 63 64 | 
             
                rows = [json['table']['rows']].flatten.map do |row_data|
         | 
| 64 65 | 
             
                  row = {}
         | 
| @@ -73,7 +74,8 @@ class RubyDesk::TimeReport | |
| 73 74 |  | 
| 74 75 | 
             
              def self.build_query(options)
         | 
| 75 76 | 
             
                gds_query = ""
         | 
| 76 | 
            -
                gds_query << "SELECT " << options[:select]
         | 
| 77 | 
            +
                gds_query << "SELECT " << (options[:select].respond_to?(:join)?
         | 
| 78 | 
            +
                  options[:select].join(",") : options[:select])
         | 
| 77 79 | 
             
                if options[:conditions]
         | 
| 78 80 | 
             
                  gds_query << " WHERE "
         | 
| 79 81 | 
             
                  combined = options[:conditions].map do |field, condition|
         | 
| @@ -83,10 +85,11 @@ class RubyDesk::TimeReport | |
| 83 85 | 
             
                        "#{field}=#{value_to_str(condition)}"
         | 
| 84 86 | 
             
                      when Array then
         | 
| 85 87 | 
             
                        condition.map{|v| "#{field}=#{value_to_str(v)}"}.join(" OR ")
         | 
| 86 | 
            -
                      when Range
         | 
| 88 | 
            +
                      when Range then
         | 
| 87 89 | 
             
                        "#{field}>=#{value_to_str(condition.first)} AND #{field}" +
         | 
| 88 90 | 
             
                          (condition.exclude_end? ? "<" : "<=") +
         | 
| 89 91 | 
             
                          value_to_str(condition.last)
         | 
| 92 | 
            +
                      else raise "Invalid condition for field: #{field}"
         | 
| 90 93 | 
             
                    end +
         | 
| 91 94 | 
             
                    ")"
         | 
| 92 95 | 
             
                  end
         | 
    
        data/lib/ruby_desk.rb
    CHANGED
    
    | @@ -1,8 +1,18 @@ | |
| 1 1 | 
             
            require 'rubygems'
         | 
| 2 2 | 
             
            require 'json'
         | 
| 3 | 
            +
            require 'logger'
         | 
| 3 4 |  | 
| 4 5 | 
             
            module RubyDesk
         | 
| 5 6 | 
             
              class Error < RuntimeError; end;
         | 
| 7 | 
            +
              class UnauthorizedError < Error; end;
         | 
| 8 | 
            +
              class ServerError < Error; end;
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              class << self
         | 
| 11 | 
            +
                attr_accessor :logger
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              self.logger = Logger.new(STDERR)
         | 
| 15 | 
            +
              self.logger.sev_threshold = Logger::FATAL
         | 
| 6 16 | 
             
            end
         | 
| 7 17 |  | 
| 8 18 | 
             
            # This first file is required by other files
         | 
    
        data/test/test_ruby_desk.rb
    CHANGED
    
    | @@ -2,6 +2,17 @@ require 'helper' | |
| 2 2 | 
             
            require 'date'
         | 
| 3 3 |  | 
| 4 4 | 
             
            class TestRubyDesk < Test::Unit::TestCase
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def dummy_connector(result_filename)
         | 
| 7 | 
            +
                connector = RubyDesk::Connector.new('824d225a889aca186c55ac49a6b23957',
         | 
| 8 | 
            +
                  '984aa36db13fff5c')
         | 
| 9 | 
            +
                connector.instance_variable_set '@result_filename', result_filename
         | 
| 10 | 
            +
                def connector.invoke_api_call(*args)
         | 
| 11 | 
            +
                  File.read(File.join(File.dirname(__FILE__), @result_filename))
         | 
| 12 | 
            +
                end if result_filename
         | 
| 13 | 
            +
                return connector
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 5 16 | 
             
              def test_sign
         | 
| 6 17 | 
             
                connector  = RubyDesk::Connector.new('824d225a889aca186c55ac49a6b23957',
         | 
| 7 18 | 
             
                  '984aa36db13fff5c')
         | 
| @@ -32,10 +43,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 32 43 | 
             
              end
         | 
| 33 44 |  | 
| 34 45 | 
             
              def test_provider_search
         | 
| 35 | 
            -
                connector =  | 
| 36 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 37 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'providers.json'))
         | 
| 38 | 
            -
                end
         | 
| 46 | 
            +
                connector = dummy_connector('providers.json')
         | 
| 39 47 |  | 
| 40 48 | 
             
                providers = RubyDesk::Provider.search(connector, 'rails')
         | 
| 41 49 |  | 
| @@ -46,10 +54,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 46 54 | 
             
              end
         | 
| 47 55 |  | 
| 48 56 | 
             
              def test_get_profile
         | 
| 49 | 
            -
                connector =  | 
| 50 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 51 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'profile.json'))
         | 
| 52 | 
            -
                end
         | 
| 57 | 
            +
                connector = dummy_connector('profile.json')
         | 
| 53 58 |  | 
| 54 59 | 
             
                profile = RubyDesk::Provider.get_profile(connector, 'aseldawy')
         | 
| 55 60 |  | 
| @@ -59,10 +64,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 59 64 | 
             
              end
         | 
| 60 65 |  | 
| 61 66 | 
             
              def test_team_rooms
         | 
| 62 | 
            -
                connector =  | 
| 63 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 64 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'teamrooms.json'))
         | 
| 65 | 
            -
                end
         | 
| 67 | 
            +
                connector = dummy_connector('teamrooms.json')
         | 
| 66 68 |  | 
| 67 69 | 
             
                teamrooms = RubyDesk::TeamRoom.get_teamrooms(connector)
         | 
| 68 70 |  | 
| @@ -71,10 +73,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 71 73 | 
             
              end
         | 
| 72 74 |  | 
| 73 75 | 
             
              def test_workdiary
         | 
| 74 | 
            -
                connector =  | 
| 75 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 76 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'workdiary.json'))
         | 
| 77 | 
            -
                end
         | 
| 76 | 
            +
                connector = dummy_connector('workdiary.json')
         | 
| 78 77 |  | 
| 79 78 | 
             
                snapshots = RubyDesk::Snapshot.work_diary(connector, 'techunlimited',
         | 
| 80 79 | 
             
                  'aseldawy')
         | 
| @@ -83,10 +82,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 83 82 | 
             
              end
         | 
| 84 83 |  | 
| 85 84 | 
             
              def test_snapshot
         | 
| 86 | 
            -
                connector =  | 
| 87 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 88 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'snapshot.json'))
         | 
| 89 | 
            -
                end
         | 
| 85 | 
            +
                connector = dummy_connector('snapshot.json')
         | 
| 90 86 |  | 
| 91 87 | 
             
                snapshots = RubyDesk::Snapshot.snapshot_details(connector, 'techunlimited',
         | 
| 92 88 | 
             
                  'aseldawy', Time.now)
         | 
| @@ -107,6 +103,8 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 107 103 | 
             
                    "SELECT worked_on WHERE (provider_id>=1 AND provider_id<=3)"],
         | 
| 108 104 | 
             
                  [{:select=>"worked_on", :conditions=>{:provider_id=>1...3}},
         | 
| 109 105 | 
             
                    "SELECT worked_on WHERE (provider_id>=1 AND provider_id<3)"],
         | 
| 106 | 
            +
                  [{:select=>["worked_on", "hours"]},
         | 
| 107 | 
            +
                    "SELECT worked_on,hours"],
         | 
| 110 108 | 
             
                ]
         | 
| 111 109 | 
             
                test_data.each do |options, query|
         | 
| 112 110 | 
             
                  assert query.include?(RubyDesk::TimeReport.build_query(options))
         | 
| @@ -114,10 +112,7 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 114 112 | 
             
              end
         | 
| 115 113 |  | 
| 116 114 | 
             
              def test_timreport
         | 
| 117 | 
            -
                connector =  | 
| 118 | 
            -
                def connector.prepare_and_invoke_api_call(*args)
         | 
| 119 | 
            -
                  File.read(File.join(File.dirname(__FILE__), 'timereport.json'))
         | 
| 120 | 
            -
                end
         | 
| 115 | 
            +
                connector = dummy_connector('timereport.json')
         | 
| 121 116 |  | 
| 122 117 | 
             
                timereport = RubyDesk::TimeReport.find(connector,
         | 
| 123 118 | 
             
                  :select=>"worked_on, sum(hours), provider_id")
         | 
| @@ -127,5 +122,13 @@ class TestRubyDesk < Test::Unit::TestCase | |
| 127 122 | 
             
                assert timereport.first['hours'].is_a?(Numeric)
         | 
| 128 123 | 
             
              end
         | 
| 129 124 |  | 
| 125 | 
            +
              def test_timreport_error
         | 
| 126 | 
            +
                assert_raises RubyDesk::Error do
         | 
| 127 | 
            +
                  connector = dummy_connector('timereport_error.json')
         | 
| 128 | 
            +
                  timereport = RubyDesk::TimeReport.find(connector,
         | 
| 129 | 
            +
                    :select=>"worked_on, sum(hours), provider_id")
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
             | 
| 130 133 | 
             
            end
         | 
| 131 134 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: ruby_desk
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Ahmed ElDawy
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2010-01- | 
| 12 | 
            +
            date: 2010-01-21 00:00:00 +02:00
         | 
| 13 13 | 
             
            default_executable: 
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -51,6 +51,7 @@ files: | |
| 51 51 | 
             
            - test/teamrooms.json
         | 
| 52 52 | 
             
            - test/test_ruby_desk.rb
         | 
| 53 53 | 
             
            - test/timereport.json
         | 
| 54 | 
            +
            - test/timereport_error.json
         | 
| 54 55 | 
             
            - test/workdiary.json
         | 
| 55 56 | 
             
            has_rdoc: true
         | 
| 56 57 | 
             
            homepage: http://github.com/aseldawy/ruby_desk
         |