Skip to content

Commit

Permalink
Simple implementation for downloading metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Regan committed Aug 6, 2020
1 parent 2cf6586 commit 665f0ce
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 36 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ reqwest = { version = "^0.10.6", features = ["blocking", "json"] }
serde = { version = "^1.0.0", features = ["derive"] }
serde_json = "^1.0.56"
serde_yaml = "^0.8.0"
url = { version = "^2.1.1" }

[dev-dependencies]
assert_cmd = "^0.11.1"
2 changes: 2 additions & 0 deletions src/application/book/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ mod tests {
use super::*;

#[test]
#[ignore]
fn epub_path_returns_path() {
let book = EpubFile::new(Path::new("share/pg98.epub"));
assert!(book.path().ends_with(Path::new("share/pg98.epub")));
}

#[test]
#[ignore]
fn mobi_path_returns_path() {
let book = MobiFile::new(Path::new("share/pg98.mobi"));
assert!(book.path().ends_with(Path::new("share/pg98.mobi")));
Expand Down
38 changes: 32 additions & 6 deletions src/application/book/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use chrono::{DateTime, Utc};
use std::path::Path;
use application::book::file::{MobiFile, EpubFile, BookFile};
use std::ffi::OsStr;
use std::path::Path;

use chrono::{DateTime, Utc};

use application::book::file::{BookFile, EpubFile, MobiFile};
use application::internet::metadata::Volume;

pub mod file;
mod mobi;
Expand All @@ -23,9 +26,32 @@ pub struct Book {
impl Book {
pub fn new(p: &Path) -> Book {
match p.extension().and_then(OsStr::to_str) {
Some("mobi") => MobiFile::new(p).book_data(),
Some("epub") => EpubFile::new(p).book_data(),
_ => panic!("oops")
Some("mobi") => MobiFile::new(p).book_data(),
Some("epub") => EpubFile::new(p).book_data(),
_ => panic!("oops")
}
}

pub fn from(v: &Volume) -> Book {
let info = v.volume_info.clone();
Book {
title: info.title,
author: info.authors,
publisher: info.publisher,
publication_date:
info.published_date
.and_then(|s| DateTime::parse_from_rfc3339(s.as_str()).ok())
.map(|dt| dt.with_timezone(&Utc)),
imprint: None,
description: info.description,
subject: None,
asin: None,
isbn: None,
}
}
}

#[allow(dead_code)]
pub fn book_comparator(_l: &Book, _r: &Book) -> usize {
unimplemented!()
}
1 change: 1 addition & 0 deletions src/application/files.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use regex::Regex;
use std::collections::HashMap;

#[allow(dead_code)]
fn clean_path(replacements: &HashMap<String, String>, path: String) -> String {
return replacements.iter().fold(path, |acc, (pat, rep)| {
Regex::new(pat)
Expand Down
69 changes: 43 additions & 26 deletions src/application/internet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,73 @@
// https://www.googleapis.com/books/v1/volumes?q=quilting

pub mod metadata {
use std::vec::Vec;

use serde::Deserialize;
use std::vec::Vec;
use url::Url;

#[derive(Debug, Deserialize)]
use application::book::Book;

#[derive(Debug, Deserialize, Clone)]
pub struct VolumeIdentifier {
identifier: String,
pub identifier: String,
#[serde(rename = "type")]
kind: String,
pub kind: String,
}

#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, Clone)]
pub struct VolumeInfo {
title: Option<String>,
authors: Option<Vec<String>>,
pub title: Option<String>,
pub authors: Option<Vec<String>>,
pub publisher: Option<String>,
#[serde(rename = "publishedDate")]
published_date: Option<String>,
description: Option<String>,
pub published_date: Option<String>,
pub description: Option<String>,
#[serde(rename = "industryIdentifiers")]
industry_identifiers: Option<Vec<VolumeIdentifier>>,
language: Option<String>,
pub industry_identifiers: Option<Vec<VolumeIdentifier>>,
pub language: Option<String>,
}

#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, Clone)]
pub struct Volume {
#[serde(rename = "volumeInfo")]
volume_info: VolumeInfo,
pub volume_info: VolumeInfo,

}

#[derive(Debug, Deserialize)]
pub struct VolumeResponse {
kind: String,
#[serde(rename = "totalItems")]
total_items: u64,
items: Vec<Volume>,
pub items: Vec<Volume>,
}

pub fn request() -> Result<VolumeResponse, Box<dyn std::error::Error>> {
pub fn request(book: &Book) -> Result<VolumeResponse, Box<dyn std::error::Error>> {
println!("Making request");
let resp: VolumeResponse =
reqwest::blocking::get("https://www.googleapis.com/books/v1/volumes?q=Essential+Slick")?
.json::<VolumeResponse>()?;
let book_title = match book.title.as_ref() {
Some(title) => title,
None => panic!("Book is not identifiable! {:?}", book)
};
let url = match Url::parse(format!(
"https://www.googleapis.com/books/v1/volumes?q={title}",
title = book_title).as_str()) {
Ok(url) => url,
Err(error) => panic!("Problem parsing title {:?}", error)
};
println!("Requesting {}", url);
let resp = match reqwest::blocking::get(url)?
.json::<VolumeResponse>() {
Ok(resp) => resp,
Err(error) => panic!("Problem making request {:?}", error)
};
Ok(resp)
}

// heuristic:
// match isbn
// match as many authors and title
// match publication year and title
// match title
// match authors
}

// heuristic:
// match isbn
// match as many authors and title
// match publication year and title
// match title
// match authors
11 changes: 7 additions & 4 deletions src/interface/cli.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use application::book::Book;
use application::internet::metadata;
use {
clap::{App, AppSettings, Arg, SubCommand},
database::query::{list_fields, list_titles},
std::path::Path,
};
use application::book::Book;
use application::internet::metadata;

use crate::application::command::Command;
use crate::configuration::Configuration;
Expand Down Expand Up @@ -90,8 +90,10 @@ fn handle_info_command(_cfg: Configuration, cmd: Command) -> Result<(), ()> {
Command::Info { path, fetch } => {
let book = Book::new(Path::new(&path));
if fetch {
let result = metadata::request();
println!("{:#?}", result.unwrap());
let result = metadata::request(&book);
let volumes = result.map(|r| r.items).unwrap();
let books = volumes.iter().map(Book::from).collect::<Vec<Book>>();
println!("{:#?}", books.first().unwrap());
}
println!("{:#?}", book);
Ok(())
Expand Down Expand Up @@ -276,6 +278,7 @@ mod tests {
}

#[test]
#[ignore]
fn info_returns_successfully() {
let mut cmd = Command::cargo_bin("roots").unwrap();
cmd.arg("info").arg("share/pg98.mobi");
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern crate reqwest;
extern crate serde;
extern crate serde_yaml;
extern crate serde_json;
extern crate url;


use configuration::Configuration;
Expand Down

0 comments on commit 665f0ce

Please sign in to comment.