ruby_desk 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -6,6 +6,8 @@ A gem built by BadrIT (www.badrit.com) that works as an interface for oDesk APIs
6
6
  If you want to use oDesk APIs with Rails applications you may better use ror_desk.
7
7
  ror_desk is a plugin built on Ruby Desk and makes it much easier to use with Rails.
8
8
 
9
+ For more information read the documentation at http://aseldawy.github.com/ruby_desk/
10
+
9
11
  == Example
10
12
  Initialize with your api key
11
13
  rd = RubyDesk::Connector.new(api_key, api_secret)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.8.0
@@ -6,6 +6,8 @@ require 'rexml/document'
6
6
  require 'json'
7
7
 
8
8
  module RubyDesk
9
+ # Basic methods used for connecting with oDesk like signing request parameters and parsing response.
10
+ # This class is also responsible for authorizing user
9
11
  class Connector
10
12
  ODESK_URL = "www.odesk.com/"
11
13
  ODESK_API_URL = "#{ODESK_URL}api/"
@@ -15,6 +17,7 @@ module RubyDesk
15
17
  :base_url=>ODESK_API_URL, :auth=>true}
16
18
 
17
19
  attr_writer :frob
20
+ attr_accessor :auth_user
18
21
 
19
22
  def initialize(api_key=nil, api_secret=nil, api_token=nil)
20
23
  @api_key = api_key
@@ -76,7 +79,8 @@ module RubyDesk
76
79
  http = Net::HTTP.new(url.host, url.port)
77
80
  http.use_ssl = true
78
81
 
79
- data = api_call[:params].to_a.map{|pair| pair.join '='}.join('&')
82
+ # Concatenate parameters to form data
83
+ data = api_call[:params].to_a.map{|pair| pair.map{|x| URI.escape(x.to_s)}.join '='}.join('&')
80
84
  headers = {
81
85
  'Content-Type' => 'application/x-www-form-urlencoded'
82
86
  }
@@ -99,9 +103,11 @@ module RubyDesk
99
103
 
100
104
  case resp.code
101
105
  when "200" then return data
102
- when "401" then raise RubyDesk::UnauthorizedError, data
106
+ when "400" then raise RubyDesk::BadRequest, data
107
+ when "401", "403" then raise RubyDesk::UnauthorizedError, data
103
108
  when "404" then raise RubyDesk::PageNotFound, data
104
109
  when "500" then raise RubyDesk::ServerError, data
110
+ else raise RubyDesk::Error, data
105
111
  end
106
112
 
107
113
  end
@@ -131,7 +137,7 @@ module RubyDesk
131
137
  # return the URL that logs user out of odesk applications
132
138
  def logout_url
133
139
  logout_call = prepare_api_call("", :base_url=>ODESK_AUTH_URL,
134
- :secure=>false, :auth=>false)
140
+ :secure=>false, :auth=>false, :format=>nil)
135
141
  return logout_call[:url]
136
142
  end
137
143
 
@@ -147,6 +153,7 @@ module RubyDesk
147
153
  json = prepare_and_invoke_api_call 'auth/v1/keys/tokens',
148
154
  :params=>{:frob=>@frob, :api_key=>@api_key}, :method=>:post,
149
155
  :auth=>false
156
+ @auth_user = User.new(json['auth_user'])
150
157
  @api_token = json['token']
151
158
  end
152
159
 
