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 +2 -0
- data/VERSION +1 -1
- data/lib/ruby_desk/connector.rb +10 -3
- data/lib/ruby_desk/job.rb +215 -0
- data/lib/ruby_desk/odesk_entity.rb +53 -2
- data/lib/ruby_desk/provider.rb +141 -4
- data/lib/ruby_desk/snapshot.rb +128 -0
- data/lib/ruby_desk/team_room.rb +3 -0
- data/lib/ruby_desk/time_report.rb +179 -14
- data/lib/ruby_desk.rb +16 -3
- data/test/jobs.json +1 -0
- data/test/test_ruby_desk.rb +7 -0
- metadata +14 -5
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.
|
1
|
+
0.8.0
|
data/lib/ruby_desk/connector.rb
CHANGED
@@ -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
|
-
|
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 "
|
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> </p>
|
75
|
+
# <ul>
|
76
|
+
# <li><b>q -</b> OpeningData<b> </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> (</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> </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> </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> </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> </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> </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 < 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> </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> </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> </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> </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> - 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> </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
|
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
|
data/lib/ruby_desk/provider.rb
CHANGED
@@ -1,3 +1,126 @@
|
|
1
|
+
# A provider in oDesk.
|
2
|
+
# <p>There is a TON 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> </p>
|
5
|
+
# <ul>
|
6
|
+
# <li><dev_userid>scoopwilson</dev_userid> The odesk users id of the provider</li>
|
7
|
+
# <li><dev_rank_percentile>82</dev_rank_percentile> The providers rank overall on oDesk</li>
|
8
|
+
# <li><dev_usr_score>4.9681818181818</dev_usr_score> The providers feedback score</li>
|
9
|
+
#
|
10
|
+
# <li><dev_profile_access>public</dev_profile_access> The status of the providers profile (public or private)</li>
|
11
|
+
# <li><skill> The Skill tag describes a skill that the provider has listed in their profile</li>
|
12
|
+
# <li><tsexam> tsexam describes a test that the provider has taken and made public.</li>
|
13
|
+
# <li><dev_score> dev_score describes feedback that the provider has received after a job has been completed (or just closed)</li>
|
14
|
+
#
|
15
|
+
# <li><dev_recent_rank_percentile>80</dev_recent_rank_percentile> The providers rank on oDesk using data from the last 90 days.</li>
|
16
|
+
# <li><dev_active_interviews>0</dev_active_interviews> How many active interviews the provider is engaged in now.</li>
|
17
|
+
# <li><dev_total_hours>2526.1666666667</dev_total_hours> The providers total hours worked on oDesk.</li>
|
18
|
+
#
|
19
|
+
# <li><experience> Describes the providers experience as listed in their profile under the Experience section</li>
|
20
|
+
# <li><assignment> 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
|
-
|
125
|
-
providers
|
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(
|
data/lib/ruby_desk/snapshot.rb
CHANGED
@@ -1,3 +1,126 @@
|
|
1
|
+
# <h2>Response Details</h2>
|
2
|
+
# <ul>
|
3
|
+
# <li><snapshot>
|
4
|
+
# <ul>
|
5
|
+
# <li>Snapshot detail container</li>
|
6
|
+
# </ul>
|
7
|
+
# </li>
|
8
|
+
# <li><status>PRIVATE</status>
|
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><time>1229521500</time>
|
22
|
+
#
|
23
|
+
# <ul>
|
24
|
+
# <li>The GMT that the snapshot was taken</li>
|
25
|
+
# </ul>
|
26
|
+
# </li>
|
27
|
+
# <li><billing_status>non-billed.disconnected</billing_status>
|
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><activity>0</activity></li>
|
40
|
+
# <li><online_presence></online_presence></li>
|
41
|
+
# <li><user>
|
42
|
+
# <ul>
|
43
|
+
# <li>The general user details associated with the current use</li>
|
44
|
+
#
|
45
|
+
# </ul>
|
46
|
+
# </li>
|
47
|
+
# <li><mouse_events_count/>
|
48
|
+
# <ul>
|
49
|
+
# <li>The number of mouse events associated with this snapshot</li>
|
50
|
+
# </ul>
|
51
|
+
# </li>
|
52
|
+
# <li><company_id>agencyone</company_id>
|
53
|
+
# <ul>
|
54
|
+
# <li>Company ID associated with this snapshot</li>
|
55
|
+
#
|
56
|
+
# </ul>
|
57
|
+
# </li>
|
58
|
+
# <li><timezone>America/Los_Angeles</timezone>
|
59
|
+
# <ul>
|
60
|
+
# <li>User's time zone</li>
|
61
|
+
# </ul>
|
62
|
+
# </li>
|
63
|
+
# <li><uid/>
|
64
|
+
# <ul>
|
65
|
+
# <li>The user id</li>
|
66
|
+
# </ul>
|
67
|
+
#
|
68
|
+
# </li>
|
69
|
+
# <li><keyboard_events_count/>
|
70
|
+
# <ul>
|
71
|
+
# <li>Number of keyboard events counted for this snapshot</li>
|
72
|
+
# </ul>
|
73
|
+
# </li>
|
74
|
+
# <li><last_worked>
|
75
|
+
# <ul>
|
76
|
+
# <li>The timestamp last worked
|
77
|
+
# <ul>
|
78
|
+
# <li>Format: [<em>1240637782</em>]</li>
|
79
|
+
#
|
80
|
+
# </ul>
|
81
|
+
# </li>
|
82
|
+
# </ul>
|
83
|
+
# </li>
|
84
|
+
# <li><memo/>
|
85
|
+
# <ul>
|
86
|
+
# <li>Memo associated with the current time stamp</li>
|
87
|
+
# </ul>
|
88
|
+
# </li>
|
89
|
+
# <li><active_window_title/>
|
90
|
+
# <ul>
|
91
|
+
# <li>The title of the active window when the snapshot was taken</li>
|
92
|
+
# </ul>
|
93
|
+
#
|
94
|
+
# </li>
|
95
|
+
# <li><report24_img>
|
96
|
+
# <ul>
|
97
|
+
# <li>URL to a graph that describes a users activitly over a 24hr period</li>
|
98
|
+
# </ul>
|
99
|
+
# </li>
|
100
|
+
# <li><computer_name/>
|
101
|
+
# <ul>
|
102
|
+
# <li>The name of the computer where the snapshot was taken</li>
|
103
|
+
# </ul>
|
104
|
+
# </li>
|
105
|
+
# <li><online_presence_img>
|
106
|
+
#
|
107
|
+
# <ul>
|
108
|
+
# <li>URL for the default online user activity</li>
|
109
|
+
# </ul>
|
110
|
+
# </li>
|
111
|
+
# <li><user_id>
|
112
|
+
# <ul>
|
113
|
+
# <li>User id associated with the current snapshot</li>
|
114
|
+
# </ul>
|
115
|
+
# </li>
|
116
|
+
# <li><client_version/>
|
117
|
+
# <ul>
|
118
|
+
# <li>The oDesk Time Tracker version used to take the snapshot</li>
|
119
|
+
#
|
120
|
+
# </ul>
|
121
|
+
# </li>
|
122
|
+
# <li><teamroom_api>/api/team/v1/teamrooms/agencyone.xml</teamroom_api> </li>
|
123
|
+
# <li><workdiary_api>/api/team/v1/workdiaries/agencyone/scoopwilson/20081217.xml</workdiary_api></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
|