freelancer 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  .document
2
2
  Gemfile.lock
3
3
  pkg
4
+ rdoc
5
+ coverage
data/Gemfile CHANGED
@@ -2,10 +2,10 @@ source :rubygems
2
2
 
3
3
  gem "oauth", ">= 0.4.0"
4
4
  gem "htmlentities", ">= 4.2.1"
5
- gem "json_mapper", ">= 0.2.0"
5
+ gem "json_mapper", ">= 0.2.1"
6
6
 
7
7
  group :development do
8
- gem "jeweler"
8
+ gem "jeweler", ">= 1.4.0"
9
9
  gem "shoulda", ">= 2.10.3"
10
10
  gem "mcmire-matchy", ">= 0.5.2"
11
11
  gem "mocha", ">= 0.9.8"
@@ -1,6 +1,6 @@
1
1
  = Freelancer API
2
- by Trond Arve Nordheim -
3
- {Binary Marbles}[http://www.binarymarbles.com/]
2
+
3
+ Copyright (C) 2010 Trond Arve Nordheim - {Binary Marbles}[http://www.binarymarbles.com/]
4
4
 
5
5
  == NOTICE
6
6
 
@@ -18,25 +18,22 @@ A Ruby gem for working with the new Freelancer.com API.
18
18
  * oAuth authentication.
19
19
  * Support for all Freelancer.com APIs.
20
20
  * Per-environment configuration and sandboxing.
21
+ * Ruby on Rails support (via separate project {freelancer-rails}[http://github.com/tanordheim/freelancer-rails])
21
22
 
22
23
  == Issues and missing features
23
24
 
24
- * The Profile API is missing support for SetProfileInfo.
25
- * The Employer API is missing support for PostNewProject, PostNewTrialProject, PostNewDraftProject, ChooseWinnerForProject, InviteUserForProject, UpdateProjectDetails, PublishDraftProject, UpgradeTrialProject and DeleteDraftProject.
26
- * The Freelancer API is missing support for PlaceBidOnProject, RetractBidFromProject and AcceptBidWon.
27
- * The Common API is missing support for RequestCancelProject, PostFeedback, PostReplyForFeedback and RequestWithdrawFeedback.
28
- * The Payment API is missing support for RequestWithdrawal, CreateMilestonePayment, TransferMoney, RequestCancelWithdrawal, CancelMilestone, RequestReleaseMilestone, ReleaseMilestone and PrepareTransfer.
29
- * The Project API is missing support for PostPublicMessage.
30
- * The Message API is missing support for SendMessage and MarkMessageAsRead.
25
+ * Multipart fields are not implemented yet.
26
+ * File associations on projects and messages are not implemented yet.
31
27
 
32
- == Usage
28
+ == Documentation
33
29
 
34
- Examples have not been written yet.
30
+ * RDoc: http://rdoc.info/projects/tanordheim/freelancer-ruby
31
+ * Usage: http://wiki.github.com/tanordheim/freelancer-ruby/
35
32
 
36
33
  == Requirements
37
34
 
38
35
  * {oauth}[http://rubygems.org/gems/oauth]
39
- * {json}[http://rubygems.org/gems/json]
36
+ * {json_mapper}[http://rubygems.org/gems/json_mapper]
40
37
  * {htmlentities}[http://rubygems.org/gems/htmlentities]
41
38
 
42
39
  == Installation
data/Rakefile CHANGED
@@ -1,23 +1,33 @@
1
1
  require "rake"
2
- require "jeweler"
3
2
  require "bundler"
4
3
  require "rake/testtask"
4
+ require "rake/rdoctask"
5
5
 
6
6
  # Gemcutter/Jeweler configuration
7
7
  # -----------------------------------------------------------------------------
8
- Jeweler::Tasks.new do |gem|
9
-
10
- gem.name = "freelancer"
11
- gem.summary = "Freelancer API"
12
- gem.description = "Ruby gem implementation of the Freelancer.com API"
13
- gem.email = "tanordheim@gmail.com"
14
- gem.homepage = "http://github.com/tanordheim/freelancer"
15
- gem.authors = [ "Trond Arve Nordheim" ]
16
-
17
- gem.add_bundler_dependencies
8
+ begin
9
+
10
+ require "jeweler"
11
+
12
+ Jeweler::Tasks.new do |gem|
13
+
14
+ gem.name = "freelancer"
15
+ gem.summary = "Freelancer API"
16
+ gem.description = "Ruby gem implementation of the Freelancer.com API"
17
+ gem.email = "tanordheim@gmail.com"
18
+ gem.homepage = "http://github.com/tanordheim/freelancer-ruby"
19
+ gem.authors = [ "Trond Arve Nordheim" ]
20
+
21
+ gem.add_bundler_dependencies
22
+
23
+ end
18
24
 
25
+ Jeweler::GemcutterTasks.new
26
+
27
+ rescue LoadError
28
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
29
  end
20
- Jeweler::GemcutterTasks.new
30
+
21
31
 
22
32
  # Test setup
23
33
  # -----------------------------------------------------------------------------
@@ -28,6 +38,39 @@ Rake::TestTask.new(:test) do |t|
28
38
  t.verbose = true
29
39
  end
30
40
 
41
+ # RDoc setup
42
+ # ----------------------------------------------------------------------------
43
+ Rake::RDocTask.new do |rdoc|
44
+
45
+ version = File.exists?("VERSION") ? File.read("VERSION") : ""
46
+
47
+ rdoc.rdoc_dir = "rdoc"
48
+ rdoc.title = "freelancer #{version}"
49
+ rdoc.rdoc_files.include("README.rdoc")
50
+ rdoc.rdoc_files.include("lib/**/*.rb")
51
+
52
+ end
53
+
54
+ # Rcov setup
55
+ # ----------------------------------------------------------------------------
56
+ begin
57
+
58
+ require "rcov/rcovtask"
59
+
60
+ Rcov::RcovTask.new do |test|
61
+
62
+ test.libs << "test"
63
+ test.pattern = "test/**/*_test.rb"
64
+ test.verbose = "true"
65
+
66
+ end
67
+
68
+ rescue LoadError
69
+ task :rcov do
70
+ abort "Rcov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
71
+ end
72
+ end
73
+
31
74
  # Task setups
32
75
  # -----------------------------------------------------------------------------
33
76
  task :test => :check_dependencies
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{freelancer}
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Trond Arve Nordheim"]
12
- s.date = %q{2010-08-09}
12
+ s.date = %q{2010-08-10}
13
13
  s.description = %q{Ruby gem implementation of the Freelancer.com API}
14
14
  s.email = %q{tanordheim@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -57,6 +57,7 @@ Gem::Specification.new do |s|
57
57
  "lib/freelancer/models/project_options.rb",
58
58
  "lib/freelancer/models/rating.rb",
59
59
  "lib/freelancer/models/review.rb",
60
+ "lib/freelancer/models/status_confirmation.rb",
60
61
  "lib/freelancer/models/transaction.rb",
61
62
  "lib/freelancer/models/user.rb",
62
63
  "lib/freelancer/models/withdrawal.rb",
@@ -98,6 +99,7 @@ Gem::Specification.new do |s|
98
99
  "test/fixtures/employer/update_project_details.xml",
99
100
  "test/fixtures/employer/upgrade_trial_project.json",
100
101
  "test/fixtures/employer/upgrade_trial_project.xml",
102
+ "test/fixtures/error.json",
101
103
  "test/fixtures/freelancer/accept_bid_won.json",
102
104
  "test/fixtures/freelancer/accept_bid_won.xml",
103
105
  "test/fixtures/freelancer/get_project_list_for_placed_bids.json",
@@ -183,6 +185,7 @@ Gem::Specification.new do |s|
183
185
  "test/fixtures/project/search_projects.json",
184
186
  "test/fixtures/project/search_projects.xml",
185
187
  "test/fixtures/project/send_message.xml",
188
+ "test/fixtures/status_confirmation.json",
186
189
  "test/fixtures/user/get_user_details.json",
187
190
  "test/fixtures/user/get_user_details.xml",
188
191
  "test/fixtures/user/get_user_feedback.json",
@@ -222,7 +225,7 @@ Gem::Specification.new do |s|
222
225
  "test/freelancer_test.rb",
223
226
  "test/test_helper.rb"
224
227
  ]
225
- s.homepage = %q{http://github.com/tanordheim/freelancer}
228
+ s.homepage = %q{http://github.com/tanordheim/freelancer-ruby}
226
229
  s.rdoc_options = ["--charset=UTF-8"]
227
230
  s.require_paths = ["lib"]
228
231
  s.rubygems_version = %q{1.3.7}
@@ -269,8 +272,8 @@ Gem::Specification.new do |s|
269
272
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
270
273
  s.add_runtime_dependency(%q<oauth>, [">= 0.4.0"])
271
274
  s.add_runtime_dependency(%q<htmlentities>, [">= 4.2.1"])
272
- s.add_runtime_dependency(%q<json_mapper>, [">= 0.2.0"])
273
- s.add_development_dependency(%q<jeweler>, [">= 0"])
275
+ s.add_runtime_dependency(%q<json_mapper>, [">= 0.2.1"])
276
+ s.add_development_dependency(%q<jeweler>, [">= 1.4.0"])
274
277
  s.add_development_dependency(%q<shoulda>, [">= 2.10.3"])
275
278
  s.add_development_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
276
279
  s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
@@ -278,8 +281,8 @@ Gem::Specification.new do |s|
278
281
  else
279
282
  s.add_dependency(%q<oauth>, [">= 0.4.0"])
280
283
  s.add_dependency(%q<htmlentities>, [">= 4.2.1"])
281
- s.add_dependency(%q<json_mapper>, [">= 0.2.0"])
282
- s.add_dependency(%q<jeweler>, [">= 0"])
284
+ s.add_dependency(%q<json_mapper>, [">= 0.2.1"])
285
+ s.add_dependency(%q<jeweler>, [">= 1.4.0"])
283
286
  s.add_dependency(%q<shoulda>, [">= 2.10.3"])
284
287
  s.add_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
285
288
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
@@ -288,8 +291,8 @@ Gem::Specification.new do |s|
288
291
  else
289
292
  s.add_dependency(%q<oauth>, [">= 0.4.0"])
290
293
  s.add_dependency(%q<htmlentities>, [">= 4.2.1"])
291
- s.add_dependency(%q<json_mapper>, [">= 0.2.0"])
292
- s.add_dependency(%q<jeweler>, [">= 0"])
294
+ s.add_dependency(%q<json_mapper>, [">= 0.2.1"])
295
+ s.add_dependency(%q<jeweler>, [">= 1.4.0"])
293
296
  s.add_dependency(%q<shoulda>, [">= 2.10.3"])
294
297
  s.add_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
295
298
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
@@ -5,6 +5,8 @@ require "json_mapper"
5
5
  module Freelancer
6
6
 
7
7
  class FreelancerError < StandardError; end
8
+ class FreelancerRequestError < FreelancerError; end
9
+ class FreelancerResponseError < FreelancerError; end
8
10
 
9
11
  autoload :API, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "api")
10
12
  autoload :Client, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "client")
@@ -45,6 +47,7 @@ module Freelancer
45
47
  autoload :Bid, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "models", "bid")
46
48
  autoload :Message, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "models", "message")
47
49
  autoload :ProjectBudget, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "models", "project_budget")
50
+ autoload :StatusConfirmation, File.join(File.expand_path(File.dirname(__FILE__)), "freelancer", "models", "status_confirmation")
48
51
  end
49
52
 
50
53
  end
@@ -52,6 +52,104 @@ module Freelancer
52
52
 
53
53
  end
54
54
 
55
+ # Request to cancel an awarded project
56
+ #
57
+ # Valid parameters are:
58
+ # - project_id: the id of the project to cancel
59
+ # - selected_winner: the id of the selected winner of the project
60
+ # - comment: the comment for the cancellation request
61
+ # - reason: the reason for cancelling the project
62
+ # - followed_guidelines: if the guidelines for cancelling the project has been followed
63
+ def request_cancel_project(*args)
64
+
65
+ params = extract_params(args)
66
+
67
+ # Execute the service call
68
+ result = api_get("/Common/requestCancelProject.json", build_api_params({
69
+ :projectid => params[:project_id],
70
+ :selectedwinner => params[:selected_winner],
71
+ :commenttext => params[:comment],
72
+ :reasoncancellation => params[:reason],
73
+ :followedguidelinesstatus => params[:followed_guidelines]
74
+ }))
75
+
76
+ # Parse and return the response
77
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
78
+
79
+ end
80
+
81
+ # Post feedback for a user
82
+ #
83
+ # Valid parameters are:
84
+ # - project_id: the project id related to the feedback
85
+ # - user_id: the id of the user to rate
86
+ # - username: the username of the user to rate
87
+ # - comment: the feedback comment
88
+ # - rating: the feedback rating
89
+ def post_feedback(*args)
90
+
91
+ params = extract_params(args)
92
+
93
+ # Execute the service call
94
+ result = api_get("/Common/postFeedback.json", build_api_params({
95
+ :projectid => params[:project_id],
96
+ :userid => params[:user_id],
97
+ :username => params[:username],
98
+ :feedbacktext => params[:comment],
99
+ :rating => params[:rating]
100
+ }))
101
+
102
+ # Parse and return the response
103
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
104
+
105
+ end
106
+
107
+ # Post reply to a feedback given to you
108
+ #
109
+ # Valid parameters are:
110
+ # - project_id: the id of the project related to the feedback
111
+ # - user_id: the id of the user to reply to
112
+ # - username: the username of the user to reply to
113
+ # - comment: the feedback comment
114
+ def post_feedback_reply(*args)
115
+
116
+ params = extract_params(args)
117
+
118
+ # Execute the service call
119
+ result = api_get("/Common/postReplyForFeedback.json", build_api_params({
120
+ :projectid => params[:project_id],
121
+ :userid => params[:user_id],
122
+ :username => params[:username],
123
+ :feedbacktext => params[:comment]
124
+ }))
125
+
126
+ # Parse and return the response
127
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
128
+
129
+ end
130
+
131
+ # Request that posted feedback is withdrawn
132
+ #
133
+ # Valid parameters are:
134
+ # - project_id: the id of the project related to feedback
135
+ # - user_id: the user id the feedback is posted to
136
+ # - username: the username the feedback is posted to
137
+ def request_withdraw_feedback(*args)
138
+
139
+ params = extract_params(args)
140
+
141
+ # Execute the service call
142
+ result = api_get("/Common/requestWithdrawFeedback.json", build_api_params({
143
+ :projectid => params[:project_id],
144
+ :userid => params[:user_id],
145
+ :username => params[:username]
146
+ }))
147
+
148
+ # Parse and return the response
149
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
150
+
151
+ end
152
+
55
153
  end
56
154
  end
57
155
  end
@@ -50,6 +50,175 @@ module Freelancer
50
50
  !eligibility.nil? && eligibility.eligible?
51
51
  end
52
52
 
53
+ # Post a new project
54
+ def new_project(project)
55
+
56
+ params = new_project_params(project)
57
+
58
+ # Execute the service call
59
+ result = api_get("/Employer/postNewProject.json", params)
60
+
61
+ # Parse and return the response
62
+ ::Freelancer::Models::Project.parse(result, :shift => :"json-result")
63
+
64
+ end
65
+
66
+ # Post a new project draft
67
+ def new_project_draft(project)
68
+
69
+ params = new_project_params(project)
70
+
71
+ # Execute the service call
72
+ result = api_get("/Employer/postNewDraftProject.json", params)
73
+
74
+ # Parse and return the response
75
+ ::Freelancer::Models::Project.parse(result, :shift => :"json-result")
76
+
77
+ end
78
+
79
+ # Post a new trial project
80
+ def new_trial_project(project)
81
+
82
+ params = new_project_params(project)
83
+
84
+ # Execute the service call
85
+ result = api_get("/Employer/postNewTrialProject.json", params)
86
+
87
+ # Parse and return the response
88
+ ::Freelancer::Models::Project.parse(result, :shift => :"json-result")
89
+
90
+ end
91
+
92
+ # Update a project
93
+ def update_project(project)
94
+
95
+ params = {}
96
+ params[:projectid] = project.id
97
+ params[:projectdesc] = project.short_description
98
+ params[:jobtypecsv] = project.jobs.join(",")
99
+
100
+ # Execute the service call
101
+ result = api_get("/Employer/updateProjectDetails.json", params)
102
+
103
+ # Parse and return the response
104
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
105
+
106
+ end
107
+
108
+ # Upgrade a trial project to a normal project
109
+ #
110
+ # Valid parameters are:
111
+ # - project_id: the id of the project to ugprade
112
+ def upgrade_trial_project(*args)
113
+
114
+ params = extract_params(args)
115
+
116
+ # Execute the service call
117
+ result = api_get("/Employer/upgradeTrialProject.json", build_api_params({
118
+ :projectid => params[:project_id]
119
+ }))
120
+
121
+ # Parse and return the response
122
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
123
+
124
+ end
125
+
126
+ # Delete a draft project
127
+ #
128
+ # Valid parameters are:
129
+ # - project_id: the id of the project to delete
130
+ def delete_draft_project(*args)
131
+
132
+ params = extract_params(args)
133
+
134
+ # Execute the service call
135
+ result = api_get("/Employer/deleteDraftProject.json", build_api_params({
136
+ :projectid => params[:project_id]
137
+ }))
138
+
139
+ # Parse and return the response
140
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
141
+
142
+ end
143
+
144
+ # Choose one or more winners for a project
145
+ #
146
+ # Valid parameters are:
147
+ # - project_id: the id of the project to choose a winner for
148
+ # - user_id: a single user id, or an array of user ids, to be made winners of the project
149
+ def choose_winner_for_project(*args)
150
+
151
+ params = extract_params(args)
152
+
153
+ # Handle the user id attribute, make sure it's an array and not set to nil to
154
+ # simplify the handling below.
155
+ params[:user_id] ||= []
156
+ params[:user_id] = [ params[:user_id] ] unless params[:user_id].is_a?(Array)
157
+
158
+ # Execute the service call
159
+ result = api_get("/Employer/chooseWinnerForProject.json", build_api_params({
160
+ :projectid => params[:project_id],
161
+ :useridcsv => params[:user_id].join(",")
162
+ }))
163
+
164
+ # Parse and return the response
165
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
166
+
167
+ end
168
+
169
+ # Invite one or more users to bid on a project
170
+ #
171
+ # Valid parameters are:
172
+ # - project_id: the id of the project to invite users to
173
+ # - user_id: a single user id, or an array of user ids, to invite to the project
174
+ # - username: a single username, or an array of usernames, to invite to the project
175
+ def invite_user_to_project(*args)
176
+
177
+ params = extract_params(args)
178
+
179
+ # Handle the username and user id attributes, make sure they're an array and not
180
+ # set to nil to simplify the handling below.
181
+ params[:user_id] ||= []
182
+ params[:user_id] = [ params[:user_id] ] unless params[:user_id].is_a?(Array)
183
+ params[:username] ||= []
184
+ params[:username] = [ params[:username] ] unless params[:username].is_a?(Array)
185
+
186
+ # Execute the service call
187
+ result = api_get("/Employer/inviteUserForProject.json", build_api_params({
188
+ :projectid => params[:project_id],
189
+ :useridcsv => params[:user_id].join(","),
190
+ :usernamecsv => params[:username].join(",")
191
+ }))
192
+
193
+ # Parse and return the response
194
+ ::Freelancer::Models::StatusConfirmation.parse(result, :shift => :"json-result")
195
+
196
+ end
197
+
198
+ private
199
+
200
+ def new_project_params(project)
201
+
202
+ params = {}
203
+
204
+ params[:projectname] = project.name
205
+ params[:projectdesc] = project.short_description
206
+ params[:jobtypecsv] = project.jobs.join(",")
207
+ params[:budgetoption] = project.budget_option
208
+ if project.budget_option == 0
209
+ params[:budget] = "#{project.minimum_budget}-#{project.maximum_budget}"
210
+ end
211
+ params[:duration] = project.duration
212
+
213
+ params[:isfeatured] = 1 if project.options.featured?
214
+ params[:isnonpublic] = 1 if project.options.non_public?
215
+ params[:isbidhidden] = 1 if project.options.hidden_bids?
216
+ params[:isfulltime] = 1 if project.options.full_time?
217
+
218
+ params
219
+
220
+ end
221
+
53
222
  end
54
223
  end
55
224
  end