seperate model files

This commit is contained in:
Sebastian Hugentobler 2017-05-10 11:29:24 +02:00
parent 2147f2534b
commit 2f85d2459f
12 changed files with 217 additions and 199 deletions

View File

@ -13,7 +13,12 @@
use configfiles::{ConfigFiles, ConfigError};
use http::{Http, HttpError};
use models;
use models::{Token, Content, ContentInfo, DataInfo, ExtraInfo, Data};
use models::content::Content;
use models::contentinfo::ContentInfo;
use models::datainfo::DataInfo;
use models::extrainfo::ExtraInfo;
use models::data::Data;
use models::token::Token;
use serde_json;
use serde_json::Value;
use std::collections::HashMap;

View File

@ -23,7 +23,7 @@ use configfiles::ConfigFiles;
use clap::{Arg, App};
use gog::Gog;
use http::Http;
use models::Config;
use models::config::Config;
fn main() {
env_logger::init().unwrap();

View File

@ -1,197 +0,0 @@
use chrono::UTC;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::hash_map::DefaultHasher;
use serde::{Deserialize, Deserializer};
use regex::Regex;
#[derive(Serialize, Deserialize)]
pub struct Token {
pub access_token: String,
pub expires_in: u16,
pub token_type: String,
pub scope: String,
pub session_id: String,
pub refresh_token: String,
pub user_id: String,
#[serde(default = "timestamp")]
pub timestamp: i64,
}
impl Token {
pub fn is_expired(&self) -> bool {
let now = UTC::now().timestamp();
now > self.timestamp + self.expires_in as i64
}
}
fn timestamp() -> i64 {
UTC::now().timestamp()
}
fn default_list() -> Vec<String> {
Vec::new()
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
#[serde(default)]
pub game_storage: String,
#[serde(default)]
pub movie_storage: String,
#[serde(default = "default_list")]
pub os_filters: Vec<String>,
#[serde(default = "default_list")]
pub language_filters: Vec<String>,
#[serde(default = "default_list")]
pub resolution_filters: Vec<String>,
#[serde(default)]
pub skip_movies: bool,
#[serde(default)]
pub skip_games: bool,
}
impl Config {
pub fn new() -> Config {
Config {
game_storage: String::from("."),
movie_storage: String::from("."),
os_filters: Vec::new(),
language_filters: Vec::new(),
resolution_filters: Vec::new(),
skip_movies: false,
skip_games: false,
}
}
}
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Content {
#[serde(skip_deserializing)]
pub id: u64,
#[serde(deserialize_with = "normalize_title")]
pub title: String,
#[serde(skip_deserializing)]
#[serde(rename(deserialize = "cdKey"))]
pub cd_keys: BTreeMap<String, String>,
#[serde(skip_deserializing)]
pub is_movie: bool,
#[serde(skip_deserializing)]
pub data: Vec<Data>,
pub extras: Vec<Extra>,
}
impl fmt::Display for Content {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({})", self.title)
}
}
fn normalize_title<D>(deserializer: D) -> Result<String, D::Error>
where D: Deserializer
{
let raw_title = String::deserialize(deserializer)?.replace(":", " - ");
let regex_normalize = Regex::new(r"[^'^\w^\s^-]+").unwrap();
let regex_whitespace = Regex::new(r"\s\s+").unwrap();
let title_normalized = regex_normalize
.replace_all(raw_title.as_str(), "")
.to_string();
let title_whitespace = regex_whitespace
.replace_all(title_normalized.as_str(), " ")
.to_string();
Ok(title_whitespace)
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ContentInfo {
#[serde(skip_deserializing)]
pub id: u64,
pub hash: u64,
pub title: String,
pub cd_keys: BTreeMap<String, String>,
pub data: HashMap<String, DataInfo>,
pub extras: HashMap<String, ExtraInfo>,
}
impl ContentInfo {
pub fn new() -> ContentInfo {
ContentInfo {
id: 0,
hash: 0,
title: String::new(),
cd_keys: BTreeMap::new(),
data: HashMap::new(),
extras: HashMap::new(),
}
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataInfo {
pub hash: u64,
pub filename: String,
pub language: String,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExtraInfo {
pub hash: u64,
pub filename: String,
pub name: String,
}
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Data {
pub manual_url: String,
pub version: String,
pub os: String,
pub language: String,
}
impl fmt::Display for Data {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"({}, {}, {}, {})",
self.manual_url,
self.version,
self.os,
self.language)
}
}
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Extra {
pub manual_url: String,
pub name: String,
}
impl fmt::Display for Extra {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.manual_url, self.name)
}
}
pub fn get_hash<T>(obj: &T) -> u64
where T: Hash
{
let mut s = DefaultHasher::new();
obj.hash(&mut s);
s.finish()
}

36
src/models/config.rs Normal file
View File

