squash_matrix 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7f3c73a85e406636213cedf77e71fbce5d4c76c7
4
- data.tar.gz: 24f57ca32dcb19c25d4effa0b248279770c42ea5
2
+ SHA256:
3
+ metadata.gz: 88789ae3eee0e457e795db28cc4243a48567d325e9e89e206bad10fb35db0bab
4
+ data.tar.gz: 9164726d86ae99d833080ecacf7c0ce0ddb948af81cd29ad985a99790741bcaa
5
5
  SHA512:
6
- metadata.gz: 24be0f0f3c6cbd4df937c61861a0990666a16812ee84bfbd51564db31bbaa28f4daa0cc8b60edf935a85a680e39adc04642298ec6162dd547cc31fcf60692b65
7
- data.tar.gz: 73dd1e9747fb354bdc84344099c6a87bbe7b23f27222a7768b89b0a72629616fae6b150a9fde531f55438d7b74fa49d84b14fc050ef7b87ce8b8b12599182c4d
6
+ metadata.gz: 1c6699aaa0333a24a262f53990e2dabe0a4058e990b7a386f4c5e6ed2dd7a749582afb24fc38cb15775349342bf8b62e1255985f7904a25080dc0bab5843d27b
7
+ data.tar.gz: '09153a6dc3e3ff96f0afaa4ff6ae522caff6af637f6871cda0724997481bbb8a9dc8f09fbae76ef66846af302e36c7a058c099895206aa1c9024b3d99b546238'
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
  **/*.gem
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ # Rubocop
13
+ **/*.rubocop.yml
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- squash_matrix (0.1.1)
4
+ squash_matrix (1.0.0)
5
5
  http-cookie (~> 1.0, >= 1.0.3)
6
6
  nokogiri (~> 1.8, >= 1.8.4)
7
7
  user-agent-randomizer (~> 0.2)
@@ -54,4 +54,4 @@ DEPENDENCIES
54
54
  squash_matrix!
55
55
 
56
56
  BUNDLED WITH
57
- 1.16.2
57
+ 1.16.4
data/README.md CHANGED
@@ -21,9 +21,9 @@ Or install it yourself as:
21
21
  ## Usage
22
22
 
23
23
  ```ruby
24
- client = SquashMatrix::Client.new # initialize client
24
+ client = SquashMatrix::Client.new(player: 42547, password: "foo")# initialize client
25
25
  => SquashMatrix::Client
26
- client.player_info(42547) # retrieve player results for joshua wilkosz #42547
26
+ client.get_player_info(42547) # retrieve player info for joshua wilkosz #42547
27
27
  => {
28
28
  :rating=>"250.202",
29
29
  :clubs=>[
@@ -39,7 +39,7 @@ client.player_info(42547) # retrieve player results for joshua wilkosz #42547
39
39
  }
40
40
  ]
41
41
  }
42
- client.player_results(42547) # retrieve player results for joshua wilkosz #42547
42
+ client.get_player_results(42547) # retrieve player results for joshua wilkosz #42547
43
43
  => [
44
44
  {
45
45
  :event=>"2017 Melbourne Autumn State Open Pennant",
@@ -57,7 +57,7 @@ client.player_results(42547) # retrieve player results for joshua wilkosz #42547
57
57
  :match_id=>1003302
58
58
  }
59
59
  ]
60
- client.club_info(336) # retrieve club info for melbourne university #336
60
+ client.get_club_info(336) # retrieve club info for melbourne university #336
61
61
  => {
62
62
  :name=>"Melbourne University Squash Club",
63
63
  :players=>[
@@ -77,7 +77,7 @@ client.club_info(336) # retrieve club info for melbourne university #336
77
77
  }
78
78
  ]
79
79
  }
80
- client.search("joshua") # search for 'joshua'
80
+ client.get_search_results("joshua") # search results for 'joshua'
81
81
  => {
82
82
  :players=>[
83
83
  {
@@ -97,7 +97,7 @@ client.search("joshua") # search for 'joshua'
97
97
  ],
98
98
  :clubs=>[]
99
99
  }
100
- client.search("melbourne") # search for 'melbourne'
100
+ client.get_search_results("melbourne") # search results for 'melbourne'
101
101
  => {
102
102
  :players=>[
103
103
  {
@@ -123,7 +123,20 @@ client.search("melbourne") # search for 'melbourne'
123
123
  }
124
124
  ]
125
125
  }
126
+ # saving authentication state or using multiple clients
127
+ p = client.get_save_params
128
+ p => {
129
+ :player=>42547,
130
+ :password=>"Foo",
131
+ :suppress_errors=>false,
132
+ :user_agent=>"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101213 Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01",
133
+ :cookie=>".ASPXAUTH=CDA48BC54FCEB4F164D6AC464EFB3414866040FF085915F32BA18EFD5CF995DC59889B5E2124567CBE1B53DE66D6318E6510C5B884EAB5216457092AC079999C3E63BDDA45C94CCA1CD82E485A30D698BA426F4AA9C94301125966DB5D05FD4D; ASP.NET_SessionId=tx02u3xp51js1s3mgwwxhgq1; GroupId=0",
134
+ :expires=>"2018-08-25 17:05:04 UTC"
135
+ }
136
+ replica_client = SquashMatrix::Client.new(p)
137
+ => SquashMatrix::Client
126
138
  ```
