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 +5 -5
- data/.gitignore +2 -0
- data/Gemfile.lock +2 -2
- data/README.md +20 -7
- data/lib/squash_matrix/client.rb +150 -92
- data/lib/squash_matrix/constants.rb +16 -13
- data/lib/squash_matrix/errors.rb +2 -0
- data/lib/squash_matrix/nokogiri-parser.rb +25 -26
- data/lib/squash_matrix/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 88789ae3eee0e457e795db28cc4243a48567d325e9e89e206bad10fb35db0bab
|
4
|
+
data.tar.gz: 9164726d86ae99d833080ecacf7c0ce0ddb948af81cd29ad985a99790741bcaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c6699aaa0333a24a262f53990e2dabe0a4058e990b7a386f4c5e6ed2dd7a749582afb24fc38cb15775349342bf8b62e1255985f7904a25080dc0bab5843d27b
|
7
|
+
data.tar.gz: '09153a6dc3e3ff96f0afaa4ff6ae522caff6af637f6871cda0724997481bbb8a9dc8f09fbae76ef66846af302e36c7a058c099895206aa1c9024b3d99b546238'
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
squash_matrix (0.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
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
|
|
data/lib/squash_matrix/client.rb
CHANGED
@@ -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,
|
25
|
-
|
26
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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]
|
87
|
-
# @return [Hash] hash object containing
|
88
|
-
|
89
|
-
def
|
90
|
-
|
91
|
-
|
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::
|
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
|
-
|
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
|
-
|
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
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
raise SquashMatrix::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
|
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:
|
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,
|
154
|
-
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
@
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
|
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 =
|
5
|
-
LOGIN_PATH =
|
6
|
-
PLAYER_RESULTS_PATH =
|
7
|
-
PLAYER_HOME_PATH =
|
8
|
-
CLUB_PATH =
|
9
|
-
|
10
|
-
PLAYER_RSULTS_QUERY =
|
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 =
|
18
|
-
ASPXAUTH_COOKIE_NAME =
|
19
|
-
ASP_NET_SESSION_ID_COOKIE_NAME =
|
20
|
-
GROUP_ID_COOKIE_NAME =
|
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 =
|
31
|
-
ERROR_RETRIEVING_ASPAUX_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/
|
data/lib/squash_matrix/errors.rb
CHANGED
@@ -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
|
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
|
30
|
+
end
|
31
|
+
rtn.compact
|
29
32
|
end
|
30
33
|
|
31
|
-
def
|
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
|
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
|
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
|
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
|
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 ==
|
97
|
+
if c.name == 'h2'
|
95
98
|
case c.text
|
96
|
-
when
|
97
|
-
rtn[:players] =
|
98
|
-
when
|
99
|
-
rtn[:teams] =
|
100
|
-
when
|
101
|
-
rtn[:clubs] =
|
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
|
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
|
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
|
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
|
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
|
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
|
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.
|
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-
|
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.
|
169
|
+
rubygems_version: 2.7.7
|
170
170
|
signing_key:
|
171
171
|
specification_version: 4
|
172
172
|
summary: Ruby SDK for www.squashmatrix.com
|