hawatel_search_jobs 0.1.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.
@@ -0,0 +1,126 @@
1
+ module HawatelSearchJobs
2
+ module Api
3
+ module CareerJet
4
+ class << self
5
+ include HawatelSearchJobs::Helpers::Base
6
+
7
+ DEFAULT = {
8
+ :keywords => '',
9
+ :location => '',
10
+ :company => ''
11
+ }
12
+
13
+ # Search jobs based on specified keywords or location
14
+ #
15
+ # @param args [Hash]
16
+ # @option args :query [Hash] search criteria
17
+ # - *:keywords*​ (String) - keywords for search
18
+ # @option args [Integer] :page page number (default value 0)
19
+ # @option args [String] :query_key option provided by page() method
20
+ #
21
+ # @example
22
+ # search(:settings => HawatelSearchJobs.careerjet,:query => {:keywords => 'ruby'})
23
+ # search(:query_key => 'http://api.../search?locale_code=US_en&sort=date&keywords=ruby', :page => 0)
24
+ #
25
+ # @return [Hash<OpenStruct>]
26
+ def search(args)
27
+ args[:query] = DEFAULT.merge(args[:query]) if args[:query]
28
+ args[:page] = 0 if args[:page].nil?
29
+
30
+ if args[:query_key].to_s.empty?
31
+ url_request = build_url(args)
32
+ else
33
+ url_request = args[:query_key]
34
+ end
35
+
36
+ if url_request
37
+ attributes = Hash.new
38
+ response = send_request(url_request)
39
+ result = JSON(response.body)
40
+ if response.code == '200' && result['type'] == 'ERROR'
41
+ attributes[:code] = 501
42
+ attributes[:msg] = result['error']
43
+ return OpenStruct.new(attributes)
44
+ else
45
+ attributes[:code] = response.code
46
+ attributes[:msg] = response.message
47
+ return OpenStruct.new(attributes) if response.code != '200'
48
+ end
49
+ attributes[:totalResults] = result['hits']
50
+ attributes[:page] = args[:page]
51
+ attributes[:last] = result['pages'] - 1
52
+ attributes[:key] = url_request
53
+ attributes[:jobs] = parse_raw_data(result)
54
+ OpenStruct.new(attributes)
55
+ else
56
+ OpenStruct.new({:code => 501, :msg => 'lack of keywords or api setting'})
57
+ end
58
+ end
59
+
60
+ # Show next page of results
61
+ #
62
+ # @param args [Hash]
63
+ # @option args [Integer] :page specified page number (default 0)
64
+ # @option args [String] :query_key full url from last query
65
+ #
66
+ # @example
67
+ # page({:query_key => result.key, :page => 2}
68
+ #
69
+ # @return [Hash<OpenStrunct>]
70
+ def page(args)
71
+ args[:page] = 0 if args[:page].nil?
72
+ args[:query_key] = args[:query_key].gsub(/&page=.*/, '') << "&page=#{args[:page]+1}"
73
+ return search(args)
74
+ end
75
+
76
+ private
77
+
78
+ # Build query URL
79
+ #
80
+ # @param args [Hash]
81
+ # @option args query [Hash] - search criteria
82
+ # - *:keywords* (String) - keywords for search
83
+ # - *:location* (String) - specified location for search criteria (default: europe)
84
+ # @option settings [Hash]
85
+ # - *:api* (String) - api ip or domainname
86
+ #
87
+ # @example
88
+ # build_url(:query => {:keywords => 'ruby'}, :settings => {:api => 'http://api...'} }
89
+ #
90
+ # @return [String] ready to call URL
91
+ def build_url(args)
92
+ keywords = args[:query][:keywords] if !args[:query][:keywords].to_s.empty?
93
+ api_url = args[:settings][:api] if !args[:settings][:api].to_s.empty?
94
+ if keywords && api_url
95
+ !args[:query][:location].to_s.empty? ? location = args[:query][:location] : location = 'europe'
96
+ "http://#{api_url}/search?locale_code=US_en&pagesize=25&sort=date&keywords=#{keywords}&location=#{location}&page=1"
97
+ end
98
+ end
99
+
100
+
101
+ # Build jobs array with specified attributes
102
+ #
103
+ # @param result [Hash]
104
+ # @option result [Hash] :jobs jobs hash array return from API
105
+ #
106
+ # @return [Array<OpenStruct>]
107
+ def parse_raw_data(result)
108
+ jobs = Array.new
109
+ return jobs if result['jobs'].to_s.empty?
110
+ result['jobs'].each do |offer|
111
+ job = Hash.new
112
+ job[:jobtitle] = offer['title']
113
+ job[:location] = offer['locations']
114
+ job[:company] = offer['company']
115
+ job[:date] = convert_date_to_format(offer['date'],'%d/%m/%y')
116
+ job[:url] = offer['url']
117
+ job = convert_empty_to_nil(job)
118
+ jobs << OpenStruct.new(job)
119
+ end
120
+ return jobs
121
+ end
122
+
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,158 @@
1
+ require 'ostruct'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module HawatelSearchJobs
6
+ module Api
7
+ module Indeed
8
+ class << self
9
+ include HawatelSearchJobs::Helpers::Base
10
+
11
+ DEFAULT = {
12
+ :keywords => '',
13
+ :location => '',
14
+ :company => ''
15
+ }
16
+
17
+ # Search jobs based on specified keywords or location
18
+ #
19
+ # @param args [Hash]
20
+ # @option args [String] :query_key full url from last query, option deliverd by page() method
21
+ # @option args :query [Hash] search criteria
22
+ # - *:keywords* (String) keywords for search
23
+ # - *:location* (String) specified location for search criteria (default all countries)
24
+ # @option args :settings [Hash]
25
+ # - *:api* (String) hostname or ip address api server
26
+ # - *:publisher* (String) authentication string
27
+ #
28
+ # @example
29
+ # search(:settings => HawatelSearchJobs.indeed,:query => {:keywords => 'ruby'})
30
+ # search(:query_key => 'http://api.../ads/apisearch?publisher=12323&q=ruby')
31
+ #
32
+ # @return [Hash<OpenStruct>]
33
+ def search(args)
34
+ args[:query] = DEFAULT.merge(args[:query]) if args[:query]
35
+ if args[:query_key].to_s.empty?
36
+ url_request = build_url(args)
37
+ else
38
+ url_request = args[:query_key]
39
+ end
40
+
41
+ if url_request
42
+ attributes = Hash.new
43
+ response = send_request(url_request)
44
+ result = JSON(response.body)
45
+ if response.code == '200' && result['error']
46
+ attributes[:code] = 501
47
+ attributes[:msg] = result['error']
48
+ return OpenStruct.new(attributes)
49
+ else
50
+ attributes[:code] = response.code
51
+ attributes[:msg] = response.message
52
+ return OpenStruct.new(attributes) if response.code != '200'
53
+ end
54
+ attributes[:totalResults] = result['totalResults']
55
+ attributes[:page] = result['pageNumber']
56
+ #attributes[:last] = (result['totalResults'] / 25) - 1
57
+ attributes[:last] = paging_info(25, result['totalResults'])
58
+ attributes[:key] = url_request
59
+ attributes[:jobs] = parse_raw_data(result)
60
+ OpenStruct.new(attributes)
61
+ else
62
+ OpenStruct.new({:code => 501, :msg => 'lack of api or publisher setting'})
63
+ end
64
+ end
65
+
66
+ # Show next page of results
67
+ #
68
+ # @param args [Hash]
69
+ # @option args [Integer] :page page number (default 0)
70
+ # @option args [String] :query_key url from last query
71
+ #
72
+ # @example
73
+ # page({:query_key => result.key, :page => 2}
74
+ #
75
+ # @return [Hash<OpenStruct>]
76
+ def page(args)
77
+ args[:page] = 0 if args[:page].nil?
78
+ if args[:query_key]
79
+ url = args[:query_key].gsub(/&start=.*/, '') << "&start=#{args[:page]*25}"
80
+ search({:query_key => url})
81
+ end
82
+ end
83
+
84
+ private
85
+ # Build query URL
86
+ #
87
+ # @param args [Hash]
88
+ # option args :query [Hash]
89
+ # - *:keywords* (String) keywords for search
90
+ # - *:location* (String) search jobs from specified location
91
+ # - *:salary* (String) show only position above specified salary
92
+ # - *:company* (String) find position from specified company
93
+ # @option args :settings [Hash]
94
+ # - *:api* (String) hostname or ip address api server
95
+ # - *:publisher* (String) authentication string
96
+ #
97
+ # @example
98
+ # build_url(:query => {:keywords => 'ruby'}, :settings => {:api => 'http://api...',:publisher => '23234'}}
99
+ #
100
+ # @return [String]
101
+ def build_url(args)
102
+ api_url = args[:settings][:api]
103
+ publisher = args[:settings][:publisher]
104
+ location = args[:query][:location]
105
+ salary = args[:query][:salary]
106
+ company = args[:query][:company]
107
+ keywords = args[:query][:keywords]
108
+
109
+ if !keywords.to_s.empty? && !company.to_s.empty?
110
+ keywords = "company:#{company}+#{keywords}"
111
+ elsif keywords.to_s.empty? && !company.to_s.empty?
112
+ keywords = "company:#{company}"
113
+ end
114
+ if api_url && publisher
115
+ "http://#{api_url}/ads/apisearch?publisher=#{publisher}&q=#{keywords}&salary=#{salary}&l=#{location}"\
116
+ "&v=2&format=json&limit=25&start=0"
117
+ end
118
+ end
119
+
120
+ # Build jobs array with specified attributes
121
+ #
122
+ # @param result [Hash]
123
+ # @option result [Hash] :results job attributes
124
+ #
125
+ # @return [Array<OpenStruct>]
126
+ def parse_raw_data(result)
127
+ jobs = Array.new
128
+ return jobs if result['results'].to_s.empty?
129
+ result['results'].each do |offer|
130
+ job = Hash.new
131
+ job[:jobtitle] = offer['jobtitle'] if offer['jobtitle']
132
+ job[:location] = "#{offer['country']}, #{offer['city']}"
133
+ job[:company] = offer['company']
134
+ job[:date] = convert_date_to_format(offer['date'],'%d/%m/%y')
135
+ job[:url] = offer['url']
136
+ job = convert_empty_to_nil(job)
137
+ jobs << OpenStruct.new(job)
138
+ end
139
+ return jobs
140
+ end
141
+
142
+ def paging_info(limit, total_result)
143
+ return nil if total_result == 0
144
+
145
+ mod = total_result.to_i % limit.to_i
146
+ if mod == 0
147
+ last = (total_result.to_i / limit.to_i) - 1
148
+ else
149
+ last = (total_result.to_i / limit.to_i).to_i
150
+ end
151
+
152
+ last
153
+ end
154
+
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,186 @@
1
+ require 'ostruct'
2
+
3
+ module HawatelSearchJobs
4
+ module Api
5
+ ##
6
+ # = Reed.co.uk API
7
+ #
8
+ # @see https://www.reed.co.uk/developers/Jobseeker
9
+ module Reed
10
+ class << self
11
+ include HawatelSearchJobs::Helpers::Base
12
+
13
+ DEFAULT = {
14
+ :keywords => '',
15
+ :location => '',
16
+ }
17
+
18
+ RESULT_LIMIT = 25
19
+
20
+ # Search jobs by specific criteria
21
+ # @param [Hash] args
22
+ # @option args :settings [Hash] search criteria
23
+ # - *:api* (String) - URL API (default: reed.co.uk/api)
24
+ # - *:version* (String) - a version of API (default: 1.0)
25
+ # - *:clientid* (String) - API Key (see https://www.reed.co.uk/developers/Jobseeker)
26
+ # @option args :query [Hash] settings of API
27
+ # - *:keywors* (String)
28
+ # - *:location* (String)
29
+ # @example
30
+ # jobs = Reed.search({:settings => {
31
+ # :api => 'reed.co.uk/api',
32
+ # :version => '1.0',
33
+ # :clientid => 'secret-code'},
34
+ # :query => {
35
+ # :keywords => 'ruby',
36
+ # :location => 'London'})
37
+ # @return [Hash] First page of the result (see constant RESULT_LIMIT)
38
+ def search(args)
39
+ args[:query] = DEFAULT.merge(args[:query]) if args[:query]
40
+
41
+ if args[:query_key].nil?
42
+ url_request = prepare_conn_string(args) + prepare_query(args)
43
+ else
44
+ url_request = args[:query_key]
45
+ end
46
+
47
+ response = api_request(url_request, args[:settings][:clientid])
48
+ attributes = build_jobs_table(response, url_request)
49
+ OpenStruct.new(attributes)
50
+ end
51
+
52
+ # Get a specific page result
53
+ # At the beging you have to run {search} method and get :key from result and pass it to the argument :query_key
54
+ # @param [Hash] args
55
+ # @option args :settings [Hash] see {search}
56
+ # @option args [Integer] :page page number counted from 0
57
+ # @option args [String] :query_key
58
+ # @example
59
+ # jobs = Careerbuilder.page({:settings => {
60
+ # :api => 'api.careerbuilder.com',
61
+ # :version => 'v2',
62
+ # :clientid => 'secret-code'},
63
+ # :page => 5,
64
+ # :query_key => 'value from :key returned by search method'})
65
+ # @return [Hash] Job offers from specific page
66
+ def page(args)
67
+ page = args[:page].to_i || 0
68
+ if args[:query_key]
69
+ limit = result_limit(args[:query_key])
70
+ url_request = args[:query_key].gsub(/&resultsToSkip=\d+/, '') << "&resultsToSkip=#{page * limit}"
71
+ args[:query_key] = url_request
72
+ search(args)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def build_jobs_table(response, url_request)
79
+ attributes = Hash.new
80
+ attributes[:code] = response.code.to_i
81
+ attributes[:msg] = response.message
82
+
83
+ attributes[:totalResults] = 0
84
+ attributes[:page] = nil
85
+ attributes[:last] = nil
86
+ attributes[:key] = url_request
87
+ attributes[:jobs] = nil
88
+
89
+
90
+ if response.code.to_i == 200
91
+ json_response = JSON.parse(response.body)
92
+ begin
93
+ if !json_response['results'].to_s.empty?
94
+ attributes[:totalResults] = json_response['totalResults'] || 0
95
+
96
+ page_info = paging_info(url_request, attributes[:totalResults])
97
+ attributes[:page] = page_info.page
98
+ attributes[:last] = page_info.last
99
+
100
+ attributes[:key] = url_request
101
+ attributes[:jobs] = parse_raw_data(json_response)
102
+ end
103
+ rescue
104
+ raise "Something wrong with returned data: #{json_response}"
105
+ end
106
+ end
107
+ attributes
108
+ end
109
+
110
+ def api_request(url, clientid = nil)
111
+ opt = Hash.new
112
+
113
+ if clientid
114
+ opt = { :basic_auth => {
115
+ :username => clientid,
116
+ :password => ''
117
+ }}
118
+ end
119
+
120
+ send_request(url, opt)
121
+ end
122
+
123
+ def prepare_query(args)
124
+ "keywords=#{args[:query][:keywords]}&locationName=#{args[:query][:location]}"
125
+ end
126
+
127
+ def prepare_conn_string(args)
128
+ conn_string = "https://#{args[:settings][:api]}/#{args[:settings][:version]}/search?resultsToTake=#{RESULT_LIMIT}&"
129
+ conn_string
130
+ end
131
+
132
+ def parse_raw_data(data)
133
+ jobs = Array.new
134
+ data['results'].each do |offer|
135
+ job = Hash.new
136
+ job[:jobtitle] = offer['jobTitle'] if offer['jobTitle']
137
+ job[:location] = "United Kingdom, #{offer['locationName']}"
138
+ job[:company] = offer['employerName']
139
+ job[:date] = convert_date_to_format(offer['date'],'%d/%m/%y')
140
+ job[:url] = offer['jobUrl']
141
+
142
+ job = convert_empty_to_nil(job)
143
+
144
+ jobs << OpenStruct.new(job)
145
+ end
146
+ jobs
147
+ rescue
148
+ raise "Cannot parse raw data: #{data}"
149
+ end
150
+
151
+ def result_limit(url)
152
+ result = url.match(/\resultsToTake=(\d+)/)
153
+ result ? result[1].to_i : RESULT_LIMIT
154
+ end
155
+
156
+ def result_skip(url)
157
+ result = url.match(/\&resultsToSkip=(\d+)/)
158
+ result ? result[1].to_i : 0
159
+ end
160
+
161
+ def paging_info(url, total_result)
162
+ return OpenStruct.new({:page => nil, :last => nil}) if total_result == 0
163
+
164
+ result_limit = result_limit(url)
165
+ result_skip = result_skip(url)
166
+
167
+ if result_skip == 0 && total_result > 0
168
+ page = 0
169
+ else
170
+ page = (result_skip / result_limit).to_i
171
+ end
172
+
173
+ mod = total_result.to_i % result_limit.to_i
174
+ if mod == 0
175
+ last = (total_result.to_i / result_limit.to_i) - 1
176
+ else
177
+ last = (total_result.to_i / result_limit.to_i).to_i
178
+ end
179
+
180
+ OpenStruct.new({:page => page, :last => last})
181
+ end
182
+
183
+ end
184
+ end
185
+ end
186
+ end