freelancer4r 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,6 @@
1
+ == Freelancer4r 1.0.1 (2010.07.15)
2
+ * Added widget api for call http://www.freelancer.com/affiliate-api.html API
3
+ * First public release
4
+
5
+ == Freelancer4r 1.0.0 (2010.07.13)
6
+ * First release to Freelancer API
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