ruby_desk 0.7.0 → 0.8.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 +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
|