diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4da8f7c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Utilisez IntelliSense pour en savoir plus sur les attributs possibles. + // Pointez pour afficher la description des attributs existants. + // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Lancer", + "type": "cppdbg", + "request": "launch", + "program": "target/debug/deps/price_checker-9ac713c382a0d250", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Activer l'impression en mode Pretty pour gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 7e71ea8..6682dcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,9 +38,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bumpalo" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" +checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6" [[package]] name = "byteorder" @@ -56,9 +56,9 @@ checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" [[package]] name = "cc" -version = "1.0.52" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" +checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" [[package]] name = "cfg-if" @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.5" +version = "0.99.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" +checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d" dependencies = [ "proc-macro2", "quote", @@ -152,9 +152,9 @@ dependencies = [ [[package]] name = "fnv" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" @@ -298,9 +298,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" +checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" dependencies = [ "libc", ] @@ -593,9 +593,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" [[package]] name = "openssl" @@ -619,9 +619,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" -version = "0.9.56" +version = "0.9.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e" +checksum = "7410fef80af8ac071d4f63755c0ab89ac3df0fd1ea91f1d1f37cf5cec4395990" dependencies = [ "autocfg", "cc", @@ -692,18 +692,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1" +checksum = "edc93aeee735e60ecb40cf740eb319ff23eab1c5748abfdb5c180e4ce49f7791" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" +checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40" dependencies = [ "proc-macro2", "quote", @@ -730,9 +730,9 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "ppv-lite86" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "precomputed-hash" @@ -785,18 +785,18 @@ checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" [[package]] name = "proc-macro2" -version = "1.0.12" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +checksum = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e" +checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" dependencies = [ "proc-macro2", ] @@ -1078,9 +1078,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060" +checksum = "95b5f192649e48a5302a13f2feb224df883b98933222369e4b3b0fe2a5447269" dependencies = [ "proc-macro2", "quote", @@ -1257,9 +1257,9 @@ checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] name = "version_check" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "want" diff --git a/src/parser.rs b/src/parser.rs index 2620400..14e9106 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,5 @@ pub mod darty; +pub mod fnac; extern crate arraygen; extern crate url; @@ -24,14 +25,17 @@ pub trait PriceParser{ /// Represent the list of all the parser pub struct List { #[in_array(get_price)] - darty: darty::Darty + darty: darty::Darty, + #[in_array(get_price)] + fnac: fnac::Fnac, } impl List { /// Create the list pub fn new() -> Result { Ok(List { - darty: darty::Darty::new()? + darty: darty::Darty::new()?, + fnac: fnac::Fnac::new()? }) } } @@ -39,5 +43,5 @@ impl List { #[test] fn test_parser_list() { let parser_list = List::new().unwrap(); - assert_eq!(parser_list.get_price().len(), 1); + assert_eq!(parser_list.get_price().len(), 2); } \ No newline at end of file diff --git a/src/parser/fnac.rs b/src/parser/fnac.rs new file mode 100644 index 0000000..ac0d654 --- /dev/null +++ b/src/parser/fnac.rs @@ -0,0 +1,58 @@ +use super::PriceParser; +use crate::PriceResult; +use scraper::{Selector, Html}; +use url::Url; +use anyhow::{Result, anyhow}; + +#[derive(Debug)] +/// Parser for the darty website +pub struct Fnac { + price_selector: Selector, + name_selector: Selector, + product_selector: Selector +} + +impl PriceParser for Fnac { + fn new() -> Result { + Ok(Fnac { + price_selector: Selector::parse(r#".f-priceBox-price.checked"#).unwrap(), + name_selector: Selector::parse(r#".f-productHeader-Title"#).unwrap(), + product_selector: Selector::parse(r#".f-productHeader-subTitleLink"#).unwrap() + }) + } + + fn can_parse(&self, url : &Url) -> bool { + url.host_str().unwrap_or("") == "www.fnac.com" + } + + fn parse(&self, html : &Html) -> Result { + // Get price + let price_element = html.select(&self.price_selector).next().ok_or(anyhow!("No price element"))?; + let mut price_text_it = price_element.text(); + let price_ent : u32 = price_text_it.next().unwrap_or("0").trim_end_matches(',').parse()?; + let price_dec : u32 = price_text_it.next().unwrap_or("0").trim_start_matches('€').parse()?; + let price = price_ent as f64 + (price_dec as f64) / 100.; + + // Get name + let name_element = html.select(&self.name_selector).next().ok_or(anyhow!("No name element"))?; + let name = name_element.text().next().unwrap_or("").trim().replace('\n', "-"); + + // Get product + let family_element = html.select(&self.product_selector).next().ok_or(anyhow!("No product element"))?; + let family = family_element.text().next().unwrap_or("").trim().replace('\n', "-"); + + Ok(PriceResult { + name: name.to_owned(), + product: family.to_owned(), + price + }) + } +} + +#[test] +fn test_parser_fnac() { + let fnac_parser = Fnac::new().unwrap(); + assert!(fnac_parser.can_parse(&Url::parse("https://www.fnac.com/Apple-iPhone-XS-64-Go-5-8-Argent/a12849718/w-4?CtoPid=488371").unwrap())); + assert!(fnac_parser.can_parse(&Url::parse("http://www.fnac.com/Apple-iPhone-XS-64-Go-5-8-Argent/a12849718/w-4?CtoPid=488371").unwrap())); + assert!(fnac_parser.can_parse(&Url::parse("https://www.fnace.com").unwrap()) == false); +} \ No newline at end of file diff --git a/src/price_checker.rs b/src/price_checker.rs index 6b1eb99..d746a3c 100644 --- a/src/price_checker.rs +++ b/src/price_checker.rs @@ -45,4 +45,10 @@ fn test_price_checker() { assert!(price_result.name != ""); assert!(price_result.price != 0.); assert!(price_result.product != ""); + + // Test fnac + let price_result = price_checker.get_price(Url::parse("https://www.fnac.com/PC-Gaming-Milenium-MM1-Ekko-R207-A536X-W-S-R48-B-D1-AMD-Ryzen-5-32-Go-RAM-500-Go-SSD-1-To-SATA-Noir/a14620943/w-4").unwrap()).unwrap(); + assert!(price_result.name != ""); + assert!(price_result.price != 0.); + assert!(price_result.product != ""); } \ No newline at end of file