139
+ *Note: in previous example `client` and `replica_client` authentication will expire at `2018-08-25 17:05:04 UTC` and make separate calls for re-authentication and thereafter will have separate instance states*
127
140
 
128
141
  ## Development
129
142
 
@@ -135,7 +148,7 @@ To run tests, run `bundle exec rspec`
135
148
 
136
149
  ## Contributing
137
150
 
138
- Bug reports and pull requests are welcome on GitHub at https://github.com/wilkosz/squash_matrix. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
151
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/wilkosz/squash_matrix>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
139
152
 
140
153
  ## License
141
154
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'date'
3
5
  require 'timeout'
@@ -8,30 +10,57 @@ require_relative 'nokogiri-parser'
8
10
  require_relative 'errors'
9
11
 
10
12
  module SquashMatrix
11
-
12
13
  # Client for retrieving player and club information from squashmatrix.com.
13
14
  # If authentication credentials are provided squash matrix will allow
14
15
  # considerably more requests for an IP address and allow forbidden conent
15
16
  # to be requested.
16
17
 
17
18
  class Client
19
+ # Returns params to create existing authenticated client
20
+ # @return [Hash]
21
+
22
+ def get_save_params
23
+ {
24
+ player: @player,
25
+ email: @email,
26
+ password: @password,
27
+ suppress_errors: @suppress_errors,
28
+ timeout: @timeout,
29
+ user_agent: @user_agent,
30
+ cookie: get_cookie_string,
31
+ expires: @expires.to_s
32
+ }.delete_if { |_k, v| v.nil? }
33
+ end
18
34
 
19
35
  # Returns newly created Client
20
36
  # @note If suppress_errors == false SquashMatrix::Errors::AuthorizationError will be raised if specified credentials are incorrect and squash matrix authentication returns forbidden
21
37
  # @param [Hash] opts the options to create client
22
38
  # @return [Client]
23
39
 
24
- def initialize(player: nil, email: nil, password: nil, suppress_errors: false, timeout: 60)
25
- @user_agent = UserAgentRandomizer::UserAgent.fetch(type: "desktop_browser").string
26
- @squash_matrix_home_uri = URI::HTTP.build({ host: SquashMatrix::Constants::SQUASH_MATRIX_URL })
40
+ def initialize(player: nil,
41
+ email: nil,
42
+ password: nil,
43
+ suppress_errors: false,
44
+ timeout: 60,
45
+ user_agent: nil,
46
+ cookie: nil,
47
+ expires: nil)
48
+ @user_agent = user_agent || UserAgentRandomizer::UserAgent.fetch(type: 'desktop_browser').string
49
+ @squash_matrix_home_uri = URI::HTTP.build(host: SquashMatrix::Constants::SQUASH_MATRIX_URL)
27
50
  @suppress_errors = suppress_errors
28
51
  @timeout = timeout
29
- if ![player || email, password].any?(&:nil?)
30
- @cookie_jar = HTTP::CookieJar.new()
31
- @player = player
32
- @email = email
33
- @password = password
34
- authenticate
52
+ return unless [player || email, password].none?(&:nil?)
53
+ @cookie_jar = HTTP::CookieJar.new
54
+ @player = player
55
+ @email = email
56
+ @password = password
57
+ @expires = expires && Time.parse(expires).utc
58
+ if cookie && @expires > Time.now.utc
59
+ cookie.split('; ').each do |v|
60
+ @cookie_jar.parse(v, @squash_matrix_home_uri)
61
+ end
62
+ else
63
+ setup_authentication
35
64
  end
36
65
  end
37
66
 
@@ -40,13 +69,15 @@ module SquashMatrix
40
69
  # @param id [Fixnum] club id found on squash matrix
41
70
  # @return [Hash] hash object containing club information
42
71
 
43
- def club_info(id=nil)
72
+ def get_club_info(id = nil)
44
73
  return if id.nil?
45
- uri = URI::HTTP.build({
74
+ uri = URI::HTTP.build(
46
75
  host: SquashMatrix::Constants::SQUASH_MATRIX_URL,
47
76
  path: SquashMatrix::Constants::CLUB_PATH.gsub(':id', id.to_s)
48
- })
49
- success_proc = lambda {|res| SquashMatrix::NokogiriParser.club_info(res.body)}
77
+ )
78
+ success_proc = lambda do |res|
79
+ SquashMatrix::NokogiriParser.get_club_info(res.body)
80
+ end
50
81
  handle_http_request(uri, success_proc)
51
82
  end
52
83
 
@@ -55,14 +86,16 @@ module SquashMatrix
55
86
  # @param id [Fixnum] played id found on squash matrix
56
87
  # @return [Array<Hash>] Array of player match results
57
88
 
58
- def player_results(id=nil)
89
+ def get_player_results(id = nil)
59
90
  return if id.nil?
60
- uri = URI::HTTP.build({
91
+ uri = URI::HTTP.build(
61
92
  host: SquashMatrix::Constants::SQUASH_MATRIX_URL,
62
93
  path: SquashMatrix::Constants::PLAYER_RESULTS_PATH.gsub(':id', id.to_s),
63
94
  query: SquashMatrix::Constants::PLAYER_RSULTS_QUERY
64
- })
65
- success_proc = lambda {|res| SquashMatrix::NokogiriParser.player_results(res.body)}
95
+ )
96
+ success_proc = lambda do |res|
97
+ SquashMatrix::NokogiriParser.get_player_results(res.body)
98
+ end
66
99
  handle_http_request(uri, success_proc)
67
100
  end
68
101
 
@@ -71,124 +104,149 @@ module SquashMatrix
71
104
  # @param id [Fixnum] played id found on squash matrix
72
105
  # @return [Hash] hash object containing player information
73
106
 
74
- def player_info(id=nil)
107
+ def get_player_info(id = nil)
75
108
  return if id.nil?
76
- uri = URI::HTTP.build({
109
+ uri = URI::HTTP.build(
77
110
  host: SquashMatrix::Constants::SQUASH_MATRIX_URL,
78
111
  path: SquashMatrix::Constants::PLAYER_HOME_PATH.gsub(':id', id.to_s)
79
- })
80
- success_proc = lambda {|res| SquashMatrix::NokogiriParser.player_info(res.body)}
112
+ )
113
+ success_proc = lambda do |res|
114
+ SquashMatrix::NokogiriParser.get_player_info(res.body)
115
+ end
81
116
  handle_http_request(uri, success_proc)
82
117
  end
83
118
 
84
- # Returns search results
119
+ # Returns get_search_results results
85
120
  # @note If suppress_errors == false SquashMatrix Errors will be raised upon HttpNotFound, HttpConflict, Timeout::Error, etc...
86
- # @param query [String] search query
87
- # @return [Hash] hash object containing search results
88
-
89
- def search(query=nil, squash_only: false, racquetball_only: false)
90
- return if query.nil? || query.empty?
91
- uri = URI::HTTP.build({
121
+ # @param query [String] get_search_results query
122
+ # @return [Hash] hash object containing get_search_results results
123
+
124
+ def get_search_results(query = nil,
125
+ squash_only: false,
126
+ racquetball_only: false)
127
+ return if query.blank?
128
+ uri = URI::HTTP.build(
92
129
  host: SquashMatrix::Constants::SQUASH_MATRIX_URL,
93
- path: SquashMatrix::Constants::SEARCH_PATH})
130
+ path: SquashMatrix::Constants::SEARCH_RESULTS_PATH
131
+ )
94
132
  query_params = {
95
133
  Criteria: query,
96
134
  SquashOnly: squash_only,
97
- RacquetballOnly: racquetball_only}
98
- success_proc = lambda {|res| SquashMatrix::NokogiriParser.search_results(res.body)}
135
+ RacquetballOnly: racquetball_only
136
+ }
137
+ success_proc = lambda do |res|
138
+ SquashMatrix::NokogiriParser.get_search_results(res.body)
139
+ end
99
140
  handle_http_request(uri, success_proc,
100
- {
101
- is_get_request: false,
102
- query_params: query_params
103
- })
141
+ is_get_request: false,
142
+ query_params: query_params)
104
143
  end
105
144
 
106
145
  private
107
146
 
108
- def handle_http_request(uri, success_proc, is_get_request: true, query_params: nil, headers: nil)
109
- begin
110
- Timeout.timeout(@timeout) do
111
- if is_get_request
112
- req = Net::HTTP::Get.new(uri)
113
- set_headers(req, headers: headers)
114
- else
115
- req = Net::HTTP::Post.new(uri)
116
- set_headers(req)
117
- form_data = []
118
- query_params.each {|key, value| form_data.push([key.to_s, value.to_s])}
119
- set_headers(req, headers: headers)
120
- req.set_form(form_data, SquashMatrix::Constants::MULTIPART_FORM_DATA)
147
+ def check_authentication
148
+ return unless @expires && @cookie_jar && @expires <= Time.now.utc
149
+ @cookie_jar = HTTP::CookieJar.new
150
+ setup_authentication && sleep(5)
151
+ end
152
+
153
+ def handle_http_request(uri, success_proc,
154
+ is_get_request: true,
155
+ query_params: nil,
156
+ headers: nil,
157
+ is_authentication_request: false)
158
+ Timeout.timeout(@timeout) do
159
+ check_authentication unless is_authentication_request
160
+ if is_get_request
161
+ req = Net::HTTP::Get.new(uri)
162
+ set_headers(req, headers: headers)
163
+ else
164
+ req = Net::HTTP::Post.new(uri)
165
+ set_headers(req)
166
+ form_data = []
167
+ query_params.each do |key, value|
168
+ form_data.push([key.to_s, value.to_s])
121
169
  end
122
- res = Net::HTTP.start(uri.hostname, uri.port, {use_ssl: uri.scheme == 'https'}) {|http| http.request(req)}
123
- case res
124
- when Net::HTTPSuccess, Net::HTTPFound
125
- return success_proc && success_proc.call(res) || res
126
- when Net::HTTPConflict
127
- unless @suppress_errors
128
- raise SquashMatrix::Errors::ForbiddenError.new(res.body) if SquashMatrix::Constants::FORBIDDEN_ERROR_REGEX.match(res.body)
129
- raise SquashMatrix::Errors::TooManyRequestsError.new(res.body) if SquashMatrix::Constants::TOO_MANY_REQUESTS_ERROR_REGEX.match(res.body)
130
- end
131
- else
132
- raise SquashMatrix::Errors::UnknownError.new(res) unless @suppress_errors
170
+ set_headers(req, headers: headers)
171
+ req.set_form(form_data, SquashMatrix::Constants::MULTIPART_FORM_DATA)
172
+ end
173
+ res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
174
+ case res
175
+ when Net::HTTPSuccess, Net::HTTPFound
176
+ return success_proc&.call(res) || res
177
+ when Net::HTTPConflict
178
+ unless @suppress_errors
179
+ raise SquashMatrix::Errors::ForbiddenError, res.body if SquashMatrix::Constants::FORBIDDEN_ERROR_REGEX.match(res.body)
180
+ raise SquashMatrix::Errors::TooManyRequestsError, res.body if SquashMatrix::Constants::TOO_MANY_REQUESTS_ERROR_REGEX.match(res.body)
133
181
  end
182
+ else
183
+ raise SquashMatrix::Errors::UnknownError, res unless @suppress_errors
134
184
  end
135
- rescue Timeout::Error => e
136
- raise e unless @suppress_errors
137
185
  end
186
+ rescue Timeout::Error => e
187
+ raise e unless @suppress_errors
138
188
  end
139
189
 
