Compare commits
No commits in common. "97623afd8d11d29f7c4b9f0f4d0572c1674a360d" and "714274659edfc8caff3dffb10c5473aea054b295" have entirely different histories.
97623afd8d
...
714274659e
38 changed files with 308 additions and 281 deletions
247
Cargo.lock
generated
247
Cargo.lock
generated
|
@ -32,9 +32,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.3"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
@ -163,7 +163,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -183,13 +183,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.79"
|
version = "0.1.77"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
|
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -209,15 +209,15 @@ checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.2.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.7.5"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
|
checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
|
@ -240,7 +240,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_path_to_error",
|
"serde_path_to_error",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper 1.0.1",
|
"sync_wrapper",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
|
@ -263,7 +263,7 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"sync_wrapper 0.1.2",
|
"sync_wrapper",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -295,17 +295,17 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
|
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.1",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-test"
|
name = "axum-test"
|
||||||
version = "14.8.0"
|
version = "14.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db705caa0b050aa7247c4748293b09e4cddaf7a3c4a87faf145859c11ce501e3"
|
checksum = "673f937bbc7eaadff359e2797c0de2c20e02c9db5bd6f2aed457c7ae93559b9b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -332,9 +332,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.71"
|
version = "0.3.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"addr2line",
|
"addr2line",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -380,9 +380,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.5.0"
|
version = "2.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -407,9 +407,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.16.0"
|
version = "3.15.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
|
@ -419,15 +419,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.6.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.92"
|
version = "1.0.90"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
|
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -444,16 +444,15 @@ dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time 0.1.45",
|
"time 0.1.45",
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.4"
|
version = "4.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -475,14 +474,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.4"
|
version = "4.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -517,9 +516,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie"
|
name = "cookie"
|
||||||
version = "0.18.1"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"time 0.3.34",
|
"time 0.3.34",
|
||||||
|
@ -543,9 +542,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc"
|
name = "crc"
|
||||||
version = "3.2.1"
|
version = "3.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc-catalog",
|
"crc-catalog",
|
||||||
]
|
]
|
||||||
|
@ -583,9 +582,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.9"
|
version = "0.7.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"pem-rfc7468",
|
"pem-rfc7468",
|
||||||
|
@ -700,9 +699,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.0.2"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "finl_unicode"
|
name = "finl_unicode"
|
||||||
|
@ -802,7 +801,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -846,9 +845,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.14"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
|
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
@ -863,6 +862,25 @@ version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.1.0",
|
||||||
|
"indexmap",
|
||||||
|
"slab",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.3"
|
version = "0.14.3"
|
||||||
|
@ -891,12 +909,6 @@ dependencies = [
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "heck"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -1017,6 +1029,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"h2",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
|
@ -1083,9 +1096,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.6"
|
version = "2.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
@ -1102,9 +1115,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
|
@ -1117,9 +1130,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "julid-rs"
|
name = "julid-rs"
|
||||||
version = "1.6.18033988"
|
version = "1.6.1803398"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82f75e4d7184b798c5b8e3b9ead1a3d1ea121091a84089bb39138e6a5500ca61"
|
checksum = "98270c2a07b60873e7b164cebea22f83bbe42632c9774c5360e0f7ef0a63986d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -1162,12 +1175,13 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
version = "0.1.3"
|
version = "0.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.4.2",
|
||||||
"libc",
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1231,9 +1245,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.2"
|
version = "2.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
|
@ -1433,7 +1447,7 @@ name = "optional_optional_user"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1537,14 +1551,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.14"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
|
@ -1660,9 +1674,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.5"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
|
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"libredox",
|
"libredox",
|
||||||
|
@ -1671,14 +1685,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.6",
|
"regex-automata 0.4.6",
|
||||||
"regex-syntax 0.8.3",
|
"regex-syntax 0.8.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1698,7 +1712,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax 0.8.3",
|
"regex-syntax 0.8.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1709,9 +1723,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.3"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reserve-port"
|
name = "reserve-port"
|
||||||
|
@ -1804,11 +1818,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.32"
|
version = "0.38.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.4.2",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
|
@ -1817,9 +1831,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.15"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
|
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
|
@ -1850,14 +1864,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.115"
|
version = "1.0.114"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
|
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -1968,9 +1982,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
|
@ -2041,7 +2055,6 @@ dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
|
||||||
"crc",
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"either",
|
"either",
|
||||||
|
@ -2093,7 +2106,7 @@ checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"either",
|
"either",
|
||||||
"heck 0.4.1",
|
"heck",
|
||||||
"hex",
|
"hex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -2119,10 +2132,9 @@ checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.4.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
|
||||||
"crc",
|
"crc",
|
||||||
"digest",
|
"digest",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
@ -2163,9 +2175,8 @@ checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.4.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"chrono",
|
|
||||||
"crc",
|
"crc",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"etcetera",
|
"etcetera",
|
||||||
|
@ -2202,7 +2213,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
|
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"chrono",
|
|
||||||
"flume",
|
"flume",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -2233,9 +2243,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
|
@ -2256,9 +2266,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.58"
|
version = "2.0.52"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2271,12 +2281,6 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sync_wrapper"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.10.1"
|
version = "3.10.1"
|
||||||
|
@ -2306,7 +2310,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2378,9 +2382,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.37.0"
|
version = "1.36.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2403,14 +2407,14 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.15"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
|
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -2428,13 +2432,14 @@ dependencies = [
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.12"
|
version = "0.8.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
|
@ -2453,9 +2458,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.9"
|
version = "0.22.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
|
checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2503,7 +2508,7 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
|
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.4.2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -2536,9 +2541,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-sessions"
|
name = "tower-sessions"
|
||||||
version = "0.11.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b27326208b21807803c5f5aa1020d30ca0432b78cfe251b51a67a05e0baea102"
|
checksum = "989b4d77286a7fb96b094b9e62c4524cebe7bb720769b41588ebaac5d9a787ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -2554,9 +2559,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-sessions-core"
|
name = "tower-sessions-core"
|
||||||
version = "0.11.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afd1c5040577134115d8cc758d7757da29e171f83102de3ed1b86e3a2405533f"
|
checksum = "c0a9049748900860b01f92d3decf5fec71b9d75008f07732956288b003a2282f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
|
@ -2575,9 +2580,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-sessions-memory-store"
|
name = "tower-sessions-memory-store"
|
||||||
version = "0.11.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88ac75309918b8f6ba16d09865a2a64f81e01b05cf42d5e88e5d3c6cbf775486"
|
checksum = "36baf499920bb861ec9fa929a1f879cec0759af987c6360bd65226bc484ab846"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"time 0.3.34",
|
"time 0.3.34",
|
||||||
|
@ -2619,7 +2624,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2816,7 +2821,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2838,7 +2843,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
@ -3092,7 +3097,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -16,7 +16,7 @@ async-trait = "0.1"
|
||||||
axum = { version = "0.7", features = ["macros"] }
|
axum = { version = "0.7", features = ["macros"] }
|
||||||
axum-login = "0.14"
|
axum-login = "0.14"
|
||||||
axum-macros = "0.4"
|
axum-macros = "0.4"
|
||||||
chrono = { version = "0.4", default-features = false, features = ["std", "clock", "serde"] }
|
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
|
||||||
clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] }
|
clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] }
|
||||||
confy = "0.6"
|
confy = "0.6"
|
||||||
dirs = "5"
|
dirs = "5"
|
||||||
|
@ -29,7 +29,7 @@ password-hash = { version = "0.5", features = ["std", "getrandom"] }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
sha256 = { version = "1", default-features = false }
|
sha256 = { version = "1", default-features = false }
|
||||||
sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio", "sqlite", "tls-none", "migrate", "chrono"] }
|
sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio", "sqlite", "tls-none", "migrate"] }
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
tokio = { version = "1", features = ["rt-multi-thread", "signal", "tracing"], default-features = false }
|
tokio = { version = "1", features = ["rt-multi-thread", "signal", "tracing"], default-features = false }
|
||||||
tower = { version = "0.4", features = ["util", "timeout"], default-features = false }
|
tower = { version = "0.4", features = ["util", "timeout"], default-features = false }
|
||||||
|
|
2
julid
2
julid
|
@ -1 +1 @@
|
||||||
Subproject commit 1e93d0b1e4bc76ff19e1ce8e638c60204f458604
|
Subproject commit 705afc19e953133aadf811a0a51597e169f7aa62
|
|
@ -3,11 +3,11 @@ create table if not exists users (
|
||||||
username text not null unique,
|
username text not null unique,
|
||||||
displayname text,
|
displayname text,
|
||||||
email text,
|
email text,
|
||||||
last_seen text,
|
last_seen int,
|
||||||
pwhash blob not null,
|
pwhash blob not null,
|
||||||
invited_by blob not null,
|
invited_by blob not null,
|
||||||
is_active boolean not null default true,
|
is_active boolean not null default true,
|
||||||
last_updated text not null default CURRENT_TIMESTAMP,
|
last_updated int not null default (unixepoch()),
|
||||||
foreign key (invited_by) references users (id)
|
foreign key (invited_by) references users (id)
|
||||||
);
|
);
|
||||||
create index if not exists users_username_dex on users (lower(username));
|
create index if not exists users_username_dex on users (lower(username));
|
||||||
|
@ -18,16 +18,16 @@ create trigger if not exists update_last_updated_users
|
||||||
after update on users
|
after update on users
|
||||||
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
||||||
BEGIN
|
BEGIN
|
||||||
update users set last_updated = CURRENT_TIMESTAMP where id=NEW.id;
|
update users set last_updated = (select unixepoch()) where id=NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- invitations
|
-- invitations
|
||||||
create table if not exists invites (
|
create table if not exists invites (
|
||||||
id blob not null primary key default (julid_new()),
|
id blob not null primary key default (julid_new()),
|
||||||
owner blob not null,
|
owner blob not null,
|
||||||
expires_at text,
|
expires_at int,
|
||||||
remaining int not null default 1,
|
remaining int not null default 1,
|
||||||
last_updated text not null default CURRENT_TIMESTAMP,
|
last_updated int not null default (unixepoch()),
|
||||||
foreign key (owner) references users (id) on delete cascade on update no action
|
foreign key (owner) references users (id) on delete cascade on update no action
|
||||||
);
|
);
|
||||||
create index if not exists invites_owner_dex on invites (owner);
|
create index if not exists invites_owner_dex on invites (owner);
|
||||||
|
@ -36,6 +36,6 @@ create trigger if not exists update_last_updated_invites
|
||||||
after update on invites
|
after update on invites
|
||||||
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
||||||
BEGIN
|
BEGIN
|
||||||
update invites set last_updated = CURRENT_TIMESTAMP where id=NEW.id;
|
update invites set last_updated = (select unixepoch()) where id=NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ create table if not exists watches (
|
||||||
title text not null,
|
title text not null,
|
||||||
metadata_url text, -- possible url for imdb or other metadata-esque site to show the user
|
metadata_url text, -- possible url for imdb or other metadata-esque site to show the user
|
||||||
length int,
|
length int,
|
||||||
release_date text,
|
release_date int,
|
||||||
added_by blob not null, -- ID of the user that added it
|
added_by blob not null, -- ID of the user that added it
|
||||||
last_updated text not null default CURRENT_TIMESTAMP,
|
last_updated int not null default (unixepoch()),
|
||||||
foreign key (added_by) references users (id)
|
foreign key (added_by) references users (id)
|
||||||
);
|
);
|
||||||
create index if not exists watches_title_dex on watches (lower(title));
|
create index if not exists watches_title_dex on watches (lower(title));
|
||||||
|
@ -16,7 +16,7 @@ create trigger if not exists update_last_updated_watches
|
||||||
after update on watches
|
after update on watches
|
||||||
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
||||||
BEGIN
|
BEGIN
|
||||||
update watches set last_updated = CURRENT_TIMESTAMP where id=NEW.id;
|
update watches set last_updated = (select unixepoch()) where id=NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- table of what people want to watch
|
-- table of what people want to watch
|
||||||
|
@ -26,9 +26,9 @@ create table if not exists watch_quests (
|
||||||
priority int, -- 1-5 how much do you want to watch it
|
priority int, -- 1-5 how much do you want to watch it
|
||||||
public boolean not null default true,
|
public boolean not null default true,
|
||||||
watched boolean not null default false,
|
watched boolean not null default false,
|
||||||
when_watched text,
|
when_watched int,
|
||||||
created_at text not null default CURRENT_TIMESTAMP,
|
created_at int not null default (unixepoch()),
|
||||||
last_updated text not null default CURRENT_TIMESTAMP,
|
last_updated int not null default (unixepoch()),
|
||||||
foreign key (user) references users (id) on delete cascade on update no action,
|
foreign key (user) references users (id) on delete cascade on update no action,
|
||||||
foreign key (watch) references watches (id) on delete cascade on update no action,
|
foreign key (watch) references watches (id) on delete cascade on update no action,
|
||||||
primary key (user, watch)
|
primary key (user, watch)
|
||||||
|
@ -40,7 +40,7 @@ create trigger if not exists update_last_updated_watch_quests
|
||||||
after update on watch_quests
|
after update on watch_quests
|
||||||
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
||||||
BEGIN
|
BEGIN
|
||||||
update watch_quests set last_updated = CURRENT_TIMESTAMP where watch=NEW.watch and user=NEW.user;
|
update watch_quests set last_updated = (select unixepoch()) where watch=NEW.watch and user=NEW.user;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- notes on stuff to watch
|
-- notes on stuff to watch
|
||||||
|
@ -50,7 +50,7 @@ create table if not exists watch_notes (
|
||||||
watch blob not null,
|
watch blob not null,
|
||||||
note blob,
|
note blob,
|
||||||
public boolean not null,
|
public boolean not null,
|
||||||
last_updated text not null default CURRENT_TIMESTAMP,
|
last_updated int not null default (unixepoch()),
|
||||||
foreign key (user) references users (id) on delete cascade on update no action,
|
foreign key (user) references users (id) on delete cascade on update no action,
|
||||||
foreign key (watch) references watches (id) on delete cascade on update no action
|
foreign key (watch) references watches (id) on delete cascade on update no action
|
||||||
);
|
);
|
||||||
|
@ -61,5 +61,5 @@ create trigger if not exists update_last_updated_watch_notes
|
||||||
after update on watch_notes
|
after update on watch_notes
|
||||||
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
when OLD.last_updated = NEW.last_updated or OLD.last_updated is null
|
||||||
BEGIN
|
BEGIN
|
||||||
update watch_notes set last_updated = CURRENT_TIMESTAMP where id=NEW.id;
|
update watch_notes set last_updated = (select unixepoch()) where id=NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
|
@ -2,8 +2,8 @@ create table if not exists stars (
|
||||||
id blob not null primary key default (julid_new()),
|
id blob not null primary key default (julid_new()),
|
||||||
name text not null,
|
name text not null,
|
||||||
metadata_url text,
|
metadata_url text,
|
||||||
born text,
|
born int,
|
||||||
died text
|
died int
|
||||||
);
|
);
|
||||||
create index if not exists stars_name_dex on stars (lower(name));
|
create index if not exists stars_name_dex on stars (lower(name));
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
create table if not exists follows (
|
create table if not exists follows (
|
||||||
follower blob not null,
|
follower blob not null,
|
||||||
followee blob not null,
|
followee blob not null,
|
||||||
created_at text not null default CURRENT_TIMESTAMP,
|
created_at int not null default (unixepoch()),
|
||||||
foreign key (follower) references users (id) on delete cascade on update no action,
|
foreign key (follower) references users (id) on delete cascade on update no action,
|
||||||
foreign key (followee) references users (id) on delete cascade on update no action,
|
foreign key (followee) references users (id) on delete cascade on update no action,
|
||||||
unique (follower, followee)
|
unique (follower, followee)
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
drop view if exists q;
|
|
||||||
drop view if exists i;
|
|
||||||
drop view if exists u;
|
|
||||||
drop view if exists s;
|
|
||||||
drop view if exists w;
|
|
|
@ -1,6 +0,0 @@
|
||||||
-- human-friendly views with joined fields and string julids
|
|
||||||
create view if not exists w as select julid_string(id) id, kind, title, metadata_url, length, release_date, last_updated from watches;
|
|
||||||
create view if not exists s as select julid_string(id) id, name, born, died from stars;
|
|
||||||
create view if not exists u as select julid_string(id) id, username, displayname, email, (select username from users where id = invited_by) invited_by, last_seen, last_updated from users;
|
|
||||||
create view if not exists i as select julid_string(invites.id) id, users.username, expires_at, remaining, invites.last_updated from invites inner join users on users.id = owner;
|
|
||||||
create view if not exists q as select users.username, watches.title, julid_string(watch) from watch_quests inner join users on users.id = user inner join watches on watch = watches.id;
|
|
|
@ -50,10 +50,9 @@ impl AuthnBackend for AuthStore {
|
||||||
let username = creds.username.trim();
|
let username = creds.username.trim();
|
||||||
let password = creds.password.trim();
|
let password = creds.password.trim();
|
||||||
|
|
||||||
let user = User::try_get(username, &self.0).await.map_err(|e| {
|
let user = User::try_get(username, &self.0)
|
||||||
tracing::debug!("Got error getting {username}: {e:?}");
|
.await
|
||||||
AuthErrorKind::Internal
|
.map_err(|_| AuthErrorKind::Internal)?;
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(user.filter(|user| verify_password(password, &user.pwhash).is_ok()))
|
Ok(user.filter(|user| verify_password(password, &user.pwhash).is_ok()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,18 +33,8 @@ fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
let now = std::time::Instant::now();
|
|
||||||
let ids = rt.block_on(import_watches(&w2w_db, &cli));
|
let ids = rt.block_on(import_watches(&w2w_db, &cli));
|
||||||
let dur = std::time::Instant::now() - now;
|
|
||||||
println!(
|
|
||||||
"Imported {} watches in {} seconds",
|
|
||||||
ids.len(),
|
|
||||||
dur.as_secs()
|
|
||||||
);
|
|
||||||
let now = std::time::Instant::now();
|
|
||||||
rt.block_on(save_ids(&cli.db_path, ids));
|
rt.block_on(save_ids(&cli.db_path, ids));
|
||||||
let dur = std::time::Instant::now() - now;
|
|
||||||
println!("Saved the IDs in {} seconds", dur.as_secs());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn import_watches(w2w_db: &SqlitePool, cli: &Cli) -> IdMap {
|
async fn import_watches(w2w_db: &SqlitePool, cli: &Cli) -> IdMap {
|
||||||
|
@ -74,7 +64,6 @@ async fn save_ids(path: &OsStr, ids: IdMap) {
|
||||||
let file = path.file_name().unwrap();
|
let file = path.file_name().unwrap();
|
||||||
let file = file.to_str().unwrap();
|
let file = file.to_str().unwrap();
|
||||||
let path = format!("{}/w2w-{file}", path.parent().unwrap().to_str().unwrap());
|
let path = format!("{}/w2w-{file}", path.parent().unwrap().to_str().unwrap());
|
||||||
println!("Writing IDs to {path}");
|
|
||||||
|
|
||||||
let conn_opts = SqliteConnectOptions::new()
|
let conn_opts = SqliteConnectOptions::new()
|
||||||
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
||||||
|
|
|
@ -7,7 +7,6 @@ const CONFIG_NAME: Option<&str> = Some("config");
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub base_url: String,
|
pub base_url: String,
|
||||||
pub db_file: String,
|
pub db_file: String,
|
||||||
pub julid_plugin: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
@ -15,14 +14,9 @@ impl Default for Config {
|
||||||
let mut datadir = dirs::data_dir().unwrap();
|
let mut datadir = dirs::data_dir().unwrap();
|
||||||
datadir.push(APP_NAME);
|
datadir.push(APP_NAME);
|
||||||
datadir.push("what2watch.db");
|
datadir.push("what2watch.db");
|
||||||
let db_file = datadir.as_os_str().to_string_lossy().to_string();
|
|
||||||
datadir.pop();
|
|
||||||
datadir.push("libjulid"); // don't have the '.so' extension here
|
|
||||||
let julid_plugin = datadir.as_os_str().to_string_lossy().to_string();
|
|
||||||
Self {
|
Self {
|
||||||
base_url: "http://localhost:3000".into(),
|
base_url: "http://localhost:3000".into(),
|
||||||
db_file,
|
db_file: datadir.as_os_str().to_string_lossy().to_string(),
|
||||||
julid_plugin,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,14 @@ use sqlx::{
|
||||||
|
|
||||||
const MAX_CONNS: u32 = 200;
|
const MAX_CONNS: u32 = 200;
|
||||||
const MIN_CONNS: u32 = 5;
|
const MIN_CONNS: u32 = 5;
|
||||||
const TIMEOUT: u64 = 20;
|
const TIMEOUT: u64 = 3;
|
||||||
|
|
||||||
pub fn get_db_pool() -> SqlitePool {
|
pub fn get_db_pool() -> SqlitePool {
|
||||||
let conf = crate::conf::Config::get();
|
|
||||||
let db_filename = {
|
let db_filename = {
|
||||||
std::env::var("DATABASE_FILE").unwrap_or_else(|_| {
|
std::env::var("DATABASE_FILE").unwrap_or_else(|_| {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
{
|
{
|
||||||
let f = conf.db_file;
|
let f = crate::conf::Config::get().db_file;
|
||||||
let p = std::path::Path::new(&f);
|
let p = std::path::Path::new(&f);
|
||||||
let p = p.parent().unwrap();
|
let p = p.parent().unwrap();
|
||||||
std::fs::create_dir_all(p).expect("couldn't create data dir");
|
std::fs::create_dir_all(p).expect("couldn't create data dir");
|
||||||
|
@ -37,15 +36,13 @@ pub fn get_db_pool() -> SqlitePool {
|
||||||
|
|
||||||
tracing::info!("Connecting to DB at {db_filename}");
|
tracing::info!("Connecting to DB at {db_filename}");
|
||||||
|
|
||||||
let plugin = conf.julid_plugin;
|
|
||||||
|
|
||||||
let conn_opts = SqliteConnectOptions::new()
|
let conn_opts = SqliteConnectOptions::new()
|
||||||
.foreign_keys(true)
|
.foreign_keys(true)
|
||||||
.journal_mode(SqliteJournalMode::Wal)
|
.journal_mode(SqliteJournalMode::Wal)
|
||||||
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
|
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
|
||||||
.filename(&db_filename)
|
.filename(&db_filename)
|
||||||
// be sure to have run `make` so that the libjulid extension is built
|
// be sure to have run `make` so that the libjulid extension is built
|
||||||
.extension(plugin)
|
.extension("./libjulid")
|
||||||
.busy_timeout(Duration::from_secs(TIMEOUT))
|
.busy_timeout(Duration::from_secs(TIMEOUT))
|
||||||
.create_if_missing(true)
|
.create_if_missing(true)
|
||||||
.optimize_on_close(true, None)
|
.optimize_on_close(true, None)
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub async fn handle_slash_redir() -> impl IntoResponse {
|
||||||
Redirect::to("/")
|
Redirect::to("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[axum::debug_handler]
|
|
||||||
pub async fn handle_slash(auth: AuthSession) -> impl IntoResponse {
|
pub async fn handle_slash(auth: AuthSession) -> impl IntoResponse {
|
||||||
if let Some(ref user) = auth.user {
|
if let Some(ref user) = auth.user {
|
||||||
let name = &user.username;
|
let name = &user.username;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use julid::Julid;
|
use julid::Julid;
|
||||||
use sqlx::{Sqlite, SqlitePool};
|
use sqlx::{Connection, Sqlite, SqlitePool};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
import_utils::{insert_credit, insert_star, insert_watch},
|
import_utils::{insert_credit, insert_star, insert_watch},
|
||||||
|
misc_util::year_to_epoch,
|
||||||
Credit, ShowKind, Star, Watch,
|
Credit, ShowKind, Star, Watch,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ impl From<ImportImdbMovie> for Watch {
|
||||||
Watch {
|
Watch {
|
||||||
id: OMEGA_ID, // this is ignored by the inserter
|
id: OMEGA_ID, // this is ignored by the inserter
|
||||||
title: value.title,
|
title: value.title,
|
||||||
release_date: value.year,
|
release_date: year_to_epoch(value.year.as_deref()),
|
||||||
length: value.length.and_then(|v| v.parse::<i64>().ok()),
|
length: value.length.and_then(|v| v.parse::<i64>().ok()),
|
||||||
kind: ShowKind::Movie,
|
kind: ShowKind::Movie,
|
||||||
metadata_url: Some(format!("https://imdb.com/title/{}/", &value.id)),
|
metadata_url: Some(format!("https://imdb.com/title/{}/", &value.id)),
|
||||||
|
@ -38,7 +39,7 @@ impl From<&ImportImdbMovie> for Watch {
|
||||||
Watch {
|
Watch {
|
||||||
id: OMEGA_ID,
|
id: OMEGA_ID,
|
||||||
title: value.title.to_string(),
|
title: value.title.to_string(),
|
||||||
release_date: value.year.clone(),
|
release_date: year_to_epoch(value.year.as_deref()),
|
||||||
length: value.length.as_ref().and_then(|v| v.parse::<i64>().ok()),
|
length: value.length.as_ref().and_then(|v| v.parse::<i64>().ok()),
|
||||||
kind: ShowKind::Movie,
|
kind: ShowKind::Movie,
|
||||||
metadata_url: Some(format!("https://imdb.com/title/{}/", value.id)),
|
metadata_url: Some(format!("https://imdb.com/title/{}/", value.id)),
|
||||||
|
@ -65,8 +66,8 @@ impl From<&ImdbStar> for Star {
|
||||||
Self {
|
Self {
|
||||||
name: value.name.clone(),
|
name: value.name.clone(),
|
||||||
metadata_url,
|
metadata_url,
|
||||||
born: value.born.clone(),
|
born: year_to_epoch(value.born.as_deref()),
|
||||||
died: value.died.clone(),
|
died: year_to_epoch(value.died.as_deref()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +83,8 @@ pub async fn import_imdb_data(w2w_db: &SqlitePool, imdb: &SqlitePool, ids: &mut
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
for batch in iwatches.chunks(5_000) {
|
for batch in iwatches.chunks(5_000) {
|
||||||
let mut tx = w2w_db.begin().await.unwrap();
|
let mut tx = w2w_db.acquire().await.unwrap();
|
||||||
|
let mut tx = tx.begin().await.unwrap();
|
||||||
for iwatch in batch {
|
for iwatch in batch {
|
||||||
let aid = iwatch.id.clone();
|
let aid = iwatch.id.clone();
|
||||||
let kind = show_kind(iwatch.kind.as_ref().unwrap());
|
let kind = show_kind(iwatch.kind.as_ref().unwrap());
|
||||||
|
|
|
@ -31,8 +31,8 @@ pub async fn insert_star(star: &Star, db: &mut SqliteConnection) -> Julid {
|
||||||
sqlx::query_scalar(q)
|
sqlx::query_scalar(q)
|
||||||
.bind(&star.name)
|
.bind(&star.name)
|
||||||
.bind(&star.metadata_url)
|
.bind(&star.metadata_url)
|
||||||
.bind(&star.born)
|
.bind(star.born)
|
||||||
.bind(&star.died)
|
.bind(star.died)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -22,7 +22,6 @@ pub use users::User;
|
||||||
pub use watches::{ShowKind, Watch, WatchQuest};
|
pub use watches::{ShowKind, Watch, WatchQuest};
|
||||||
|
|
||||||
pub type WWRouter = axum::Router<SqlitePool>;
|
pub type WWRouter = axum::Router<SqlitePool>;
|
||||||
pub type WatchDate = chrono::DateTime<chrono::Utc>;
|
|
||||||
|
|
||||||
// everything else is private to the crate
|
// everything else is private to the crate
|
||||||
mod auth;
|
mod auth;
|
||||||
|
@ -56,9 +55,6 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
|
||||||
post_add_watch_quest,
|
post_add_watch_quest,
|
||||||
};
|
};
|
||||||
|
|
||||||
let conf = crate::conf::Config::get();
|
|
||||||
tracing::info!("Using config: {conf:#?}");
|
|
||||||
|
|
||||||
let auth_layer = {
|
let auth_layer = {
|
||||||
let session_layer = session_layer(db_pool.clone()).await;
|
let session_layer = session_layer(db_pool.clone()).await;
|
||||||
let store = AuthStore::new(db_pool.clone());
|
let store = AuthStore::new(db_pool.clone());
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn main() {
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(
|
.with(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
.unwrap_or_else(|_| "what2watch=debug,axum=debug".into()),
|
.unwrap_or_else(|_| "what2watch=debug,axum::routing=debug".into()),
|
||||||
)
|
)
|
||||||
.with(tracing_subscriber::fmt::layer())
|
.with(tracing_subscriber::fmt::layer())
|
||||||
.init();
|
.init();
|
||||||
|
|
|
@ -35,3 +35,17 @@ where
|
||||||
.map(Some),
|
.map(Some),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a stringy number like "1999" to a 64-bit signed unix epoch-based
|
||||||
|
/// timestamp
|
||||||
|
pub fn year_to_epoch(year: Option<&str>) -> Option<i64> {
|
||||||
|
year?
|
||||||
|
.trim()
|
||||||
|
.parse::<i32>()
|
||||||
|
.map(|year| {
|
||||||
|
let years = (year - 1970) as f32;
|
||||||
|
let days = (years * 365.2425) as i64;
|
||||||
|
days * 24 * 60 * 60
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use axum::{
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::{query_as, SqlitePool};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
misc_util::empty_string_as_none, AuthSession, OptionalOptionalUser, Star, User, Watch,
|
misc_util::empty_string_as_none, AuthSession, OptionalOptionalUser, Star, User, Watch,
|
||||||
|
@ -25,29 +25,44 @@ pub enum SearchResult {
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq)]
|
||||||
pub struct SearchQuery {
|
pub struct SearchQuery {
|
||||||
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
|
pub search: Option<String>,
|
||||||
#[serde(default, deserialize_with = "empty_string_as_none")]
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
#[serde(default, deserialize_with = "empty_string_as_none")]
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
pub year: Option<String>,
|
pub kind: Option<String>,
|
||||||
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
|
pub year: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_search_watch(
|
pub async fn get_search_watch(
|
||||||
auth: AuthSession,
|
auth: AuthSession,
|
||||||
State(pool): State<SqlitePool>,
|
State(pool): State<SqlitePool>,
|
||||||
Query(search): Query<SearchQuery>,
|
search: Query<SearchQuery>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let user = auth.user;
|
const DEFAULT_WATCHES_QUERY: &str =
|
||||||
let SearchQuery { title, year } = &search;
|
"select * from (select * from watches order by random() limit 50) order by release_date asc";
|
||||||
|
|
||||||
let watches: Vec<Watch> = match (title, year) {
|
let user = auth.user;
|
||||||
(Some(title), None) => sqlx::query_as(
|
let search_query = search.0;
|
||||||
"select * from watches where id in (select id from watch_search where title match ? order by rank)").bind(
|
|
||||||
title.trim()).fetch_all(&pool).await.unwrap_or_default(),
|
let query = if search_query == SearchQuery::default() {
|
||||||
(Some(title), Some(year)) => sqlx::query_as("select * from watches where id in (select id from watch_search where title match ? order by rank) and release_date = ?").bind(title.trim()).bind(year.trim()).fetch_all(&pool).await.unwrap_or_default(),
|
query_as(DEFAULT_WATCHES_QUERY)
|
||||||
(None, Some(year)) => sqlx::query_as("select * from watches where release_date = ? order by title").bind(year.trim()).fetch_all(&pool).await.unwrap_or_default(),
|
} else if let Some(title) = search_query.title {
|
||||||
_ => sqlx::query_as("select * from (select * from watches order by random() limit 50) order by release_date asc").fetch_all(&pool).await.unwrap_or_default()
|
query_as(
|
||||||
|
"select * from watches where id in (select id from watch_search where title match ? order by rank)",
|
||||||
|
)
|
||||||
|
.bind(title)
|
||||||
|
} else if let Some(ref search) = search_query.search {
|
||||||
|
query_as("select * from watches where id in (select id from watch_search where title match ?) outer join (select * from stars where id in (select id from star_search where name match ?)) s")
|
||||||
|
.bind(search).bind(search)
|
||||||
|
} else {
|
||||||
|
query_as(DEFAULT_WATCHES_QUERY)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// until tantivy search
|
||||||
|
let watches: Vec<Watch> = query.fetch_all(&pool).await.unwrap();
|
||||||
|
|
||||||
SearchPage {
|
SearchPage {
|
||||||
results: watches,
|
results: watches,
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -250,7 +250,7 @@ async fn validate_invitation(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ts) = invitation.expires_at {
|
if let Some(ts) = invitation.expires_at {
|
||||||
let now = chrono::Utc::now();
|
let now = chrono::Utc::now().timestamp();
|
||||||
if ts < now {
|
if ts < now {
|
||||||
return Err(CreateUserErrorKind::BadInvitation);
|
return Err(CreateUserErrorKind::BadInvitation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ use julid::Julid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
use crate::WatchDate;
|
|
||||||
|
|
||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
pub mod templates;
|
pub mod templates;
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ pub enum CreateInviteErrorKind {
|
||||||
pub struct Invitation {
|
pub struct Invitation {
|
||||||
id: Julid,
|
id: Julid,
|
||||||
owner: Julid,
|
owner: Julid,
|
||||||
expires_at: Option<WatchDate>,
|
expires_at: Option<i64>,
|
||||||
remaining: i16,
|
remaining: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,9 +85,8 @@ impl Invitation {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_expires_in(&self, expires_in: Duration) -> Self {
|
pub fn with_expires_in(&self, expires_in: Duration) -> Self {
|
||||||
let now = chrono::Utc::now();
|
|
||||||
Self {
|
Self {
|
||||||
expires_at: Some(now + expires_in),
|
expires_at: Some((chrono::Utc::now() + expires_in).timestamp()),
|
||||||
..*self
|
..*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ pub struct Star {
|
||||||
pub id: Julid,
|
pub id: Julid,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub metadata_url: Option<String>,
|
pub metadata_url: Option<String>,
|
||||||
pub born: Option<String>,
|
pub born: Option<i64>,
|
||||||
pub died: Option<String>,
|
pub died: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, FromRow)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, FromRow)]
|
||||||
|
|
57
src/users.rs
57
src/users.rs
|
@ -9,7 +9,12 @@ use julid::Julid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{sqlite::SqliteRow, Row, SqlitePool};
|
use sqlx::{sqlite::SqliteRow, Row, SqlitePool};
|
||||||
|
|
||||||
use crate::{AuthSession, WatchDate};
|
use crate::AuthSession;
|
||||||
|
|
||||||
|
const USERNAME_QUERY: &str = "select * from users where username = $1";
|
||||||
|
const LAST_SEEN_QUERY: &str = "update users set last_seen = (select unixepoch()) where id = $1";
|
||||||
|
const INSERT_QUERY: &str =
|
||||||
|
"insert into users (id, username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5, $6)";
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
|
@ -17,7 +22,7 @@ pub struct User {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub displayname: Option<String>,
|
pub displayname: Option<String>,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub last_seen: Option<WatchDate>,
|
pub last_seen: Option<i64>,
|
||||||
pub pwhash: String,
|
pub pwhash: String,
|
||||||
pub invited_by: Julid,
|
pub invited_by: Julid,
|
||||||
pub is_active: bool,
|
pub is_active: bool,
|
||||||
|
@ -76,43 +81,42 @@ impl Debug for User {
|
||||||
impl Display for User {
|
impl Display for User {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let uname = &self.username;
|
let uname = &self.username;
|
||||||
let dname = self.displayname.as_deref().unwrap_or("");
|
let dname = if let Some(ref n) = self.displayname {
|
||||||
let email = self.email.as_deref().unwrap_or("");
|
n
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
let email = if let Some(ref e) = self.email { e } else { "" };
|
||||||
write!(f, "Username: {uname}\nDisplayname: {dname}\nEmail: {email}")
|
write!(f, "Username: {uname}\nDisplayname: {dname}\nEmail: {email}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
pub async fn try_get(username: &str, db: &SqlitePool) -> Result<Option<Self>, sqlx::Error> {
|
pub async fn try_get(username: &str, db: &SqlitePool) -> Result<Option<Self>, sqlx::Error> {
|
||||||
sqlx::query_as("select * from users where username = ?")
|
sqlx::query_as(USERNAME_QUERY)
|
||||||
.bind(username)
|
.bind(username)
|
||||||
.fetch_optional(db)
|
.fetch_optional(db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is mostly for tests and to ensure that the system accounts are
|
|
||||||
/// present. Most of the time, users should not be inserted with an ID, but
|
|
||||||
/// should let the DB assign them an ID.
|
|
||||||
pub async fn try_insert(&self, db: &SqlitePool) -> Result<(), sqlx::Error> {
|
pub async fn try_insert(&self, db: &SqlitePool) -> Result<(), sqlx::Error> {
|
||||||
sqlx::query!("insert into users (id, username, displayname, email, pwhash, invited_by) values (?, ?, ?, ?, ?, ?)",
|
sqlx::query(INSERT_QUERY)
|
||||||
self.id,
|
.bind(self.id)
|
||||||
self.username,
|
.bind(&self.username)
|
||||||
self.displayname,
|
.bind(&self.displayname)
|
||||||
self.email,
|
.bind(&self.email)
|
||||||
self.pwhash,
|
.bind(&self.pwhash)
|
||||||
self.invited_by)
|
.bind(self.invited_by)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_last_seen(&self, pool: &SqlitePool) {
|
pub async fn update_last_seen(&self, pool: &SqlitePool) {
|
||||||
match sqlx::query!(
|
match sqlx::query(LAST_SEEN_QUERY)
|
||||||
"update users set last_seen = CURRENT_TIMESTAMP where id = ?",
|
.bind(self.id)
|
||||||
self.id
|
.execute(pool)
|
||||||
)
|
.await
|
||||||
.execute(pool)
|
|
||||||
.await
|
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -143,12 +147,15 @@ pub async fn handle_update_last_seen(
|
||||||
request: Request,
|
request: Request,
|
||||||
next: Next,
|
next: Next,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
if let Some(user) = auth.user {
|
if let Some(user) = auth.user {
|
||||||
if let Some(then) = &user.last_seen {
|
if let Some(then) = user.last_seen {
|
||||||
let now = chrono::Utc::now();
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_secs() as i64;
|
||||||
// The Nyquist frequency for 1-day tracking resolution is 12 hours.
|
// The Nyquist frequency for 1-day tracking resolution is 12 hours.
|
||||||
let dur = chrono::Duration::hours(12);
|
if now - then > 12 * 3600 {
|
||||||
if (now - then) > dur {
|
|
||||||
user.update_last_seen(&pool).await;
|
user.update_last_seen(&pool).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,8 @@ use sqlx::{query, query_as, query_scalar, SqlitePool};
|
||||||
|
|
||||||
use super::templates::{AddNewWatchPage, AddWatchButton, GetWatchPage};
|
use super::templates::{AddNewWatchPage, AddWatchButton, GetWatchPage};
|
||||||
use crate::{
|
use crate::{
|
||||||
misc_util::empty_string_as_none, AuthSession, MyWatchesPage, ShowKind, Watch, WatchQuest,
|
misc_util::{empty_string_as_none, year_to_epoch},
|
||||||
|
AuthSession, MyWatchesPage, ShowKind, Watch, WatchQuest,
|
||||||
};
|
};
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
@ -98,11 +99,12 @@ pub async fn post_add_new_watch(
|
||||||
) -> Result<impl IntoResponse, AddError> {
|
) -> Result<impl IntoResponse, AddError> {
|
||||||
if let Some(user) = auth.user {
|
if let Some(user) = auth.user {
|
||||||
{
|
{
|
||||||
|
let release_date = year_to_epoch(form.year.as_deref());
|
||||||
let watch = Watch {
|
let watch = Watch {
|
||||||
title: form.title,
|
title: form.title,
|
||||||
kind: form.kind,
|
kind: form.kind,
|
||||||
metadata_url: form.metadata_url,
|
metadata_url: form.metadata_url,
|
||||||
release_date: form.year,
|
release_date,
|
||||||
added_by: user.id,
|
added_by: user.id,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
@ -130,7 +132,7 @@ async fn add_new_watch_impl(db_pool: &SqlitePool, watch: &Watch) -> Result<Julid
|
||||||
let watch_id: Julid = query_scalar(ADD_WATCH_QUERY)
|
let watch_id: Julid = query_scalar(ADD_WATCH_QUERY)
|
||||||
.bind(&watch.title)
|
.bind(&watch.title)
|
||||||
.bind(watch.kind)
|
.bind(watch.kind)
|
||||||
.bind(&watch.release_date)
|
.bind(watch.release_date)
|
||||||
.bind(&watch.metadata_url)
|
.bind(&watch.metadata_url)
|
||||||
.bind(watch.added_by)
|
.bind(watch.added_by)
|
||||||
.bind(watch.length)
|
.bind(watch.length)
|
||||||
|
|
|
@ -73,10 +73,22 @@ pub struct Watch {
|
||||||
pub kind: ShowKind,
|
pub kind: ShowKind,
|
||||||
pub metadata_url: Option<String>,
|
pub metadata_url: Option<String>,
|
||||||
pub length: Option<i64>,
|
pub length: Option<i64>,
|
||||||
pub release_date: Option<String>,
|
pub release_date: Option<i64>,
|
||||||
pub added_by: Julid, // this shouldn't be exposed to randos in the application
|
pub added_by: Julid, // this shouldn't be exposed to randos in the application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Watch {
|
||||||
|
pub fn year(&self) -> Option<String> {
|
||||||
|
if let Some(year) = self.release_date {
|
||||||
|
let date = chrono::NaiveDateTime::from_timestamp_opt(year, 0)?;
|
||||||
|
let year = format!("{}", date.format("%Y"));
|
||||||
|
Some(year)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
/// Something a user wants to watch
|
/// Something a user wants to watch
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% import "macros.html" as m %}
|
{% import "macros.html" as m %}
|
||||||
|
|
||||||
{% block title %}Welcome to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Welcome to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% import "macros.html" as m %}
|
{% import "macros.html" as m %}
|
||||||
|
|
||||||
{% block title %}Welcome to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Welcome to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
{% when Some with (watch) %}
|
{% when Some with (watch) %}
|
||||||
|
|
||||||
<div class="watch">
|
<div class="watch">
|
||||||
<span class="watchtitle">{{watch.title}}</span> -- {% call m::get_or_default(watch.release_date, "when??") %}
|
<span class="watchtitle">{{watch.title}}</span> -- {% call m::get_or_default(watch.year(), "when??") %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Welcome to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Welcome to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Login to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Login to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Logout of What 2 Watch, Buddy{% endblock %}
|
{% block title %}Logout of What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Thanks for Signing Up for What 2 Watch, Buddy{% endblock %}
|
{% block title %}Thanks for Signing Up for What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% import "macros.html" as m %}
|
{% import "macros.html" as m %}
|
||||||
|
|
||||||
{% block title %}Welcome to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Welcome to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -28,8 +28,7 @@
|
||||||
<div class="watchlist">
|
<div class="watchlist">
|
||||||
<ul>
|
<ul>
|
||||||
{% for watch in watches %}
|
{% for watch in watches %}
|
||||||
<li><span class="watchtitle">{{watch.title}}</span> -- {% call m::get_or_default(watch.release_date, "when??")
|
<li><span class="watchtitle">{{watch.title}}</span> -- {% call m::get_or_default(watch.year(), "when??") %}
|
||||||
%}
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,33 +1,11 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% import "macros.html" as m %}
|
{% import "macros.html" as m %}
|
||||||
|
|
||||||
{% block title %}Welcome to What 2 Watch, Buddy{% endblock %}
|
{% block title %}Welcome to What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h1>Whatcha Watchin?</h1>
|
<h1>Whatcha Watchin?</h1>
|
||||||
|
|
||||||
<div class="fullsearch">
|
|
||||||
<form action="/search" enctype="application/x-www-form-urlencoded" method="get">
|
|
||||||
<h2>Search</h2>
|
|
||||||
|
|
||||||
<label for="title">Title</label>
|
|
||||||
<input type="text" name="title" id="title-search"></br>
|
|
||||||
|
|
||||||
<label for="year">Release Year</label>
|
|
||||||
<input type="text" name="year" id="title-year-search"></br>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<label for="person">Person</label>
|
|
||||||
<input type="text" name="person" id="person-search"></br>
|
|
||||||
|
|
||||||
<input type="submit" value="Let's go!">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<div class="watchlist">
|
<div class="watchlist">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -45,6 +23,39 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Simple Search</h2>
|
||||||
|
<div class="simplesearch">
|
||||||
|
<form action="/search" enctype="application/x-www-form-urlencoded" method="get">
|
||||||
|
<label for="search">Looking for something else to watch?</label>
|
||||||
|
<input type="text" name="search" id="search"></br>
|
||||||
|
<input type="submit" value="Let's go!">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Fussy Search</h2>
|
||||||
|
<div class="fullsearch">
|
||||||
|
<label for="title">Title</label>
|
||||||
|
<input type="text" name="title" id="title"></br>
|
||||||
|
|
||||||
|
<label for="year">Release Year</label>
|
||||||
|
<input type="text" name="year" id="year"></br>
|
||||||
|
|
||||||
|
<label for="kind">Type</label>
|
||||||
|
<select id="kind" name="kind">
|
||||||
|
<option value="">Unknown</option>
|
||||||
|
<option value="0">Movie</option>
|
||||||
|
<option value="1">Series</option>
|
||||||
|
<option value="2">Limited Series</option>
|
||||||
|
<option value="3">Short</option>
|
||||||
|
<option value="4">Other</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<input type="submit" value="Let's go!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Sign Up for What 2 Watch, Buddy{% endblock %}
|
{% block title %}Sign Up for What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block header %} {% endblock %}
|
{% block header %} {% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Dang, Buddy{% endblock %}
|
{% block title %}Dang, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Thanks for Signing Up for What 2 Watch, Buddy{% endblock %}
|
{% block title %}Thanks for Signing Up for What 2 Watch, Bish{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{{res.kind}}</td>
|
<td>{{res.kind}}</td>
|
||||||
<td> {% call m::get_or_default(res.release_date, "when??") -%}</td>
|
<td> {% call m::get_or_default(res.year(), "when??") -%}</td>
|
||||||
<td>
|
<td>
|
||||||
<span id="add-watch-{{res.id}}">
|
<span id="add-watch-{{res.id}}">
|
||||||
<span hx-get="/watch/status/{{res.id}}" hx-target="this" hx-trigger="load, reveal"
|
<span hx-get="/watch/status/{{res.id}}" hx-target="this" hx-trigger="load, reveal"
|
||||||
|
|
Loading…
Reference in a new issue