Compare commits

..

No commits in common. "rust" and "v0.4.0" have entirely different histories.
rust ... v0.4.0

20 changed files with 127 additions and 843 deletions

554
Cargo.lock generated
View file

@ -90,12 +90,6 @@ version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -201,57 +195,12 @@ dependencies = [
"typenum",
]
[[package]]
name = "darling"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "data-encoding"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
"serde",
]
[[package]]
name = "digest"
version = "0.10.7"
@ -345,12 +294,6 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-sink"
version = "0.3.29"
@ -370,10 +313,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
dependencies = [
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
@ -408,9 +349,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "git2"
version = "0.19.0"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724"
checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd"
dependencies = [
"bitflags 2.4.1",
"libc",
@ -432,39 +373,14 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.11",
"indexmap 2.1.0",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "h2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 1.1.0",
"indexmap 2.1.0",
"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.3"
@ -477,10 +393,10 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
dependencies = [
"base64 0.21.5",
"base64",
"bytes",
"headers-core",
"http 0.2.11",
"http",
"httpdate",
"mime",
"sha1",
@ -492,7 +408,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
dependencies = [
"http 0.2.11",
"http",
]
[[package]]
@ -501,12 +417,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.11"
@ -518,17 +428,6 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.5"
@ -536,30 +435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http 0.2.11",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.1.0",
]
[[package]]
name = "http-body-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
dependencies = [
"bytes",
"futures-core",
"http 1.1.0",
"http-body 1.0.0",
"http",
"pin-project-lite",
]
@ -585,9 +461,9 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.22",
"http 0.2.11",
"http-body 0.4.5",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
@ -599,26 +475,6 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.4",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
@ -626,64 +482,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http 0.2.11",
"hyper 0.14.27",
"rustls 0.21.10",
"http",
"hyper",
"rustls",
"tokio",
"tokio-rustls 0.24.1",
]
[[package]]
name = "hyper-rustls"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [
"futures-util",
"http 1.1.0",
"hyper 1.3.1",
"hyper-util",
"rustls 0.23.10",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.26.0",
"tower-service",
"tokio-rustls",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"http-body-util",
"hyper 1.3.1",
"hyper-util",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.3.1",
"pin-project-lite",
"socket2 0.5.5",
"tokio",
"tower",
"tower-service",
"tracing",
]
[[package]]
@ -709,12 +525,6 @@ dependencies = [
"cc",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.5.0"
@ -725,17 +535,6 @@ 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",
"serde",
]
[[package]]
name = "indexmap"
version = "2.1.0"
@ -743,20 +542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
"serde",
]
[[package]]
name = "ip2location"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c1511093b9295abf32d5b63cfefa2c59cd237fde31c339fabf9710a54c16c69"
dependencies = [
"memmap",
"serde",
"serde_json",
"serde_with",
"hashbrown",
]
[[package]]
@ -782,20 +568,18 @@ dependencies = [
[[package]]
name = "jonas_jones-api"
version = "0.4.1"
version = "0.3.0"
dependencies = [
"chrono",
"dotenv",
"git2",
"ip2location",
"lastfm",
"log",
"parking_lot",
"regex",
"reqwest 0.12.5",
"reqwest",
"serde",
"serde_json",
"sha2",
"tokio",
"toml",
"warp",
@ -812,16 +596,16 @@ dependencies = [
[[package]]
name = "lastfm"
version = "0.10.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1c7d19b3dabcb2ccef2ffe389604248cdcbc063e3455e9079992e4ec336158"
checksum = "aed1b6ed29669ba37e7a2a8a939b7e2ff456883f0eb71a173635fae0ddc1cb5b"
dependencies = [
"async-stream",
"chrono",
"dotenv",
"lazy_static",
"rand",
"reqwest 0.11.22",
"reqwest",
"serde",
"serde_json",
"thiserror",
@ -846,9 +630,9 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "libgit2-sys"
version = "0.17.0+1.8.1"
version = "0.16.1+1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224"
checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c"
dependencies = [
"cc",
"libc",
@ -912,16 +696,6 @@ version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "memmap"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "mime"
version = "0.3.17"
@ -967,7 +741,7 @@ dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http 0.2.11",
"http",
"httparse",
"log",
"memchr",
@ -994,12 +768,6 @@ dependencies = [
"tempfile",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
version = "0.2.17"
@ -1145,12 +913,6 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1249,60 +1011,17 @@ version = "0.11.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
dependencies = [
"base64 0.21.5",
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.3.22",
"http 0.2.11",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-rustls 0.24.2",
"ipnet",
"js-sys",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls 0.21.10",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
"system-configuration",
"tokio",
"tokio-rustls 0.24.1",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots",
"winreg 0.50.0",
]
[[package]]
name = "reqwest"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.4.4",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"hyper 1.3.1",
"hyper-rustls 0.27.2",
"h2",
"http",
"http-body",
"hyper",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
@ -1311,20 +1030,22 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile 2.1.2",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg 0.52.0",
"webpki-roots",
"winreg",
]
[[package]]
@ -1368,48 +1089,19 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring",
"rustls-webpki 0.101.7",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls"
version = "0.23.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
dependencies = [
"once_cell",
"rustls-pki-types",
"rustls-webpki 0.102.4",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.5",
"base64",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
@ -1420,17 +1112,6 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.15"
@ -1543,36 +1224,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20"
dependencies = [
"base64 0.22.1",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.1.0",
"serde",
"serde_derive",
"serde_json",
"serde_with_macros",
"time",
]
[[package]]
name = "serde_with_macros"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sha1"
version = "0.10.6"
@ -1584,17 +1235,6 @@ dependencies = [
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -1615,9 +1255,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.2"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "socket2"
@ -1645,18 +1285,6 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.39"
@ -1668,12 +1296,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "system-configuration"
version = "0.5.1"
@ -1728,37 +1350,6 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1820,18 +1411,7 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls 0.21.10",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls 0.23.10",
"rustls-pki-types",
"rustls",
"tokio",
]
@ -1899,35 +1479,13 @@ version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
dependencies = [
"indexmap 2.1.0",
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"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",
"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"
@ -1981,7 +1539,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http 0.2.11",
"http",
"httparse",
"log",
"rand",
@ -2101,15 +1659,15 @@ dependencies = [
"futures-channel",
"futures-util",
"headers",
"http 0.2.11",
"hyper 0.14.27",
"http",
"hyper",
"log",
"mime",
"mime_guess",
"multer",
"percent-encoding",
"pin-project",
"rustls-pemfile 1.0.4",
"rustls-pemfile",
"scoped-tls",
"serde",
"serde_json",
@ -2391,19 +1949,3 @@ dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"

View file

@ -1,6 +1,6 @@
[package]
name = "jonas_jones-api"
version = "0.4.1"
version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -11,13 +11,11 @@ parking_lot = "0.12.1"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.35", features = ["macros"] }
dotenv = "0.15.0"
lastfm = "0.10.0"
lastfm = "0.8.1"
log = "0.4.20"
chrono = "0.4.31"
toml = "0.8.8"
reqwest = { version = "0.12.5", features = ["json", "blocking"] }
reqwest = { version = "0.11.22", features = ["json"] }
serde_json = "1.0.108"
regex = "1"
git2 = "0.19.0"
ip2location = "0.5.0"
sha2 = "0.10.8"
git2 = "0.18.1"

View file

@ -34,34 +34,3 @@ export API_IP={ip_address}
export LASTFM_API_KEY={lastfm_api_key}
export LASTFM_API_SECRET={lastfm_api_secret}
```
## Docker Compose
`docker-compose.yaml` (folder paths need adjusting):
```yaml
version: '3.8'
services:
arch-linux:
image: archlinux:latest
container_name: jonas_jones-api
ports:
- "3030:3030"
volumes:
- /home/jonas_jones/jonas_jones-api:/home/jonas_jones/jonas_jones-api
- /home/jonas_jones/.config/rclone/:/root/.config/rclone/
command: ["sh", "-c", "pacman -Syu --noconfirm --needed pkg-config openssl python3 python-pip rclone cargo && python3 -m venv api-venv && source api-venv/bin/activate && cd /home/jonas_jones/jonas_jones-api && pip install -r requirements.txt && /usr/bin/cargo run"]
```
run container:
```sh
docker-compose up -d
```
## Roadmap
- analytics backend. track request origin through IP from header (store IP hash, region and time)
- rewrite all scripts in rust
- DB implementation for projects, kcomebacks, minecraft mod versions
- session backend, auth token system
- implementation for dashboard front-end with analytics/config
- complete minecraft mod implementation

View file

@ -1,11 +0,0 @@
version: '3.8'
services:
arch-linux:
image: archlinux:latest
container_name: jonas_jones-api
ports:
- "3030:3030"
volumes:
- /home/jonas_jones/jonas_jones-api:/home/jonas_jones/jonas_jones-api
- /home/jonas_jones/.config/rclone/:/root/.config/rclone/
command: ["sh", "-c", "pacman -Syu --noconfirm --needed pkg-config openssl python3 python-pip rclone cargo && python3 -m venv api-venv && source api-venv/bin/activate && cd /home/jonas_jones/jonas_jones-api && pip install -r requirements.txt && /usr/bin/cargo run"]

View file

@ -1,9 +0,0 @@
requests
datetime
python-dotenv
spotipy
praw
spotipy
pylast
typing
markdown

View file

@ -1,14 +0,0 @@
use ip2location::{DB, Record};
pub fn ip_lookup(ip: &str) -> String {
let database_path = "resources/IP2LOCATION-LITE-DB5.IPV6.BIN/IP2LOCATION-LITE-DB5.IPV6.BIN";
let mut db = DB::from_file(database_path).unwrap();
let geo_info = db.ip_lookup(ip.parse().unwrap()).unwrap();
let record = if let Record::LocationDb(rec) = geo_info {
Some(rec)
} else { None };
return record.unwrap().country.unwrap().short_name.to_string();
}

View file

@ -1,50 +1,19 @@
use dotenv::dotenv;
use tokio::time::{sleep, Duration};
use v1::{run_sync_all_command};
use std::fs;
pub mod v1;
pub mod logger;
pub mod tools;
pub mod server;
pub mod error_responses;
pub mod iplookup;
pub mod request_logger;
pub use logger::Logger;
pub use tools::parse_ip;
async fn periodic_script_runner() {
loop {
Logger::info("Running periodic scripts...");
// Run all Functions
let _ = run_sync_all_command();
// Sleep for 6 hours
sleep(Duration::from_secs(6 * 60 * 60)).await;
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
// Load .env file
// load .env file
dotenv().ok();
// Start the api
let server_task = tokio::spawn(async {
server::serve().await;
});
// periodic script runner
let second_task = tokio::spawn(async {
// check if the local repository exists, if not, clone it
if !fs::metadata("./resources/turbo_octo_potato").is_ok() {
v1::run_setup().unwrap();
};
periodic_script_runner().await;
});
// Wait for both tasks to complete
let _ = tokio::try_join!(server_task, second_task);
}

View file

@ -1,71 +0,0 @@
use chrono::Utc;
use reqwest::Client;
use reqwest::blocking::get;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sha2::{Digest, Sha256};
use std::fs::OpenOptions;
use std::io::{BufReader, BufWriter};
use warp::http::Method;
use std::path::Path;
#[derive(Serialize, Deserialize)]
struct RequestLog {
timestamp: String,
method: String,
pathname: String,
ip_country_code: String,
ip_hash: String,
}
async fn get_ip_country_code(ip: &str) -> Result<String, Box<dyn std::error::Error>> {
let url = format!("http://ip-api.com/json/{}", ip);
let response: Value = get(&url)?.json()?;
if let Some(country_code) = response["countryCode"].as_str() {
Ok(country_code.to_string())
} else {
Err("Could not fetch country code".into())
}
}
async fn hash_ip(ip: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(ip);
format!("{:x}", hasher.finalize())
}
pub async fn log_request(client: &Client, ip: &str, pathname: &str, method: &Method, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
let method_str = method.as_str();
let timestamp = Utc::now().to_rfc3339();
let ip_country_code = get_ip_country_code(ip).await?;
let ip_hash = hash_ip(ip).await;
let log_entry = RequestLog {
timestamp,
method: method_str.to_string(),
pathname: pathname.to_string(),
ip_country_code,
ip_hash,
};
let path = Path::new(file_path);
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path)?;
let mut logs: Vec<RequestLog> = if path.exists() {
let reader = BufReader::new(&file);
serde_json::from_reader(reader)?
} else {
Vec::new()
};
logs.push(log_entry);
let writer = BufWriter::new(&file);
serde_json::to_writer_pretty(writer, &logs)?;
Ok(())
}

View file

@ -1,19 +1,13 @@
use std::convert::Infallible;
use std::net::SocketAddr;
use std::env;
use lastfm::reqwest::StatusCode;
use warp::filters::path::FullPath;
use warp::http::Method;
use reqwest::StatusCode;
use warp::Filter;
use warp::reply::Reply;
use reqwest::Client;
use crate::error_responses::{ErrorMessage, InternalServerError, BadRequestError, NotFoundError, NotImplementedError};
use crate::v1::get_v1_routes;
use crate::{parse_ip, request_logger, Logger};
use crate::iplookup::ip_lookup;
use crate::{Logger, parse_ip};
pub async fn serve() {
@ -26,38 +20,9 @@ pub async fn serve() {
let favicon = warp::path("favicon.ico").and(warp::fs::file("./src/favicon.png"));
// /status => 200 OK
let status = warp::path("status")
.map(|| warp::reply());
// Middleware filter to log request details
let log_request = warp::any()
.and(warp::method())
.and(warp::path::full())
.and(warp::addr::remote())
.and(warp::header::optional::<String>("x-forwarded-for"))
.map(|method: Method, path: FullPath, addr: Option<SocketAddr>, fwd_for: Option<String>| {
let client_ip = fwd_for.unwrap_or_else(|| addr.map(|a| a.ip().to_string()).unwrap_or_else(|| String::from("unknown")));
let path_str = path.as_str().to_string(); // Convert to owned String
let method_clone = method.clone();
let method_str = method_clone.clone().as_str().to_string();
let client_ip_clone = client_ip.clone(); // Clone for use outside the async block
let path_str_clone = path_str.clone();
/*tokio::spawn(async move {
let client = Client::new();
if let Err(e) = request_logger::log_request(&client, &client_ip, &path_str, &method_clone, "requests.json").await {
eprintln!("Failed to log request: {:?}", e);
}
});*/
Logger::info(&format!("{} {} from {} ({})", method_str, path_str_clone, ip_lookup(&client_ip_clone), client_ip_clone));
});
// GET (any) => reply with return from handle_path
let routes = log_request
.clone().untuple_one().and(favicon.or(status.or(get_v1_routes())
.recover(handle_rejection)));
let routes = favicon.or(get_v1_routes())
.recover(handle_rejection);
async fn handle_rejection(err: warp::Rejection) -> Result<impl Reply, Infallible> {
@ -78,7 +43,7 @@ pub async fn serve() {
message: message.into(),
});
Ok(warp::reply::with_status(json, StatusCode::from_u16(code.as_u16()).unwrap()))
Ok(warp::reply::with_status(json, code))
}

View file

@ -1,8 +0,0 @@
use warp::Filter;
pub fn get_analytics_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("analytics"))
.and((warp::path("logcdnrequest").map(|| "Please refer to the wiki at https://wiki.jonasjones.dev/Api/"))
.or(warp::path("ping").map(|| "pong"))
.or(warp::path("version").map(|| warp::reply::json(&[option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")]))))
}

View file

@ -1,7 +0,0 @@
use warp::Filter;
pub fn get_auth_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("auth"))
.and((warp::path("requestsession").and(warp))
.or(warp::path("login")))
}

View file

@ -1,6 +1,6 @@
use warp::Filter;
pub fn get_builtin_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_builtin_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("v1")
.and((warp::path("help").map(|| "Please refer to the wiki at https://wiki.jonasjones.dev/Api/"))
.or(warp::path("ping").map(|| "pong"))

View file

@ -1,6 +1,6 @@
use warp::Filter;
pub fn get_debug_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_debug_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("debug")
.and(warp::path("headers").and(warp::header::headers_cloned().map(handle_with_headers)))
}

View file

@ -6,7 +6,7 @@ use warp::Filter;
use crate::{error_responses::{BadRequestError, InternalServerError}, v1::kcomebacks::{fetch_data, create_json_response, parse_item, Item as EntryItem}};
pub fn get_kcomebacks_filter_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_kcomebacks_filter_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("filter")
.and((warp::path("id").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(filter_id_handler))
.or(warp::path("getall").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(filter_getall_handler))

View file

@ -10,7 +10,7 @@ use filter::get_kcomebacks_filter_routes;
use upcoming::get_kcomebacks_upcoming_routes;
use crate::error_responses::InternalServerError;
pub fn get_kcomebacks_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_kcomebacks_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("kcomebacks"))
.and(warp::path("last_update").and(warp::get()).and_then(last_update)

View file

@ -4,7 +4,7 @@ use warp::Filter;
use crate::v1::kcomebacks::filter::filter_daterange_handler;
pub fn get_kcomebacks_upcoming_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_kcomebacks_upcoming_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("upcoming")
.and((warp::path("today").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(upcoming_today_handler))
.or(warp::path("week").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(upcoming_week_handler))

View file

@ -2,20 +2,17 @@ mod builtin;
mod debug;
mod kcomebacks;
mod projects;
mod run;
pub use run::setup as run_setup;
pub use run::run_sync_all_command;
mod update;
pub use builtin::get_builtin_routes as get_v1_builtin_routes;
pub use debug::get_debug_routes as get_v1_debug_routes;
pub use kcomebacks::get_kcomebacks_routes as get_v1_kcomebacks_routes;
pub use projects::get_project_routes as get_v1_project_routes;
pub use run::get_run_routes as get_v1_updates_routes;
pub use update::get_update_routes as get_v1_updates_routes;
use warp::Filter;
pub fn get_v1_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_v1_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
return get_v1_builtin_routes()
.or(get_v1_debug_routes())
.or(get_v1_kcomebacks_routes())

View file

@ -5,7 +5,7 @@ use warp::Filter;
use crate::{error_responses::BadRequestError, v1::projects::{fetch_data, create_json_response, Project as EntryProject}};
pub fn get_project_filter_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_project_filter_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("filter")
.and((warp::path("getall").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(filter_getall_handler))
.or(warp::path("lastupdaterange").and(warp::get()).and(warp::query::<HashMap<String, String>>()).and_then(filter_lastupdaterange_handler))

View file

@ -10,7 +10,7 @@ use filter::get_project_filter_routes;
use crate::error_responses::InternalServerError;
pub fn get_project_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
pub fn get_project_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("projects"))
.and(warp::path("last_update").and(warp::get()).and_then(last_update)

View file

@ -1,10 +1,10 @@
use std::fs;
// use std::io::BufRead;
use std::io::BufRead;
use std::process::{Stdio, Command};
use serde::{Deserialize, Serialize};
use serde_json::json;
// use tokio::sync::mpsc;
use tokio::sync::mpsc;
use tokio::task;
use warp::Filter;
use crate::error_responses::InternalServerError;
@ -16,8 +16,8 @@ pub struct DiscographyQuery {
artists: String,
}
pub fn get_run_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("run"))
pub fn get_update_routes() -> impl warp::Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("update"))
// update/kcomebacks
// update/projects
// update/makediscography?artists=artist1,artist2,artist3
@ -26,7 +26,6 @@ pub fn get_run_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error =
.or(warp::path("projects").and_then(update_projects))
.or(warp::path("makediscography").map(||"Not implemented yet"))
.or(warp::path("synclikedsongs").and_then(sync_liked_songs))
.or(warp::path("sync_all").and_then(sync_all))
)
}
@ -81,24 +80,7 @@ async fn sync_liked_songs() -> Result<impl warp::Reply, warp::Rejection> {
}
async fn sync_all() -> Result<impl warp::Reply, warp::Rejection> {
// check if the local repository exists, if not, clone it
if !fs::metadata("./resources/turbo_octo_potato").is_ok() {
setup().unwrap();
};
if let Err(err) = run_sync_all_command() {
// Handle the error here
eprintln!("Error: {}", err);
// Return an appropriate response or error
return Err(warp::reject::custom(InternalServerError));
}
Ok(warp::reply::json(&json!({"status": "syncing..."})))
}
pub fn setup() -> Result<(), git2::Error> {
fn setup() -> Result<(), git2::Error> {
let repository_url = "https://github.com/JonasunderscoreJones/turbo-octo-potato.git";
let local_directory = "resources/turbo_octo_potato";
@ -149,8 +131,8 @@ pub fn setup() -> Result<(), git2::Error> {
// run_command with python file and args as parameters
pub fn run_kcomebacks_command() -> Result<(), std::io::Error> {
// let (tx, mut rx) = mpsc::channel(1);
fn run_kcomebacks_command() -> Result<(), std::io::Error> {
let (tx, mut rx) = mpsc::channel(1);
task::spawn_blocking(move || {
let mut child = Command::new("python3")
@ -161,36 +143,35 @@ pub fn run_kcomebacks_command() -> Result<(), std::io::Error> {
.spawn()
.expect("failed to execute child");
// let stdout = child.stdout.as_mut().unwrap();
let stdout = child.stdout.as_mut().unwrap();
// let mut reader = std::io::BufReader::new(stdout);
let mut reader = std::io::BufReader::new(stdout);
// let mut line = String::new();
let mut line = String::new();
// loop {
// let len = reader.read_line(&mut line).unwrap();
// if len == 0 {
// break;
// }
// tx.blocking_send(line.clone()).unwrap();
// line.clear();
// }
loop {
let len = reader.read_line(&mut line).unwrap();
if len == 0 {
break;
}
tx.blocking_send(line.clone()).unwrap();
line.clear();
}
child.wait().unwrap();
});
// task::spawn(async move {
// while let Some(line) = rx.recv().await {
// Logger::info(&format!("[/v1/kcomebacks/update]: {}", line));
// }
// });
Logger::info("Updating kcomebacks...");
task::spawn(async move {
while let Some(line) = rx.recv().await {
Logger::info(&format!("[/v1/kcomebacks/update]: {}", line));
}
});
Ok(())
}
pub fn run_projects_command() -> Result<(), std::io::Error> {
// let (tx, mut rx) = mpsc::channel(1);
fn run_projects_command() -> Result<(), std::io::Error> {
let (tx, mut rx) = mpsc::channel(1);
task::spawn_blocking(move || {
let mut child = Command::new("python3")
@ -201,36 +182,35 @@ pub fn run_projects_command() -> Result<(), std::io::Error> {
.spawn()
.expect("failed to execute child");
// let stdout = child.stdout.as_mut().unwrap();
let stdout = child.stdout.as_mut().unwrap();
// let mut reader = std::io::BufReader::new(stdout);
let mut reader = std::io::BufReader::new(stdout);
// let mut line = String::new();
let mut line = String::new();
// loop {
// let len = reader.read_line(&mut line).unwrap();
// if len == 0 {
// break;
// }
// tx.blocking_send(line.clone()).unwrap();
// line.clear();
// }
loop {
let len = reader.read_line(&mut line).unwrap();
if len == 0 {
break;
}
tx.blocking_send(line.clone()).unwrap();
line.clear();
}
child.wait().unwrap();
});
// task::spawn(async move {
// while let Some(line) = rx.recv().await {
// Logger::info(&format!("[/v1/projects/update]: {}", line));
// }
// });
Logger::info("Updating projects...");
task::spawn(async move {
while let Some(line) = rx.recv().await {
Logger::info(&format!("[/v1/projects/update]: {}", line));
}
});
Ok(())
}
pub fn run_likedsongs_command() -> Result<(), std::io::Error> {
// let (tx, mut rx) = mpsc::channel(1);
fn run_likedsongs_command() -> Result<(), std::io::Error> {
let (tx, mut rx) = mpsc::channel(1);
task::spawn_blocking(move || {
let mut child = Command::new("python3")
@ -240,45 +220,29 @@ pub fn run_likedsongs_command() -> Result<(), std::io::Error> {
.spawn()
.expect("failed to execute child");
// let stdout = child.stdout.as_mut().unwrap();
let stdout = child.stdout.as_mut().unwrap();
// let mut reader = std::io::BufReader::new(stdout);
let mut reader = std::io::BufReader::new(stdout);
// let mut line = String::new();
let mut line = String::new();
// loop {
// let len = reader.read_line(&mut line).unwrap();
// if len == 0 {
// break;
// }
// tx.blocking_send(line.clone()).unwrap();
// line.clear();
// }
loop {
let len = reader.read_line(&mut line).unwrap();
if len == 0 {
break;
}
tx.blocking_send(line.clone()).unwrap();
line.clear();
}
child.wait().unwrap();
});
// task::spawn(async move {
// while let Some(line) = rx.recv().await {
// Logger::info(&format!("[/v1/synclikedsongs]: {}", line));
// }
// });
Logger::info("Syncing liked songs...");
Ok(())
}
pub fn run_sync_all_command() -> Result<(), std::io::Error> {
task::spawn_blocking(move || {
let mut child = Command::new("python3")
.arg("script_interval_runner.py")
.current_dir("resources/turbo_octo_potato")
.stdout(Stdio::piped())
.spawn()
.expect("failed to execute child");
child.wait().unwrap();
task::spawn(async move {
while let Some(line) = rx.recv().await {
Logger::info(&format!("[/v1/synclikedsongs]: {}", line));
}
});
Logger::info("Running all Sync Scripts...");
Ok(())
}