140
- def authenticate
141
- uri = URI::HTTPS.build({
190
+ def setup_authentication
191
+ uri = URI::HTTPS.build(
142
192
  host: SquashMatrix::Constants::SQUASH_MATRIX_URL,
143
- path: SquashMatrix::Constants::LOGIN_PATH})
193
+ path: SquashMatrix::Constants::LOGIN_PATH
194
+ )
144
195
  query_params = {
145
196
  UserName: @player&.to_s || @email,
146
197
  Password: @password,
147
- RememberMe: false
198
+ RememberMe: true
148
199
  }
149
200
  headers = {
150
201
  SquashMatrix::Constants::CONTENT_TYPE_HEADER => SquashMatrix::Constants::MULTIPART_FORM_DATA
151
202
  }
152
203
  # need to retrieve the asp.net session id
153
- home_page_res = handle_http_request(@squash_matrix_home_uri, nil)
154
- raise SquashMatrix::Errors::AuthorizationError.new(SquashMatrix::Constants::ERROR_RETRIEVING_ASPNET_SESSION) unless home_page_res
204
+ home_page_res = handle_http_request(@squash_matrix_home_uri,
205
+ nil,
206
+ is_authentication_request: true)
207
+ raise SquashMatrix::Errors::AuthorizationError, SquashMatrix::Constants::ERROR_RETRIEVING_ASPNET_SESSION unless home_page_res
155
208
  home_page_res[SquashMatrix::Constants::SET_COOKIE_HEADER].split('; ').each do |v|
156
209
  @cookie_jar.parse(v, @squash_matrix_home_uri)
157
210
  end
158
211
  res = handle_http_request(uri, nil,
159
- {
160
- is_get_request: false,
161
- query_params: query_params,
162
- headers: headers
163
- })
164
- raise SquashMatrix::Errors::AuthorizationError.new(SquashMatrix::Constants::ERROR_RETRIEVING_ASPAUX_TOKEN) unless res
165
- res[SquashMatrix::Constants::SET_COOKIE_HEADER].split('; ').each do |v|
212
+ is_get_request: false,
213
+ query_params: query_params,
214
+ headers: headers,
215
+ is_authentication_request: true)
216
+ raise SquashMatrix::Errors::AuthorizationError, SquashMatrix::Constants::ERROR_RETRIEVING_ASPAUX_TOKEN unless res
217
+ res[SquashMatrix::Constants::SET_COOKIE_HEADER]&.split('; ')&.each do |v|
218
+ parts = SquashMatrix::Constants::EXPIRES_FROM_COOKIE_REGEX.match(v)
219
+ @expires = Time.parse(parts[1]).utc if parts
166
220
  @cookie_jar.parse(v, @squash_matrix_home_uri)
167
221
  end
168
- @player = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(res[SquashMatrix::Constants::LOCATION_HEADER])[1] if @player.nil? && res[SquashMatrix::Constants::LOCATION_HEADER]
169
- unless !@suppress_errors && @cookie_jar.cookies(@squash_matrix_home_uri).find {|c| c.name == SquashMatrix::Constants::ASPXAUTH_COOKIE_NAME && !c.value.empty?}
170
- error_string = SquashMatrix::NokogiriParser.log_on_error(res.body).join(', ')
171
- raise SquashMatrix::Errors::AuthorizationError.new(error_string)
172
- end
222
+ @expires ||= Time.now.utc + 60 * 60 * 24 * 2 # default expires in two days (usually 52 hours)
223
+ @player = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(res[SquashMatrix::Constants::LOCATION_HEADER])[1] if @player.nil? && !res[SquashMatrix::Constants::LOCATION_HEADER].empty?
224
+ return unless !@suppress_errors && !@cookie_jar&.cookies(@squash_matrix_home_uri)&.find { |c| c.name == SquashMatrix::Constants::ASPXAUTH_COOKIE_NAME && !c.value.empty? }
225
+ error_string = SquashMatrix::NokogiriParser.get_log_on_error(res.body).join(', ')
226
+ raise SquashMatrix::Errors::AuthorizationError, error_string
173
227
  end
174
228
 
175
- def set_headers(req=nil, headers: nil)
229
+ def set_headers(req = nil, headers: nil)
176
230
  return unless req
