From 227d09bce7b2aa46f17f5ca99755767e13c00c7b Mon Sep 17 00:00:00 2001 From: jb-alvarado Date: Mon, 6 Jun 2022 23:07:11 +0200 Subject: [PATCH] start with API --- .gitignore | 1 + Cargo.lock | 809 ++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 9 + src/api/handles.rs | 102 ++++++ src/api/mod.rs | 3 + src/api/models.rs | 17 + src/api/routes.rs | 41 +++ src/bin/ffpapi.rs | 109 ++++++ src/lib.rs | 1 + src/main.rs | 9 +- src/tests/mod.rs | 17 +- src/tests/utils/mod.rs | 2 +- src/utils/arg_parse.rs | 2 +- src/utils/config.rs | 97 ++--- src/utils/logging.rs | 14 +- src/utils/mod.rs | 2 +- 16 files changed, 1160 insertions(+), 75 deletions(-) create mode 100644 src/api/handles.rs create mode 100644 src/api/mod.rs create mode 100644 src/api/models.rs create mode 100644 src/api/routes.rs create mode 100644 src/bin/ffpapi.rs diff --git a/.gitignore b/.gitignore index d43385d9..3cf88035 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,6 @@ *tar.gz *.deb *.rpm +/assets/*.db* .vscode/ diff --git a/Cargo.lock b/Cargo.lock index d8935839..a5e4bade 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,202 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix-codec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "log", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util 0.7.2", +] + +[[package]] +name = "actix-http" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5885cb81a0d4d0d322864bea1bb6c2a8144626b4fdc625d4c51eba197e7797a" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha-1", + "smallvec", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb60846b52c118f2f04a56cc90880a274271c489b2498623d58176f8ca21fa80" +dependencies = [ + "bytestring", + "firestorm", + "http", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio 0.8.3", + "num_cpus", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e5ebffd51d50df56a3ae0de0e59487340ca456f05dd0b90c0a7a6dd6a74d31" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if 1.0.0", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time 0.3.9", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7525bedf54704abb1d469e88d7e7e9226df73778798a69cea5022d53b2ae91bc" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -17,6 +207,30 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + [[package]] name = "atty" version = "0.2.14" @@ -46,6 +260,36 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bstr" version = "0.2.17" @@ -61,17 +305,35 @@ version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "bytestring" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" +dependencies = [ + "bytes", +] + [[package]] name = "cc" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -85,6 +347,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi 0.3.9", +] + [[package]] name = "chrono" version = "0.4.19" @@ -136,6 +410,23 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" +dependencies = [ + "percent-encoding", + "time 0.3.9", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -152,6 +443,30 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + [[package]] name = "crc32fast" version = "1.3.2" @@ -171,6 +486,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.8" @@ -181,6 +506,51 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "email-encoding" version = "0.1.0" @@ -199,6 +569,23 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "event-listener" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" + +[[package]] +name = "faccess" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" +dependencies = [ + "bitflags", + "libc", + "winapi 0.3.9", +] + [[package]] name = "fastrand" version = "1.7.0" @@ -212,9 +599,11 @@ dependencies = [ name = "ffplayout-engine" version = "0.9.8" dependencies = [ - "chrono", + "actix-web", + "chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)", "clap", "crossbeam-channel", + "faccess", "ffprobe", "file-rotate", "jsonrpc-http-server", @@ -228,8 +617,10 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "sha-crypt", "shlex", "simplelog", + "sqlx", "time 0.3.9", "walkdir", ] @@ -249,7 +640,7 @@ name = "file-rotate" version = "0.6.0" source = "git+https://github.com/Ploppz/file-rotate.git?branch=timestamp-parse-fix#cb1874a15a7a18de820a57df48d3513e5a4076f4" dependencies = [ - "chrono", + "chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)", "flate2", ] @@ -265,6 +656,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "firestorm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c5f6c2c942da57e2aaaa84b8a521489486f14e75e7fa91dab70aba913975f98" + [[package]] name = "flate2" version = "1.0.24" @@ -275,6 +672,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.10.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -383,6 +792,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + [[package]] name = "futures-io" version = "0.3.21" @@ -430,6 +850,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.6" @@ -478,12 +908,27 @@ name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown", +] [[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -494,6 +939,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hostname" version = "0.3.1" @@ -641,12 +1092,30 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.57" @@ -683,7 +1152,7 @@ dependencies = [ "jsonrpc-server-utils", "log", "net2", - "parking_lot", + "parking_lot 0.11.2", "unicase", ] @@ -715,6 +1184,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.4.0" @@ -754,12 +1229,41 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "local-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + [[package]] name = "lock_api" version = "0.4.7" @@ -1049,7 +1553,17 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.3", ] [[package]] @@ -1066,12 +1580,51 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" + [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1245,6 +1798,15 @@ dependencies = [ "winreg", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.10" @@ -1299,6 +1861,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" + [[package]] name = "serde" version = "1.0.137" @@ -1354,12 +1922,54 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha-crypt" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0193e80e8a92aa7173dad160cfd5f5eda57ba146aac9826ea5c9dc3d5492072" +dependencies = [ + "rand", + "sha2", + "subtle", +] + +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "simplelog" version = "0.12.0" @@ -1394,12 +2004,133 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "spin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash", + "atoi", + "bitflags", + "byteorder", + "bytes", + "chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "actix-rt", + "native-tls", + "once_cell", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.95" @@ -1440,6 +2171,26 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" @@ -1496,7 +2247,9 @@ dependencies = [ "mio 0.8.3", "num_cpus", "once_cell", + "parking_lot 0.12.1", "pin-project-lite", + "signal-hook-registry", "socket2", "winapi 0.3.9", ] @@ -1563,6 +2316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if 1.0.0", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1594,6 +2348,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + [[package]] name = "unicase" version = "2.6.0" @@ -1624,6 +2384,18 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "url" version = "2.2.2" @@ -1870,3 +2642,32 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] + +[[package]] +name = "zstd" +version = "0.10.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.6+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" +dependencies = [ + "cc", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 6bcee844..3396a03e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,11 @@ edition = "2021" default-run = "ffplayout" [dependencies] +actix-web = "4" chrono = { git = "https://github.com/sbrocket/chrono", branch = "parse-error-kind-public" } clap = { version = "3.1", features = ["derive"] } crossbeam-channel = "0.5" +faccess = "0.2" ffprobe = "0.3" file-rotate = { git = "https://github.com/Ploppz/file-rotate.git", branch = "timestamp-parse-fix" } jsonrpc-http-server = "18.0" @@ -21,11 +23,14 @@ notify = "4.0" rand = "0.8" regex = "1" reqwest = { version = "0.11", features = ["blocking"] } +sha-crypt = { version = "0.4", features = ["simple"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" shlex = "1.1" simplelog = { version = "^0.12", features = ["paris"] } + +sqlx = { version = "0.5", features = [ "chrono", "runtime-actix-native-tls", "sqlite" ] } time = { version = "0.3", features = ["formatting", "macros"] } walkdir = "2" @@ -36,6 +41,10 @@ openssl = { version = "0.10", features = ["vendored"] } name = "ffplayout" path = "src/main.rs" +[[bin]] +name = "ffpapi" +path = "src/bin/ffpapi.rs" + [profile.release] opt-level = 3 strip = true diff --git a/src/api/handles.rs b/src/api/handles.rs new file mode 100644 index 00000000..67b9b546 --- /dev/null +++ b/src/api/handles.rs @@ -0,0 +1,102 @@ +use std::path::Path; + +use faccess::PathExt; +use simplelog::*; +use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Pool, Sqlite, SqlitePool}; + +pub fn db_path() -> Result> { + let sys_path = Path::new("/usr/share/ffplayout"); + let mut db_path = String::from("./ffplayout.db"); + + if sys_path.is_dir() && sys_path.writable() { + db_path = String::from("/usr/share/ffplayout/ffplayout.db"); + } else if Path::new("./assets").is_dir() { + db_path = String::from("./assets/ffplayout.db"); + } + + Ok(db_path) +} + +async fn cretea_schema() -> Result { + let pool = db_connection().await?; + let query = "PRAGMA foreign_keys = ON; + CREATE TABLE IF NOT EXISTS groups + ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + UNIQUE(name) + ); + CREATE TABLE IF NOT EXISTS settings + ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + channel_name TEXT NOT NULL, + preview_url TEXT NOT NULL, + settings_path TEXT NOT NULL, + extra_extensions TEXT NOT NULL, + UNIQUE(channel_name) + ); + CREATE TABLE IF NOT EXISTS user + ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + email TEXT NOT NULL, + username TEXT NOT NULL, + password TEXT NOT NULL, + group_id INTEGER NOT NULL DEFAULT 2, + FOREIGN KEY (group_id) REFERENCES groups (id) ON UPDATE SET NULL ON DELETE SET NULL, + UNIQUE(email, username) + );"; + let result = sqlx::query(query).execute(&pool).await; + pool.close().await; + + result +} + +pub async fn db_init() -> Result<&'static str, Box> { + let db_path = db_path()?; + + if !Sqlite::database_exists(&db_path).await.unwrap_or(false) { + Sqlite::create_database(&db_path).await.unwrap(); + match cretea_schema().await { + Ok(_) => info!("Database created Successfully"), + Err(e) => panic!("{e}"), + } + } + let instances = db_connection().await?; + + let query = "INSERT INTO groups(name) VALUES('admin'), ('user'); + INSERT INTO settings(channel_name, preview_url, settings_path, extra_extensions) + VALUES('Channel 1', 'http://localhost/live/preview.m3u8', + '/etc/ffplayout/ffplayout.yml', '.jpg,.jpeg,.png');"; + sqlx::query(query).execute(&instances).await?; + + instances.close().await; + + Ok("Database initialized!") +} + +pub async fn db_connection() -> Result, sqlx::Error> { + let db_path = db_path().unwrap(); + + let pool = SqlitePool::connect(&db_path).await?; + + Ok(pool) +} + +pub async fn add_user( + instances: &SqlitePool, + mail: &str, + user: &str, + pass: &str, + group: &i64, +) -> Result { + let query = "INSERT INTO user (email, username, password, group_id) VALUES($1, $2, $3, $4)"; + let result = sqlx::query(query) + .bind(mail) + .bind(user) + .bind(pass) + .bind(group) + .execute(instances) + .await?; + + Ok(result) +} diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 00000000..2ce89ab9 --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,3 @@ +pub mod handles; +pub mod models; +pub mod routes; diff --git a/src/api/models.rs b/src/api/models.rs new file mode 100644 index 00000000..feaad65a --- /dev/null +++ b/src/api/models.rs @@ -0,0 +1,17 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct User { + pub email: String, + pub username: String, + pub password: String, + pub group_id: i64, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct Settings { + pub channel_name: String, + pub preview_url: String, + pub settings_path: String, + pub extra_extensions: String, +} diff --git a/src/api/routes.rs b/src/api/routes.rs new file mode 100644 index 00000000..39c135ee --- /dev/null +++ b/src/api/routes.rs @@ -0,0 +1,41 @@ +use crate::api::{ + handles::{add_user, db_connection}, + models::User, +}; +use actix_web::{get, post, web, Responder}; +use sha_crypt::{sha512_simple, Sha512Params}; + +#[get("/hello/{name}")] +async fn greet(name: web::Path) -> impl Responder { + format!("Hello {name}!") +} + +/// curl -X POST -H "Content-Type: application/json" -d '{"username": "USER", "password": "abc123", "email":"user@example.org" }' http://127.0.0.1:8080/api/user/ +#[post("/api/user/")] +pub async fn user(user: web::Json) -> impl Responder { + let params = Sha512Params::new(10_000).expect("RandomError!"); + + let hashed_password = sha512_simple(&user.password, ¶ms).expect("Should not fail"); + + // // Verifying a stored password + // assert!(sha512_check("Not so secure password", &hashed_password).is_ok()); + + if let Ok(pool) = db_connection().await { + if let Err(e) = add_user( + &pool, + &user.email, + &user.username, + &hashed_password, + &user.group_id, + ) + .await + { + pool.close().await; + return e.to_string(); + }; + + pool.close().await; + } + + format!("User {} added", user.username) +} diff --git a/src/bin/ffpapi.rs b/src/bin/ffpapi.rs new file mode 100644 index 00000000..2789b987 --- /dev/null +++ b/src/bin/ffpapi.rs @@ -0,0 +1,109 @@ +use std::process::exit; + +use actix_web::{App, HttpServer}; +use clap::Parser; +use sha_crypt::{sha512_simple, Sha512Params}; +use simplelog::*; + +use ffplayout_engine::{ + api::{ + handles::{add_user, db_connection, db_init}, + routes::user, + }, + utils::{init_logging, GlobalConfig}, +}; + +#[derive(Parser, Debug)] +#[clap(version, + name = "ffpapi", + version = "0.1.0", + about = "ffplayout REST API", + long_about = None)] +pub struct Args { + #[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8080")] + pub listen: Option, + + #[clap(short, long, help = "Initialize Database")] + pub init: bool, + + #[clap(short, long, help = "Create admin user")] + pub username: Option, + + #[clap(short, long, help = "Admin email")] + pub email: Option, + + #[clap(short, long, help = "Admin password")] + pub password: Option, +} + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + let args = Args::parse(); + + if !args.init && args.listen.is_none() && args.username.is_none() { + error!("Wrong number of arguments! Run ffpapi --help for more information."); + + exit(1); + } + + let mut config = GlobalConfig::new(None); + config.mail.recipient = String::new(); + config.logging.log_to_file = false; + + let logging = init_logging(&config, None, None); + CombinedLogger::init(logging).unwrap(); + + if args.init { + if let Err(e) = db_init().await { + panic!("{e}"); + }; + + exit(0); + } + + if let Some(username) = args.username { + if args.email.is_none() || args.password.is_none() { + error!("Email/password missing!"); + exit(1); + } + + let params = Sha512Params::new(10_000).expect("RandomError!"); + + let hashed_password = + sha512_simple(&args.password.unwrap(), ¶ms).expect("Should not fail"); + + match db_connection().await { + Ok(pool) => { + if let Err(e) = + add_user(&pool, &args.email.unwrap(), &username, &hashed_password, &1).await + { + pool.close().await; + error!("{e}"); + exit(1); + }; + + pool.close().await; + info!("Create admin user \"{username}\" done..."); + + exit(0); + } + Err(e) => { + panic!("{e}") + } + } + } + + if let Some(conn) = args.listen { + let ip_port = conn.split(':').collect::>(); + let addr = ip_port[0]; + let port = ip_port[1].parse::().unwrap(); + info!("running ffplayout API, listen on {conn}"); + + HttpServer::new(|| App::new().service(user)) + .bind((addr, port))? + .run() + .await + } else { + panic!("Run ffpapi with listen parameter!") + } +} diff --git a/src/lib.rs b/src/lib.rs index 0738833b..89174366 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ extern crate log; extern crate simplelog; +pub mod api; pub mod filter; pub mod input; pub mod macros; diff --git a/src/main.rs b/src/main.rs index 4feba587..da758623 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,8 @@ use ffplayout_engine::{ output::{player, write_hls}, rpc::json_rpc_server, utils::{ - generate_playlist, init_logging, send_mail, validate_ffmpeg, GlobalConfig, PlayerControl, - PlayoutStatus, ProcessControl, + generate_playlist, get_args, init_logging, send_mail, validate_ffmpeg, GlobalConfig, + PlayerControl, PlayoutStatus, ProcessControl, }, }; @@ -56,7 +56,8 @@ fn status_file(stat_file: &str, playout_stat: &PlayoutStatus) { } fn main() { - let config = GlobalConfig::new(); + let args = get_args(); + let config = GlobalConfig::new(Some(args)); let config_clone = config.clone(); let play_control = PlayerControl::new(); let playout_stat = PlayoutStatus::new(); @@ -67,7 +68,7 @@ fn main() { let proc_ctl2 = proc_control.clone(); let messages = Arc::new(Mutex::new(Vec::new())); - let logging = init_logging(&config, proc_ctl1, messages.clone()); + let logging = init_logging(&config, Some(proc_ctl1), Some(messages.clone())); CombinedLogger::init(logging).unwrap(); validate_ffmpeg(&config); diff --git a/src/tests/mod.rs b/src/tests/mod.rs index d12fd964..859b2026 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,5 +1,4 @@ use std::{ - sync::{Arc, Mutex}, thread::{self, sleep}, time::Duration, }; @@ -22,26 +21,24 @@ fn timed_kill(sec: u64, mut proc_ctl: ProcessControl) { #[test] #[ignore] fn playlist_change_at_midnight() { - let mut config = GlobalConfig::new(); + let mut config = GlobalConfig::new(None); config.mail.recipient = "".into(); config.processing.mode = "playlist".into(); config.playlist.day_start = "00:00:00".into(); config.playlist.length = "24:00:00".into(); config.logging.log_to_file = false; - let messages = Arc::new(Mutex::new(Vec::new())); let play_control = PlayerControl::new(); let playout_stat = PlayoutStatus::new(); let proc_control = ProcessControl::new(); let proc_ctl = proc_control.clone(); - let proc_ctl2 = proc_control.clone(); - let logging = init_logging(&config, proc_ctl, messages); + let logging = init_logging(&config, None, None); CombinedLogger::init(logging).unwrap(); mock_time::set_mock_time("2022-05-09T23:59:45"); - thread::spawn(move || timed_kill(30, proc_ctl2)); + thread::spawn(move || timed_kill(30, proc_ctl)); player(&config, play_control, playout_stat, proc_control); } @@ -49,26 +46,24 @@ fn playlist_change_at_midnight() { #[test] #[ignore] fn playlist_change_at_six() { - let mut config = GlobalConfig::new(); + let mut config = GlobalConfig::new(None); config.mail.recipient = "".into(); config.processing.mode = "playlist".into(); config.playlist.day_start = "06:00:00".into(); config.playlist.length = "24:00:00".into(); config.logging.log_to_file = false; - let messages = Arc::new(Mutex::new(Vec::new())); let play_control = PlayerControl::new(); let playout_stat = PlayoutStatus::new(); let proc_control = ProcessControl::new(); let proc_ctl = proc_control.clone(); - let proc_ctl2 = proc_control.clone(); - let logging = init_logging(&config, proc_ctl, messages); + let logging = init_logging(&config, None, None); CombinedLogger::init(logging).unwrap(); mock_time::set_mock_time("2022-05-09T05:59:45"); - thread::spawn(move || timed_kill(30, proc_ctl2)); + thread::spawn(move || timed_kill(30, proc_ctl)); player(&config, play_control, playout_stat, proc_control); } diff --git a/src/tests/utils/mod.rs b/src/tests/utils/mod.rs index 2267bdfe..af2766b7 100644 --- a/src/tests/utils/mod.rs +++ b/src/tests/utils/mod.rs @@ -39,7 +39,7 @@ fn get_date_tomorrow() { #[test] fn test_delta() { - let mut config = GlobalConfig::new(); + let mut config = GlobalConfig::new(None); config.mail.recipient = "".into(); config.processing.mode = "playlist".into(); config.playlist.day_start = "00:00:00".into(); diff --git a/src/utils/arg_parse.rs b/src/utils/arg_parse.rs index f5c28ec2..ef0550ba 100644 --- a/src/utils/arg_parse.rs +++ b/src/utils/arg_parse.rs @@ -1,6 +1,6 @@ use clap::Parser; -#[derive(Parser, Debug)] +#[derive(Parser, Debug, Clone)] #[clap(version, about = "ffplayout, Rust based 24/7 playout solution.", override_usage = "Run without any command to use config file only, or with commands to override parameters:\n\n ffplayout [OPTIONS]", diff --git a/src/utils/config.rs b/src/utils/config.rs index 2593c5bf..8c291c24 100644 --- a/src/utils/config.rs +++ b/src/utils/config.rs @@ -8,7 +8,7 @@ use std::{ use serde::{Deserialize, Serialize}; use shlex::split; -use crate::utils::{get_args, time_to_sec}; +use crate::utils::{time_to_sec, Args}; use crate::vec_strings; /// Global Config @@ -136,11 +136,10 @@ pub struct Out { impl GlobalConfig { /// Read config from YAML file, and set some extra config values. - pub fn new() -> Self { - let args = get_args(); + pub fn new(args: Option) -> Self { let mut config_path = PathBuf::from("/etc/ffplayout/ffplayout.yml"); - if let Some(cfg) = args.config { + if let Some(cfg) = args.clone().and_then(|a| a.config) { config_path = PathBuf::from(cfg); } @@ -219,55 +218,57 @@ impl GlobalConfig { // Read command line arguments, and override the config with them. - if let Some(gen) = args.generate { - config.general.generate = Some(gen); - } - - if let Some(log_path) = args.log { - if Path::new(&log_path).is_dir() { - config.logging.log_to_file = true; + if let Some(arg) = args { + if let Some(gen) = arg.generate { + config.general.generate = Some(gen); } - config.logging.log_path = log_path; - } - if let Some(playlist) = args.playlist { - config.playlist.path = playlist; - } - - if let Some(mode) = args.play_mode { - config.processing.mode = mode; - } - - if let Some(folder) = args.folder { - config.storage.path = folder; - config.processing.mode = "folder".into(); - } - - if let Some(start) = args.start { - config.playlist.day_start = start.clone(); - config.playlist.start_sec = Some(time_to_sec(&start)); - } - - if let Some(length) = args.length { - config.playlist.length = length.clone(); - - if length.contains(':') { - config.playlist.length_sec = Some(time_to_sec(&length)); - } else { - config.playlist.length_sec = Some(86400.0); + if let Some(log_path) = arg.log { + if Path::new(&log_path).is_dir() { + config.logging.log_to_file = true; + } + config.logging.log_path = log_path; } - } - if args.infinit { - config.playlist.infinit = args.infinit; - } + if let Some(playlist) = arg.playlist { + config.playlist.path = playlist; + } - if let Some(output) = args.output { - config.out.mode = output; - } + if let Some(mode) = arg.play_mode { + config.processing.mode = mode; + } - if let Some(volume) = args.volume { - config.processing.volume = volume; + if let Some(folder) = arg.folder { + config.storage.path = folder; + config.processing.mode = "folder".into(); + } + + if let Some(start) = arg.start { + config.playlist.day_start = start.clone(); + config.playlist.start_sec = Some(time_to_sec(&start)); + } + + if let Some(length) = arg.length { + config.playlist.length = length.clone(); + + if length.contains(':') { + config.playlist.length_sec = Some(time_to_sec(&length)); + } else { + config.playlist.length_sec = Some(86400.0); + } + } + + if arg.infinit { + config.playlist.infinit = arg.infinit; + } + + if let Some(output) = arg.output { + config.out.mode = output; + } + + if let Some(volume) = arg.volume { + config.processing.volume = volume; + } } config @@ -276,7 +277,7 @@ impl GlobalConfig { impl Default for GlobalConfig { fn default() -> Self { - Self::new() + Self::new(None) } } diff --git a/src/utils/logging.rs b/src/utils/logging.rs index 88a379f4..2b853d52 100644 --- a/src/utils/logging.rs +++ b/src/utils/logging.rs @@ -167,8 +167,8 @@ fn clean_string(text: &str) -> String { /// - mail logger pub fn init_logging( config: &GlobalConfig, - proc_ctl: ProcessControl, - messages: Arc>>, + proc_ctl: Option, + messages: Option>>>, ) -> Vec> { let config_clone = config.clone(); let app_config = config.logging.clone(); @@ -182,6 +182,8 @@ pub fn init_logging( let mut log_config = ConfigBuilder::new() .set_thread_level(LevelFilter::Off) .set_target_level(LevelFilter::Off) + .add_filter_ignore_str("sqlx") + .add_filter_ignore_str("reqwest") .set_level_padding(LevelPadding::Left) .set_time_level(time_level) .clone(); @@ -247,10 +249,12 @@ pub fn init_logging( // set mail logger only the recipient is set in config if config.mail.recipient.contains('@') && config.mail.recipient.contains('.') { - let messages_clone = messages.clone(); + let messages_clone = messages.clone().unwrap(); let interval = config.mail.interval; - thread::spawn(move || mail_queue(config_clone, proc_ctl, messages_clone, interval)); + thread::spawn(move || { + mail_queue(config_clone, proc_ctl.unwrap(), messages_clone, interval) + }); let mail_config = log_config.build(); @@ -260,7 +264,7 @@ pub fn init_logging( _ => LevelFilter::Error, }; - app_logger.push(LogMailer::new(filter, mail_config, messages)); + app_logger.push(LogMailer::new(filter, mail_config, messages.unwrap())); } app_logger diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 5e01c6f7..232a6b68 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -23,7 +23,7 @@ pub mod json_serializer; mod json_validate; mod logging; -pub use arg_parse::get_args; +pub use arg_parse::{get_args, Args}; pub use config::GlobalConfig; pub use controller::{PlayerControl, PlayoutStatus, ProcessControl, ProcessUnit::*}; pub use generator::generate_playlist;