Cache works, but needs a lot more work.
This commit is contained in:
66
src/context.rs
Normal file
66
src/context.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use std::fs;
|
||||
use std::io;
|
||||
|
||||
use directories::ProjectDirs;
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Cache {
|
||||
timestamp: u64,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
dirs: ProjectDirs,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Context {
|
||||
Context {
|
||||
dirs: ProjectDirs::from("com", "logaritmisk", "whoareyou").unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cache_get(&mut self, bin: &str, key: &str) -> Option<Cache> {
|
||||
let cache = self.dirs.cache_dir().join(format!("{}-{}.bin", bin, key));
|
||||
|
||||
if cache.exists() {
|
||||
fs::File::open(cache)
|
||||
.and_then(|file| {
|
||||
bincode::deserialize_from(&file)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "failed to deserialize cache entry"))
|
||||
})
|
||||
.ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cache_set<D>(&mut self, bin: &str, key: &str, data: D) -> Result<(), io::Error>
|
||||
where
|
||||
D: AsRef<[u8]>,
|
||||
{
|
||||
let entry = Cache {
|
||||
timestamp: 0,
|
||||
data: data.as_ref().to_vec(),
|
||||
};
|
||||
|
||||
let cache = self.dirs.cache_dir();
|
||||
|
||||
if !cache.exists() {
|
||||
fs::create_dir_all(&cache)?;
|
||||
}
|
||||
|
||||
let cache = cache.join(format!("{}-{}.bin", bin, key));
|
||||
|
||||
fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(cache)
|
||||
.and_then(|mut file| {
|
||||
bincode::serialize_into(&mut file, &entry)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "failed to serialize cache entry"))
|
||||
})
|
||||
}
|
||||
}
|
||||
32
src/main.rs
32
src/main.rs
@@ -1,36 +1,12 @@
|
||||
use std::env;
|
||||
|
||||
use directories::ProjectDirs;
|
||||
|
||||
mod context;
|
||||
mod probe;
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::*;
|
||||
|
||||
struct Context {
|
||||
dirs: ProjectDirs,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
fn new() -> Context {
|
||||
Context {
|
||||
dirs: ProjectDirs::from("com", "logaritmisk", "whoareyou").unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cache_get(&mut self, key: &str) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn cache_set(&mut self, key: &str) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Some(proj_dirs) = ProjectDirs::from("com", "logaritmisk", "whoareyou") {
|
||||
println!("{:?}", proj_dirs.cache_dir());
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
|
||||
let number = env::args()
|
||||
.nth(1)
|
||||
.expect("must specify a number to search for");
|
||||
@@ -43,7 +19,9 @@ fn main() {
|
||||
Box::new(VemRingde),
|
||||
];
|
||||
|
||||
let mut ctx = Context::new();
|
||||
|
||||
for probe in &mut probes {
|
||||
probe.search(&number);
|
||||
probe.search(&mut ctx, &number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ pub use self::konsument_info::KonsumentInfo;
|
||||
pub use self::telefonforsaljare::Telefonforsaljare;
|
||||
pub use self::vem_ringde::VemRingde;
|
||||
|
||||
use crate::context::Context;
|
||||
|
||||
pub trait Probe {
|
||||
fn search(&mut self, _: &str);
|
||||
fn search(&mut self, _: &mut Context, _: &str);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::Probe;
|
||||
|
||||
// https://gulasidorna.eniro.se/hitta:{}
|
||||
pub struct Eniro;
|
||||
|
||||
impl Probe for Eniro {
|
||||
fn search(&mut self, _: &str) {}
|
||||
fn search(&mut self, ctx: &mut Context, number: &str) {
|
||||
let body = if let Some(cache) = ctx.cache_get("eniro", &number) {
|
||||
String::from_utf8(cache.data)
|
||||
.unwrap()
|
||||
} else {
|
||||
reqwest::get(&format!("https://gulasidorna.eniro.se/hitta:{}", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
ctx.cache_set("eniro", &number, body.as_bytes()).expect("wut?! why not?!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::Probe;
|
||||
|
||||
// https://www.hitta.se/vem-ringde/{}
|
||||
pub struct Hitta;
|
||||
|
||||
impl Probe for Hitta {
|
||||
fn search(&mut self, number: &str) {
|
||||
let body = reqwest::get(&format!("https://www.hitta.se/vem-ringde/{}", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap();
|
||||
fn search(&mut self, ctx: &mut Context, number: &str) {
|
||||
let body = if let Some(cache) = ctx.cache_get("hitta", &number) {
|
||||
String::from_utf8(cache.data)
|
||||
.unwrap()
|
||||
} else {
|
||||
reqwest::get(&format!("https://www.hitta.se/vem-ringde/{}", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
ctx.cache_set("hitta", &number, body.as_bytes()).expect("wut?! why not?!");
|
||||
|
||||
let document = Html::parse_document(&body);
|
||||
|
||||
// Header.
|
||||
let selector = Selector::parse(r#"div[class^="Header__WhoCalledHeader"] > h1"#).unwrap();
|
||||
|
||||
print!("Hitta.se:");
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::Probe;
|
||||
|
||||
// http://konsumentinfo.se/telefonnummer/sverige/{}
|
||||
pub struct KonsumentInfo;
|
||||
|
||||
impl Probe for KonsumentInfo {
|
||||
fn search(&mut self, _: &str) {}
|
||||
fn search(&mut self, ctx: &mut Context, number: &str) {
|
||||
let body = if let Some(cache) = ctx.cache_get("konsument_info", &number) {
|
||||
String::from_utf8(cache.data)
|
||||
.unwrap()
|
||||
} else {
|
||||
reqwest::get(&format!("http://konsumentinfo.se/telefonnummer/sverige/{}", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
ctx.cache_set("konsument_info", &number, body.as_bytes()).expect("wut?! why not?!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::Probe;
|
||||
|
||||
// http://www.telefonforsaljare.nu/telefonnummer/{}/
|
||||
pub struct Telefonforsaljare;
|
||||
|
||||
impl Probe for Telefonforsaljare {
|
||||
fn search(&mut self, _: &str) {}
|
||||
fn search(&mut self, ctx: &mut Context, number: &str) {
|
||||
let body = if let Some(cache) = ctx.cache_get("telefonforsaljare", &number) {
|
||||
String::from_utf8(cache.data)
|
||||
.unwrap()
|
||||
} else {
|
||||
reqwest::get(&format!("http://www.telefonforsaljare.nu/telefonnummer/{}/", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
ctx.cache_set("telefonforsaljare", &number, body.as_bytes()).expect("wut?! why not?!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::probe::Probe;
|
||||
|
||||
// http://vemringde.se/?q={}
|
||||
pub struct VemRingde;
|
||||
|
||||
impl Probe for VemRingde {
|
||||
fn search(&mut self, _: &str) {}
|
||||
fn search(&mut self, ctx: &mut Context, number: &str) {
|
||||
let body = if let Some(cache) = ctx.cache_get("vem_ringde", &number) {
|
||||
String::from_utf8(cache.data)
|
||||
.unwrap()
|
||||
} else {
|
||||
reqwest::get(&format!("http://vemringde.se/?q={}", number))
|
||||
.unwrap()
|
||||
.text()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
ctx.cache_set("vem_ringde", &number, body.as_bytes()).expect("wut?! why not?!");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user