177
231
  headers_to_add = {
178
232
  SquashMatrix::Constants::USER_AGENT_HEADER => @user_agent,
179
- SquashMatrix::Constants::HOST_HEADER => SquashMatrix::Constants::SQUASH_MATRIX_URL}
233
+ SquashMatrix::Constants::HOST_HEADER => SquashMatrix::Constants::SQUASH_MATRIX_URL
234
+ }
180
235
  headers_to_add = headers_to_add.merge(headers) if headers
181
- if @cookie_jar
182
- cookies = @cookie_jar.cookies(@squash_matrix_home_uri).select do |c|
183
- [
184
- SquashMatrix::Constants::ASP_NET_SESSION_ID_COOKIE_NAME,
185
- SquashMatrix::Constants::GROUP_ID_COOKIE_NAME,
186
- SquashMatrix::Constants::ASPXAUTH_COOKIE_NAME
187
- ].include?(c.name)
188
- end
189
- headers_to_add = headers_to_add.merge({SquashMatrix::Constants::COOKIE_HEADER => HTTP::Cookie.cookie_value(cookies)})
236
+ headers_to_add = headers_to_add.merge(SquashMatrix::Constants::COOKIE_HEADER => get_cookie_string) if @cookie_jar
237
+ headers_to_add.each { |key, val| req[key.to_s] = val }
238
+ end
239
+
240
+ def get_cookie_string
241
+ return unless @cookie_jar
242
+ cookies = @cookie_jar.cookies(@squash_matrix_home_uri).select do |c|
243
+ [
244
+ SquashMatrix::Constants::ASP_NET_SESSION_ID_COOKIE_NAME,
245
+ SquashMatrix::Constants::GROUP_ID_COOKIE_NAME,
246
+ SquashMatrix::Constants::ASPXAUTH_COOKIE_NAME
247
+ ].include?(c.name)
190
248
  end
191
- headers_to_add.each {|key, val| req[key.to_s] = val}
249
+ HTTP::Cookie.cookie_value(cookies)
192
250
  end
193
251
  end
194
252
  end
@@ -1,34 +1,37 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module SquashMatrix
3
4
  module Constants
4
- SQUASH_MATRIX_URL = "www.squashmatrix.com"
5
- LOGIN_PATH = "/Account/LogOn"
6
- PLAYER_RESULTS_PATH = "/Home/PlayerResults/:id"
7
- PLAYER_HOME_PATH = "/Home/Player/:id"
8
- CLUB_PATH = "/Home/Club/:id"
9
- SEARCH_PATH = "/Home/Search"
10
- PLAYER_RSULTS_QUERY = "max=0&X-Requested-With=XMLHttpRequest"
5
+ SQUASH_MATRIX_URL = 'www.squashmatrix.com'
6
+ LOGIN_PATH = '/Account/LogOn'
7
+ PLAYER_RESULTS_PATH = '/Home/PlayerResults/:id'
8
+ PLAYER_HOME_PATH = '/Home/Player/:id'
9
+ CLUB_PATH = '/Home/Club/:id'
10
+ SEARCH_RESULTS_PATH = '/Home/get_search_results'
11
+ PLAYER_RSULTS_QUERY = 'max=0&X-Requested-With=XMLHttpRequest'
11
12
  SET_COOKIE_HEADER = 'set-cookie'
12
13
  COOKIE_HEADER = 'cookie'
13
14
  LOCATION_HEADER = 'location'
14
15
  X_WWW__FROM_URL_ENCODED = 'application/x-www-form-urlencoded'
15
16
  MULTIPART_FORM_DATA = 'multipart/form-data'
16
17
  CONTENT_TYPE_HEADER = 'content-type'
17
- REFERER = "Home/Player/:id"
18
- ASPXAUTH_COOKIE_NAME = ".ASPXAUTH"
19
- ASP_NET_SESSION_ID_COOKIE_NAME = "ASP.NET_SessionId"
20
- GROUP_ID_COOKIE_NAME = "GroupId"
18
+ REFERER = 'Home/Player/:id'
19
+ ASPXAUTH_COOKIE_NAME = '.ASPXAUTH'
20
+ ASP_NET_SESSION_ID_COOKIE_NAME = 'ASP.NET_SessionId'
21
+ GROUP_ID_COOKIE_NAME = 'GroupId'
21
22
  HOST_HEADER = 'host'
