sync dlcs (fixes #12)

break content deserializing and sync code into smaller pieces (fixes #9)
This commit is contained in:
Sebastian Hugentobler 2017-05-10 14:50:38 +02:00
parent 7a40242d67
commit 1f8329cd3a
6 changed files with 78 additions and 16 deletions

View File

@ -1,3 +1,7 @@
## 0.3.4 (2017-05-10)
- sync dlcs (fixes #12)
- break content deserializing and sync code into smaller pieces (fixes #9)
## 0.3.3 (2017-05-09) ## 0.3.3 (2017-05-09)
- normalize content directory names (fixes #11) - normalize content directory names (fixes #11)

2
Cargo.lock generated
View File

@ -1,6 +1,6 @@
[root] [root]
name = "gog-sync" name = "gog-sync"
version = "0.3.3" version = "0.3.4"
dependencies = [ dependencies = [
"chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.24.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.24.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "gog-sync" name = "gog-sync"
version = "0.3.3" version = "0.3.4"
authors = ["Sebastian Hugentobler <sebastian@vanwa.ch>"] authors = ["Sebastian Hugentobler <sebastian@vanwa.ch>"]
description = "Synchronizes a GOG library with a local folder." description = "Synchronizes a GOG library with a local folder."
documentation = "https://docs.rs/crate/gog-sync" documentation = "https://docs.rs/crate/gog-sync"

View File

@ -252,6 +252,14 @@ impl<'a> Gog<'a> {
fs::create_dir_all(&data_root)?; fs::create_dir_all(&data_root)?;
let data_uri = format!("https://embed.gog.com{}", relative_uri); let data_uri = format!("https://embed.gog.com{}", relative_uri);
let filename = self.api_request_get_filename(&data_uri)?;
let file_path = Path::new(&data_root).join(&filename);
if file_path.exists() {
info!("{} for {} already exists", &filename, content_title);
return Ok(filename.to_owned());
}
info!("downloading {} for {}...", &relative_uri, content_title); info!("downloading {} for {}...", &relative_uri, content_title);
self.api_request_download(data_uri.as_str(), &data_root) self.api_request_download(data_uri.as_str(), &data_root)
} }
@ -422,8 +430,7 @@ impl<'a> Gog<'a> {
content_ids.push(content_id_parsed); content_ids.push(content_id_parsed);
} }
//Ok(content_ids) Ok(content_ids)
Ok(vec![1207658995])
} }
fn api_request_ensure_token(&mut self, response: &str) -> Result<bool, GogError> { fn api_request_ensure_token(&mut self, response: &str) -> Result<bool, GogError> {
@ -452,6 +459,15 @@ impl<'a> Gog<'a> {
} }
} }
fn api_request_get_filename(&mut self, uri: &str) -> Result<String, GogError> {
let response = self.http_client.get_filename(uri)?;
if self.api_request_ensure_token(&response)? {
Ok(self.http_client.get_filename(uri)?)
} else {
Ok(response)
}
}
fn api_request_download(&mut self, uri: &str, path: &PathBuf) -> Result<String, GogError> { fn api_request_download(&mut self, uri: &str, path: &PathBuf) -> Result<String, GogError> {
let response = self.http_client.download(uri, path)?; let response = self.http_client.download(uri, path)?;
if self.api_request_ensure_token(&response)? { if self.api_request_ensure_token(&response)? {

View File

@ -96,10 +96,11 @@ impl Http {
self.curl.url(uri)?; self.curl.url(uri)?;
{ {
let mut transfer = self.curl.transfer(); let mut transfer = self.curl.transfer();
transfer.write_function(|new_data| { transfer
data.extend_from_slice(new_data); .write_function(|new_data| {
Ok(new_data.len()) data.extend_from_slice(new_data);
})?; Ok(new_data.len())
})?;
transfer.perform()?; transfer.perform()?;
} }
@ -129,6 +130,46 @@ impl Http {
} }
} }
/// Find the filename for a download uri.
///
/// Useful if the initial link gets redirected.
///
/// The filename is taken from the last URI segment and returned in the result.
/// # Example
/// ```
/// use http::Http;
/// use std::path::Path;
///
/// let mut http_client = Http::new();
///
/// http_client.get_filename("https://example.com/sed");
/// ```
pub fn get_filename(&mut self, download_uri: &str) -> Result<String, HttpError> {
self.curl.url(download_uri)?;
self.curl.nobody(true)?;
self.curl.perform()?;
self.curl.nobody(false)?;
let download_url_string = match self.curl.effective_url()? {
Some(value) => value,
None => return Err(HttpError::Error("Can't get effective download url.")),
};
let download_url = Url::parse(download_url_string)?;
let download_url_segments = match download_url.path_segments() {
Some(value) => value,
None => return Err(HttpError::Error("Can't parse download segments.")),
};
let file_name = match download_url_segments.last() {
Some(value) => value,
None => return Err(HttpError::Error("No segments in download url.")),
};
Ok(file_name.to_owned())
}
/// Download a file to the specified folder without creating the folder. /// Download a file to the specified folder without creating the folder.
/// ///
/// The filename is taken from the last URI segment and returned in the result. /// The filename is taken from the last URI segment and returned in the result.
@ -152,13 +193,14 @@ impl Http {
self.curl.url(download_uri)?; self.curl.url(download_uri)?;
{ {
let mut transfer = self.curl.transfer(); let mut transfer = self.curl.transfer();
transfer.write_function(|data| { transfer
match file_download.write(data) { .write_function(|data| {
Ok(_) => Ok(()), match file_download.write(data) {
Err(error) => Err(HttpError::IOError(error)), Ok(_) => Ok(()),
}?; Err(error) => Err(HttpError::IOError(error)),
Ok(data.len()) }?;
})?; Ok(data.len())
})?;
transfer.perform()?; transfer.perform()?;
} }

View File

@ -29,7 +29,7 @@ fn main() {
env_logger::init().unwrap(); env_logger::init().unwrap();
let matches = App::new("Gog Synchronizer") let matches = App::new("Gog Synchronizer")
.version("0.3.3") .version("0.3.4")
.author("Sebastian Hugentobler <sebastian@vanwa.ch>") .author("Sebastian Hugentobler <sebastian@vanwa.ch>")
.about("Synchronizes your gog library to a local folder.") .about("Synchronizes your gog library to a local folder.")
.arg(Arg::with_name("game-storage") .arg(Arg::with_name("game-storage")