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