rockauto_api 0.1.1 → 0.2.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 +4 -4
- data/README.md +380 -0
- data/lib/rockauto_api/client.rb +41 -13
- data/lib/rockauto_api/endpoints/account.rb +45 -10
- data/lib/rockauto_api/endpoints/part_categories.rb +9 -16
- data/lib/rockauto_api/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d861f195fe9c02dc5737f5756f0c3e7248ddad192a380913dd9e95a65d327b8
|
|
4
|
+
data.tar.gz: 93ef1dddb194b74a1d091039460b3586466f1e225bba2289b0da43cfe5253e02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4606e5e6fe6ea4b7301722ddaba983dfab6de91c47ea8510054898b1d95f292b44c4adf2e98ce5bd44bca10d8dc2f7c86b539df7f888863b0b86e821f809d91
|
|
7
|
+
data.tar.gz: 0d6ec3fdb8ba7f234e91dbfcbd31b504d44dc53b10ab3c1d3610e28a63dd3c4f983a79b077f3312c3922f1e3c824fb6c1688aeebf7e1c404c8716482e38ba7d0
|
data/README.md
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# RockautoApi
|
|
2
|
+
|
|
3
|
+
An unofficial Ruby API client for [RockAuto.com](https://www.rockauto.com). Browse vehicle catalogs, search parts by number, look up fitments, check order status, and manage your RockAuto account.
|
|
4
|
+
|
|
5
|
+
**Disclaimer:** This gem is for **educational and research purposes only**. It is not affiliated with, endorsed by, or officially connected to RockAuto LLC. Automated scraping of RockAuto.com may violate their Terms of Service. Use responsibly and respect rate limits.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add to your Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem "rockauto_api"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
bundle install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or install directly:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
gem install rockauto_api
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
require "rockauto_api"
|
|
35
|
+
|
|
36
|
+
client = RockautoApi::Client.new
|
|
37
|
+
|
|
38
|
+
# Browse what RockAuto sells
|
|
39
|
+
makes = client.get_makes
|
|
40
|
+
makes.makes #=> ["ACURA", "AUDI", "BMW", ...]
|
|
41
|
+
|
|
42
|
+
years = client.get_years_for_make("AUDI")
|
|
43
|
+
years.years #=> [1980, 1981, ..., 2026]
|
|
44
|
+
|
|
45
|
+
models = client.get_models_for_make_year("AUDI", 2019)
|
|
46
|
+
models.models #=> ["A4", "A5", "A6", "A7", ...]
|
|
47
|
+
|
|
48
|
+
engines = client.get_engines_for_vehicle("AUDI", 2019, "A4")
|
|
49
|
+
engines.engines #=> [Engine(description: "2.0L L4 Turbocharged", carcode: "3443561"), ...]
|
|
50
|
+
|
|
51
|
+
# Get part categories for a vehicle
|
|
52
|
+
categories = client.get_part_categories("AUDI", 2019, "A4", "3443561")
|
|
53
|
+
categories.categories #=> [PartCategory(name: "Belt Drive"), ...]
|
|
54
|
+
|
|
55
|
+
# Get parts in a category
|
|
56
|
+
parts = client.get_parts_by_category("AUDI", 2019, "A4", "3443561", "Belt Drive")
|
|
57
|
+
parts.parts #=> [PartInfo, ...]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## All Endpoints
|
|
63
|
+
|
|
64
|
+
### Vehicle Catalog
|
|
65
|
+
|
|
66
|
+
Browse the vehicle catalog to find makes, years, models, and engines.
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
# List all makes
|
|
70
|
+
makes = client.get_makes
|
|
71
|
+
makes.makes #=> ["ACURA", "AUDI", "BMW", ...]
|
|
72
|
+
makes.count #=> Integer
|
|
73
|
+
|
|
74
|
+
# List years for a make
|
|
75
|
+
years = client.get_years_for_make("ACURA")
|
|
76
|
+
years.make #=> "ACURA"
|
|
77
|
+
years.years #=> [1986, 1987, ..., 2026]
|
|
78
|
+
years.count #=> Integer
|
|
79
|
+
|
|
80
|
+
# List models for a make and year
|
|
81
|
+
models = client.get_models_for_make_year("ACURA", 2020)
|
|
82
|
+
models.make #=> "ACURA"
|
|
83
|
+
models.year #=> 2020
|
|
84
|
+
models.models #=> ["MDX", "TLX", ...]
|
|
85
|
+
models.count #=> Integer
|
|
86
|
+
|
|
87
|
+
# List engines for a specific vehicle
|
|
88
|
+
engines = client.get_engines_for_vehicle("ACURA", 2020, "MDX")
|
|
89
|
+
engines.make #=> "ACURA"
|
|
90
|
+
engines.year #=> 2020
|
|
91
|
+
engines.model #=> "MDX"
|
|
92
|
+
engines.engines #=> [Engine(description, carcode, href), ...]
|
|
93
|
+
engines.count #=> Integer
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Part Categories
|
|
97
|
+
|
|
98
|
+
Get the part categories available for a specific vehicle, and parts within a category.
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
# Get all part categories for a vehicle
|
|
102
|
+
categories = client.get_part_categories("ACURA", 2020, "MDX", "3444459")
|
|
103
|
+
categories.make #=> "ACURA"
|
|
104
|
+
categories.year #=> 2020
|
|
105
|
+
categories.model #=> "MDX"
|
|
106
|
+
categories.carcode #=> "3444459"
|
|
107
|
+
categories.categories #=> [PartCategory(name, group_name, href), ...]
|
|
108
|
+
categories.count #=> Integer
|
|
109
|
+
|
|
110
|
+
# Get parts in a category
|
|
111
|
+
parts = client.get_parts_by_category("ACURA", 2020, "MDX", "3444459", "Brake & Wheel Hub")
|
|
112
|
+
parts.make #=> "ACURA"
|
|
113
|
+
parts.year #=> 2020
|
|
114
|
+
parts.model #=> "MDX"
|
|
115
|
+
parts.carcode #=> "3444459"
|
|
116
|
+
parts.category #=> "Brake & Wheel Hub"
|
|
117
|
+
parts.parts #=> [PartInfo, ...]
|
|
118
|
+
parts.count #=> Integer
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Part Search
|
|
122
|
+
|
|
123
|
+
Search for parts by number, name, or browse available manufacturers, groups, and types.
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# Browse available manufacturers (cached for 24 hours)
|
|
127
|
+
manufacturers = client.get_manufacturers
|
|
128
|
+
manufacturers.manufacturers #=> [PartSearchOption(value, text), ...]
|
|
129
|
+
manufacturers.lookup("Bosch") #=> PartSearchOption(value: "128", text: "Bosch")
|
|
130
|
+
|
|
131
|
+
# Browse part groups (cached for 24 hours)
|
|
132
|
+
groups = client.get_part_groups
|
|
133
|
+
groups.part_groups #=> [PartSearchOption(value, text), ...]
|
|
134
|
+
|
|
135
|
+
# Browse part types (cached for 24 hours)
|
|
136
|
+
types = client.get_part_types
|
|
137
|
+
types.part_types #=> [PartSearchOption(value, text), ...]
|
|
138
|
+
|
|
139
|
+
# Search parts by number
|
|
140
|
+
results = client.search_parts_by_number("FG0326")
|
|
141
|
+
results.parts #=> [PartInfo, ...]
|
|
142
|
+
results.count #=> Integer
|
|
143
|
+
results.search_term #=> "FG0326"
|
|
144
|
+
results.manufacturer #=> "All"
|
|
145
|
+
results.part_group #=> "All"
|
|
146
|
+
|
|
147
|
+
# Search with filters
|
|
148
|
+
results = client.search_parts_by_number(
|
|
149
|
+
"FG0326",
|
|
150
|
+
manufacturer: "Bosch",
|
|
151
|
+
part_group: "Brakes",
|
|
152
|
+
part_type: "Pads"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Include fitment data (triggers additional API call per part)
|
|
156
|
+
results = client.search_parts_by_number("FG0326", include_fitments: true)
|
|
157
|
+
results.parts.first.buyers_guide #=> BuyersGuideResult
|
|
158
|
+
|
|
159
|
+
# Look up what a part is called
|
|
160
|
+
results = client.what_is_part_called("brake pad")
|
|
161
|
+
results.results #=> [WhatIsPartCalledResult(main_category, subcategory, full_path), ...]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Fitment / Buyers Guide
|
|
165
|
+
|
|
166
|
+
Get vehicle fitment information for a specific part.
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
fitment = client.get_fitment_for_part(listing_data)
|
|
170
|
+
# listing_data comes from PartInfo#listing_data or can be constructed manually
|
|
171
|
+
fitment.part_number #=> "FG0326"
|
|
172
|
+
fitment.brand #=> "Bosch"
|
|
173
|
+
fitment.fitments #=> [FitmentInfo(year, make, model, engine, ...), ...]
|
|
174
|
+
fitment.count #=> Integer
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Order Status
|
|
178
|
+
|
|
179
|
+
Look up order status and request order lists (no login required).
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
# Look up an order by email and order number
|
|
183
|
+
result = client.lookup_order_status("you@example.com", "RA-123456")
|
|
184
|
+
result.success #=> true/false
|
|
185
|
+
result.order #=> OrderStatus (if found)
|
|
186
|
+
result.error #=> OrderStatusError (if not found)
|
|
187
|
+
|
|
188
|
+
# Order status details
|
|
189
|
+
order = result.order
|
|
190
|
+
order.order_number #=> "RA-123456"
|
|
191
|
+
order.order_date #=> "2024-01-15"
|
|
192
|
+
order.status #=> "Shipped"
|
|
193
|
+
order.items #=> [OrderItem(part_number, description, quantity, ...), ...]
|
|
194
|
+
order.billing #=> BillingInfo(subtotal, shipping_cost, tax, total, ...)
|
|
195
|
+
order.shipping #=> ShippingInfo(method, carrier, tracking_number, ...)
|
|
196
|
+
order.notes #=> String
|
|
197
|
+
order.return_eligibility #=> String
|
|
198
|
+
|
|
199
|
+
# Request RockAuto to email you a list of your orders
|
|
200
|
+
client.request_order_list(:email, "you@example.com") #=> true
|
|
201
|
+
|
|
202
|
+
# Request via SMS
|
|
203
|
+
client.request_order_list(:sms, "+15551234567") #=> true
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Account (Authenticated)
|
|
207
|
+
|
|
208
|
+
Requires logging in with valid RockAuto credentials.
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
# Configure credentials globally
|
|
212
|
+
RockautoApi.configure do |config|
|
|
213
|
+
config.credentials = { email: "you@example.com", password: "your_password" }
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Or pass credentials per-session
|
|
217
|
+
client = RockautoApi::Client.new
|
|
218
|
+
client.login("you@example.com", "your_password")
|
|
219
|
+
|
|
220
|
+
# Check login status
|
|
221
|
+
client.authenticated? #=> true/false
|
|
222
|
+
|
|
223
|
+
# Get saved addresses
|
|
224
|
+
addresses = client.get_saved_addresses
|
|
225
|
+
addresses.addresses #=> [SavedAddress(name, full_name, address_line1, city, state, ...), ...]
|
|
226
|
+
addresses.count #=> Integer
|
|
227
|
+
addresses.has_default #=> true/false
|
|
228
|
+
|
|
229
|
+
# Get saved vehicles
|
|
230
|
+
vehicles = client.get_saved_vehicles
|
|
231
|
+
vehicles.vehicles #=> [SavedVehicle(year, make, model, engine, carcode, ...), ...]
|
|
232
|
+
vehicles.count #=> Integer
|
|
233
|
+
|
|
234
|
+
# Get order history
|
|
235
|
+
history = client.get_order_history
|
|
236
|
+
history.orders #=> [OrderHistoryItem(order_number, date, status, total, vehicle), ...]
|
|
237
|
+
history.count #=> Integer
|
|
238
|
+
history.search_time #=> "2026-06-28T..."
|
|
239
|
+
|
|
240
|
+
# Get full account activity (addresses + vehicles)
|
|
241
|
+
activity = client.get_account_activity
|
|
242
|
+
activity.saved_addresses #=> SavedAddressesResult
|
|
243
|
+
activity.saved_vehicles #=> SavedVehiclesResult
|
|
244
|
+
|
|
245
|
+
# Add an external order to your account
|
|
246
|
+
client.add_external_order("you@example.com", "RA-123456") #=> true
|
|
247
|
+
|
|
248
|
+
# Logout
|
|
249
|
+
client.logout #=> true
|
|
250
|
+
client.authenticated? #=> false
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Tools
|
|
254
|
+
|
|
255
|
+
Browse RockAuto's tool catalog.
|
|
256
|
+
|
|
257
|
+
```ruby
|
|
258
|
+
# Get tool categories
|
|
259
|
+
categories = client.get_tool_categories
|
|
260
|
+
categories.categories #=> [ToolCategory(name, group_name, href, level), ...]
|
|
261
|
+
categories.count #=> Integer
|
|
262
|
+
|
|
263
|
+
# Get tools in a category
|
|
264
|
+
tools = client.get_tools_by_category("/en/tools/?parttype=260")
|
|
265
|
+
tools.tools #=> [ToolInfo(name, part_number, brand, description, ...), ...]
|
|
266
|
+
tools.count #=> Integer
|
|
267
|
+
tools.category #=> "?parttype=260"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Configuration
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
RockautoApi.configure do |config|
|
|
276
|
+
config.default_mobile = true # Use mobile site headers (slimmer HTML)
|
|
277
|
+
config.request_timeout = 30 # HTTP timeout in seconds
|
|
278
|
+
config.credentials = { email: "me@example.com", password: "s3cret" }
|
|
279
|
+
config.cache = Rails.cache # Use Rails cache for 24h/7d TTLs
|
|
280
|
+
end
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Rails Integration
|
|
286
|
+
|
|
287
|
+
The gem includes a Railtie that automatically hooks into `Rails.cache`. No extra setup needed:
|
|
288
|
+
|
|
289
|
+
```ruby
|
|
290
|
+
# Gemfile
|
|
291
|
+
gem "rockauto_api"
|
|
292
|
+
|
|
293
|
+
# config/initializers/rockauto_api.rb
|
|
294
|
+
RockautoApi.configure do |config|
|
|
295
|
+
config.default_mobile = false
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# app/models/part_lookup.rb
|
|
299
|
+
class PartLookup
|
|
300
|
+
def search(query)
|
|
301
|
+
client = RockautoApi::Client.new
|
|
302
|
+
client.search_parts_by_number(query)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Error Handling
|
|
310
|
+
|
|
311
|
+
All errors inherit from `RockautoApi::Error`:
|
|
312
|
+
|
|
313
|
+
| Error Class | When It's Raised |
|
|
314
|
+
|---|---|
|
|
315
|
+
| `RockautoApi::AuthenticationError` | Calling authenticated methods without logging in |
|
|
316
|
+
| `RockautoApi::NetworkError` | HTTP request fails (timeout, connection error) |
|
|
317
|
+
| `RockautoApi::CaptchaError` | RockAuto returns a CAPTCHA challenge |
|
|
318
|
+
| `RockautoApi::ParseError` | Failed to parse HTML response |
|
|
319
|
+
| `RockautoApi::NotFoundError` | Resource not found |
|
|
320
|
+
|
|
321
|
+
Example:
|
|
322
|
+
|
|
323
|
+
```ruby
|
|
324
|
+
begin
|
|
325
|
+
client.get_saved_addresses
|
|
326
|
+
rescue RockautoApi::AuthenticationError => e
|
|
327
|
+
puts "Please login first: #{e.message}"
|
|
328
|
+
rescue RockautoApi::NetworkError => e
|
|
329
|
+
puts "Network issue: #{e.message}"
|
|
330
|
+
end
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Development
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
git clone https://github.com/bendangelo/rockauto_api
|
|
339
|
+
cd rockauto_api
|
|
340
|
+
bin/setup
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Run the test suite:
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
bundle exec rspec
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Tests use [VCR](https://github.com/vcr/vcr) to record and replay HTTP interactions. To re-record cassettes with live data:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
rm -rf spec/cassettes/
|
|
353
|
+
bundle exec rspec
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
New cassettes will be created recording real HTTP requests. Sensitive data (credentials, cookies) is automatically filtered.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Contributing
|
|
361
|
+
|
|
362
|
+
1. Fork the repository
|
|
363
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
364
|
+
3. Commit your changes (`git commit -am "Add my feature"`)
|
|
365
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
366
|
+
5. Open a Pull Request
|
|
367
|
+
|
|
368
|
+
Please include tests for any new functionality and ensure the full suite passes.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## License
|
|
373
|
+
|
|
374
|
+
Apache 2.0. See [LICENSE](LICENSE).
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Disclaimer
|
|
379
|
+
|
|
380
|
+
This software is provided for **educational and research purposes only**. It is not affiliated with, endorsed by, or officially connected to RockAuto LLC. Automated access to RockAuto.com may violate their Terms of Service. Users are solely responsible for ensuring their use complies with all applicable terms and laws. The authors assume no liability for any misuse.
|
data/lib/rockauto_api/client.rb
CHANGED
|
@@ -68,6 +68,7 @@ module RockautoApi
|
|
|
68
68
|
|
|
69
69
|
resp = @conn.get("/")
|
|
70
70
|
@nck_token = Parsers::HtmlHelpers.extract_javascript_variable(resp.body, "_nck")
|
|
71
|
+
@nck_token ||= Parsers::HtmlHelpers.extract_csrf_token(resp.body, "_nck")
|
|
71
72
|
@jnck_token = @nck_token ? CGI.escape(@nck_token) : nil
|
|
72
73
|
@session_initialized = true
|
|
73
74
|
end
|
|
@@ -126,23 +127,50 @@ module RockautoApi
|
|
|
126
127
|
end
|
|
127
128
|
|
|
128
129
|
if make
|
|
129
|
-
payload =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"fetching" => true,
|
|
136
|
-
"max_group_index" => 363,
|
|
137
|
-
"mkt_US" => true,
|
|
138
|
-
"mkt_CA" => false,
|
|
139
|
-
"mkt_MX" => false
|
|
140
|
-
}
|
|
141
|
-
}
|
|
130
|
+
payload = navnode_fetch_payload(
|
|
131
|
+
make: make,
|
|
132
|
+
nodetype: "make",
|
|
133
|
+
label: make,
|
|
134
|
+
href: "#{BASE_URL}/en/catalog/#{make.downcase}"
|
|
135
|
+
)
|
|
142
136
|
call_catalog_api("navnode_fetch", payload)
|
|
143
137
|
end
|
|
144
138
|
end
|
|
145
139
|
|
|
140
|
+
def navnode_fetch_payload(make:, nodetype:, label: nil, href: nil, year: nil, model: nil, carcode: nil)
|
|
141
|
+
jsn = {
|
|
142
|
+
"tab" => "catalog",
|
|
143
|
+
"make" => make,
|
|
144
|
+
"nodetype" => nodetype,
|
|
145
|
+
"jsdata" => {
|
|
146
|
+
"markets" => [
|
|
147
|
+
{"c" => "US", "y" => "Y", "i" => "Y"},
|
|
148
|
+
{"c" => "CA", "y" => "Y", "i" => "Y"},
|
|
149
|
+
{"c" => "MX", "y" => "Y", "i" => "Y"}
|
|
150
|
+
],
|
|
151
|
+
"mktlist" => "US,CA,MX",
|
|
152
|
+
"showForMarkets" => {"US" => true, "CA" => true, "MX" => true},
|
|
153
|
+
"importanceByMarket" => {"US" => "Y", "CA" => "Y", "MX" => "Y"},
|
|
154
|
+
"Show" => 1
|
|
155
|
+
},
|
|
156
|
+
"loaded" => false,
|
|
157
|
+
"expand_after_load" => true,
|
|
158
|
+
"fetching" => true
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
jsn["year"] = year.to_s if year
|
|
162
|
+
jsn["model"] = model if model
|
|
163
|
+
jsn["carcode"] = carcode if carcode
|
|
164
|
+
jsn["label"] = label if label
|
|
165
|
+
jsn["href"] = href if href
|
|
166
|
+
jsn["labelset"] = true if label || href
|
|
167
|
+
jsn["jump_to_after_expand"] = true if nodetype == "make"
|
|
168
|
+
jsn["dont_change_url"] = true if nodetype == "make"
|
|
169
|
+
jsn["has_more_auto_open_steps"] = true if nodetype == "make"
|
|
170
|
+
|
|
171
|
+
{ "jsn" => jsn, "max_group_index" => 388 }
|
|
172
|
+
end
|
|
173
|
+
|
|
146
174
|
def get(path)
|
|
147
175
|
init_session!
|
|
148
176
|
resp = @conn.get(path)
|
|
@@ -8,23 +8,41 @@ module RockautoApi
|
|
|
8
8
|
ORDER_HISTORY_URL = "/en/orderhistory/"
|
|
9
9
|
|
|
10
10
|
def login(email, password)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
init_session!
|
|
12
|
+
|
|
13
|
+
form_data = {
|
|
14
|
+
"loginaction" => "login",
|
|
15
|
+
"accountemail" => email,
|
|
16
|
+
"captchacode" => "",
|
|
17
|
+
"passworddecoy" => "",
|
|
18
|
+
"password" => password,
|
|
19
|
+
"passwordconfirmdecoy" => "",
|
|
20
|
+
"passwordconfirm" => "",
|
|
21
|
+
"keepsignin" => "false",
|
|
22
|
+
"async" => "1",
|
|
23
|
+
"accountlogin_php" => "1"
|
|
17
24
|
}
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
resp = account_api_post(form_data)
|
|
27
|
+
|
|
28
|
+
result = JSON.parse(resp.body)
|
|
29
|
+
@authenticated = result["message"]&.include?("Successful") || false
|
|
21
30
|
@authenticated
|
|
22
|
-
rescue
|
|
31
|
+
rescue StandardError
|
|
23
32
|
@authenticated = false
|
|
24
33
|
end
|
|
25
34
|
|
|
26
35
|
def logout
|
|
27
|
-
|
|
36
|
+
init_session!
|
|
37
|
+
|
|
38
|
+
form_data = {
|
|
39
|
+
"loginaction" => "logout",
|
|
40
|
+
"async" => "1",
|
|
41
|
+
"accountlogin_php" => "1"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
account_api_post(form_data)
|
|
45
|
+
|
|
28
46
|
@authenticated = false
|
|
29
47
|
true
|
|
30
48
|
rescue StandardError
|
|
@@ -154,6 +172,23 @@ module RockautoApi
|
|
|
154
172
|
def require_authentication!
|
|
155
173
|
raise AuthenticationError, "Not authenticated. Call login(email, password) first." unless @authenticated
|
|
156
174
|
end
|
|
175
|
+
|
|
176
|
+
def account_api_post(form_data)
|
|
177
|
+
Faraday.new(url: Client::BASE_URL) do |f|
|
|
178
|
+
f.request :url_encoded
|
|
179
|
+
f.use :cookie_jar
|
|
180
|
+
f.adapter Faraday.default_adapter
|
|
181
|
+
f.options.timeout = RockautoApi.configuration&.request_timeout || 30
|
|
182
|
+
@conn.headers["Cookie"].to_s.split(";").each do |cookie|
|
|
183
|
+
name, val = cookie.strip.split("=", 2)
|
|
184
|
+
f.headers["Cookie"] = "#{f.headers['Cookie']}; #{name}=#{val}" if name && val
|
|
185
|
+
end
|
|
186
|
+
f.headers["User-Agent"] = Client::MOBILE_HEADERS["User-Agent"]
|
|
187
|
+
f.headers["Referer"] = "#{Client::BASE_URL}/"
|
|
188
|
+
f.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
|
|
189
|
+
f.headers["X-Requested-With"] = "XMLHttpRequest"
|
|
190
|
+
end.post("/catalog/catalogapi.php", form_data)
|
|
191
|
+
end
|
|
157
192
|
end
|
|
158
193
|
end
|
|
159
194
|
end
|
|
@@ -4,22 +4,15 @@ module RockautoApi
|
|
|
4
4
|
module Endpoints
|
|
5
5
|
module PartCategories
|
|
6
6
|
def get_part_categories(make, year, model, carcode)
|
|
7
|
-
payload =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"fetching" => true,
|
|
17
|
-
"max_group_index" => 0,
|
|
18
|
-
"mkt_US" => true,
|
|
19
|
-
"mkt_CA" => false,
|
|
20
|
-
"mkt_MX" => false
|
|
21
|
-
}
|
|
22
|
-
}
|
|
7
|
+
payload = navnode_fetch_payload(
|
|
8
|
+
make: make,
|
|
9
|
+
nodetype: "model",
|
|
10
|
+
label: model,
|
|
11
|
+
href: "#{Client::BASE_URL}/en/catalog/#{make.downcase},#{year},#{model.downcase}",
|
|
12
|
+
year: year,
|
|
13
|
+
model: model,
|
|
14
|
+
carcode: carcode
|
|
15
|
+
)
|
|
23
16
|
|
|
24
17
|
response = call_catalog_api("navnode_fetch", payload)
|
|
25
18
|
html = response.dig("html_fill_sections", "navchildren[]") || ""
|
data/lib/rockauto_api/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rockauto_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ben D'Angelo
|
|
@@ -141,6 +141,7 @@ executables: []
|
|
|
141
141
|
extensions: []
|
|
142
142
|
extra_rdoc_files: []
|
|
143
143
|
files:
|
|
144
|
+
- README.md
|
|
144
145
|
- lib/rockauto_api.rb
|
|
145
146
|
- lib/rockauto_api/cache.rb
|
|
146
147
|
- lib/rockauto_api/client.rb
|