-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from arghyadipchak/master
Code Refactor
- Loading branch information
Showing
7 changed files
with
216 additions
and
277 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
edition = "2021" | ||
max_width = 80 | ||
tab_spaces = 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,46 @@ | ||
//! Test the precision of the captcha solver | ||
use std::time::Instant; | ||
use std::{fs, time::Instant}; | ||
|
||
extern crate amazon_captcha_rs; | ||
use amazon_captcha_rs::Solver; | ||
|
||
fn main() { | ||
let start = Instant::now(); | ||
let files = std::fs::read_dir("examples/dataset").unwrap(); | ||
let solver = amazon_captcha_rs::new_solver(); | ||
let solver = Solver::new().unwrap(); | ||
|
||
let mut solved = 0; | ||
let mut total = 0; | ||
let (mut resolved, mut total) = (0u32, 0u32); | ||
let mut times = Vec::new(); | ||
|
||
files.for_each(|file| { | ||
let now = Instant::now(); | ||
let file = file.unwrap(); | ||
let path = file.path(); | ||
|
||
for file in fs::read_dir("examples/dataset").unwrap() { | ||
let path = file.unwrap().path(); | ||
let expect = path | ||
.as_path() | ||
.file_name() | ||
.unwrap() | ||
.unwrap_or_default() | ||
.to_str() | ||
.unwrap() | ||
.split(".") | ||
.unwrap_or_default() | ||
.split('.') | ||
.next() | ||
.unwrap(); | ||
.unwrap_or_default(); | ||
|
||
if expect.len() < 6 { | ||
return; | ||
} | ||
|
||
total += 1; | ||
let img = image::open(&path).unwrap(); | ||
|
||
let Some(result) = solver.resolve_image(&img) else { | ||
println!("{:?}: Failed to resolve", &path.as_path()); | ||
return; | ||
}; | ||
let now = Instant::now(); | ||
let result = solver.resolve_image(&image::open(&path).unwrap()); | ||
times.push(now.elapsed().as_millis()); | ||
|
||
if expect == result { | ||
solved += 1; | ||
resolved += 1; | ||
} else { | ||
println!( | ||
"{:?}: Expect '{}', got '{}'", | ||
&path.as_path(), | ||
expect, | ||
result | ||
); | ||
eprintln!("{path:?}: Expected '{expect}', got '{result}'"); | ||
} | ||
} | ||
|
||
times.push(now.elapsed().as_millis()); | ||
}); | ||
|
||
println!("Solved: {}/{}", solved, total); | ||
println!("Precision: {:.2}%", solved as f32 / total as f32 * 100.0); | ||
println!( | ||
"Average time: {:.2}ms", | ||
"Resolved: {resolved}/{total}\nPrecision: {:.2}%\nAverage Time: {:.2}ms", | ||
resolved as f32 / total as f32 * 100.0, | ||
times.iter().sum::<u128>() as f32 / times.len() as f32 | ||
); | ||
println!("Total time: {:.2}s", start.elapsed().as_secs_f32()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,64 @@ | ||
//! Benchmark running on an infinite loop. | ||
use std::{error, time::Instant}; | ||
|
||
use amazon_captcha_rs::Solver; | ||
use image::EncodableLayout; | ||
use regex::Regex; | ||
use reqwest::Client; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let solver = amazon_captcha_rs::new_solver(); | ||
async fn main() -> Result<(), Box<dyn error::Error>> { | ||
let solver = Solver::new()?; | ||
|
||
let mut resolved = 0; | ||
let mut total = 0; | ||
let code_regex = Regex::new(r#"name="amzn" value="(.*?)" \/>"#)?; | ||
let img_regex = Regex::new(r#"<img src="((.*).jpg)">"#)?; | ||
|
||
loop { | ||
let ok = resolve_captcha(&solver).await?; | ||
let (mut resolved, mut total) = (0u32, 0u32); | ||
let mut times = Vec::new(); | ||
|
||
loop { | ||
total += 1; | ||
if ok { | ||
resolved += 1; | ||
} | ||
|
||
if total % 10 == 0 { | ||
println!("Resolved: {}/{}", resolved, total); | ||
println!("Precision: {:.2}%", resolved as f32 / total as f32 * 100.0); | ||
} | ||
} | ||
} | ||
|
||
async fn resolve_captcha(solver: &Solver) -> Result<bool, Box<dyn std::error::Error>> { | ||
let text = reqwest::get("https://www.amazon.com/errors/validateCaptcha") | ||
.await? | ||
.text() | ||
.await?; | ||
let text = | ||
reqwest::get("https://www.amazon.com/errors/validateCaptcha") | ||
.await? | ||
.text() | ||
.await?; | ||
|
||
let img_regex = Regex::new(r#"<img src="((.*).jpg)">"#)?; | ||
let cap = img_regex.captures(&text).unwrap(); | ||
let url = cap.get(1).unwrap().as_str(); | ||
let code = code_regex.captures(&text).unwrap().get(1).unwrap().as_str(); | ||
|
||
let code_regex = Regex::new(r#"name="amzn" value="(.*?)" \/>"#).unwrap(); | ||
let code = code_regex.captures(&text).unwrap().get(1).unwrap().as_str(); | ||
let url = img_regex.captures(&text).unwrap().get(1).unwrap().as_str(); | ||
let img = image::load_from_memory( | ||
reqwest::get(url).await?.bytes().await?.as_bytes(), | ||
)?; | ||
|
||
let img = reqwest::get(url).await?.bytes().await?; | ||
let img = image::load_from_memory(img.as_bytes())?; | ||
let now = Instant::now(); | ||
let result = solver.resolve_image(&img); | ||
times.push(now.elapsed().as_millis()); | ||
|
||
let Some(result) = solver.resolve_image(&img) else { | ||
return Ok(false); | ||
}; | ||
|
||
let response = reqwest::Client::new() | ||
.get("https://www.amazon.com/errors/validateCaptcha") | ||
.query(&[("amzn", code), ("amzn-r", "/"), ("field-keywords", &result)]) | ||
.send() | ||
.await?; | ||
if Client::new() | ||
.get("https://www.amazon.com/errors/validateCaptcha") | ||
.query(&[ | ||
("amzn", code), | ||
("amzn-r", "/"), | ||
("field-keywords", &result), | ||
]) | ||
.send() | ||
.await? | ||
.url() | ||
.to_string() | ||
== "https://www.amazon.com/" | ||
{ | ||
resolved += 1; | ||
} | ||
|
||
Ok(response.url().to_string() == "https://www.amazon.com/") | ||
if total % 10 == 0 { | ||
println!( | ||
"Resolved: {resolved}/{total}\nPrecision: {:.2}%\nAverage Time: {:.2}ms", | ||
resolved as f32 / total as f32 * 100.0, | ||
times.iter().sum::<u128>() as f32 / times.len() as f32 | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,31 @@ | ||
//! Download captcha image to test precision | ||
use std::{error, fs}; | ||
|
||
use regex::Regex; | ||
use std::{fs::File, io::Write}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
async fn main() -> Result<(), Box<dyn error::Error>> { | ||
println!("Downloading captcha images..."); | ||
|
||
for i in 0..100 { | ||
let img = download_captcha().await?; | ||
|
||
let path = format!("examples/dataset/{}.jpg", i); | ||
let img_regex = Regex::new(r#"<img src="((.*).jpg)">"#)?; | ||
|
||
File::create(path)?.write_all(&img)?; | ||
for i in 0..100 { | ||
let text = | ||
reqwest::get("https://www.amazon.com/errors/validateCaptcha") | ||
.await? | ||
.text() | ||
.await?; | ||
|
||
let url = img_regex.captures(&text).unwrap().get(1).unwrap().as_str(); | ||
|
||
fs::write( | ||
format!("examples/dataset/{i}.jpg"), | ||
reqwest::get(url).await?.bytes().await?, | ||
)?; | ||
} | ||
|
||
println!("Done!"); | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn download_captcha() -> Result<Vec<u8>, Box<dyn std::error::Error>> { | ||
let text = reqwest::get("https://www.amazon.com/errors/validateCaptcha") | ||
.await? | ||
.text() | ||
.await?; | ||
|
||
let re = Regex::new(r#"<img src="((.*).jpg)">"#)?; | ||
let cap = re.captures(&text).unwrap(); | ||
let url = cap.get(1).unwrap().as_str(); | ||
|
||
let img = reqwest::get(url).await?.bytes().await?; | ||
|
||
Ok(img.to_vec()) | ||
} |
Oops, something went wrong.