22
23
  USER_AGENT_HEADER = 'user-agent'
24
+ EXPIRES_COOKIE_NAME = 'expires'
23
25
 
24
26
  PLAYER_FROM_PATH_REGEX = /\/Home\/Player\/(.*)/
25
27
  TEAM_FROM_PATH_REGEX = /\/Home\/Team\/(.*)/
26
28
  CLUB_FROM_PATH_REGEX = /\/Home\/Club\/(.*)/
27
29
  MATCH_FROM_PATH_REGEX = /\/Home\/Match\/(.*)/
28
30
  CLUB_FROM_TITLE_REGEX = /Club - (.*)/
31
+ EXPIRES_FROM_COOKIE_REGEX = /expires=(.*)/
29
32
 
30
- ERROR_RETRIEVING_ASPNET_SESSION = "Error retrieving ASP.NET_SessionId"
31
- ERROR_RETRIEVING_ASPAUX_TOKEN = "Error retrieving .ASPXAUTH_TOKEN"
33
+ ERROR_RETRIEVING_ASPNET_SESSION = 'Error retrieving ASP.NET_SessionId'
34
+ ERROR_RETRIEVING_ASPAUX_TOKEN = 'Error retrieving .ASPXAUTH_TOKEN'
32
35
 
33
36
  TOO_MANY_REQUESTS_ERROR_REGEX = /Request made too soon. This is to prevent abuse to the site. We apologise for the inconvenience/
34
37
  FORBIDDEN_ERROR_REGEX = /Forbidden/
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SquashMatrix
2
4
  module Errors
3
5
  class TooManyRequestsError < StandardError; end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
  require_relative 'constants'
3
5
 
4
6
  module SquashMatrix
5
7
  class NokogiriParser
6
8
  class << self
7
- def player_rsults(body)
8
- Nokogiri::HTML(body)&.xpath('//table[@id="results"]//tbody//tr')&.map do |r|
9
+ def get_player_rsults(body)
10
+ rtn = Nokogiri::HTML(body)&.xpath('//table[@id="results"]//tbody//tr')&.map do |r|
9
11
  date = r.at_css('td[1]')&.content
10
12
  opponent_id = r.at_css('td[10]//a')&.attribute('href')&.content
11
13
  match_id = r.at_css('td[12]//a')&.attribute('href')&.content
@@ -25,10 +27,11 @@ module SquashMatrix
25
27
  rtn[:opponent_id] = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(opponent_id)[1].to_i if opponent_id
26
28
  rtn[:match_id] = SquashMatrix::Constants::MATCH_FROM_PATH_REGEX.match(match_id)[1].to_i if match_id
27
29
  rtn.values.any?(&:nil?) ? nil : rtn
28
- end.compact
30
+ end
31
+ rtn.compact
29
32
  end
30
33
 
31
- def player_info(body)
34
+ def get_player_info(body)
32
35
  rows = Nokogiri::HTML(body)&.xpath('//table[@id="profile"]//tbody//tr')
33
36
  rating = rows[1]&.css('td[2]')&.text
34
37
  clubs = rows[2]&.css('td[2]')&.css('ul//li')&.map do |c|
@@ -54,7 +57,7 @@ module SquashMatrix
54
57
  }
55
58
  end
56
59
 
57
- def club_info(body)
60
+ def get_club_info(body)
58
61
  html = Nokogiri::HTML(body)
59
62
  name = SquashMatrix::Constants::CLUB_FROM_TITLE_REGEX.match(html.css('title').text)[1]
60
63
  players = html.xpath('//div[@id="Rankings"]//div[@class="columnmain"]//table[@class="alternaterows"]//tbody//tr')&.map do |r|
@@ -67,7 +70,7 @@ module SquashMatrix
67
70
  rtn[:rank] = rank.to_i if rank
68
71
  rtn[:id] = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(player_path)[1].to_i if player_path
69
72
  rtn
70
- end.compact
73
+ end
71
74
  juniors = html.xpath('//div[@id="Rankings"]//div[@class="columnside"]//table[@class="alternaterows"]//tbody//tr')&.map do |r|
72
75
  player_path = r.css('td[2]//a').attribute('href').value
73
76
  rank = r.css('td[1]').text
