From f0709a2a4b507e2f4b869e451c57913ed2422332 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 9 Oct 2021 12:04:26 +0200 Subject: [PATCH] Add socket server and initialization Signed-off-by: trivernis --- mediarepo-daemon/Cargo.lock | 125 +++++++++++++++++- mediarepo-daemon/Cargo.toml | 8 +- mediarepo-daemon/mediarepo-core/Cargo.lock | 88 +++++++++++- mediarepo-daemon/mediarepo-core/Cargo.toml | 4 + mediarepo-daemon/mediarepo-core/src/error.rs | 9 ++ mediarepo-daemon/mediarepo-core/src/lib.rs | 1 + .../mediarepo-core/src/settings.rs | 27 +++- .../mediarepo-core/src/type_keys.rs | 8 ++ .../mediarepo-database/Cargo.lock | 54 +++++++- .../mediarepo-database/src/entities/file.rs | 22 ++- .../mediarepo-database/src/entities/hash.rs | 2 +- .../src/entities/hash_source.rs | 18 ++- .../src/entities/hash_tag.rs | 18 ++- .../src/entities/namespace.rs | 6 +- .../mediarepo-database/src/entities/source.rs | 9 +- .../src/entities/storage.rs | 4 +- .../mediarepo-database/src/entities/tag.rs | 10 +- .../mediarepo-database/src/lib.rs | 4 + mediarepo-daemon/mediarepo-model/Cargo.lock | 55 +++++++- mediarepo-daemon/mediarepo-model/Cargo.toml | 1 + .../mediarepo-model/src/{models => }/file.rs | 8 +- .../src/{models => }/file_type.rs | 0 mediarepo-daemon/mediarepo-model/src/lib.rs | 6 +- .../mediarepo-model/src/models/mod.rs | 3 - mediarepo-daemon/mediarepo-model/src/repo.rs | 29 ++++ .../src/{models => }/storage.rs | 4 +- .../mediarepo-model/src/type_keys.rs | 8 ++ mediarepo-daemon/mediarepo-socket/Cargo.toml | 2 +- mediarepo-daemon/mediarepo-socket/src/lib.rs | 12 +- .../mediarepo-socket/src/namespaces/mod.rs | 0 mediarepo-daemon/src/constants.rs | 2 + mediarepo-daemon/src/main.rs | 85 +++++++++++- mediarepo-daemon/src/utils.rs | 31 +++++ 33 files changed, 587 insertions(+), 76 deletions(-) create mode 100644 mediarepo-daemon/mediarepo-core/src/type_keys.rs rename mediarepo-daemon/mediarepo-model/src/{models => }/file.rs (96%) rename mediarepo-daemon/mediarepo-model/src/{models => }/file_type.rs (100%) delete mode 100644 mediarepo-daemon/mediarepo-model/src/models/mod.rs create mode 100644 mediarepo-daemon/mediarepo-model/src/repo.rs rename mediarepo-daemon/mediarepo-model/src/{models => }/storage.rs (97%) create mode 100644 mediarepo-daemon/mediarepo-model/src/type_keys.rs create mode 100644 mediarepo-daemon/mediarepo-socket/src/namespaces/mod.rs create mode 100644 mediarepo-daemon/src/constants.rs create mode 100644 mediarepo-daemon/src/utils.rs diff --git a/mediarepo-daemon/Cargo.lock b/mediarepo-daemon/Cargo.lock index a022ec6..933ae3f 100644 --- a/mediarepo-daemon/Cargo.lock +++ b/mediarepo-daemon/Cargo.lock @@ -13,6 +13,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "arrayref" version = "0.3.6" @@ -72,6 +81,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -203,6 +223,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -637,9 +672,11 @@ name = "mediarepo" version = "0.1.0" dependencies = [ "mediarepo-core", - "mediarepo-database", + "mediarepo-model", "mediarepo-socket", + "structopt", "tokio", + "toml", ] [[package]] @@ -649,10 +686,14 @@ dependencies = [ "base64", "multibase", "multihash", + "rmp-ipc", "sea-orm", + "serde", "sqlx", "thiserror", "tokio", + "toml", + "typemap_rev", ] [[package]] @@ -665,6 +706,18 @@ dependencies = [ "sqlx", ] +[[package]] +name = "mediarepo-model" +version = "0.1.0" +dependencies = [ + "chrono", + "mediarepo-core", + "mediarepo-database", + "sea-orm", + "tokio", + "typemap_rev", +] + [[package]] name = "mediarepo-socket" version = "0.1.0" @@ -1087,9 +1140,9 @@ dependencies = [ [[package]] name = "rmp-ipc" -version = "0.2.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89adfd1783c5091d67736f75c3e257e672303287b5faf4696ab209cb56385f9a" +checksum = "af495ca346adde10163eb920b52b5a3992fb209b31df58ece4ed0f855661978c" dependencies = [ "lazy_static", "log", @@ -1097,6 +1150,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "typemap_rev", ] [[package]] @@ -1428,6 +1482,36 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +dependencies = [ + "heck", + "proc-macro-error 1.0.4", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" version = "1.0.78" @@ -1476,20 +1560,29 @@ dependencies = [ "winapi", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1580,6 +1673,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typemap_rev" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + [[package]] name = "typenum" version = "1.14.0" @@ -1607,6 +1706,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -1653,6 +1758,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.3" diff --git a/mediarepo-daemon/Cargo.toml b/mediarepo-daemon/Cargo.toml index 78c7434..a32bf64 100644 --- a/mediarepo-daemon/Cargo.toml +++ b/mediarepo-daemon/Cargo.toml @@ -6,16 +6,18 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +toml = "0.5.8" +structopt = "0.3.23" [dependencies.mediarepo-core] path = "./mediarepo-core" -[dependencies.mediarepo-database] -path = "./mediarepo-database" +[dependencies.mediarepo-model] +path = "./mediarepo-model" [dependencies.mediarepo-socket] path = "./mediarepo-socket" [dependencies.tokio] version = "1.12.0" -features = ["macros", "rt-multi-thread"] \ No newline at end of file +features = ["macros", "rt-multi-thread", "io-std", "io-util"] \ No newline at end of file diff --git a/mediarepo-daemon/mediarepo-core/Cargo.lock b/mediarepo-daemon/mediarepo-core/Cargo.lock index 560442e..7e3bb88 100644 --- a/mediarepo-daemon/mediarepo-core/Cargo.lock +++ b/mediarepo-daemon/mediarepo-core/Cargo.lock @@ -556,10 +556,14 @@ dependencies = [ "base64", "multibase", "multihash", + "rmp-ipc", "sea-orm", + "serde", "sqlx", "thiserror", "tokio", + "toml", + "typemap_rev", ] [[package]] @@ -574,6 +578,28 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c835948974f68e0bd58636fc6c5b1fbff7b297e3046f11b3b3c18bbac012c6d" +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + [[package]] name = "multibase" version = "0.9.1" @@ -627,6 +653,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -764,6 +799,42 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rmp" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f55e5fa1446c4d5dd1f5daeed2a4fe193071771a2636274d0d7a3b082aa7ad6" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "rmp-ipc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af495ca346adde10163eb920b52b5a3992fb209b31df58ece4ed0f855661978c" +dependencies = [ + "lazy_static", + "log", + "rmp-serde", + "serde", + "thiserror", + "tokio", + "typemap_rev", +] + +[[package]] +name = "rmp-serde" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723ecff9ad04f4ad92fe1c8ca6c20d2196d9286e9c60727c4cb5511629260e9d" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1006,18 +1077,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1047,8 +1118,11 @@ checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" dependencies = [ "autocfg", "bytes", + "libc", "memchr", + "mio", "pin-project-lite", + "winapi", ] [[package]] @@ -1060,6 +1134,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typemap_rev" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + [[package]] name = "typenum" version = "1.14.0" diff --git a/mediarepo-daemon/mediarepo-core/Cargo.toml b/mediarepo-daemon/mediarepo-core/Cargo.toml index b1ce352..db4e526 100644 --- a/mediarepo-daemon/mediarepo-core/Cargo.toml +++ b/mediarepo-daemon/mediarepo-core/Cargo.toml @@ -10,6 +10,10 @@ thiserror = "1.0.29" multihash = "0.15.0" multibase = "0.9.1" base64 = "0.13.0" +toml = "0.5.8" +serde = "1.0.130" +rmp-ipc = "0.4.0" +typemap_rev = "0.1.5" [dependencies.sea-orm] version = "0.2.4" diff --git a/mediarepo-daemon/mediarepo-core/src/error.rs b/mediarepo-daemon/mediarepo-core/src/error.rs index c237da5..10f5a5a 100644 --- a/mediarepo-daemon/mediarepo-core/src/error.rs +++ b/mediarepo-daemon/mediarepo-core/src/error.rs @@ -14,6 +14,15 @@ pub enum RepoError { #[error(transparent)] Multibase(#[from] multibase::Error), + + #[error("Config Error: {0}")] + TomlDe(#[from] toml::de::Error), + + #[error("Config Error: {0}")] + TomlSer(#[from] toml::ser::Error), + + #[error(transparent)] + IPC(#[from] rmp_ipc::error::Error), } #[derive(Error, Debug)] diff --git a/mediarepo-daemon/mediarepo-core/src/lib.rs b/mediarepo-daemon/mediarepo-core/src/lib.rs index e70f174..d065439 100644 --- a/mediarepo-daemon/mediarepo-core/src/lib.rs +++ b/mediarepo-daemon/mediarepo-core/src/lib.rs @@ -2,3 +2,4 @@ pub mod context; pub mod error; pub mod file_hash_store; pub mod settings; +pub mod type_keys; diff --git a/mediarepo-daemon/mediarepo-core/src/settings.rs b/mediarepo-daemon/mediarepo-core/src/settings.rs index eb066f1..fff82aa 100644 --- a/mediarepo-daemon/mediarepo-core/src/settings.rs +++ b/mediarepo-daemon/mediarepo-core/src/settings.rs @@ -1,6 +1,9 @@ -#[derive(Clone, Debug)] +use crate::error::RepoResult; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Settings { - pub repo_path: String, + pub listen_address: String, pub database_path: String, pub default_file_store: String, } @@ -8,9 +11,23 @@ pub struct Settings { impl Default for Settings { fn default() -> Self { Self { - repo_path: "".to_string(), - database_path: "".to_string(), - default_file_store: "".to_string(), + listen_address: "127.0.0.1:3425".to_string(), + database_path: "./db/database.db".to_string(), + default_file_store: "./files".to_string(), } } } + +impl Settings { + /// Parses settings from a string + pub fn from_toml_string(s: &str) -> RepoResult { + let settings = toml::from_str(s)?; + Ok(settings) + } + + /// Converts the settings into a toml string + pub fn to_toml_string(&self) -> RepoResult { + let string = toml::to_string(&self)?; + Ok(string) + } +} diff --git a/mediarepo-daemon/mediarepo-core/src/type_keys.rs b/mediarepo-daemon/mediarepo-core/src/type_keys.rs new file mode 100644 index 0000000..8e97c2e --- /dev/null +++ b/mediarepo-daemon/mediarepo-core/src/type_keys.rs @@ -0,0 +1,8 @@ +use crate::settings::Settings; +use typemap_rev::TypeMapKey; + +pub struct SettingsKey; + +impl TypeMapKey for SettingsKey { + type Value = Settings; +} diff --git a/mediarepo-daemon/mediarepo-database/Cargo.lock b/mediarepo-daemon/mediarepo-database/Cargo.lock index 8431ad8..604dc8f 100644 --- a/mediarepo-daemon/mediarepo-database/Cargo.lock +++ b/mediarepo-daemon/mediarepo-database/Cargo.lock @@ -639,10 +639,14 @@ dependencies = [ "base64", "multibase", "multihash", + "rmp-ipc", "sea-orm", + "serde", "sqlx", "thiserror", "tokio", + "toml", + "typemap_rev", ] [[package]] @@ -1057,6 +1061,42 @@ dependencies = [ "winapi", ] +[[package]] +name = "rmp" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f55e5fa1446c4d5dd1f5daeed2a4fe193071771a2636274d0d7a3b082aa7ad6" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "rmp-ipc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af495ca346adde10163eb920b52b5a3992fb209b31df58ece4ed0f855661978c" +dependencies = [ + "lazy_static", + "log", + "rmp-serde", + "serde", + "thiserror", + "tokio", + "typemap_rev", +] + +[[package]] +name = "rmp-serde" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723ecff9ad04f4ad92fe1c8ca6c20d2196d9286e9c60727c4cb5511629260e9d" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "rust_decimal" version = "1.16.0" @@ -1425,18 +1465,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1514,6 +1554,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typemap_rev" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + [[package]] name = "typenum" version = "1.14.0" diff --git a/mediarepo-daemon/mediarepo-database/src/entities/file.rs b/mediarepo-daemon/mediarepo-database/src/entities/file.rs index b02c0e3..ff35d0c 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/file.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/file.rs @@ -1,16 +1,16 @@ -use sea_orm::prelude::*; use chrono::NaiveDateTime; +use sea_orm::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "files")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, + pub id: i64, pub file_type: u32, pub name: Option, pub comment: Option, - pub storage_id: u64, - pub hash_id: u64, + pub storage_id: i64, + pub hash_id: i64, pub import_time: NaiveDateTime, pub creation_time: NaiveDateTime, pub change_time: NaiveDateTime, @@ -18,10 +18,18 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { - #[sea_orm(belongs_to = "super::hash::Entity", from = "Column::HashId", to = "super::hash::Column::Id")] + #[sea_orm( + belongs_to = "super::hash::Entity", + from = "Column::HashId", + to = "super::hash::Column::Id" + )] Hash, - #[sea_orm(belongs_to = "super::storage::Entity", from = "Column::StorageId", to = "super::storage::Column::Id")] + #[sea_orm( + belongs_to = "super::storage::Entity", + from = "Column::StorageId", + to = "super::storage::Column::Id" + )] Storage, } @@ -37,4 +45,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/entities/hash.rs b/mediarepo-daemon/mediarepo-database/src/entities/hash.rs index 57292e2..984b469 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/hash.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/hash.rs @@ -4,7 +4,7 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "hashes")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, + pub id: i64, pub value: String, } diff --git a/mediarepo-daemon/mediarepo-database/src/entities/hash_source.rs b/mediarepo-daemon/mediarepo-database/src/entities/hash_source.rs index c54b7da..df5eb6a 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/hash_source.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/hash_source.rs @@ -4,16 +4,24 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "hash_source_mappings")] pub struct Model { #[sea_orm(primary_key)] - pub hash_id: u64, + pub hash_id: i64, #[sea_orm(primary_key)] - pub source_id: u64, + pub source_id: i64, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { - #[sea_orm(belongs_to = "super::hash::Entity", from = "Column::HashId", to = "super::hash::Column::Id")] + #[sea_orm( + belongs_to = "super::hash::Entity", + from = "Column::HashId", + to = "super::hash::Column::Id" + )] Hash, - #[sea_orm(belongs_to = "super::source::Entity", from = "Column::SourceId", to = "super::source::Column::Id")] + #[sea_orm( + belongs_to = "super::source::Entity", + from = "Column::SourceId", + to = "super::source::Column::Id" + )] Source, } @@ -29,4 +37,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/entities/hash_tag.rs b/mediarepo-daemon/mediarepo-database/src/entities/hash_tag.rs index 1bb2317..51fb7ea 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/hash_tag.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/hash_tag.rs @@ -4,16 +4,24 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "hash_tag_mappings")] pub struct Model { #[sea_orm(primary_key)] - pub hash_id: u64, + pub hash_id: i64, #[sea_orm(primary_key)] - pub tag_id: u64, + pub tag_id: i64, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { - #[sea_orm(belongs_to = "super::hash::Entity", from = "Column::HashId", to = "super::hash::Column::Id")] + #[sea_orm( + belongs_to = "super::hash::Entity", + from = "Column::HashId", + to = "super::hash::Column::Id" + )] Hash, - #[sea_orm(belongs_to = "super::tag::Entity", from = "Column::TagId", to = "super::tag::Column::Id")] + #[sea_orm( + belongs_to = "super::tag::Entity", + from = "Column::TagId", + to = "super::tag::Column::Id" + )] Tag, } @@ -29,4 +37,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/entities/namespace.rs b/mediarepo-daemon/mediarepo-database/src/entities/namespace.rs index 6574d32..7fd555e 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/namespace.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/namespace.rs @@ -4,8 +4,8 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "namespaces")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, - pub name: String + pub id: i64, + pub name: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] @@ -20,4 +20,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/entities/source.rs b/mediarepo-daemon/mediarepo-database/src/entities/source.rs index f4adcbe..62703e3 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/source.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/source.rs @@ -4,13 +4,12 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "sources")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, - pub url: String + pub id: i64, + pub url: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { -} +pub enum Relation {} impl Related for Entity { fn to() -> RelationDef { @@ -22,4 +21,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/entities/storage.rs b/mediarepo-daemon/mediarepo-database/src/entities/storage.rs index bf13b97..10b2ce8 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/storage.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/storage.rs @@ -1,10 +1,10 @@ use sea_orm::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] -#[sea_orm(table_name = "storages")] +#[sea_orm(table_name = "storage_locations")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, + pub id: i64, pub name: String, pub path: String, } diff --git a/mediarepo-daemon/mediarepo-database/src/entities/tag.rs b/mediarepo-daemon/mediarepo-database/src/entities/tag.rs index eba6841..b890c4c 100644 --- a/mediarepo-daemon/mediarepo-database/src/entities/tag.rs +++ b/mediarepo-daemon/mediarepo-database/src/entities/tag.rs @@ -4,14 +4,18 @@ use sea_orm::prelude::*; #[sea_orm(table_name = "tags")] pub struct Model { #[sea_orm(primary_key)] - pub id: u64, + pub id: i64, pub namespace_id: Option, pub name: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { - #[sea_orm(belongs_to = "super::namespace::Entity", from = "Column::NamespaceId", to = "super::namespace::Column::Id")] + #[sea_orm( + belongs_to = "super::namespace::Entity", + from = "Column::NamespaceId", + to = "super::namespace::Column::Id" + )] Namespace, } @@ -25,4 +29,4 @@ impl Related for Entity { } } -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file +impl ActiveModelBehavior for ActiveModel {} diff --git a/mediarepo-daemon/mediarepo-database/src/lib.rs b/mediarepo-daemon/mediarepo-database/src/lib.rs index d7ea59d..2361700 100644 --- a/mediarepo-daemon/mediarepo-database/src/lib.rs +++ b/mediarepo-daemon/mediarepo-database/src/lib.rs @@ -1,5 +1,6 @@ use mediarepo_core::error::RepoDatabaseResult; use sea_orm::{Database, DatabaseConnection}; +use sqlx::migrate::MigrateDatabase; pub mod entities; @@ -13,6 +14,9 @@ pub async fn get_database>(uri: S) -> RepoDatabaseResult RepoDatabaseResult<()> { use sqlx::Connection; + if !sqlx::Sqlite::database_exists(uri).await? { + sqlx::Sqlite::create_database(uri).await?; + } let mut conn = sqlx::SqliteConnection::connect(uri).await?; sqlx::migrate!().run(&mut conn).await?; diff --git a/mediarepo-daemon/mediarepo-model/Cargo.lock b/mediarepo-daemon/mediarepo-model/Cargo.lock index f990c4a..bcb5b70 100644 --- a/mediarepo-daemon/mediarepo-model/Cargo.lock +++ b/mediarepo-daemon/mediarepo-model/Cargo.lock @@ -639,10 +639,14 @@ dependencies = [ "base64", "multibase", "multihash", + "rmp-ipc", "sea-orm", + "serde", "sqlx", "thiserror", "tokio", + "toml", + "typemap_rev", ] [[package]] @@ -664,6 +668,7 @@ dependencies = [ "mediarepo-database", "sea-orm", "tokio", + "typemap_rev", ] [[package]] @@ -1068,6 +1073,42 @@ dependencies = [ "winapi", ] +[[package]] +name = "rmp" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f55e5fa1446c4d5dd1f5daeed2a4fe193071771a2636274d0d7a3b082aa7ad6" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "rmp-ipc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af495ca346adde10163eb920b52b5a3992fb209b31df58ece4ed0f855661978c" +dependencies = [ + "lazy_static", + "log", + "rmp-serde", + "serde", + "thiserror", + "tokio", + "typemap_rev", +] + +[[package]] +name = "rmp-serde" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723ecff9ad04f4ad92fe1c8ca6c20d2196d9286e9c60727c4cb5511629260e9d" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "rust_decimal" version = "1.16.0" @@ -1436,18 +1477,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1526,6 +1567,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typemap_rev" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + [[package]] name = "typenum" version = "1.14.0" diff --git a/mediarepo-daemon/mediarepo-model/Cargo.toml b/mediarepo-daemon/mediarepo-model/Cargo.toml index 3dc7e80..4fe34cd 100644 --- a/mediarepo-daemon/mediarepo-model/Cargo.toml +++ b/mediarepo-daemon/mediarepo-model/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] chrono = "0.4.19" +typemap_rev = "0.1.5" [dependencies.mediarepo-core] path = "../mediarepo-core" diff --git a/mediarepo-daemon/mediarepo-model/src/models/file.rs b/mediarepo-daemon/mediarepo-model/src/file.rs similarity index 96% rename from mediarepo-daemon/mediarepo-model/src/models/file.rs rename to mediarepo-daemon/mediarepo-model/src/file.rs index aef89b3..a5eb9e4 100644 --- a/mediarepo-daemon/mediarepo-model/src/models/file.rs +++ b/mediarepo-daemon/mediarepo-model/src/file.rs @@ -1,5 +1,5 @@ -use crate::models::file_type::FileType; -use crate::models::storage::Storage; +use crate::file_type::FileType; +use crate::storage::Storage; use chrono::NaiveDateTime; use mediarepo_core::error::RepoResult; use mediarepo_database::entities::file; @@ -23,7 +23,7 @@ impl File { } /// Fetches the file by id - pub async fn by_id(db: DatabaseConnection, id: u64) -> RepoResult> { + pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult> { if let Some((model, Some(hash))) = file::Entity::find_by_id(id) .find_also_related(hash::Entity) .one(&db) @@ -55,7 +55,7 @@ impl File { } /// Returns the unique identifier of the file - pub fn id(&self) -> u64 { + pub fn id(&self) -> i64 { self.model.id } diff --git a/mediarepo-daemon/mediarepo-model/src/models/file_type.rs b/mediarepo-daemon/mediarepo-model/src/file_type.rs similarity index 100% rename from mediarepo-daemon/mediarepo-model/src/models/file_type.rs rename to mediarepo-daemon/mediarepo-model/src/file_type.rs diff --git a/mediarepo-daemon/mediarepo-model/src/lib.rs b/mediarepo-daemon/mediarepo-model/src/lib.rs index ff92946..dc1152b 100644 --- a/mediarepo-daemon/mediarepo-model/src/lib.rs +++ b/mediarepo-daemon/mediarepo-model/src/lib.rs @@ -1 +1,5 @@ -pub mod models; \ No newline at end of file +pub mod file; +pub mod file_type; +pub mod repo; +pub mod storage; +pub mod type_keys; diff --git a/mediarepo-daemon/mediarepo-model/src/models/mod.rs b/mediarepo-daemon/mediarepo-model/src/models/mod.rs deleted file mode 100644 index 0d43719..0000000 --- a/mediarepo-daemon/mediarepo-model/src/models/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod file; -pub mod file_type; -pub mod storage; diff --git a/mediarepo-daemon/mediarepo-model/src/repo.rs b/mediarepo-daemon/mediarepo-model/src/repo.rs new file mode 100644 index 0000000..7505124 --- /dev/null +++ b/mediarepo-daemon/mediarepo-model/src/repo.rs @@ -0,0 +1,29 @@ +use crate::storage::Storage; +use mediarepo_core::error::RepoResult; +use mediarepo_database::get_database; +use sea_orm::DatabaseConnection; + +pub struct Repo { + db: DatabaseConnection, +} + +impl Repo { + pub(crate) fn new(db: DatabaseConnection) -> Self { + Self { db } + } + + /// Connects to the database with the given uri + pub async fn connect>(uri: S) -> RepoResult { + let db = get_database(uri).await?; + Ok(Self::new(db)) + } + + /// Adds a storage to the repository + pub async fn add_storage( + &self, + name: S1, + path: S2, + ) -> RepoResult { + Storage::create(self.db.clone(), name, path).await + } +} diff --git a/mediarepo-daemon/mediarepo-model/src/models/storage.rs b/mediarepo-daemon/mediarepo-model/src/storage.rs similarity index 97% rename from mediarepo-daemon/mediarepo-model/src/models/storage.rs rename to mediarepo-daemon/mediarepo-model/src/storage.rs index d4ee185..eaacb47 100644 --- a/mediarepo-daemon/mediarepo-model/src/models/storage.rs +++ b/mediarepo-daemon/mediarepo-model/src/storage.rs @@ -26,7 +26,7 @@ impl Storage { } /// Returns the storage by id - pub async fn by_id(db: DatabaseConnection, id: u64) -> RepoResult> { + pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult> { if let Some(model) = storage::Entity::find_by_id(id).one(&db).await? { let storage = Self::new(db, model); Ok(Some(storage)) @@ -78,7 +78,7 @@ impl Storage { } /// Returns the unique identifier of this storage - pub fn id(&self) -> u64 { + pub fn id(&self) -> i64 { self.model.id } diff --git a/mediarepo-daemon/mediarepo-model/src/type_keys.rs b/mediarepo-daemon/mediarepo-model/src/type_keys.rs new file mode 100644 index 0000000..1105ea8 --- /dev/null +++ b/mediarepo-daemon/mediarepo-model/src/type_keys.rs @@ -0,0 +1,8 @@ +use crate::repo::Repo; +use typemap_rev::TypeMapKey; + +pub struct RepoKey; + +impl TypeMapKey for RepoKey { + type Value = Repo; +} diff --git a/mediarepo-daemon/mediarepo-socket/Cargo.toml b/mediarepo-daemon/mediarepo-socket/Cargo.toml index 6c7f799..96c909d 100644 --- a/mediarepo-daemon/mediarepo-socket/Cargo.toml +++ b/mediarepo-daemon/mediarepo-socket/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rmp-ipc = "0.2.1" +rmp-ipc = "0.4.0" [dependencies.tokio] version = "1.12.0" diff --git a/mediarepo-daemon/mediarepo-socket/src/lib.rs b/mediarepo-daemon/mediarepo-socket/src/lib.rs index 31e1bb2..58ac1c3 100644 --- a/mediarepo-daemon/mediarepo-socket/src/lib.rs +++ b/mediarepo-daemon/mediarepo-socket/src/lib.rs @@ -1,7 +1,7 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } +use rmp_ipc::IPCBuilder; + +mod namespaces; + +pub fn get_builder(address: &str) -> IPCBuilder { + IPCBuilder::new().address(address) } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/mod.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/mediarepo-daemon/src/constants.rs b/mediarepo-daemon/src/constants.rs new file mode 100644 index 0000000..4d39e62 --- /dev/null +++ b/mediarepo-daemon/src/constants.rs @@ -0,0 +1,2 @@ +pub static SETTINGS_PATH: &str = "./repo.toml"; +pub static DEFAULT_STORAGE_NAME: &str = "Main"; diff --git a/mediarepo-daemon/src/main.rs b/mediarepo-daemon/src/main.rs index 7f755fb..5c5f6a9 100644 --- a/mediarepo-daemon/src/main.rs +++ b/mediarepo-daemon/src/main.rs @@ -1,2 +1,85 @@ +mod constants; +mod utils; + +use crate::constants::{DEFAULT_STORAGE_NAME, SETTINGS_PATH}; +use crate::utils::{create_paths_for_repo, get_repo, load_settings}; +use mediarepo_core::error::RepoResult; +use mediarepo_core::settings::Settings; +use mediarepo_core::type_keys::SettingsKey; +use mediarepo_model::type_keys::RepoKey; +use mediarepo_socket::get_builder; +use std::path::PathBuf; +use structopt::StructOpt; +use tokio::fs; + +#[derive(Debug, StructOpt)] +#[structopt(name = "mediarepo", about = "A multimedia repository")] +struct Opt { + /// The path to the repository. Defaults to the current working directory + #[structopt(long, short, parse(from_os_str), default_value = ".")] + repo: PathBuf, + + /// The subcommand to invoke + #[structopt(subcommand)] + cmd: SubCommand, +} + +#[derive(Debug, StructOpt)] +enum SubCommand { + /// Initializes an empty repository + Init { + /// Forces the creation of a new repository. This will delete everything in the repository + /// path to create an empty repository. + #[structopt(short, long)] + force: bool, + }, + + /// Starts the event server for the selected repository + Start, +} + #[tokio::main] -async fn main() {} +async fn main() -> RepoResult<()> { + let opt: Opt = Opt::from_args(); + match opt.cmd { + SubCommand::Init { force } => init(opt, force).await, + SubCommand::Start => start_server(opt).await, + }?; + + Ok(()) +} + +/// Starts the server +async fn start_server(opt: Opt) -> RepoResult<()> { + let settings = load_settings(&opt.repo.join(SETTINGS_PATH)).await?; + let repo = get_repo(&opt.repo.join(&settings.database_path).to_str().unwrap()).await?; + + get_builder(&settings.listen_address) + .insert::(settings) + .insert::(repo) + .build_server() + .await?; + + Ok(()) +} + +/// Initializes an empty repository +async fn init(opt: Opt, force: bool) -> RepoResult<()> { + if force { + fs::remove_dir_all(&opt.repo).await?; + } + let settings = Settings::default(); + create_paths_for_repo(&opt.repo, &settings).await?; + let db_path = opt.repo.join(&settings.database_path); + if db_path.exists() { + panic!("Database already exists in location. Use --force with init to delete everything and start a new repository"); + } + let repo = get_repo(&db_path.to_str().unwrap()).await?; + let storage_path = opt.repo.join(&settings.default_file_store); + repo.add_storage(DEFAULT_STORAGE_NAME, storage_path.to_str().unwrap()) + .await?; + let settings_string = settings.to_toml_string()?; + fs::write(opt.repo.join(SETTINGS_PATH), &settings_string.into_bytes()).await?; + + Ok(()) +} diff --git a/mediarepo-daemon/src/utils.rs b/mediarepo-daemon/src/utils.rs new file mode 100644 index 0000000..91f5d9d --- /dev/null +++ b/mediarepo-daemon/src/utils.rs @@ -0,0 +1,31 @@ +use mediarepo_core::error::RepoResult; +use mediarepo_core::settings::Settings; +use mediarepo_model::repo::Repo; +use std::path::PathBuf; +use tokio::fs; + +/// Loads the settings from a toml path +pub async fn load_settings(path: &PathBuf) -> RepoResult { + let contents = fs::read_to_string(path).await?; + Settings::from_toml_string(&contents) +} + +pub async fn get_repo(db_path: &str) -> RepoResult { + Repo::connect(format!("sqlite://{}", db_path)).await +} + +pub async fn create_paths_for_repo(root: &PathBuf, settings: &Settings) -> RepoResult<()> { + if !root.exists() { + fs::create_dir_all(&root).await?; + } + let db_path = root.join(&settings.database_path); + if !db_path.exists() { + fs::create_dir_all(db_path.parent().unwrap()).await?; + } + let storage_path = root.join(&settings.default_file_store); + if !storage_path.exists() { + fs::create_dir_all(storage_path).await?; + } + + Ok(()) +}