@@ -0,0 +1,215 @@
1
+ # A job opening with the following attributes
2
+ # * adj_score
3
+ # * amount
4
+ # * ciphertext
5
+ # * country
6
+ # * create_date
7
+ # * engagement_weeks
8
+ # * hours_per_week
9
+ # * job_category_level_one
10
+ # * job_category_level_two
11
+ # * job_type
12
+ # * op_adjusted_score
13
+ # * op_amount
14
+ # * op_buyer_ace
15
+ # * op_city
16
+ # * op_company_name
17
+ # * op_contract_date
18
+ # * op_country
19
+ # * op_date_created
20
+ # * op_description
21
+ # * op_eng_duration
22
+ # * op_hrs_per_week
23
+ # * op_job
24
+ # * op_job_category_
25
+ # * op_job_type
26
+ # * op_num_of_pending_invites
27
+ # * op_pref_english_skill
28
+ # * op_pref_fb_score
29
+ # * op_pref_hourly_rate
30
+ # * op_pref_odesk_hours
31
+ # * op_pref_test
32
+ # * op_pref_test_name
33
+ # * op_recno
34
+ # * op_required_skills
35
+ # * op_status_for_search
36
+ # * op_title
37
+ # * op_tot_asgs
38
+ # * op_tot_cand
39
+ # * op_tot_cand_client
40
+ # * op_tot_cand_prof
41
+ # * op_tot_feedback
42
+ # * op_tot_fp_asgs
43
+ # * op_tot_fp_charge
44
+ # * op_tot_hours
45
+ # * op_tot_hr_asgs
46
+ # * op_tot_hr_charge
47
+ # * op_tot_intv
48
+ # * op_tot_jobs_filled
49
+ # * op_tot_jobs_posted
50
+ # * record_id
51
+ # * search_status
52
+ # * timezone
53
+ # * total_billed_assignments
54
+ # * total_charge
55
+ # * total_hours
56
+ class RubyDesk::Job < RubyDesk::OdeskEntity
57
+ attributes :op_tot_hours, :job_category_level_two, :op_company_name,
58
+ :op_tot_cand_client, :record_id, :op_amount, :total_hours,
59
+ :op_date_created, :op_city, :country, :op_tot_intv, :op_tot_feedback,
60
+ :search_status, :op_job, :op_hrs_per_week, :op_job_category_, :op_country,
61
+ :amount, :op_tot_cand_prof, :op_tot_asgs, :total_charge,
62
+ :op_status_for_search, :op_tot_cand, :op_buyer_ace,
63
+ :job_category_level_one, :timezone, :op_pref_test, :adj_score,
64
+ :op_num_of_pending_invites, :op_tot_fp_asgs, :op_required_skills,
65
+ :ciphertext, :op_title, :op_pref_fb_score, :op_tot_hr_asgs, :create_date,
66
+ :op_tot_jobs_filled, :op_pref_hourly_rate, :op_tot_jobs_posted,
67
+ :job_type, :hours_per_week, :op_job_type, :op_pref_test_name,
68
+ :op_pref_english_skill, :op_pref_odesk_hours, :op_tot_fp_charge,
69
+ :op_contract_date, :op_tot_hr_charge, :engagement_weeks,
70
+ :op_adjusted_score, :op_recno, :total_billed_assignments,
71
+ :op_description, :op_eng_duration
72
+
73
+ # <h2>Details on Search Parameters</h2>
74
+ # <p>&nbsp;</p>
75
+ # <ul>
76
+ # <li><b>q -</b> OpeningData<b>&nbsp;</b>(Opening Data)
77
+ #
78
+ # <ul>
79
+ # <li>Search the text of the job description</li>
80
+ # </ul>
81
+ # </li>
82
+ # <li><b>c1 -</b> JobCategory<b>&nbsp;(</b>Level One Job Category)
83
+ # <ul>
84
+ # <li>Limit your search to a specific <a href="/all-categories">category</a></li>
85
+ # </ul>
86
+ # </li>
87
+ # <li><b>c2 -</b> second_category<b>&nbsp;</b>(Second Level Job Category)
88
+ #
89
+ # <ul>
90
+ # <li>Limit your search to a specific <a href="/all-categories">sub-category</a>
91
+ # <ul>
92
+ # <li>You must use a level one category in order to use a second level category.</li>
93
+ # </ul>
94
+ # </li>
95
+ # </ul>
96
+ # </li>
97
+ # <li><b>fb -</b> adjusted_score<b>&nbsp;</b>(Adjusted Score)
98
+ # <ul>
99
+ # <li>Limit your search to buyers with at least a score of the number passed in this parameter.
100
+ #
101
+ # <ul>
102
+ # <li>This number must be <strong>5</strong> or less</li>
103
+ # </ul>
104
+ # </li>
105
+ # </ul>
106
+ # </li>
107
+ # <li><b>min -</b> min_budget<b>&nbsp;</b>(Min Budget)
108
+ # <ul>
109
+ # <li>Limit your search to jobs with a budget greater than this number.</li>
110
+ #
111
+ # </ul>
112
+ # </li>
113
+ # <li><b>max -</b> max_budget<b>&nbsp;</b>(Max Budget)
114
+ # <ul>
115
+ # <li>Limit your search to jobs with a budget less than this number.</li>
116
+ # </ul>
117
+ # </li>
118
+ # <li><b>t -</b> JobType<b>&nbsp;</b>(Job Type)
119
+ # <ul>
120
+ # <li>oDesk has both hourly jobs and fixed prices jobs. This parameter allows you to limit your search to one or the other.
121
+ #
122
+ # <ul>
123
+ # <li>Hourly Jobs = '<strong>Hourly</strong>'</li>
124
+ # <li>Fixed Priced Jobs = '<strong>Fixed</strong>'</li>
125
+ # </ul>
126
+ # </li>
127
+ # <li><strong>wl -</strong> hours_per_week(Hours per Week)
128
+ # <ul>
129
+ # <li>This parameter can only be used when searching Hourly jobs. These numbers are a little arbitrary, so follow the following parameters in order to successfully use this parameter:
130
+ # <ul>
131
+ #
132
+ # <li>
133
+ # <p>As Needed &lt; 10 Hours/Week = '<strong>0</strong>'</p>
134
+ # </li>
135
+ # <li>
136
+ # <p>Part Time: 10-30 hrs/week = '<strong>20</strong>'</p>
137
+ # </li>
138
+ # <li>Full Time: 30+ hrs/week = '<strong>40</strong>'</li>
139
+ #
140
+ # </ul>
141
+ # </li>
142
+ # </ul>
143
+ # </li>
144
+ # <li><b>dur -</b> engagement_duration<b>&nbsp;</b>(Engagement Duration)
145
+ # <ul>
146
+ # <li>This parameter can only be used when searching Hourly jobs. These numbers are a little arbitrary, so follow the following parameters in order to successfully use this parameter:
147
+ # <ul>
148
+ # <li>Ongoing / More than 6 months = '<strong>1</strong>'</li>
149
+ # <li>3 to 6 months = '<strong>2</strong>'</li>
150
+ #
151
+ # <li>1 to 3 months = '<strong>3</strong>'</li>
152
+ # <li>Less than 1 month = '<strong>4</strong>'</li>
153
+ # <li>Less than 1 week = '<strong>5</strong>'</li>
154
+ # </ul>
155
+ # </li>
156
+ # </ul>
157
+ # </li>
158
+ # </ul>
159
+ #
160
+ # </li>
161
+ # <li><b>dp -</b> Date_Posted<b>&nbsp;</b><strong>(</strong>Date Posted)
162
+ # <ul>
163
+ # <li>Search jobs posted after this date.
164
+ # <ul>
165
+ # <li>Format for date: <em>07-22-2009</em></li>
166
+ # </ul>
167
+ # </li>
168
+ # </ul>
169
+ # </li>
170
+ # <li><b>st -</b> status_for_search<b>&nbsp;</b>(Status for Search)
171
+ #
172
+ # <ul>
173
+ # <li>Search Canceled jobs, In Progress Jobs and Completed Jobs: By default this default to Open Jobs
174
+ # <ul>
175
+ # <li>Open Jobs = '<strong>Open</strong>'</li>
176
+ # <li>Jobs in Progress = '<strong>In Progress</strong>'</li>
177
+ # <li>Completed Jobs = '<strong>Completed</strong>'</li>
178
+ # <li>Canceled Jobs = '<strong>Cancelled</strong>'</li>
179
+ #
180
+ # </ul>
181
+ # </li>
182
+ # </ul>
183
+ # </li>
184
+ # <li><strong>tba</strong> - total_billed_assignments<b>&nbsp;</b>(Total Billed Assignments)
185
+ # <ul>
186
+ # <li>Limit your search to buyers who completed at least this number of paid assignments
187
+ # <ul>
188
+ # <li>For example tb=5 searches buyers who have at least 5 billed assignments</li>
189
+ # </ul>
190
+ # </li>
191
+ # </ul>
192
+ # </li>
193
+ #
194
+ # <li><strong>gr</strong> -&nbsp;PrefGroup(Preferred Group)providers
195
+ # <ul>
196
+ # <li>Limits your search to buyers in a particular group</li>
197
+ # </ul>
198
+ # </li>
199
+ # <li><strong>to</strong> - titles_only<b>&nbsp;</b>(titles only)
200
+ # <ul>
201
+ # <li>Limits your search to job titles only. (you should be able to combine this search)</li>
202
+ def self.search(connector, query_options={})
203
+ if query_options.respond_to? :to_str
204
+ return search(connector, :q=>query_options.to_str)
205
+ end
206
+ json = connector.prepare_and_invoke_api_call(
207
+ 'profiles/v1/search/jobs', :method=>:get,
208
+ :auth=>false, :sign=>false, :params=>query_options)
209
+ jobs = []
210
+ [json['jobs']['job']].flatten.each do |job|
211
+ jobs << self.new(job)
212
+ end
213
+ return jobs
214
+ end
215
+ end
@@ -2,6 +2,46 @@ class RubyDesk::OdeskEntity
2
2
  @@complex_attributes = {}