@@ -78,40 +81,40 @@ module SquashMatrix
78
81
  rtn[:rank] = rank.to_i if rank
79
82
  rtn[:id] = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(player_path)[1].to_i if player_path
80
83
  rtn
81
- end.compact
84
+ end
82
85
  {
83
86
  name: name,
84
- players: players,
85
- juniors: juniors
87
+ players: players.compact,
88
+ juniors: juniors.compact
86
89
  }
87
90
  end
88
91
 
89
- def search_results(body)
92
+ def get_search_results(body)
90
93
  bc = Nokogiri::HTML.parse(body).at_xpath('//div[@id="bodycontent"]')&.children
91
94
  return unless bc&.length
92
95
  rtn = {}
93
96
  bc&.each_with_index do |c, i|
94
- if c.name == "h2"
97
+ if c.name == 'h2'
95
98
  case c.text
96
- when "Players"
97
- rtn[:players] = players_from_search(bc[i+2]) if bc[i+2].children.length
98
- when "Teams"
99
- rtn[:teams] = teams_from_search(bc[i+2]) if bc[i+2].children.length
100
- when "Clubs"
101
- rtn[:clubs] = clubs_from_search(bc[i+2]) if bc[i+2].children.length
99
+ when 'Players'
100
+ rtn[:players] = get_players_from_search_results(bc[i + 2]) if bc[i + 2].children.length
101
+ when 'Teams'
102
+ rtn[:teams] = get_teams_from_search_results(bc[i + 2]) if bc[i + 2].children.length
103
+ when 'Clubs'
104
+ rtn[:clubs] = get_clubs_from_search_results(bc[i + 2]) if bc[i + 2].children.length
102
105
  end
103
106
  end
104
107
  end
105
108
  rtn
106
109
  end
107
110
 
108
- def log_on_error(body)
111
+ def get_log_on_error(body)
109
112
  Nokogiri::HTML(body)&.xpath('//div[@class="validation-summary-errors"]//ul//li')&.map(&:content)
110
113
  end
111
114
 
112
115
  private
113
116
 
114
- def players_from_search(node)
117
+ def get_players_from_search_results(node)
115
118
  node.css('tbody//tr')&.map do |tr|
116
119
  id = tr.css('td[1]//a')&.attribute('href')&.value
117
120
  rating = tr.css('td[3]')&.text
@@ -119,13 +122,13 @@ module SquashMatrix
119
122
  name: tr.css('td[1]')&.text,
120
123
  club_name: tr.css('td[2]')&.text
121
124
  }
122
- rtn[:id] = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(id)[1].to_i if id && !id.empty?
125
+ rtn[:id] = SquashMatrix::Constants::PLAYER_FROM_PATH_REGEX.match(id)[1].to_i if id.present?
123
126
  rtn[:rating] = rating.to_f if rating
124
127
  rtn
125
128
  end
126
129
  end
127
130
 
128
- def teams_from_search(node)
131
+ def get_teams_from_search_results(node)
129
132
  node.css('tbody//tr')&.map do |tr|
130
133
  id = tr.css('td[1]//a')&.attribute('href')&.value
131
134
  rtn = {
@@ -138,7 +141,7 @@ module SquashMatrix
138
141
  end
139
142
  end
140
143
 
141
- def clubs_from_search(node)
144
+ def get_clubs_from_search_results(node)
142
145
  node.css('tbody//tr')&.map do |tr|
143
146
  id = tr.css('td[1]//a')&.attribute('href')&.value
144
147
  rtn = {
@@ -149,10 +152,6 @@ module SquashMatrix
149
152
  rtn
150
153
  end
151
154
  end
152
-
153
- def requests_made_to_soon?(body)
154
- Nokogiri::HTML(body)&.xpath('//body')
155
- end
156
155
  end
157
156
  end
158
157
  end
@@ -1,3 +1,3 @@
1
1
  module SquashMatrix
2
- VERSION = "0.1.2"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squash_matrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Wilkosz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-17 00:00:00.000000000 Z
11
+ date: 2018-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
166
  version: '0'
167
167
  requirements: []
168
168
  rubyforge_project:
169
- rubygems_version: 2.6.12
169
+ rubygems_version: 2.7.7
170
170
  signing_key:
171
171
  specification_version: 4
172
172
  summary: Ruby SDK for www.squashmatrix.com