initial movie support
This commit is contained in:
parent
e385a07aac
commit
88827749db
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
[root]
|
||||
name = "gog-sync"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std;
|
||||
use std::io::{Read, Write};
|
||||
@ -20,6 +21,15 @@ pub enum ConfigError {
|
||||
SerdeJsonError(serde_json::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for ConfigError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConfigError::IOError(ref err) => fmt::Display::fmt(err, f),
|
||||
ConfigError::SerdeJsonError(ref err) => fmt::Display::fmt(err, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ConfigError {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
ConfigError::IOError(e)
|
||||
|
47
src/gog.rs
47
src/gog.rs
@ -17,6 +17,7 @@ use models::{Token, Game, Installer, Config};
|
||||
use serde_json;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -33,6 +34,18 @@ pub enum GogError {
|
||||
IOError(io::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for GogError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
GogError::Error(ref err) => fmt::Display::fmt(err, f),
|
||||
GogError::ConfigError(ref err) => fmt::Display::fmt(err, f),
|
||||
GogError::HttpError(ref err) => fmt::Display::fmt(err, f),
|
||||
GogError::SerdeError(ref err) => fmt::Display::fmt(err, f),
|
||||
GogError::IOError(ref err) => fmt::Display::fmt(err, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConfigError> for GogError {
|
||||
fn from(e: ConfigError) -> Self {
|
||||
GogError::ConfigError(e)
|
||||
@ -109,6 +122,7 @@ impl<'a> Gog<'a> {
|
||||
/// Uses a hash to figure out whether something has changed.
|
||||
pub fn sync(&mut self,
|
||||
storage_path: &str,
|
||||
storage_path_movies: &str,
|
||||
os_filters: &Vec<String>,
|
||||
language_filters: &Vec<String>)
|
||||
-> Result<(), GogError> {
|
||||
@ -120,6 +134,7 @@ impl<'a> Gog<'a> {
|
||||
|
||||
Config {
|
||||
storage: String::from(storage_path),
|
||||
movie_storage: String::from(storage_path_movies),
|
||||
games: HashMap::new(),
|
||||
installers: HashMap::new(),
|
||||
extras: HashMap::new(),
|
||||
@ -137,7 +152,14 @@ impl<'a> Gog<'a> {
|
||||
None => u64::min_value(),
|
||||
};
|
||||
|
||||
let game = self.get_game(game_id, &os_filters, &language_filters)?;
|
||||
let game = match self.get_game(game_id, &os_filters, &language_filters) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
error!("{}", error);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let game_hash = models::get_hash(&game);
|
||||
|
||||
if game_hash_saved == game_hash {
|
||||
@ -145,7 +167,12 @@ impl<'a> Gog<'a> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let game_root = Path::new(storage_path).join(&game.title);
|
||||
let game_root = if game.is_movie {
|
||||
Path::new(storage_path_movies).join(&game.title)
|
||||
} else {
|
||||
Path::new(storage_path).join(&game.title)
|
||||
};
|
||||
|
||||
fs::create_dir_all(&game_root)?;
|
||||
|
||||
if !game.cd_key.is_empty() {
|
||||
@ -306,6 +333,17 @@ impl<'a> Gog<'a> {
|
||||
let game_raw: Value = serde_json::from_str(response.as_str())?;
|
||||
let downloads = &game_raw["downloads"];
|
||||
|
||||
if game_raw.is_object() && !game_raw.as_object().unwrap().contains_key("forumLink") {
|
||||
return Err(GogError::Error("No forumLink property"));
|
||||
}
|
||||
|
||||
let is_movie = match game_raw["forumLink"].as_str() {
|
||||
Some(value) => value == "https://embed.gog.com/forum/movies",
|
||||
None => false,
|
||||
};
|
||||
|
||||
game.is_movie = is_movie;
|
||||
|
||||
for languages in downloads.as_array() {
|
||||
for language in languages {
|
||||
if !language.is_array() || language.as_array().unwrap().len() < 2 {
|
||||
@ -323,14 +361,15 @@ impl<'a> Gog<'a> {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !language_filters.is_empty() && !language_filters.contains(&installer_language) {
|
||||
if !is_movie && !language_filters.is_empty() &&
|
||||
!language_filters.contains(&installer_language) {
|
||||
info!("Skipping {} for {}", &installer_language, game.title);
|
||||
continue;
|
||||
}
|
||||
|
||||
for systems in language[1].as_object() {
|
||||
for system in systems.keys() {
|
||||
if !os_filters.is_empty() && !os_filters.contains(system) {
|
||||
if is_movie && !os_filters.is_empty() && !os_filters.contains(system) {
|
||||
info!("Skipping {} {} for {}",
|
||||
&installer_language,
|
||||
system,
|
||||
|
13
src/http.rs
13
src/http.rs
@ -3,6 +3,7 @@
|
||||
|
||||
use curl;
|
||||
use curl::easy::{Easy, List, WriteError};
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -24,6 +25,18 @@ pub enum HttpError {
|
||||
UrlParseError(url::ParseError),
|
||||
}
|
||||
|
||||
impl fmt::Display for HttpError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
HttpError::Error(ref err) => fmt::Display::fmt(err, f),
|
||||
HttpError::CurlError(ref err) => fmt::Display::fmt(err, f),
|
||||
HttpError::Utf8Error(ref err) => fmt::Display::fmt(err, f),
|
||||
HttpError::IOError(ref err) => fmt::Display::fmt(err, f),
|
||||
HttpError::UrlParseError(ref err) => fmt::Display::fmt(err, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<curl::Error> for HttpError {
|
||||
fn from(e: curl::Error) -> Self {
|
||||
HttpError::CurlError(e)
|
||||
|
17
src/main.rs
17
src/main.rs
@ -52,6 +52,12 @@ fn main() {
|
||||
.value_name("FOLDER")
|
||||
.help("Sets the download folder (defaults to the working directory).")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("movie-storage")
|
||||
.short("m")
|
||||
.long("movie-storage")
|
||||
.value_name("FOLDER")
|
||||
.help("Sets the download folder for movies (defaults to the game directory).")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("os")
|
||||
.short("o")
|
||||
.long("os")
|
||||
@ -78,6 +84,11 @@ fn main() {
|
||||
None => config.storage.as_str(),
|
||||
};
|
||||
|
||||
let download_folder_movies: &str = match matches.value_of("movieStorage") {
|
||||
Some(value) => value,
|
||||
None => config.movie_storage.as_str(),
|
||||
};
|
||||
|
||||
let os_filters: Vec<String> = match matches.value_of("os") {
|
||||
Some(value) => value.split(',').map(String::from).collect(),
|
||||
None => config.os_filters,
|
||||
@ -91,5 +102,9 @@ fn main() {
|
||||
let mut http_client = Http::new();
|
||||
let mut gog = Gog::new(&mut http_client);
|
||||
gog.login().unwrap();
|
||||
gog.sync(download_folder, &os_filters, &language_filters).unwrap();
|
||||
gog.sync(download_folder,
|
||||
download_folder_movies,
|
||||
&os_filters,
|
||||
&language_filters)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ fn timestamp() -> i64 {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Config {
|
||||
pub storage: String,
|
||||
pub movie_storage: String,
|
||||
#[serde(default = "default_map")]
|
||||
pub games: HashMap<String, u64>,
|
||||
#[serde(default = "default_map")]
|
||||
@ -57,6 +58,7 @@ impl Config {
|
||||
pub fn new() -> Config {
|
||||
Config {
|
||||
storage: String::from("."),
|
||||
movie_storage: String::from("."),
|
||||
games: HashMap::new(),
|
||||
installers: HashMap::new(),
|
||||
extras: HashMap::new(),
|
||||
@ -73,6 +75,8 @@ pub struct Game {
|
||||
pub title: String,
|
||||
pub cd_key: String,
|
||||
#[serde(skip_deserializing)]
|
||||
pub is_movie: bool,
|
||||
#[serde(skip_deserializing)]
|
||||
pub installers: Vec<Installer>,
|
||||
pub extras: Vec<Extra>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user