3
3
 
4
4
  class << self
5
+ # Defines a new attribute or multiple attributes to this class.
6
+ # Allowed options:
7
+ # * class: The class used to initialize this attribute
8
+ # * sub_element: Indicates this is an array. Name of the key used to initialize this attribute.
9
+ #
10
+ # Here are some examples of how to use this method
11
+ # class Project
12
+ # # Defines a new attribute called 'name'.
13
+ # # This is generally used for defining simple attributes such as String or integer
14
+ # attribute :name
15
+ #
16
+ # # Defines two attributes called 'description' and 'priority'.
17
+ # attributes :description, :priority
18
+ # # The same effect can be accomplished by calling
19
+ # attribute :description
20
+ # attribute :priority
21
+ #
22
+ # # Defines an attribute called 'manager' of class User
23
+ # # This class is used to initialize this attribute as we will see later
24
+ # attribute :manager, :class=>User
25
+ #
26
+ # # Defines an attribute called 'tasks' which is an array of type Task
27
+ # attribute :tasks, :class=>Task, :sub_element=>"tasks"
28
+ # end
29
+ #
30
+ # Initialization
31
+ # ==============
32
+ # The above class Project can be initialized like this
33
+ # # An instance of class Project all attributes set to nil
34
+ # Project.new
35
+ #
36
+ # # Initialize simple attributes with the given values
37
+ # Project.new :name=>"GitHub project", :description=>"Sample project on git hub"
38
+ #
39
+ # # Initialize complex attribute
40
+ # # This will initialize manager with: User.new(:name=>"Ahmed", :birthday=>Date.parse("3/3/1983"))
41
+ # Project.new :manager=>{:name=>"Ahmed", :birthday=>Date.parse("3/3/1983")}
42
+ #
43
+ # # Initializes 'tasks' attribute with [Task.new(:name=>"task1", Task.new(:name=>"task2", :priority=>3}]
44
+ # Project.new :tasks=>[{:name=>"task1"}, {:name=>"task2", :priority=>3}]
5
45
  def attribute(*att_names)
