freelancer4r 1.0.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/CHANGELOG +6 -0
- data/LICENSE.txt +1 -0
- data/README.rdoc +50 -0
- data/Rakefile.rb +35 -0
- data/lib/freelancer.rb +75 -0
- data/lib/freelancer/api.rb +30 -0
- data/lib/freelancer/authentication.rb +104 -0
- data/lib/freelancer/common.rb +120 -0
- data/lib/freelancer/core.rb +26 -0
- data/lib/freelancer/employer.rb +122 -0
- data/lib/freelancer/freelancer.rb +82 -0
- data/lib/freelancer/job.rb +10 -0
- data/lib/freelancer/message.rb +70 -0
- data/lib/freelancer/notification.rb +17 -0
- data/lib/freelancer/payment.rb +153 -0
- data/lib/freelancer/profile.rb +83 -0
- data/lib/freelancer/project.rb +97 -0
- data/lib/freelancer/user.rb +65 -0
- data/lib/freelancer/util.rb +35 -0
- data/lib/freelancer/widget.rb +176 -0
- metadata +136 -0
data/CHANGELOG
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Copyright (c) 2010 Janos Haber
|
data/README.rdoc
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
== Introduction
|
2
|
+
Freelancer API for ruby
|
3
|
+
|
4
|
+
This api allow to call freelancer api from ruby code.
|
5
|
+
|
6
|
+
It's can login to freelancer with "mechanize", using oauth library
|
7
|
+
|
8
|
+
== Installation
|
9
|
+
|
10
|
+
gem install freelancer4r
|
11
|
+
|
12
|
+
== Usage
|
13
|
+
|
14
|
+
* Shortest way, to login
|
15
|
+
|
16
|
+
freelancer=Freelancer.new false,"application_token","application_secret","username","password"
|
17
|
+
projects=freelancer.searchProjects
|
18
|
+
|
19
|
+
* Custom one step login
|
20
|
+
|
21
|
+
freelancer=Freelancer.new false
|
22
|
+
freelancer.application_token=token
|
23
|
+
freelancer.application_secret=secret
|
24
|
+
freelancer.username=username
|
25
|
+
freelancer.password=password
|
26
|
+
|
27
|
+
freelancer.login
|
28
|
+
freelancer.searchprojects
|
29
|
+
|
30
|
+
* Hand staged login
|
31
|
+
(no username and password)
|
32
|
+
|
33
|
+
freelancer=Freelancer.new false,"application_token","application_secret"
|
34
|
+
freelancer.login_stage1
|
35
|
+
authorize_url=freelancer.login_stage2
|
36
|
+
#.... wait for user login and get the verifier key from user...
|
37
|
+
freelancer.login_stage3
|
38
|
+
freelancer.searchProjects
|
39
|
+
|
40
|
+
* Usage for webpages with callback
|
41
|
+
(no username and password)
|
42
|
+
|
43
|
+
freelancer=Freelancer.new false,"application_token","application_secret"
|
44
|
+
freelancer.callback="http://example.com/callbackurl"
|
45
|
+
freelancer.login_stage1
|
46
|
+
authorize_url=freelancer.login_stage2
|
47
|
+
#... redirect user to authorize url ...
|
48
|
+
#... user come back to callback page ...
|
49
|
+
freelancer.login_stage3
|
50
|
+
freelancer.serchProjects
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'lib/freelancer'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
desc 'generate API documentation to doc/rdocs/index.html'
|
6
|
+
|
7
|
+
spec=Gem::Specification.new do |s|
|
8
|
+
s.name = 'freelancer4r'
|
9
|
+
s.version = Freelancer::VERSION
|
10
|
+
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
s.summary = 'Freelancer API for ruby'
|
13
|
+
s.description = 'Freelancer API for ruby. More informaito about freelancer api see http://developer.freelancer.com'
|
14
|
+
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
|
17
|
+
s.files = ['README.rdoc', 'Rakefile.rb', 'LICENSE.txt']
|
18
|
+
s.files += ['lib/freelancer.rb'] + Dir['lib/freelancer/**/*.rb']
|
19
|
+
|
20
|
+
s.has_rdoc = true
|
21
|
+
s.rdoc_options = ['--main', 'README.rdoc', '--inline-source']
|
22
|
+
s.extra_rdoc_files = ['README.rdoc','CHANGELOG']
|
23
|
+
|
24
|
+
s.authors = ['Janos Haber']
|
25
|
+
s.email = 'freelancer4r@googlegroups.com'
|
26
|
+
s.homepage = 'http://github.com/b0c1/freelancer4r'
|
27
|
+
|
28
|
+
s.add_dependency(%q<json>, [">= 1.4.0"])
|
29
|
+
s.add_dependency(%q<oauth>, [">= 0.4.1"])
|
30
|
+
s.add_dependency(%q<mechanize>, [">= 1.0.0"])
|
31
|
+
end
|
32
|
+
|
33
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
34
|
+
pkg.need_tar = true
|
35
|
+
end
|
data/lib/freelancer.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
require 'freelancer/core'
|
4
|
+
require 'freelancer/authentication'
|
5
|
+
require 'freelancer/util'
|
6
|
+
require 'freelancer/api'
|
7
|
+
require 'freelancer/common'
|
8
|
+
require 'freelancer/employer'
|
9
|
+
require 'freelancer/freelancer'
|
10
|
+
require 'freelancer/job'
|
11
|
+
require 'freelancer/message'
|
12
|
+
require 'freelancer/notification'
|
13
|
+
require 'freelancer/profile'
|
14
|
+
require 'freelancer/project'
|
15
|
+
require 'freelancer/user'
|
16
|
+
require 'freelancer/widget'
|
17
|
+
require 'net/http'
|
18
|
+
|
19
|
+
#Freelancer for Ruby
|
20
|
+
#
|
21
|
+
#Load all Freelancer modules
|
22
|
+
module Freelancer
|
23
|
+
VERSION = "1.0.0"
|
24
|
+
#Initialize the Freelancer Wrapper Class
|
25
|
+
#
|
26
|
+
#Parameters
|
27
|
+
#
|
28
|
+
#<b>sandbox</b> true if we are using freelancer sandbox, default: false
|
29
|
+
#<b>username</b> the username for the automatic authorization, default: nil
|
30
|
+
#<b>password</b> the password for the automatic authorization, default: nil
|
31
|
+
#<b>application token</b> the application token from freelancer
|
32
|
+
#<b>application secret</b> the application secret from freelancer
|
33
|
+
def self.new sandbox=false,application_token=nil,application_secret=nil,username=nil,password=nil
|
34
|
+
freelancer=Freelancer.new
|
35
|
+
freelancer.sandbox=sandbox
|
36
|
+
freelancer.application_token||=application_token
|
37
|
+
freelancer.application_secret||=application_secret
|
38
|
+
freelancer.callback||=OAuth::OUT_OF_BAND
|
39
|
+
freelancer.username||=username
|
40
|
+
freelancer.password||=password
|
41
|
+
if ENV['http_proxy'] != nil
|
42
|
+
freelancer.proxy||=URI.parse(ENV['http_proxy'])
|
43
|
+
end
|
44
|
+
freelancer
|
45
|
+
end
|
46
|
+
|
47
|
+
class Freelancer
|
48
|
+
include Core
|
49
|
+
include Api
|
50
|
+
include Auth
|
51
|
+
include Util
|
52
|
+
|
53
|
+
include Common
|
54
|
+
include Employer
|
55
|
+
include FreelancersCall
|
56
|
+
include Job
|
57
|
+
include Message
|
58
|
+
include Notification
|
59
|
+
include Profile
|
60
|
+
include Project
|
61
|
+
include User
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.new_widget sandbox=false
|
65
|
+
widget=FreelancerWidget.new
|
66
|
+
widget.sandbox=sandbox
|
67
|
+
widget
|
68
|
+
end
|
69
|
+
|
70
|
+
class FreelancerWidget
|
71
|
+
include Core
|
72
|
+
include Util
|
73
|
+
include Widget
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module Freelancer
|
6
|
+
#= Freelancer API module
|
7
|
+
#== required for using freelancer api calls
|
8
|
+
module Api
|
9
|
+
#Method to call request
|
10
|
+
#
|
11
|
+
#If you not logged in, try to log in.
|
12
|
+
def request path, parameters={}
|
13
|
+
parameters||={}
|
14
|
+
params=parameters.map do |k,v|
|
15
|
+
if v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
16
|
+
v = v ? "1" : "0"
|
17
|
+
end
|
18
|
+
"#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
|
19
|
+
end.join("&")
|
20
|
+
if @request_token == nil
|
21
|
+
login
|
22
|
+
end
|
23
|
+
if @access_token == nil
|
24
|
+
login_stage3
|
25
|
+
end
|
26
|
+
result=@access_token.post(path,params)
|
27
|
+
JSON.parse(result.body)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
#Freelancer Authentication Module
|
5
|
+
#
|
6
|
+
#Author:: Janos Haber <boci.boci@gmail.com>
|
7
|
+
#Copyright:: Copyright (c) 2010 Javaportal.hu
|
8
|
+
#License::
|
9
|
+
#
|
10
|
+
#The class automatically detect environment http_proxy variable
|
11
|
+
#If you need to modify the proxy manual, set the instance.proxy to the proxy
|
12
|
+
#example:
|
13
|
+
#freelancer_auth.proxy='http://username:password@proxyhost:proxyport'
|
14
|
+
module Freelancer
|
15
|
+
module Auth
|
16
|
+
|
17
|
+
attr_accessor :application_token, :application_secret, :callback
|
18
|
+
attr_accessor :username,:password, :verifier, :authorized
|
19
|
+
attr_reader :request_token, :access_token
|
20
|
+
#Login stage one
|
21
|
+
#
|
22
|
+
#Request the token from freelancer
|
23
|
+
def login_stage1
|
24
|
+
@consumer=OAuth::Consumer.new( @application_token, @application_secret, {
|
25
|
+
:site=>api_url,
|
26
|
+
:scheme=>:query_string,
|
27
|
+
:http_method=>:get,
|
28
|
+
:request_token_path=>"/RequestRequestToken/requestRequestToken.json",
|
29
|
+
:access_token_path=>"/RequestAccessToken/requestAccessToken.json",
|
30
|
+
:authorize_url=>"#{web_url}/users/api-token/auth.php",
|
31
|
+
:callback=>@callback,
|
32
|
+
:proxy=>proxy
|
33
|
+
})
|
34
|
+
@request_token=@consumer.get_request_token
|
35
|
+
end
|
36
|
+
|
37
|
+
#Login stage two
|
38
|
+
#
|
39
|
+
#If username and password present and the login_stage1 completed
|
40
|
+
#try to login in freelancer website and authorize the application
|
41
|
+
#And set the oauth verifier number
|
42
|
+
def login_stage2
|
43
|
+
if @request_token == nil
|
44
|
+
login_stage1
|
45
|
+
end
|
46
|
+
if @username != nil && @password != nil && @callback == OAuth::OUT_OF_BAND
|
47
|
+
try_to_authorize
|
48
|
+
login_stage3
|
49
|
+
else
|
50
|
+
@request_token.authorize_url
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#Login stage three
|
55
|
+
#
|
56
|
+
#Set the access token require login stage 1 and stage 2 (authorized user)
|
57
|
+
def login_stage3
|
58
|
+
result=@consumer.token_request @consumer.http_method, "/RequestAccessToken/getRequestTokenVerifier.json",@request_token
|
59
|
+
@verifier=result[:verifier]
|
60
|
+
@access_token=@request_token.get_access_token({:oauth_verifier=>@verifier})
|
61
|
+
end
|
62
|
+
|
63
|
+
#One step login method
|
64
|
+
#
|
65
|
+
#If you set the username, password it's try to authorize the request
|
66
|
+
#If the verifier not set (bad username/password or username/password not set)
|
67
|
+
#it's return the authorize url (need manual set the verifier number)
|
68
|
+
def login
|
69
|
+
login_stage1 #login stage 1, request unauthorized token
|
70
|
+
login_stage2 #login stage 2, try to log in ang get the verifier
|
71
|
+
if @authorized
|
72
|
+
login_stage3 #if we have verifier, we get the access token key
|
73
|
+
else #if we not have verifier, authentication or not oob callback selected, request manual login, return the url
|
74
|
+
return @request_token.authorize_url
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
#Try to emulate user authorization
|
81
|
+
def try_to_authorize
|
82
|
+
require 'mechanize'
|
83
|
+
@agent ||= Mechanize.new
|
84
|
+
@agent.user_agent_alias='Mac Safari'
|
85
|
+
|
86
|
+
@agent.set_proxy(proxy.host, proxy.port, proxy.user,proxy.password) if proxy != nil
|
87
|
+
page = @agent.get(web_url)
|
88
|
+
login_form=page.form_with(:name=>'login_form')
|
89
|
+
if login_form != nil
|
90
|
+
login_form.field_with(:name=>'username').value=@username
|
91
|
+
login_form.field_with(:name=>'passwd').value=@password
|
92
|
+
@agent.submit(login_form)
|
93
|
+
end
|
94
|
+
initial_page=@agent.get(@request_token.authorize_url)
|
95
|
+
initial_page.forms.each do |form|
|
96
|
+
if form.has_field? 'oauth_token'
|
97
|
+
result=form.submit
|
98
|
+
return
|
99
|
+
end
|
100
|
+
end
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Freelancer
|
2
|
+
module Common
|
3
|
+
#Submit a request to cancel a project
|
4
|
+
#
|
5
|
+
#http://developer.freelancer.com/RequestCancelProject
|
6
|
+
#
|
7
|
+
#<b>Required:</b>
|
8
|
+
#:projectid
|
9
|
+
#:commenttext
|
10
|
+
#:reasoncancellation
|
11
|
+
# 1 - Mutual – Default
|
12
|
+
# 2 - Service Done,Not Paid
|
13
|
+
# 3 - Service Not Done.
|
14
|
+
# 4 - No Communication
|
15
|
+
# 5 - Quality of Service
|
16
|
+
# 6 - Other
|
17
|
+
#
|
18
|
+
#<b>Optional:</b>
|
19
|
+
#:followedguidelinesstatus
|
20
|
+
# 1 - I followed
|
21
|
+
# 0 - I didn't follow
|
22
|
+
# (This is option is not needed unless felt necessary)
|
23
|
+
def requestCancelProject *args
|
24
|
+
options=fill_args [
|
25
|
+
:projectid,
|
26
|
+
:commenttext,
|
27
|
+
:reasoncancellation,
|
28
|
+
:followedguidelinesstatus
|
29
|
+
],[
|
30
|
+
:projectid,
|
31
|
+
:commenttext,
|
32
|
+
:reasoncancellation
|
33
|
+
],*args
|
34
|
+
request "/Common/requestCancelProject.json", options
|
35
|
+
end
|
36
|
+
|
37
|
+
#Post a feedback for a user
|
38
|
+
#
|
39
|
+
#http://developer.freelancer.com/PostFeedback
|
40
|
+
#
|
41
|
+
#<b>Required:</b>
|
42
|
+
#:rating => 1 to 10
|
43
|
+
#:feedbacktext => Text of feedback
|
44
|
+
#:userid => UserId or username the feedback posted to
|
45
|
+
#:username => UserId or username the feedback posted to
|
46
|
+
#:projectid => Project Id associated with the feedback
|
47
|
+
def postFeedback *args
|
48
|
+
options=fill_args [
|
49
|
+
:rating,:feedbacktext,:userid,:username,:projectid
|
50
|
+
],[
|
51
|
+
:rating,:feedbacktext,:projectid
|
52
|
+
],*args
|
53
|
+
|
54
|
+
if options[:username]==nil && options[:userid]==nil
|
55
|
+
raise "Username or userid is required"
|
56
|
+
end
|
57
|
+
if options[:username]!=nil && options[:userid]!=nil
|
58
|
+
raise "Both username and userid is not allowed"
|
59
|
+
end
|
60
|
+
request "/Common/postFeedback.json", options
|
61
|
+
end
|
62
|
+
|
63
|
+
#Post a comment in reply to a feedback given to you by another user.
|
64
|
+
#
|
65
|
+
#http://developer.freelancer.com/PostReplyForFeedback
|
66
|
+
#
|
67
|
+
#<b>Required:</b>
|
68
|
+
#:feedbacktext => Text of the feedback
|
69
|
+
#:userid => UserId or username the reply posted to
|
70
|
+
#:username => UserId or username the reply posted to
|
71
|
+
#:projectid => Project Id associated with the feedback
|
72
|
+
def postReplyForFeedback *args
|
73
|
+
options=fill_args [
|
74
|
+
:feedbacktext,:userid,:username,:projectid
|
75
|
+
],[
|
76
|
+
:feedbacktext,:projectid
|
77
|
+
],*args
|
78
|
+
if options[:username]==nil && options[:userid]==nil
|
79
|
+
raise "Username or userid is required"
|
80
|
+
end
|
81
|
+
if options[:username]!=nil && options[:userid]!=nil
|
82
|
+
raise "Both username and userid is not allowed"
|
83
|
+
end
|
84
|
+
request "/Common/postReplyForFeedback.json", options
|
85
|
+
end
|
86
|
+
|
87
|
+
#Submit a request to withdraw a feedback posted by another user on a finished project
|
88
|
+
#
|
89
|
+
#http://developer.freelancer.com/RequestWithdrawFeedback
|
90
|
+
#
|
91
|
+
#<b>Required:</b>
|
92
|
+
#:userid => UserId or username the reply posted to
|
93
|
+
#:username => UserId or username the reply posted to
|
94
|
+
#:projectid => Project Id associated with the feedback
|
95
|
+
def requestWithdrawFeedback *args
|
96
|
+
options=fill_args [:userid,:username,:projectid],[:projectid],*args
|
97
|
+
if options[:username]==nil && options[:userid]==nil
|
98
|
+
raise "Username or userid is required"
|
99
|
+
end
|
100
|
+
if options[:username]!=nil && options[:userid]!=nil
|
101
|
+
raise "Both username and userid is not allowed"
|
102
|
+
end
|
103
|
+
request "/Common/requestWithdrawFeedback.json", options
|
104
|
+
end
|
105
|
+
|
106
|
+
#Get the list of projects that can be rated
|
107
|
+
#
|
108
|
+
#http://developer.freelancer.com/GetPendingFeedback
|
109
|
+
#
|
110
|
+
#<b>Optional:</b>
|
111
|
+
#:type
|
112
|
+
# P - Provider
|
113
|
+
# B - Buyer,Default
|
114
|
+
def getPendingFeedback *args
|
115
|
+
options=fill_args [:type],[],*args
|
116
|
+
request "/Common/getPendingFeedback.json", options
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Freelancer
|
2
|
+
module Core
|
3
|
+
attr_accessor :sandbox
|
4
|
+
|
5
|
+
public
|
6
|
+
#Get the proxy settings
|
7
|
+
def proxy
|
8
|
+
@proxy
|
9
|
+
end
|
10
|
+
|
11
|
+
#Set the proxy settings, you can use URI or String
|
12
|
+
def proxy=value
|
13
|
+
@proxy=value.is_a?(URI) ? value:URI.parse(value)
|
14
|
+
end
|
15
|
+
|
16
|
+
#return the used web url
|
17
|
+
def web_url
|
18
|
+
@sandbox ? "http://www.sandbox.freelancer.com":"http://www.freelancer.com"
|
19
|
+
end
|
20
|
+
|
21
|
+
#return the used api url
|
22
|
+
def api_url
|
23
|
+
@sandbox ? "http://api.sandbox.freelancer.com":"http://api.freelancer.com"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|