squash_matrix 0.1.2 → 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.
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