6
46
  options = nil
7
47
  if att_names.last.is_a?Hash
@@ -16,7 +56,18 @@ class RubyDesk::OdeskEntity
16
56
  alias attributes attribute
17
57
  end
18
58
 
19
-
59
+
60
+ # Creates a new object of this class
61
+ # Initial values of attributes is passed as a paramter
62
+ # * params: A hash used to initialize this object.
63
+ # The key is the name of the attribute to initialize.
64
+ # The value is used as the initial value for this attribute.
65
+ # If the attribute is defined a class in creation,
66
+ # the value is used as an initialization parameter with this class.
67
+ # If the attribute is marked as "sub_element" in creation,
68
+ # the value is assumed to be an array.
69
+ # Each entry in the array is used as an initialization parameter to create a new element.
70
+ # If the value is not an array, it is used to create an array of single element.
20
71
  def initialize(params={})
21
72
  params.each do |k, v|
22
73
  attribute_options = @@complex_attributes[k.to_s] || {}
@@ -34,7 +85,7 @@ class RubyDesk::OdeskEntity
34
85
  end
35
86
  end
36
87
  else
37
- # This attribute is a single comple attribute
88
+ # This attribute is a single complex attribute
38
89
  self.instance_variable_set("@#{k}", attribute_options[:class].new(v))
