diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index e8a4714..41bb99f 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -10,9 +10,21 @@
+
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -21,6 +33,13 @@
+
+
+
@@ -42,20 +61,33 @@
"WebServerToolWindowFactoryState": "false",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
- "last_opened_file_path": "/home/jude/navidrome-playlists",
+ "last_opened_file_path": "/home/jude/listenbrainz-rs",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
+ "org.rust.disableDetachedFileInspection/home/jude/navidrome-playlists/navidrome/src/client/mod.rs": "true",
+ "org.rust.disableDetachedFileInspection/home/jude/navidrome-playlists/navidrome/src/client/playlists.rs": "true",
"org.rust.disableDetachedFileInspection/home/jude/navidrome-playlists/navidrome/src/lib.rs": "true",
"org.rust.disableDetachedFileInspection/home/jude/navidrome-playlists/navidrome/src/models.rs": "true",
+ "settings.editor.selected.configurable": "language.rust.rustfmt",
"vue.rearranger.settings.migration": "true"
}
}]]>
+
+
+
+
+
+
+
+
+
+
@@ -65,11 +97,25 @@
1691949245312
-
+
+
+
+
+ 1692008860369
+
+
+
+ 1692008860369
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index a55bc75..6ee0d7c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -161,6 +161,12 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "bumpalo"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
+
[[package]]
name = "byteorder"
version = "1.4.3"
@@ -194,6 +200,22 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
+[[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"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
[[package]]
name = "cpufeatures"
version = "0.2.9"
@@ -285,6 +307,15 @@ dependencies = [
"serde",
]
+[[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -353,6 +384,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"
@@ -461,6 +507,31 @@ version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+[[package]]
+name = "h2"
+version = "0.3.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap 1.9.3",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
[[package]]
name = "hashbrown"
version = "0.14.0"
@@ -477,7 +548,7 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f"
dependencies = [
- "hashbrown",
+ "hashbrown 0.14.0",
]
[[package]]
@@ -489,6 +560,12 @@ dependencies = [
"unicode-segmentation",
]
+[[package]]
+name = "hermit-abi"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+
[[package]]
name = "hex"
version = "0.4.3"
@@ -566,6 +643,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
+ "h2",
"http",
"http-body",
"httparse",
@@ -579,6 +657,19 @@ dependencies = [
"want",
]
+[[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 = "idna"
version = "0.4.0"
@@ -589,6 +680,16 @@ dependencies = [
"unicode-normalization",
]
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+]
+
[[package]]
name = "indexmap"
version = "2.0.0"
@@ -596,9 +697,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
- "hashbrown",
+ "hashbrown 0.14.0",
]
+[[package]]
+name = "ipnet"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
+
[[package]]
name = "itertools"
version = "0.10.5"
@@ -614,6 +721,15 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+[[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -721,11 +837,31 @@ dependencies = [
"windows-sys",
]
+[[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 = "navidrome-playlists"
version = "0.1.0"
dependencies = [
"axum",
+ "reqwest",
+ "serde",
"sqlx",
"tokio",
]
@@ -788,6 +924,16 @@ dependencies = [
"libm",
]
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
[[package]]
name = "object"
version = "0.31.1"
@@ -803,6 +949,50 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+[[package]]
+name = "openssl"
+version = "0.10.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e"
+dependencies = [
+ "bitflags 1.3.2",
+ "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.28",
+]
+
+[[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.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
[[package]]
name = "parking_lot"
version = "0.12.1"
@@ -969,6 +1159,43 @@ dependencies = [
"bitflags 1.3.2",
]
+[[package]]
+name = "reqwest"
+version = "0.11.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-tls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
[[package]]
name = "rsa"
version = "0.9.2"
@@ -1022,12 +1249,44 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+[[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 = "serde"
version = "1.0.183"
@@ -1103,6 +1362,15 @@ dependencies = [
"digest",
]
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "signature"
version = "2.1.0"
@@ -1219,7 +1487,7 @@ dependencies = [
"futures-util",
"hashlink",
"hex",
- "indexmap",
+ "indexmap 2.0.0",
"log",
"memchr",
"once_cell",
@@ -1231,8 +1499,11 @@ dependencies = [
"smallvec",
"sqlformat",
"thiserror",
+ "tokio",
+ "tokio-stream",
"tracing",
"url",
+ "uuid",
]
[[package]]
@@ -1266,9 +1537,11 @@ dependencies = [
"sha2",
"sqlx-core",
"sqlx-mysql",
+ "sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109",
"tempfile",
+ "tokio",
"url",
]
@@ -1311,6 +1584,7 @@ dependencies = [
"stringprep",
"thiserror",
"tracing",
+ "uuid",
"whoami",
]
@@ -1350,6 +1624,7 @@ dependencies = [
"stringprep",
"thiserror",
"tracing",
+ "uuid",
"whoami",
]
@@ -1373,6 +1648,7 @@ dependencies = [
"sqlx-core",
"tracing",
"url",
+ "uuid",
]
[[package]]
@@ -1474,13 +1750,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920"
dependencies = [
"backtrace",
+ "bytes",
"libc",
"mio",
+ "num_cpus",
+ "parking_lot",
"pin-project-lite",
+ "signal-hook-registry",
"socket2 0.5.3",
+ "tokio-macros",
"windows-sys",
]
+[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.28",
+]
+
+[[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-stream"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
[[package]]
name = "tower"
version = "0.4.13"
@@ -1598,6 +1925,12 @@ dependencies = [
"percent-encoding",
]
+[[package]]
+name = "uuid"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+
[[package]]
name = "vcpkg"
version = "0.2.15"
@@ -1625,6 +1958,82 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.28",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.28",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+
+[[package]]
+name = "web-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
[[package]]
name = "whoami"
version = "1.4.1"
@@ -1719,6 +2128,15 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+[[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
[[package]]
name = "zeroize"
version = "1.6.0"
diff --git a/Cargo.toml b/Cargo.toml
index 2ec6bd8..33a4320 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,10 +7,10 @@ license = "AGPL-3.0 only"
[dependencies]
axum = "0.6.20"
-tokio = "1.30.0"
-sqlx = "0.7.1"
-
-
+tokio = { version = "1.0", features = ["full"] }
+sqlx = { version = "0.7.1", features = ["runtime-tokio", "postgres", "uuid"] }
+reqwest = { version = "0.11.18", features = ["json"] }
+serde = { version = "1.0.183", features = ["derive"] }
[package.metadata.deb]
depends = "$auto"
diff --git a/listenbrainz/Cargo.toml b/listenbrainz/Cargo.toml
deleted file mode 100644
index 1543f2d..0000000
--- a/listenbrainz/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "listenbrainz"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-reqwest = "0.11.18"
diff --git a/listenbrainz/src/lib.rs b/listenbrainz/src/lib.rs
deleted file mode 100644
index 7d12d9a..0000000
--- a/listenbrainz/src/lib.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-pub fn add(left: usize, right: usize) -> usize {
- left + right
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn it_works() {
- let result = add(2, 2);
- assert_eq!(result, 4);
- }
-}
diff --git a/migrations/20230816135241_initial.sql b/migrations/20230816135241_initial.sql
new file mode 100644
index 0000000..8c4d6d2
--- /dev/null
+++ b/migrations/20230816135241_initial.sql
@@ -0,0 +1,9 @@
+CREATE TABLE "tracked_playlist" (
+ rule_id BIGSERIAL NOT NULL PRIMARY KEY,
+ playlist_id UUID,
+ playlist_name VARCHAR(250),
+ playlist_size INT NOT NULL,
+ tracking_user VARCHAR(250),
+ tracking_type VARCHAR(14),
+ reduce_duplication_on VARCHAR(250)
+);
diff --git a/src/daemon.rs b/src/daemon.rs
new file mode 100644
index 0000000..b2ec1e2
--- /dev/null
+++ b/src/daemon.rs
@@ -0,0 +1,36 @@
+use crate::models::TrackedPlaylist;
+use sqlx::postgres::PgPool;
+use std::env;
+use std::time::Duration;
+use tokio::time::{interval, MissedTickBehavior};
+
+pub async fn update_playlists_daemon() -> Result<(), Box> {
+ let database = PgPool::connect(&env::var("DATABASE_URL").unwrap())
+ .await
+ .unwrap();
+
+ let mut ticker = interval(Duration::from_secs(1800));
+ ticker.set_missed_tick_behavior(MissedTickBehavior::Skip);
+
+ loop {
+ let records_res = sqlx::query_as!(TrackedPlaylist, "SELECT * FROM \"tracked_playlist\"")
+ .fetch_all(&database)
+ .await;
+
+ match records_res {
+ Ok(records) => {
+ for record in records {
+ update_playlist(record).await;
+ }
+ }
+
+ Err(e) => {
+ println!("Could not fetch tracked_playlists: {:?}", e);
+ }
+ }
+
+ ticker.tick().await;
+ }
+}
+
+async fn update_playlist(playlist: TrackedPlaylist) {}
diff --git a/src/listenbrainz.rs b/src/listenbrainz.rs
new file mode 100644
index 0000000..b27659c
--- /dev/null
+++ b/src/listenbrainz.rs
@@ -0,0 +1,93 @@
+use serde::Deserialize;
+
+const BASE: &'static str = "https://api.listenbrainz.org/1";
+
+enum StatsType {
+ Artists,
+ Recordings,
+ Releases,
+ ReleaseGroups,
+}
+
+impl StatsType {
+ fn stub(&self) -> &'static str {
+ match self {
+ StatsType::Artists => "artists",
+ StatsType::Recordings => "recordings",
+ StatsType::Releases => "releases",
+ StatsType::ReleaseGroups => "release-groups",
+ }
+ }
+}
+
+pub enum StatsRange {
+ ThisWeek,
+ ThisMonth,
+ ThisYear,
+ Week,
+ Month,
+ Quarter,
+ HalfYear,
+ Year,
+ All,
+}
+
+impl StatsRange {
+ fn param(&self) -> &'static str {
+ match self {
+ StatsRange::ThisWeek => "this_week",
+ StatsRange::ThisMonth => "this_month",
+ StatsRange::ThisYear => "this_year",
+ StatsRange::Week => "week",
+ StatsRange::Month => "month",
+ StatsRange::Quarter => "quarter",
+ StatsRange::HalfYear => "half_yearly",
+ StatsRange::Year => "year",
+ StatsRange::All => "all_time",
+ }
+ }
+}
+
+#[derive(Deserialize)]
+struct RecordingsResponse {
+ payload: RecordingsPayload,
+}
+
+#[derive(Deserialize)]
+pub struct RecordingsPayload {
+ count: u64,
+ from_ts: u64,
+ to_ts: u64,
+ last_updated: u64,
+ total_recording_count: u64,
+ user_id: String,
+ offset: u64,
+ range: String,
+ pub recordings: Vec,
+}
+
+#[derive(Deserialize)]
+pub struct RecordingsEntry {
+ pub track_name: String,
+ pub recording_mbid: String,
+ pub release_mbid: String,
+}
+
+pub async fn recordings(
+ user: &str,
+ range: StatsRange,
+) -> Result {
+ let url = format!(
+ "{}/stats/user/{}/{}?range={}",
+ BASE,
+ user,
+ StatsType::Recordings.stub(),
+ range.param()
+ );
+
+ Ok(reqwest::get(url)
+ .await?
+ .json::()
+ .await?
+ .payload)
+}
diff --git a/src/main.rs b/src/main.rs
index 7552d3a..63683a0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,14 +1,44 @@
+mod daemon;
+mod listenbrainz;
+mod models;
+
+use crate::daemon::update_playlists_daemon;
+use crate::listenbrainz::StatsRange;
+use axum::extract::State;
+use axum::routing::get;
+use axum::Router;
+use sqlx::postgres::PgPool;
+use std::env;
use std::net::SocketAddr;
#[tokio::main]
-fn main() {
- let app = Router::new().route("/", get(index));
+async fn main() -> Result<(), Box> {
+ let database = PgPool::connect(&env::var("DATABASE_URL")?).await?;
+ sqlx::migrate!().run(&database).await?;
+
+ let app = Router::new().route("/", get(index)).with_state(database);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
- .serve()
+ .serve(app.into_make_service())
+ .await?;
+
+ tokio::spawn(async move {
+ update_playlists_daemon().await.unwrap();
+ });
+
+ Ok(())
}
-async fn index() {
+async fn index(State(pool): State) -> String {
+ let response = listenbrainz::recordings("jellywx", StatsRange::Week)
+ .await
+ .unwrap();
+ response
+ .recordings
+ .iter()
+ .map(|a| a.track_name.clone())
+ .collect::>()
+ .join(", ")
}
diff --git a/src/models.rs b/src/models.rs
new file mode 100644
index 0000000..142d0a8
--- /dev/null
+++ b/src/models.rs
@@ -0,0 +1,11 @@
+use sqlx::types::Uuid;
+
+pub struct TrackedPlaylist {
+ pub rule_id: i64,
+ pub playlist_id: Option,
+ pub playlist_name: Option,
+ pub playlist_size: i32,
+ pub tracking_user: Option,
+ pub tracking_type: Option,
+ pub reduce_duplication_on: Option,
+}