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