Copied initial source
This commit is contained in:
commit
3a826e3903
2 changed files with 203 additions and 0 deletions
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "top_drives_db"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[dependencies]
|
||||||
|
scraper = "0.20.0"
|
||||||
|
reqwest = "0.12.7"
|
||||||
|
#ureq = { version = "2.6"}
|
||||||
|
#native-tls = { version = "0.2.12", features = [] }
|
||||||
|
#html_parser = "0.7.0"
|
||||||
|
tokio = { version = "1.40.0", features = ["full"] }
|
||||||
190
src/main.rs
Normal file
190
src/main.rs
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
use scraper::{Html, Selector};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::env;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use tokio;
|
||||||
|
|
||||||
|
struct Car {
|
||||||
|
class: String,
|
||||||
|
rq: u8,
|
||||||
|
manufacturer: String,
|
||||||
|
model: String,
|
||||||
|
year: u16,
|
||||||
|
// upgrade: String,
|
||||||
|
}
|
||||||
|
async fn get_page(url: &str) -> String {
|
||||||
|
match reqwest::Client::builder()
|
||||||
|
.danger_accept_invalid_certs(true)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.get(url)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(response) => match response.text().await {
|
||||||
|
Ok(text) => text,
|
||||||
|
Err(error) => {
|
||||||
|
println!("Error getting content! Error: {}", error);
|
||||||
|
String::from("")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(error) => {
|
||||||
|
println!("Error getting content! Error: {}", error);
|
||||||
|
String::from("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_best_car(text: String) -> Car {
|
||||||
|
let mut car = Car {
|
||||||
|
class: String::from("Z"),
|
||||||
|
rq: 0,
|
||||||
|
manufacturer: String::from(""),
|
||||||
|
model: String::from(""),
|
||||||
|
year: 1900,
|
||||||
|
// upgrade: String::from("000"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let document = Html::parse_document(&text);
|
||||||
|
|
||||||
|
let manufacturer_selector = Selector::parse(".carList__item-manufacturer").unwrap();
|
||||||
|
car.manufacturer = String::from(match document.select(&manufacturer_selector).next() {
|
||||||
|
None => "",
|
||||||
|
Some(manufacturer) => manufacturer.text().collect::<Vec<_>>()[0],
|
||||||
|
});
|
||||||
|
|
||||||
|
let model_selector = Selector::parse(".carList__item-model").unwrap();
|
||||||
|
car.model = String::from(match document.select(&model_selector).next() {
|
||||||
|
None => "",
|
||||||
|
Some(model) => model.text().collect::<Vec<_>>()[0],
|
||||||
|
});
|
||||||
|
|
||||||
|
let year_selector = Selector::parse(".carList__item-year").unwrap();
|
||||||
|
car.year = u16::from_str(match document.select(&year_selector).next() {
|
||||||
|
None => "1900",
|
||||||
|
Some(year) => year.text().collect::<Vec<_>>()[0],
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let level_selector = Selector::parse(".carList__item-level").unwrap();
|
||||||
|
let rq_raw = document
|
||||||
|
.select(&level_selector)
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.inner_html();
|
||||||
|
let rq_fragment = Html::parse_document(rq_raw.trim());
|
||||||
|
|
||||||
|
let span_selector = Selector::parse("span").unwrap();
|
||||||
|
let mut element_iterator = rq_fragment.select(&span_selector);
|
||||||
|
let class = String::from(match element_iterator.next() {
|
||||||
|
None => "Z",
|
||||||
|
Some(class) => class.text().collect::<Vec<_>>()[0],
|
||||||
|
});
|
||||||
|
car.class = class.to_uppercase();
|
||||||
|
let rq = match element_iterator.next() {
|
||||||
|
None => "1900",
|
||||||
|
Some(rq) => rq.text().collect::<Vec<_>>()[0],
|
||||||
|
};
|
||||||
|
car.rq = u8::from_str(rq).unwrap();
|
||||||
|
/*
|
||||||
|
let upgrade_selector = Selector::parse(".carList__item-upgrade ").unwrap();
|
||||||
|
let upgrade_raw = match document.select(&upgrade_selector).next() {
|
||||||
|
None => "",
|
||||||
|
Some(model) => model.text().collect::<Vec<_>>()[0],
|
||||||
|
};
|
||||||
|
car.upgrade = String::from(upgrade_raw).trim().parse().unwrap();
|
||||||
|
*/
|
||||||
|
car
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let args: Vec<_> = env::args().collect();
|
||||||
|
|
||||||
|
let mut min_track = 4;
|
||||||
|
let mut max_track = 278;
|
||||||
|
|
||||||
|
let min_rq = 10;
|
||||||
|
let mut max_rq = 113;
|
||||||
|
|
||||||
|
match args.len() {
|
||||||
|
1 => {}
|
||||||
|
2 => max_rq = parse_argument(&args, 1, 10, 113),
|
||||||
|
3 => {
|
||||||
|
max_rq = parse_argument(&args, 1, 10, 113);
|
||||||
|
min_track = parse_argument(&args, 2, 4, 278);
|
||||||
|
max_track = min_track;
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
max_rq = parse_argument(&args, 1, 10, 113);
|
||||||
|
min_track = parse_argument(&args, 2, 4, 278);
|
||||||
|
max_track = parse_argument(&args, 3, 4, 278);
|
||||||
|
if max_track < min_track {
|
||||||
|
let temp = min_track;
|
||||||
|
min_track = max_track;
|
||||||
|
max_track = temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("Too many arguemnts."),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut keepers: HashSet<String> = HashSet::new();
|
||||||
|
|
||||||
|
for track in min_track..max_track + 1 {
|
||||||
|
let best_car = get_best_car(track, 10).await;
|
||||||
|
if best_car.len() > 10 {
|
||||||
|
for level in min_rq..max_rq + 1 {
|
||||||
|
let best_car = get_best_car(track, level).await;
|
||||||
|
if best_car.len() > 10 {
|
||||||
|
// println!("Best Car under RQ {} for track {}: {}", level, track, best_car);
|
||||||
|
keepers.insert(best_car);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Keepers:");
|
||||||
|
for car in keepers {
|
||||||
|
println!("{}", car);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_argument(args: &Vec<String>, index: usize, min: u16, max: u16) -> u16 {
|
||||||
|
match args[index].parse::<u16>() {
|
||||||
|
Ok(parsed_value) => {
|
||||||
|
if parsed_value >= min && parsed_value <= max {
|
||||||
|
parsed_value
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"Argument {} is out of range. Please provide a value between {} and {}.",
|
||||||
|
index, min, max
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
panic!("Argument {} could not be parsed. Please provide a positive integer value between {} and {}.", index, min, max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_best_car(track: u16, max_level: u16) -> String {
|
||||||
|
let url = format!("https://topdrives.club/ajax/load-best-vehicles?sort_by=level&sortorder=desc&prize=all&level=10%3B{}&acceleration=1%3B50&grip=40%3B110&year=1900%3B2030&seats_count=1%3B9&track={}&page=0",
|
||||||
|
max_level, track);
|
||||||
|
// println!("Getting {}", url);
|
||||||
|
let text = get_page(&url).await;
|
||||||
|
if text.len() > 10 {
|
||||||
|
let best_car = parse_best_car(text);
|
||||||
|
format!(
|
||||||
|
// "{}{} {} {} {} {}",
|
||||||
|
"{}{} {} {} {}",
|
||||||
|
best_car.class,
|
||||||
|
best_car.rq,
|
||||||
|
best_car.manufacturer,
|
||||||
|
best_car.model,
|
||||||
|
best_car.year,
|
||||||
|
// best_car.upgrade,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
String::from("")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue