diff --git a/CHANGELOG.md b/CHANGELOG.md index 6492045..89557bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) - normalize content directory names (fixes #11) diff --git a/Cargo.lock b/Cargo.lock index a6fb3ef..78c132b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "gog-sync" -version = "0.3.3" +version = "0.3.4" dependencies = [ "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)", diff --git a/Cargo.toml b/Cargo.toml index ea3391c..4478e65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gog-sync" -version = "0.3.3" +version = "0.3.4" authors = ["Sebastian Hugentobler "] description = "Synchronizes a GOG library with a local folder." documentation = "https://docs.rs/crate/gog-sync" diff --git a/src/gog.rs b/src/gog.rs index 6361dae..8137c55 100644 --- a/src/gog.rs +++ b/src/gog.rs @@ -252,6 +252,14 @@ impl<'a> Gog<'a> { fs::create_dir_all(&data_root)?; 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); self.api_request_download(data_uri.as_str(), &data_root) } @@ -422,8 +430,7 @@ impl<'a> Gog<'a> { content_ids.push(content_id_parsed); } - //Ok(content_ids) - Ok(vec![1207658995]) + Ok(content_ids) } fn api_request_ensure_token(&mut self, response: &str) -> Result { @@ -452,6 +459,15 @@ impl<'a> Gog<'a> { } } + fn api_request_get_filename(&mut self, uri: &str) -> Result { + 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 { let response = self.http_client.download(uri, path)?; if self.api_request_ensure_token(&response)? { diff --git a/src/http.rs b/src/http.rs index 61335ff..c6b6f29 100644 --- a/src/http.rs +++ b/src/http.rs @@ -96,10 +96,11 @@ impl Http { self.curl.url(uri)?; { let mut transfer = self.curl.transfer(); - transfer.write_function(|new_data| { - data.extend_from_slice(new_data); - Ok(new_data.len()) - })?; + transfer + .write_function(|new_data| { + data.extend_from_slice(new_data); + Ok(new_data.len()) + })?; 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 { + 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. /// /// 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)?; { let mut transfer = self.curl.transfer(); - transfer.write_function(|data| { - match file_download.write(data) { - Ok(_) => Ok(()), - Err(error) => Err(HttpError::IOError(error)), - }?; - Ok(data.len()) - })?; + transfer + .write_function(|data| { + match file_download.write(data) { + Ok(_) => Ok(()), + Err(error) => Err(HttpError::IOError(error)), + }?; + Ok(data.len()) + })?; transfer.perform()?; } diff --git a/src/main.rs b/src/main.rs index 0c0bcd9..10d7b7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ fn main() { env_logger::init().unwrap(); let matches = App::new("Gog Synchronizer") - .version("0.3.3") + .version("0.3.4") .author("Sebastian Hugentobler ") .about("Synchronizes your gog library to a local folder.") .arg(Arg::with_name("game-storage")