freelancer 0.1.0 → 0.1.1

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/.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