39
90
  end
40
91
  else
@@ -1,3 +1,126 @@
1
+ # A provider in oDesk.
2
+ # <p>There is a TON&nbsp;of info returned here and the best way to see what this actually means is to try pulling data from a few providers and match up the fields, most of the response fields are human readable. Here is some aditional info that should help decipher this response:</p>
3
+ #
4
+ # <p>&nbsp;</p>
5
+ # <ul>
6
+ # <li>&lt;dev_userid&gt;scoopwilson&lt;/dev_userid&gt; The odesk users id of the provider</li>
7
+ # <li>&lt;dev_rank_percentile&gt;82&lt;/dev_rank_percentile&gt; The providers rank overall on oDesk</li>
8
+ # <li>&lt;dev_usr_score&gt;4.9681818181818&lt;/dev_usr_score&gt; The providers feedback score</li>
9
+ #
10
+ # <li>&lt;dev_profile_access&gt;public&lt;/dev_profile_access&gt; The status of the providers profile (public or private)</li>
11
+ # <li>&lt;skill&gt; The Skill tag describes a skill that the provider has listed in their profile</li>
12
+ # <li>&lt;tsexam&gt; tsexam describes a test that the provider has taken and made public.</li>
13
+ # <li>&lt;dev_score&gt; dev_score describes feedback that the provider has received after a job has been completed (or just closed)</li>
14
+ #
15
+ # <li>&lt;dev_recent_rank_percentile&gt;80&lt;/dev_recent_rank_percentile&gt; The providers rank on oDesk using data from the last 90 days.</li>
16
+ # <li>&lt;dev_active_interviews&gt;0&lt;/dev_active_interviews&gt; How many active interviews the provider is engaged in now.</li>
17
+ # <li>&lt;dev_total_hours&gt;2526.1666666667&lt;/dev_total_hours&gt; The providers total hours worked on oDesk.</li>
18
+ #
19
+ # <li>&lt;experience&gt; Describes the providers experience as listed in their profile under the Experience section</li>
20
+ # <li>&lt;assignment&gt; Describes past assignements that are publicly viewable.</li>
21
+ #
22
+ # Here's a full list of all attributes available:
23
+ # * affiliated
24
+ # * ag_active_assignments
25
+ # * ag_adj_score
26
+ # * ag_adj_score_recent
27
+ # * ag_billed_assignments
28
+ # * ag_city
29
+ # * ag_cny_recno
30
+ # * ag_country
31
+ # * ag_country_tz
32
+ # * ag_description
33
+ # * ag_hours_lastdays
34
+ # * ag_last_date_worked
35
+ # * ag_logo
36
+ # * ag_manager_blurb
37
+ # * ag_manager_name
38
+ # * ag_member_since
39
+ # * ag_name
40
+ # * ag_portrait
41
+ # * ag_rank_percentile
42
+ # * ag_recent_hours
43
+ # * ag_summary
44
+ # * ag_teamid
45
+ # * ag_teamid_rollup
46
+ # * ag_tot_feedback
47
+ # * ag_total_developers
48
+ # * ag_total_hours
49
+ # * agency_ciphertext
50
+ # * assignments
51
+ # * assignments_count
52
+ # * candidacies
53
+ # * certification
54
+ # * ciphertext
55
+ # * competencies
56
+ # * dev_ac_agencies
57
+ # * dev_active_interviews
58
+ # * dev_adj_score
59
+ # * dev_adj_score_recent
60
+ # * dev_agency_ciphertext
61
+ # * dev_agency_ref
62
+ # * dev_availability
63
+ # * dev_bill_rate
64
+ # * dev_billed_assignments
65
+ # * dev_billed_assignments_recent
66
+ # * dev_blurb
67
+ # * dev_blurb_short
68
+ # * dev_category
69
+ # * dev_city
70
+ # * dev_country
71
+ # * dev_cur_assignments
72
+ # * dev_eng_skill
73
+ # * dev_est_availability
74
+ # * dev_expose_full_name
75
+ # * dev_full_name
76
+ # * dev_groups
77
+ # * dev_ic
78
+ # * dev_is_affiliated
79
+ # * dev_is_ready
80
+ # * dev_last_activity
81
+ # * dev_last_worked
82
+ # * dev_location
83
+ # * dev_member_since
84
+ # * dev_pay_agency_rate
85
+ # * dev_pay_rate
86
+ # * dev_portfolio_items_count
87
+ # * dev_portrait
88
+ # * dev_profile_title
89
+ # * dev_rank_percentile
90
+ # * dev_recent_hours
91
+ # * dev_recent_rank_percentile
92
+ # * dev_recno
93
+ # * dev_region
94
+ # * dev_scores
95
+ # * dev_short_name
96
+ # * dev_test_passed_count
97
+ # * dev_timezone
98
+ # * dev_tot_feedback
99
+ # * dev_tot_feedback_recent
100
+ # * dev_total_assignments
101
+ # * dev_total_hours
102
+ # * dev_total_hours_rounded
103
+ # * dev_ui_profile_access
104
+ # * dev_usr_score
105
+ # * dev_year_exp
106
+ # * education
107
+ # * experiences
108
+ # * favorited
109
+ # * iinitialize
110
+ # * is_odesk_ready
111
+ # * job_categories
112
+ # * oth_experiences
113
+ # * permalink
114
+ # * portfolio_items
115
+ # * profile_title_full
116
+ # * provider_profile_api
117
+ # * response_time
118
+ # * search_affiliate_providers_url
119
+ # * skills
120
+ # * trends
121
+ # * tsexams
122
+ # * tsexams_count
123
+ # * version
1
124
  class RubyDesk::Provider < RubyDesk::OdeskEntity
2
125
 
3
126
  attributes :affiliated, :ag_name, :ag_description, :dev_adj_score_recent,
@@ -42,6 +165,11 @@ class RubyDesk::Provider < RubyDesk::OdeskEntity
42
165
  attribute :portfolio_items, :class=>RubyDesk::PortfolioItem, :sub_element=>'portfolio_item'
43
166
 
44
167
  class << self
168
+ # Returns all categories defined in oDesk.
169
+ # These categories are retrieved from a static text file and not updated from the web.
170
+ # Return value is a hash.
171
+ # Each key is a name of a root category.
172
+ # Value is an array of subcategories.
45
173
  def all_categories
46
174
  text = File.read(File.join(File.dirname(__FILE__), "..", "categories"))
47
175
  lines = text.split(/[\r\n]+/).map{|line| line.strip}
@@ -57,7 +185,9 @@ class RubyDesk::Provider < RubyDesk::OdeskEntity
57
185
  return categories
58
186
  end
59
187
 
60
- # Implements search with the given criteria
188
+ # Implements search with the given criteria.
189
+ # For basic search, pass a string as the second parameter
190
+ # For advanced search, pass a string according to the following parameters
61
191
  #* q - ProfileData (ProfileData)
62
192
  # * Profile data is any text that appears in a provider's profile. For example if q = 'odesk' the search would return any user's with the word odesk in their profile.
63
193
  #* c1 - JobCategory (First Level Job Category)
@@ -118,15 +248,22 @@ class RubyDesk::Provider < RubyDesk::OdeskEntity
118
248
  end
119
249
  json = connector.prepare_and_invoke_api_call(
120
250
  'profiles/v1/search/providers', :method=>:get,
121
- :auth=>false, :sign=>false)
251
+ :auth=>false, :sign=>false, :params=>options)
122
252
 
123
253
  providers = []
124
- [json['providers']['provider']].flatten.each do |provider|
125
- providers << self.new(provider)
254
+ if json['providers']['provider']
255
+ [json['providers']['provider']].flatten.each do |provider|
256
+ providers << self.new(provider)
257
+ end
126
258
  end
127
259
  return providers
128
260
  end
129
261
 
262
+ # Retrieves the profile with the given user
263
+ # * connector: The RubyDesk::Connector that is connected to oDesk
264
+ # * id: The id of the user to retrieve his profile
265
+ # * options: A hash of options
266
+ # * brief: set this to true to retrieve only a brief profile of the given user
130
267
  def get_profile(connector, id, options={})
131
268
  brief = options.delete :brief || false
132
269
  json = connector.prepare_and_invoke_api_call(
@@ -1,3 +1,126 @@
1
+ # <h2>Response Details</h2>
2
+ # <ul>
3
+ # <li>&lt;snapshot&gt;
4
+ # <ul>
5
+ # <li>Snapshot detail container</li>
6
+ # </ul>
7
+ # </li>
8
+ # <li>&lt;status&gt;PRIVATE&lt;/status&gt;
9
+ #
10
+ # <ul>
11
+ # <li>Status of the snapshot
12
+ # <ul>
13
+ # <li>LOGIN</li>
14
+ # <li>NORMAL</li>
15
+ # <li>PRIVATE</li>
16
+ # <li>EXIT</li>
17
+ # </ul>
18
+ # </li>
19
+ # </ul>
20
+ # </li>
21
+ # <li>&lt;time&gt;1229521500&lt;/time&gt;
22
+ #
23
+ # <ul>
24
+ # <li>The GMT&nbsp;that the snapshot was taken</li>
25
+ # </ul>
26
+ # </li>
27
+ # <li>&lt;billing_status&gt;non-billed.disconnected&lt;/billing_status&gt;
28
+ # <ul>
29
+ # <li>A snapshot's billing status
30
+ # <ul>
31
+ # <li>non-billed.disconnected</li>
32
+ # <li>billed.disconnected</li>
33
+ #
34
+ # <li>billed.connected</li>
35
+ # </ul>
36
+ # </li>
37
+ # </ul>
38
+ # </li>
39
+ # <li>&lt;activity&gt;0&lt;/activity&gt;</li>
40
+ # <li>&lt;online_presence&gt;&lt;/online_presence&gt;</li>
41
+ # <li>&lt;user&gt;
42
+ # <ul>
43
+ # <li>The general user details associated with the current use</li>
44
+ #
45
+ # </ul>
46
+ # </li>
47
+ # <li>&lt;mouse_events_count/&gt;
48
+ # <ul>
49
+ # <li>The number of mouse events associated with this snapshot</li>
50
+ # </ul>
51
+ # </li>
52
+ # <li>&lt;company_id&gt;agencyone&lt;/company_id&gt;
53
+ # <ul>
54
+ # <li>Company ID&nbsp;associated with this snapshot</li>
55
+ #
56
+ # </ul>
57
+ # </li>
58
+ # <li>&lt;timezone&gt;America/Los_Angeles&lt;/timezone&gt;
59
+ # <ul>
60
+ # <li>User's time zone</li>
61
+ # </ul>
62
+ # </li>
63
+ # <li>&lt;uid/&gt;
64
+ # <ul>
65
+ # <li>The user id</li>
66
+ # </ul>
67
+ #
68
+ # </li>
69
+ # <li>&lt;keyboard_events_count/&gt;
70
+ # <ul>
71
+ # <li>Number of keyboard events counted for this snapshot</li>
72
+ # </ul>
73
+ # </li>
74
+ # <li>&lt;last_worked&gt;
75
+ # <ul>
76
+ # <li>The timestamp last worked
77
+ # <ul>
78
+ # <li>Format:&nbsp;[<em>1240637782</em>]</li>
79
+ #
80
+ # </ul>
81
+ # </li>
82
+ # </ul>
83
+ # </li>
84
+ # <li>&lt;memo/&gt;
85
+ # <ul>
86
+ # <li>Memo associated with the current time stamp</li>
87
+ # </ul>
88
+ # </li>
89
+ # <li>&lt;active_window_title/&gt;
90
+ # <ul>
91
+ # <li>The title of the active window when the snapshot was taken</li>
92
+ # </ul>
93
+ #
94
+ # </li>
95
+ # <li>&lt;report24_img&gt;
96
+ # <ul>
97
+ # <li>URL to a graph that describes a users activitly over a 24hr period</li>
98
+ # </ul>
99
+ # </li>
100
+ # <li>&lt;computer_name/&gt;
101
+ # <ul>
102
+ # <li>The name of the computer where the snapshot was taken</li>
103
+ # </ul>
104
+ # </li>
105
+ # <li>&lt;online_presence_img&gt;
106
+ #
107
+ # <ul>
108
+ # <li>URL&nbsp;for the default online user activity</li>
109
+ # </ul>
110
+ # </li>
111
+ # <li>&lt;user_id&gt;
112
+ # <ul>
113
+ # <li>User id associated with the current snapshot</li>
114
+ # </ul>
115
+ # </li>
116
+ # <li>&lt;client_version/&gt;
117
+ # <ul>
118
+ # <li>The oDesk Time Tracker version used to take the snapshot</li>
119
+ #
120
+ # </ul>
121
+ # </li>
122
+ # <li>&lt;teamroom_api&gt;/api/team/v1/teamrooms/agencyone.xml&lt;/teamroom_api&gt;&nbsp;</li>
123
+ # <li>&lt;workdiary_api&gt;/api/team/v1/workdiaries/agencyone/scoopwilson/20081217.xml&lt;/workdiary_api&gt;</li>
1
124
  class RubyDesk::Snapshot < RubyDesk::OdeskEntity
2
125
  attribute :status, :time, :billing_status, :report_url, :screenshot_img, :activity,
3
126
  :online_presence, :screenshot_url, :mouse_events_count, :company_id,
@@ -8,6 +131,10 @@ class RubyDesk::Snapshot < RubyDesk::OdeskEntity
8
131
 
9
132
  attribute :user, :class=>RubyDesk::User
10
133
 
134
+ # Retrieves work diary as an array of snapshots.
135
+ # The Work Diary method retrieves all snapshots from a single user account within a single day.
136
+ # Keep in mind that a day is dependent on server time and not the day in which the query is made.
137
+ # Make sure to test with various locations before you're done.
11
138
  def self.work_diary(connector, company_id, user_id, date = nil, timezone = "mine")
12
139
  json = connector.prepare_and_invoke_api_call(
13
140
  "team/v1/workdiaries/#{company_id}/#{user_id}" + (date ? "/"+date : ""),
@@ -19,6 +146,7 @@ class RubyDesk::Snapshot < RubyDesk::OdeskEntity
19
146
  end
20
147
  end
21
148
 
149
+ # Retrieves details of one snapshot
22
150
  def self.snapshot_details(connector, company_id, user_id, timestamp = nil)
23
151
  timestamp_param = case timestamp
24
152
  when String then timestamp