@ -0,0 +1,36 @@
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
#[serde(default)]
pub game_storage: String,
#[serde(default)]
pub movie_storage: String,
#[serde(default = "default_list")]
pub os_filters: Vec<String>,
#[serde(default = "default_list")]
pub language_filters: Vec<String>,
#[serde(default = "default_list")]
pub resolution_filters: Vec<String>,
#[serde(default)]
pub skip_movies: bool,
#[serde(default)]
pub skip_games: bool,
}
impl Config {
pub fn new() -> Config {
Config {
game_storage: String::from("."),
movie_storage: String::from("."),
os_filters: Vec::new(),
language_filters: Vec::new(),
resolution_filters: Vec::new(),
skip_movies: false,
skip_games: false,
}
}
}
fn default_list() -> Vec<String> {
Vec::new()
}

49
src/models/content.rs Normal file
View File

@ -0,0 +1,49 @@
use models::data::Data;
use models::extra::Extra;
use regex::Regex;
use serde::{Deserialize, Deserializer};
use std::collections::BTreeMap;
use std::fmt;
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Content {
#[serde(skip_deserializing)]
pub id: u64,
#[serde(deserialize_with = "normalize_title")]
pub title: String,
#[serde(skip_deserializing)]
#[serde(rename(deserialize = "cdKey"))]
pub cd_keys: BTreeMap<String, String>,
#[serde(skip_deserializing)]
pub is_movie: bool,
#[serde(skip_deserializing)]
pub data: Vec<Data>,
pub extras: Vec<Extra>,
}
impl fmt::Display for Content {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({})", self.title)
}
}
fn normalize_title<D>(deserializer: D) -> Result<String, D::Error>
where D: Deserializer
{
let raw_title = String::deserialize(deserializer)?.replace(":", " - ");
let regex_normalize = Regex::new(r"[^'^\w^\s^-]+").unwrap();
let regex_whitespace = Regex::new(r"\s\s+").unwrap();
let title_normalized = regex_normalize
.replace_all(raw_title.as_str(), "")
.to_string();
let title_whitespace = regex_whitespace
.replace_all(title_normalized.as_str(), " ")
.to_string();
Ok(title_whitespace)
}

29
src/models/contentinfo.rs Normal file
View File

@ -0,0 +1,29 @@
use models::datainfo::DataInfo;
use models::extrainfo::ExtraInfo;
use std::collections::BTreeMap;
use std::collections::HashMap;
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ContentInfo {
#[serde(skip_deserializing)]
pub id: u64,
pub hash: u64,
pub title: String,
pub cd_keys: BTreeMap<String, String>,
pub data: HashMap<String, DataInfo>,
pub extras: HashMap<String, ExtraInfo>,
}
impl ContentInfo {
pub fn new() -> ContentInfo {
ContentInfo {
id: 0,
hash: 0,
title: String::new(),
cd_keys: BTreeMap::new(),
data: HashMap::new(),
extras: HashMap::new(),
}
}
}

22
src/models/data.rs Normal file
View File

@ -0,0 +1,22 @@
use std::fmt;
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Data {
pub manual_url: String,
pub version: String,
pub os: String,
pub language: String,
}
impl fmt::Display for Data {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"({}, {}, {}, {})",
self.manual_url,
self.version,
self.os,
self.language)
}
}

7
src/models/datainfo.rs Normal file
View File

@ -0,0 +1,7 @@
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataInfo {
pub hash: u64,
pub filename: String,
pub language: String,
}

15
src/models/extra.rs Normal file
View File

@ -0,0 +1,15 @@
use std::fmt;
#[derive(Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Extra {
pub manual_url: String,
pub name: String,
}
impl fmt::Display for Extra {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.manual_url, self.name)
}
}

7
src/models/extrainfo.rs Normal file
View File

@ -0,0 +1,7 @@
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExtraInfo {
pub hash: u64,
pub filename: String,
pub name: String,
}

19
src/models/mod.rs Normal file
View File

@ -0,0 +1,19 @@
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
pub mod config;
pub mod content;
pub mod contentinfo;
pub mod data;
pub mod datainfo;
pub mod extra;
pub mod extrainfo;
pub mod token;
pub fn get_hash<T>(obj: &T) -> u64
where T: Hash
{
let mut s = DefaultHasher::new();
obj.hash(&mut s);
s.finish()
}

26
src/models/token.rs Normal file
View File

@ -0,0 +1,26 @@
use chrono::UTC;
#[derive(Serialize, Deserialize)]
pub struct Token {
pub access_token: String,
pub expires_in: u16,
pub token_type: String,
pub scope: String,
pub session_id: String,
pub refresh_token: String,
pub user_id: String,
#[serde(default = "timestamp")]
pub timestamp: i64,
}
impl Token {
pub fn is_expired(&self) -> bool {
let now = UTC::now().timestamp();
now > self.timestamp + self.expires_in as i64
}
}
fn timestamp() -> i64 {
UTC::now().timestamp()
}