feat: more kejiggering, added Sentry support
and tracing spans. (personally I use glitchtip :3)
This commit is contained in:
parent
7e1f504368
commit
71b7eca0b9
23 changed files with 721 additions and 78 deletions
6
.dockerignore
Normal file
6
.dockerignore
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/.*
|
||||
/target
|
||||
/docker-compose.yml
|
||||
/Justfile
|
||||
/mounth.sh
|
||||
*.md
|
||||
2
.env.example
Normal file
2
.env.example
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export DATABASE_URL="postgres://localhost:5432/rave" # The database URL
|
||||
export RAVE_SENTRY_DSN="" # An optional Sentry DSN to send errors to
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
|||
/target
|
||||
users.db*
|
||||
.en*
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
.rave-dev-db
|
||||
|
|
|
|||
507
Cargo.lock
generated
507
Cargo.lock
generated
|
|
@ -599,6 +599,16 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.4"
|
||||
|
|
@ -722,6 +732,16 @@ dependencies = [
|
|||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "debugid"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.8"
|
||||
|
|
@ -869,6 +889,18 @@ version = "2.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "findshlibs"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "finl_unicode"
|
||||
version = "1.2.0"
|
||||
|
|
@ -902,6 +934,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
|
|
@ -1196,6 +1243,17 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"match_cfg",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
|
|
@ -1254,6 +1312,33 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.57"
|
||||
|
|
@ -1371,6 +1456,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
|
|
@ -1467,6 +1558,12 @@ dependencies = [
|
|||
"value-bag",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "match_cfg"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1567,6 +1664,24 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
|
|
@ -1678,6 +1793,50 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "3.9.1"
|
||||
|
|
@ -1687,6 +1846,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_info"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros"
|
||||
version = "0.17.2"
|
||||
|
|
@ -1773,6 +1943,26 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
|
|
@ -1863,6 +2053,7 @@ dependencies = [
|
|||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
|
@ -2089,6 +2280,8 @@ dependencies = [
|
|||
"poem-ext",
|
||||
"quick-xml",
|
||||
"sea-orm",
|
||||
"sentry",
|
||||
"sentry-tracing",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
|
|
@ -2153,6 +2346,49 @@ version = "0.7.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots 0.25.2",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfc7239"
|
||||
version = "0.1.0"
|
||||
|
|
@ -2247,6 +2483,7 @@ version = "0.21.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
|
|
@ -2277,6 +2514,15 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
|
|
@ -2437,12 +2683,157 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
|
||||
|
||||
[[package]]
|
||||
name = "sentry"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0097a48cd1999d983909f07cb03b15241c5af29e5e679379efac1c06296abecc"
|
||||
dependencies = [
|
||||
"httpdate",
|
||||
"native-tls",
|
||||
"reqwest",
|
||||
"rustls",
|
||||
"sentry-backtrace",
|
||||
"sentry-contexts",
|
||||
"sentry-core",
|
||||
"sentry-debug-images",
|
||||
"sentry-panic",
|
||||
"sentry-tower",
|
||||
"sentry-tracing",
|
||||
"tokio",
|
||||
"ureq",
|
||||
"webpki-roots 0.25.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-backtrace"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a7b80fa1dd6830a348d38a8d3a9761179047757b7dca29aef82db0118b9670"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-contexts"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7615dc588930f1fd2e721774f25844ae93add2dbe2d3c2f995ce5049af898147"
|
||||
dependencies = [
|
||||
"hostname",
|
||||
"libc",
|
||||
"os_info",
|
||||
"rustc_version",
|
||||
"sentry-core",
|
||||
"uname",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-core"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f51264e4013ed9b16558cce43917b983fa38170de2ca480349ceb57d71d6053"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"rand",
|
||||
"sentry-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-debug-images"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fe6180fa564d40bb942c9f0084ffb5de691c7357ead6a2b7a3154fae9e401dd"
|
||||
dependencies = [
|
||||
"findshlibs",
|
||||
"once_cell",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-panic"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "323160213bba549f9737317b152af116af35c0410f4468772ee9b606d3d6e0fa"
|
||||
dependencies = [
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-tower"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ffe3ab7bf7f65c9f8ccd20aa136ce5b2140aa6d6a11339e823cd43a7d694a9e"
|
||||
dependencies = [
|
||||
"sentry-core",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-tracing"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38033822128e73f7b6ca74c1631cef8868890c6cb4008a291cf73530f87b4eac"
|
||||
dependencies = [
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-types"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e663b3eb62ddfc023c9cf5432daf5f1a4f6acb1df4d78dd80b740b32dd1a740"
|
||||
dependencies = [
|
||||
"debugid",
|
||||
"hex",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"time",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
|
|
@ -2674,7 +3065,7 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
"tracing",
|
||||
"url",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.24.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2879,6 +3270,27 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.0"
|
||||
|
|
@ -2997,6 +3409,26 @@ dependencies = [
|
|||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-shield"
|
||||
version = "0.1.1"
|
||||
|
|
@ -3049,6 +3481,29 @@ dependencies = [
|
|||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
|
|
@ -3166,6 +3621,15 @@ version = "1.17.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "uname"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uncased"
|
||||
version = "0.9.9"
|
||||
|
|
@ -3239,6 +3703,22 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"log",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-webpki",
|
||||
"url",
|
||||
"webpki-roots 0.25.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
|
|
@ -3266,6 +3746,15 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
|
@ -3396,6 +3885,12 @@ dependencies = [
|
|||
"rustls-webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.4.1"
|
||||
|
|
@ -3508,6 +4003,16 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.6.0"
|
||||
|
|
|
|||
11
Justfile
11
Justfile
|
|
@ -3,5 +3,12 @@ set dotenv-load := false
|
|||
build:
|
||||
docker buildx build --pull --platform linux/amd64 -t "forge.lys.ee/lyssieth/rave:amd64" --load .
|
||||
|
||||
run: build
|
||||
docker run -it -v ./data:/storage lyssieth/rave:latest
|
||||
mount:
|
||||
bash ./mount.sh
|
||||
|
||||
run: mount
|
||||
RAVE_STORAGE_DIR=/tmp/media-for-rave cargo r
|
||||
|
||||
update-db:
|
||||
sea migrate fresh
|
||||
sea generate entity -o ./entities/src --with-serde both --date-time-crate time --lib
|
||||
|
|
@ -18,7 +18,7 @@ pub struct Model {
|
|||
pub starred: Option<TimeDateTimeWithTimeZone>,
|
||||
pub year: Option<i32>,
|
||||
pub genre_ids: Option<Vec<i64>>,
|
||||
pub played: TimeDateTimeWithTimeZone,
|
||||
pub played: Option<TimeDateTimeWithTimeZone>,
|
||||
pub user_rating: Option<i16>,
|
||||
pub artist_ids: Option<Vec<i64>>,
|
||||
pub original_release_date: Option<TimeDateTimeWithTimeZone>,
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ pub struct Model {
|
|||
pub artist_image_url: Option<String>,
|
||||
pub album_count: i32,
|
||||
pub starred: bool,
|
||||
pub music_brainz_id: String,
|
||||
pub sort_name: String,
|
||||
pub roles: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ impl MigrationTrait for Migration {
|
|||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Artist::MusicBrainzId)
|
||||
.string()
|
||||
.not_null()
|
||||
.default(""),
|
||||
)
|
||||
.col(ColumnDef::new(Artist::SortName).string().not_null())
|
||||
.col(ColumnDef::new(Artist::Roles).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
|
@ -79,7 +71,4 @@ pub enum Artist {
|
|||
ArtistImageUrl,
|
||||
AlbumCount,
|
||||
Starred,
|
||||
MusicBrainzId,
|
||||
SortName,
|
||||
Roles,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl MigrationTrait for Migration {
|
|||
.col(
|
||||
ColumnDef::new(Album::Played)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
.null(),
|
||||
)
|
||||
.col(ColumnDef::new(Album::UserRating).tiny_integer().null())
|
||||
.col(
|
||||
|
|
|
|||
23
mount.sh
Normal file
23
mount.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail # exit on error
|
||||
|
||||
# check for `fuse-overlayfs` executable
|
||||
if ! command -v fuse-overlayfs &>/dev/null; then
|
||||
echo "fuse-overlayfs could not be found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if already mounted; im /tmp so it's ephemeral
|
||||
if [ -d /tmp/media-for-rave ]; then exit 0; fi
|
||||
|
||||
# mount the music directory; assumes a fstab entry like:
|
||||
# /dev/sda1 /mnt/Media ext4 defaults 0 0
|
||||
# or equivalent; as long as it mounts to /mnt/Media
|
||||
sudo mount /mnt/Media
|
||||
|
||||
# create the overlayfs
|
||||
mkdir -p /tmp/overlay /tmp/work /tmp/media-for-rave
|
||||
|
||||
# mount the overlayfs
|
||||
fuse-overlayfs -o lowerdir=/mnt/Media/Music -o upperdir=/tmp/overlay -o workdir=/tmp/work /tmp/media-for-rave
|
||||
|
|
@ -17,6 +17,7 @@ poem = { version = "1.3.58", features = [
|
|||
"session",
|
||||
"static-files",
|
||||
"xml",
|
||||
"tower-compat",
|
||||
] }
|
||||
poem-ext = "0.9.4"
|
||||
quick-xml = { version = "0.30.0", features = ["serialize"] }
|
||||
|
|
@ -41,3 +42,15 @@ once_cell = { version = "1.18.0", features = ["parking_lot"] }
|
|||
futures-lite = "1.13.0"
|
||||
id3 = { version = "1.8.0", features = ["tokio"] }
|
||||
tracing-appender = "0.2.2"
|
||||
sentry = { version = "0.31.7", default-features = false, features = [
|
||||
"backtrace",
|
||||
"contexts",
|
||||
"panic",
|
||||
"transport",
|
||||
"debug-images",
|
||||
"reqwest",
|
||||
"rustls",
|
||||
"tower",
|
||||
"tracing",
|
||||
] }
|
||||
sentry-tracing = { version = "0.31.7", features = ["backtrace"] }
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ use color_eyre::Result;
|
|||
use migration::{Migrator, MigratorTrait};
|
||||
use poem::{
|
||||
listener::TcpListener,
|
||||
middleware,
|
||||
middleware::{self, TowerLayerCompatExt},
|
||||
web::{CompressionAlgo, CompressionLevel},
|
||||
Endpoint, EndpointExt, Route,
|
||||
Endpoint, EndpointExt, Request, Route,
|
||||
};
|
||||
use poem_ext::db::DbTransactionMiddleware;
|
||||
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||
use tracing::info;
|
||||
use sentry::integrations::tower::NewSentryLayer;
|
||||
use tracing::{debug, info};
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_subscriber::{
|
||||
fmt, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer,
|
||||
|
|
@ -36,6 +37,21 @@ async fn main() -> Result<()> {
|
|||
color_eyre::install()?;
|
||||
let _guards = install_tracing().await?;
|
||||
|
||||
let _sentry = if let Ok(dsn) = std::env::var("RAVE_SENTRY_DSN") {
|
||||
let guard = sentry::init(sentry::ClientOptions {
|
||||
dsn: Some(dsn.parse()?),
|
||||
release: sentry::release_name!(),
|
||||
traces_sample_rate: 1.0,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
debug!("Sentry initialized");
|
||||
|
||||
Some(guard)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let route = create_route();
|
||||
|
||||
let dbc = create_pool().await?;
|
||||
|
|
@ -72,6 +88,7 @@ fn create_route() -> Box<dyn Endpoint<Output = poem::Response>> {
|
|||
Route::new()
|
||||
.nest("/", ui::build())
|
||||
.nest("/rest", rest::build())
|
||||
.with(NewSentryLayer::<Request>::new_from_top().compat())
|
||||
.with(middleware::CatchPanic::new())
|
||||
.with(
|
||||
middleware::Compression::new()
|
||||
|
|
@ -117,6 +134,7 @@ async fn install_tracing() -> Result<[WorkerGuard; 1]> {
|
|||
.with_writer(non_blocking)
|
||||
.with_filter(filter),
|
||||
)
|
||||
.with(sentry_tracing::layer())
|
||||
.try_init()?;
|
||||
|
||||
Ok([guard])
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use serde::Deserialize;
|
||||
use tracing::warn;
|
||||
use tracing::error;
|
||||
|
||||
use crate::subsonic::Error;
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ impl FromStr for SortType {
|
|||
"bygenre" => Ok(Self::ByGenre),
|
||||
|
||||
_ => {
|
||||
warn!("got invalid type parameter {s}");
|
||||
error!("got invalid type parameter {s}");
|
||||
Err(Error::Generic(Some(
|
||||
"type parameter is invalid".to_string(),
|
||||
)))
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ use poem::web::{Data, Query};
|
|||
use poem_ext::db::DbTxn;
|
||||
use sea_orm::{EntityTrait, ModelTrait};
|
||||
use serde::Deserialize;
|
||||
use tracing::warn;
|
||||
use tracing::{error, instrument, warn};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn get_album(
|
||||
Data(txn): Data<&DbTxn>,
|
||||
auth: Authentication,
|
||||
|
|
@ -30,7 +31,10 @@ pub async fn get_album(
|
|||
Ok(Some(_)) => unreachable!("Some(album) covered by `let .. else`"),
|
||||
Ok(None) => return SubsonicResponse::new_error(Error::RequestedDataWasNotFound(None)),
|
||||
Err(e) => {
|
||||
warn!("Error getting album: {}", e);
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Error getting album: {e}"
|
||||
);
|
||||
return SubsonicResponse::new_error(Error::Generic(None));
|
||||
}
|
||||
}
|
||||
|
|
@ -41,12 +45,15 @@ pub async fn get_album(
|
|||
let tracks = match tracks {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
warn!("Error getting tracks: {}", e);
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Error getting tracks: {e}"
|
||||
);
|
||||
return SubsonicResponse::new_error(Error::Generic(None));
|
||||
}
|
||||
};
|
||||
|
||||
todo!()
|
||||
todo!("finish implementing get_album")
|
||||
// SubsonicResponse::new_album(album, tracks)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use poem::{
|
|||
use poem_ext::db::DbTxn;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
|
||||
use serde::Deserialize;
|
||||
use tracing::debug;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -30,6 +30,7 @@ macro_rules! error_or {
|
|||
}
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(req, txn, auth))]
|
||||
pub async fn get_album_list(
|
||||
req: &Request,
|
||||
Data(txn): Data<&DbTxn>,
|
||||
|
|
@ -66,7 +67,6 @@ pub async fn get_album_list(
|
|||
|
||||
// match album_list {
|
||||
// Ok(a) => {
|
||||
// debug!("uri path: {}", req.uri().path());
|
||||
// if req.uri().path().contains("getAlbumList2") {
|
||||
// SubsonicResponse::new_album_list2(a)
|
||||
// } else {
|
||||
|
|
@ -77,17 +77,17 @@ pub async fn get_album_list(
|
|||
// }
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(_conn, _params))]
|
||||
async fn get_album_list_random(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
_conn: DbTxn,
|
||||
_params: GetAlbumListParams,
|
||||
) -> Result<Vec<album::Model>, Error> {
|
||||
Err(Error::Generic(Some(
|
||||
"Sorting by random not implemented".to_string(),
|
||||
)))
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_newest(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -102,17 +102,22 @@ async fn get_album_list_newest(
|
|||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_highest(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
) -> Result<Vec<album::Model>, Error> {
|
||||
Err(Error::Generic(Some(
|
||||
"Sorting by highest rating not implemented".to_string(),
|
||||
)))
|
||||
let albums = Album::find()
|
||||
.order_by_desc(album::Column::UserRating)
|
||||
.limit(params.size)
|
||||
.offset(params.offset)
|
||||
.all(&*conn)
|
||||
.await;
|
||||
|
||||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_frequent(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -127,17 +132,22 @@ async fn get_album_list_frequent(
|
|||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_recent(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
) -> Result<Vec<album::Model>, Error> {
|
||||
Err(Error::Generic(Some(
|
||||
"Sorting by recently played not implemented".to_string(),
|
||||
)))
|
||||
let albums = Album::find()
|
||||
.order_by_desc(album::Column::Played)
|
||||
.limit(params.size)
|
||||
.offset(params.offset)
|
||||
.all(&*conn)
|
||||
.await;
|
||||
|
||||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_alphabetical_by_name(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -152,7 +162,7 @@ async fn get_album_list_alphabetical_by_name(
|
|||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_alphabetical_by_artist(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -171,7 +181,7 @@ async fn get_album_list_alphabetical_by_artist(
|
|||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_starred(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -186,6 +196,7 @@ async fn get_album_list_starred(
|
|||
error_or!(albums)
|
||||
}
|
||||
|
||||
#[instrument(skip(conn))]
|
||||
async fn get_album_list_by_year(
|
||||
conn: DbTxn,
|
||||
params: GetAlbumListParams,
|
||||
|
|
@ -223,14 +234,15 @@ async fn get_album_list_by_genre(
|
|||
)));
|
||||
};
|
||||
|
||||
let genre_id = Genre::find()
|
||||
let genre = Genre::find()
|
||||
.filter(genre::Column::Name.eq(genre))
|
||||
.one(&*conn)
|
||||
.await;
|
||||
|
||||
let genre = match genre_id {
|
||||
Ok(Some(g)) => g,
|
||||
Ok(None) | Err(_) => return Err(Error::Generic(Some("Genre not found".to_string()))),
|
||||
let Ok(Some(genre)) = genre else {
|
||||
return Err(Error::RequestedDataWasNotFound(Some(
|
||||
"Genre not found".to_string(),
|
||||
)));
|
||||
};
|
||||
|
||||
let albums = Album::find()
|
||||
|
|
@ -278,7 +290,6 @@ pub struct GetAlbumListParams {
|
|||
}
|
||||
|
||||
impl GetAlbumListParams {
|
||||
#[allow(clippy::result_large_err)]
|
||||
pub fn verify(self) -> Result<Self, SubsonicResponse> {
|
||||
if self.r#type == SortType::ByYear {
|
||||
if self.from_year.is_none() || self.to_year.is_none() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use poem::web::Data;
|
||||
use poem_ext::db::DbTxn;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -8,6 +9,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn get_license(Data(txn): Data<&DbTxn>, auth: Authentication) -> SubsonicResponse {
|
||||
let u = utils::verify_user(txn.clone(), auth).await;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use entities::prelude::MusicFolder;
|
|||
use poem::web::Data;
|
||||
use poem_ext::db::DbTxn;
|
||||
use sea_orm::EntityTrait;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -10,6 +11,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn get_music_folders(Data(txn): Data<&DbTxn>, auth: Authentication) -> SubsonicResponse {
|
||||
let u = utils::verify_user(txn.clone(), auth).await;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use poem::web::Data;
|
||||
use poem_ext::db::DbTxn;
|
||||
use tracing::warn;
|
||||
use tracing::{error, instrument};
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -10,6 +10,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn get_scan_status(Data(txn): Data<&DbTxn>, auth: Authentication) -> SubsonicResponse {
|
||||
let u = utils::verify_user(txn.clone(), auth).await;
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ pub async fn get_scan_status(Data(txn): Data<&DbTxn>, auth: Authentication) -> S
|
|||
match status {
|
||||
Ok(status) => SubsonicResponse::new_scan_status(status.scanning, status.count),
|
||||
Err(e) => {
|
||||
warn!("Error getting scan status: {}", e);
|
||||
error!(error = e.root_cause(), "Error getting scan status: {e}");
|
||||
SubsonicResponse::new_error(Error::Generic(None))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use poem::web::Data;
|
||||
use poem_ext::db::DbTxn;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -8,6 +9,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn ping(Data(txn): Data<&DbTxn>, auth: Authentication) -> SubsonicResponse {
|
||||
let u = utils::verify_user(txn.clone(), auth).await;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use poem::web::Data;
|
||||
use poem_ext::db::DbTxn;
|
||||
use tracing::warn;
|
||||
use tracing::{error, instrument};
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
|||
};
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn start_scan(Data(txn): Data<&DbTxn>, auth: Authentication) -> SubsonicResponse {
|
||||
let u = utils::verify_user(txn.clone(), auth).await;
|
||||
|
||||
|
|
@ -31,15 +32,15 @@ pub async fn start_scan(Data(txn): Data<&DbTxn>, auth: Authentication) -> Subson
|
|||
if status.errors.is_empty() {
|
||||
SubsonicResponse::new_scan_status(status.scanning, status.count)
|
||||
} else {
|
||||
warn!("Failed to start scan:");
|
||||
error!("Failed to start scan:");
|
||||
for e in status.errors {
|
||||
warn!("{e}");
|
||||
error!(error = e.root_cause(), "{e}");
|
||||
}
|
||||
SubsonicResponse::new_error(Error::Generic(None))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Failed to start scan: {e}");
|
||||
error!(error = e.root_cause(), "Failed to start scan: {e}");
|
||||
SubsonicResponse::new_error(Error::Generic(None))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use poem::{
|
|||
};
|
||||
use poem_ext::db::DbTxn;
|
||||
use serde::Deserialize;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
authentication::Authentication,
|
||||
|
|
@ -14,6 +15,7 @@ use crate::{
|
|||
const SONG: &[u8] = include_bytes!("../../../../data.mp3");
|
||||
|
||||
#[poem::handler]
|
||||
#[instrument(skip(txn, auth))]
|
||||
pub async fn stream(
|
||||
Data(txn): Data<&DbTxn>,
|
||||
auth: Authentication,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use std::{
|
|||
};
|
||||
use time::OffsetDateTime;
|
||||
use tokio::{fs::File, sync::RwLock};
|
||||
use tracing::{debug, info, warn};
|
||||
use tracing::{debug, error, info, instrument};
|
||||
|
||||
mod walk;
|
||||
|
||||
|
|
@ -98,7 +98,10 @@ const VALID_EXTENSIONS: &[&str] = &["mp3"];
|
|||
async fn do_entry(de: walk::DirEntry, txn: DatabaseTransaction, state: Arc<RwLock<ScanState>>) {
|
||||
if let Err(e) = handle_entry(&txn, de, state).await {
|
||||
let _ = txn.rollback().await;
|
||||
warn!("Failed to handle directory entry: {e}");
|
||||
error!(
|
||||
error = e.root_cause(),
|
||||
"Failed to handle directory entry: {e}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut write = STATUS.write().await;
|
||||
|
|
@ -114,6 +117,7 @@ async fn do_entry(de: walk::DirEntry, txn: DatabaseTransaction, state: Arc<RwLoc
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tx, state))]
|
||||
async fn handle_entry(
|
||||
tx: &DatabaseTransaction,
|
||||
entry: walk::DirEntry,
|
||||
|
|
@ -129,7 +133,7 @@ async fn handle_entry(
|
|||
let file_ext = path.extension();
|
||||
|
||||
let Some(ext) = file_ext else {
|
||||
warn!("Couldn't get file extension for {path:?}");
|
||||
error!("Couldn't get file extension for {path:?}");
|
||||
|
||||
{
|
||||
STATUS
|
||||
|
|
@ -145,10 +149,15 @@ async fn handle_entry(
|
|||
|
||||
let ext = ext.to_string_lossy();
|
||||
|
||||
if !VALID_EXTENSIONS.contains(&ext.as_ref()) {
|
||||
debug!("Skipping file with invalid extension: {path:?}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let file_stem = path.file_stem();
|
||||
|
||||
let Some(stem) = file_stem else {
|
||||
warn!("Couldn't get file stem for {path:?}");
|
||||
error!("Couldn't get file stem for {path:?}");
|
||||
|
||||
{
|
||||
STATUS
|
||||
|
|
@ -164,11 +173,6 @@ async fn handle_entry(
|
|||
|
||||
let stem = stem.to_string_lossy();
|
||||
|
||||
if !VALID_EXTENSIONS.contains(&ext.as_ref()) {
|
||||
debug!("Skipping file with invalid extension: {path:?}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let meta = { File::open(&path).await?.metadata().await? };
|
||||
|
||||
let current_album = { state.read().await.album_id };
|
||||
|
|
@ -212,6 +216,7 @@ async fn handle_entry(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(tx, tag, state))]
|
||||
async fn find_album(
|
||||
tx: &DatabaseTransaction,
|
||||
current_album: Option<i64>,
|
||||
|
|
@ -223,7 +228,7 @@ async fn find_album(
|
|||
let album = Album::find_by_id(current_album).one(tx).await?;
|
||||
|
||||
let Some(album) = album else {
|
||||
warn!("Couldn't find album with id {current_album}");
|
||||
error!("Couldn't find album with id {current_album}");
|
||||
|
||||
return Err(Report::msg(format!(
|
||||
"Couldn't find album with id {current_album}"
|
||||
|
|
@ -259,7 +264,10 @@ async fn find_album(
|
|||
|
||||
let Ok(model) = model else {
|
||||
let err = model.expect_err("somehow not err");
|
||||
warn!("Failed to insert album {err}");
|
||||
error!(
|
||||
error = &err as &dyn std::error::Error,
|
||||
"Failed to insert album {err}"
|
||||
);
|
||||
|
||||
return Err(Report::new(err));
|
||||
};
|
||||
|
|
@ -268,15 +276,19 @@ async fn find_album(
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tx))]
|
||||
async fn find_or_create_genre(tx: &DatabaseTransaction, name: &str) -> Result<i64, Report> {
|
||||
debug!("Finding genre with name {name}");
|
||||
let res = Genre::find()
|
||||
.filter(genre::Column::Name.eq(name))
|
||||
.one(tx)
|
||||
.await?;
|
||||
|
||||
if let Some(genre) = res {
|
||||
debug!("Found genre with id {}", genre.id);
|
||||
Ok(genre.id)
|
||||
} else {
|
||||
debug!("Trying to create genre");
|
||||
let am = genre::ActiveModel {
|
||||
name: Set(name.to_string()),
|
||||
..Default::default()
|
||||
|
|
@ -286,15 +298,21 @@ async fn find_or_create_genre(tx: &DatabaseTransaction, name: &str) -> Result<i6
|
|||
|
||||
let Ok(model) = model else {
|
||||
let err = model.expect_err("somehow not err");
|
||||
warn!("Failed to insert genre {err}");
|
||||
error!(
|
||||
error = &err as &dyn std::error::Error,
|
||||
"Failed to insert genre {err}"
|
||||
);
|
||||
|
||||
return Err(Report::new(err));
|
||||
};
|
||||
|
||||
debug!("Inserted genre with id {}", model.id);
|
||||
|
||||
Ok(model.id)
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tx, tag))]
|
||||
async fn find_artist(tx: &DatabaseTransaction, tag: &Tag) -> Result<Option<artist::Model>, Report> {
|
||||
let artist_to_search = match (tag.album_artist(), tag.artists()) {
|
||||
(Some(tag_artist), None) => Some(tag_artist.to_string()),
|
||||
|
|
@ -325,7 +343,10 @@ async fn find_artist(tx: &DatabaseTransaction, tag: &Tag) -> Result<Option<artis
|
|||
|
||||
let Ok(model) = model else {
|
||||
let err = model.expect_err("somehow not err");
|
||||
warn!("Failed to insert artist {err}");
|
||||
error!(
|
||||
error = &err as &dyn std::error::Error,
|
||||
"Failed to insert artist {err}"
|
||||
);
|
||||
|
||||
return Err(Report::new(err));
|
||||
};
|
||||
|
|
@ -343,6 +364,7 @@ struct ScanState {
|
|||
pub album_id: Option<i64>,
|
||||
}
|
||||
|
||||
#[instrument(skip(dbc, state))]
|
||||
async fn create_root_music_folder(
|
||||
dbc: &sea_orm::DatabaseConnection,
|
||||
root_dir: &Path,
|
||||
|
|
@ -351,7 +373,10 @@ async fn create_root_music_folder(
|
|||
let txn = dbc.begin().await;
|
||||
let Ok(txn) = txn else {
|
||||
let err = txn.expect_err("somehow not err");
|
||||
warn!("Failed to start database transaction to add the root music folder {err}");
|
||||
error!(
|
||||
error = &err as &dyn std::error::Error,
|
||||
"Failed to start database transaction to add the root music folder {err}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut stat = STATUS.write().await;
|
||||
|
|
@ -362,8 +387,22 @@ async fn create_root_music_folder(
|
|||
};
|
||||
debug!("created transaction");
|
||||
|
||||
let name = root_dir.to_string_lossy().to_string();
|
||||
|
||||
// Check for an existing one and exit early
|
||||
let res = MusicFolder::find()
|
||||
.filter(music_folder::Column::Name.eq(&name))
|
||||
.one(&txn)
|
||||
.await;
|
||||
|
||||
if let Ok(Some(res)) = res {
|
||||
state.write().await.music_folder_id = res.id;
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
// Otherwise, make it
|
||||
let new_music_folder = music_folder::ActiveModel {
|
||||
name: Set(root_dir.to_string_lossy().to_string()),
|
||||
name: Set(name),
|
||||
..Default::default()
|
||||
};
|
||||
debug!("created new music folder model");
|
||||
|
|
@ -374,7 +413,10 @@ async fn create_root_music_folder(
|
|||
|
||||
let Ok(mf) = mf else {
|
||||
let err = mf.expect_err("somehow not err");
|
||||
warn!("Failed to add the root music folder {err}");
|
||||
error!(
|
||||
error = &err as &dyn std::error::Error,
|
||||
"Failed to add the root music folder {err}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut stat = STATUS.write().await;
|
||||
|
|
@ -396,7 +438,10 @@ async fn create_txn(dbc: &sea_orm::DatabaseConnection) -> Option<DatabaseTransac
|
|||
let txn = match dbc.begin().await {
|
||||
Ok(txn) => txn,
|
||||
Err(e) => {
|
||||
warn!("Failed to start database transaction: {e}");
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Failed to start database transaction: {e}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut write = STATUS.write().await;
|
||||
|
|
@ -415,7 +460,10 @@ async fn check_dir_entry(
|
|||
let de = match res {
|
||||
Ok(de) => de,
|
||||
Err(e) => {
|
||||
warn!("Failed to read directory entry: {e}");
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Failed to read directory entry: {e}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut write = STATUS.write().await;
|
||||
|
|
@ -432,7 +480,10 @@ async fn get_dbc(conn: ConnectOptions) -> Option<sea_orm::DatabaseConnection> {
|
|||
let dbc = Database::connect(conn).await;
|
||||
let Ok(dbc) = dbc else {
|
||||
let e = dbc.expect_err("Failed to connect to database");
|
||||
warn!("Failed to connect to database: {e}");
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Failed to connect to database: {e}"
|
||||
);
|
||||
|
||||
{
|
||||
let mut stat = STATUS.write().await;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ pub async fn verify_user(
|
|||
None,
|
||||
))),
|
||||
Err(e) => {
|
||||
error!("Error getting user: {e}");
|
||||
error!(
|
||||
error = &e as &dyn std::error::Error,
|
||||
"Error getting user: {e}"
|
||||
);
|
||||
Err(SubsonicResponse::new_error(Error::WrongUsernameOrPassword(
|
||||
None,
|
||||
)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue