feat: rename / upgrades
This commit is contained in:
parent
d41d561fdc
commit
c8da87e0dd
@ -18,5 +18,5 @@ steps:
|
|||||||
- dockerd &
|
- dockerd &
|
||||||
- docker login -u kieran -p $TOKEN git.v0l.io
|
- docker login -u kieran -p $TOKEN git.v0l.io
|
||||||
- docker login -u voidic -p $TOKEN_DOCKER
|
- docker login -u voidic -p $TOKEN_DOCKER
|
||||||
- docker buildx build --push -t git.v0l.io/kieran/void-cat-rs:latest -t voidic/void-cat-rs:latest .
|
- docker buildx build --push -t git.v0l.io/kieran/route96:latest -t voidic/route96:latest .
|
||||||
- kill $(cat /var/run/docker.pid)
|
- kill $(cat /var/run/docker.pid)
|
157
Cargo.lock
generated
157
Cargo.lock
generated
@ -120,7 +120,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -131,7 +131,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -211,22 +211,22 @@ checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.64.0"
|
version = "0.69.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
|
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.6.0",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
"peeking_take_while",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 1.0.109",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -358,7 +358,7 @@ checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -705,7 +705,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim",
|
"strsim",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -716,7 +716,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -748,7 +748,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -781,7 +781,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -804,7 +804,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -859,7 +859,7 @@ dependencies = [
|
|||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -932,14 +932,13 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ffmpeg-sys-the-third"
|
name = "ffmpeg-sys-the-third"
|
||||||
version = "1.1.1+ffmpeg-6.0"
|
version = "2.0.0+ffmpeg-7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94a4b2e9c02074c0ee85661b23b3ac849bad6afc554b503c183975f5e2e0d3de"
|
checksum = "a82bfdb0a7925996707f0a7dc37b2f3251ff5a15d26e78c586adb60c240dedc5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"num_cpus",
|
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
@ -1641,6 +1640,15 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@ -2001,7 +2009,7 @@ dependencies = [
|
|||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2123,15 +2131,9 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "peeking_take_while"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -2178,7 +2180,7 @@ dependencies = [
|
|||||||
"pest_meta",
|
"pest_meta",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2209,7 +2211,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2313,7 +2315,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"version_check",
|
"version_check",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
@ -2497,7 +2499,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2652,7 +2654,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@ -2696,6 +2698,35 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "route96"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"base64 0.22.1",
|
||||||
|
"blurhash",
|
||||||
|
"candle-core",
|
||||||
|
"candle-nn",
|
||||||
|
"candle-transformers",
|
||||||
|
"chrono",
|
||||||
|
"config",
|
||||||
|
"ffmpeg-sys-the-third",
|
||||||
|
"hex",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"nostr",
|
||||||
|
"pretty_env_logger",
|
||||||
|
"rocket",
|
||||||
|
"serde",
|
||||||
|
"serde_with",
|
||||||
|
"sha2",
|
||||||
|
"sqlx",
|
||||||
|
"tokio",
|
||||||
|
"ureq",
|
||||||
|
"url",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
@ -2907,7 +2938,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2980,7 +3011,7 @@ dependencies = [
|
|||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3159,7 +3190,7 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
"sqlx-macros-core",
|
"sqlx-macros-core",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3182,7 +3213,7 @@ dependencies = [
|
|||||||
"sqlx-mysql",
|
"sqlx-mysql",
|
||||||
"sqlx-postgres",
|
"sqlx-postgres",
|
||||||
"sqlx-sqlite",
|
"sqlx-sqlite",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
@ -3341,17 +3372,6 @@ version = "2.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.76"
|
version = "2.0.76"
|
||||||
@ -3380,7 +3400,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3436,7 +3456,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3529,7 +3549,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3660,7 +3680,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3857,35 +3877,6 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "void_cat"
|
|
||||||
version = "0.1.1"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"base64 0.22.1",
|
|
||||||
"blurhash",
|
|
||||||
"candle-core",
|
|
||||||
"candle-nn",
|
|
||||||
"candle-transformers",
|
|
||||||
"chrono",
|
|
||||||
"config",
|
|
||||||
"ffmpeg-sys-the-third",
|
|
||||||
"hex",
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"nostr",
|
|
||||||
"pretty_env_logger",
|
|
||||||
"rocket",
|
|
||||||
"serde",
|
|
||||||
"serde_with",
|
|
||||||
"sha2",
|
|
||||||
"sqlx",
|
|
||||||
"tokio",
|
|
||||||
"ureq",
|
|
||||||
"url",
|
|
||||||
"uuid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -3939,7 +3930,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3973,7 +3964,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
@ -4287,7 +4278,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4309,7 +4300,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4329,7 +4320,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.76",
|
"syn",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
15
Cargo.toml
15
Cargo.toml
@ -1,10 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "void_cat"
|
name = "route96"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["nip96", "blossom"]
|
default = ["nip96", "blossom"]
|
||||||
labels = ["nip96", "dep:candle-core", "dep:candle-nn", "dep:candle-transformers"]
|
labels = ["nip96", "dep:candle-core", "dep:candle-nn", "dep:candle-transformers"]
|
||||||
@ -26,12 +24,13 @@ sha2 = "0.10.8"
|
|||||||
sqlx = { version = "0.8.1", features = ["mysql", "runtime-tokio", "chrono"] }
|
sqlx = { version = "0.8.1", features = ["mysql", "runtime-tokio", "chrono"] }
|
||||||
config = { version = "0.14.0", features = ["toml"] }
|
config = { version = "0.14.0", features = ["toml"] }
|
||||||
chrono = { version = "0.4.38", features = ["serde"] }
|
chrono = { version = "0.4.38", features = ["serde"] }
|
||||||
ffmpeg-sys-the-third = { version = "1.1.1", features = ["default"], optional = true }
|
|
||||||
libc = { version = "0.2.153", optional = true }
|
|
||||||
blurhash = { version = "0.2.1", optional = true }
|
|
||||||
ureq = { version = "2.9.7", features = ["json"] }
|
|
||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
serde_with = { version = "3.8.1", features = ["hex"] }
|
serde_with = { version = "3.8.1", features = ["hex"] }
|
||||||
|
ureq = { version = "2.9.7", features = ["json"] }
|
||||||
|
|
||||||
|
libc = { version = "0.2.153", optional = true }
|
||||||
|
blurhash = { version = "0.2.1", optional = true }
|
||||||
|
ffmpeg-sys-the-third = { version = "2.0.0+ffmpeg-7.0", features = ["default"], optional = true }
|
||||||
candle-core = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
candle-core = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
||||||
candle-nn = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
candle-nn = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
||||||
candle-transformers = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
candle-transformers = { git = "https://github.com/huggingface/candle.git", version = "^0.6.1", optional = true }
|
||||||
|
@ -38,4 +38,4 @@ RUN apt update && \
|
|||||||
COPY --from=build /app/build .
|
COPY --from=build /app/build .
|
||||||
COPY --from=build /app/src/ui ui
|
COPY --from=build /app/src/ui ui
|
||||||
COPY --from=build /app/ffmpeg/lib/ /lib
|
COPY --from=build /app/ffmpeg/lib/ /lib
|
||||||
ENTRYPOINT ["./bin/void_cat"]
|
ENTRYPOINT ["./bin/route96"]
|
@ -1,10 +1,13 @@
|
|||||||
# void-cat-rs
|
# route96
|
||||||
|
|
||||||
Image hosting service
|
Image hosting service
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- [NIP-96 Support](https://github.com/nostr-protocol/nips/blob/master/96.md)
|
- [NIP-96 Support](https://github.com/nostr-protocol/nips/blob/master/96.md)
|
||||||
- [Blossom Support](https://github.com/hzrd149/blossom/blob/master/buds/01.md)
|
- [Blossom Support](https://github.com/hzrd149/blossom/blob/master/buds/01.md)
|
||||||
|
- [BUD-01](https://github.com/hzrd149/blossom/blob/master/buds/01.md)
|
||||||
|
- [BUD-02](https://github.com/hzrd149/blossom/blob/master/buds/02.md)
|
||||||
|
- [BUD-06](https://github.com/hzrd149/blossom/blob/master/buds/06.md)
|
||||||
- Image compression to WebP (FFMPEG, NIP-96 only)
|
- Image compression to WebP (FFMPEG, NIP-96 only)
|
||||||
- Blurhash calculation (NIP-96 only)
|
- Blurhash calculation (NIP-96 only)
|
||||||
- AI image labeling ([ViT224](https://huggingface.co/google/vit-base-patch16-224))
|
- AI image labeling ([ViT224](https://huggingface.co/google/vit-base-patch16-224))
|
||||||
@ -15,7 +18,7 @@ Image hosting service
|
|||||||
## Running
|
## Running
|
||||||
|
|
||||||
### Docker Compose
|
### Docker Compose
|
||||||
The easiest way to run `void-cat-rs` is to use `docker compose`
|
The easiest way to run `route96` is to use `docker compose`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose.prod.yml up
|
docker compose -f docker-compose.prod.yml up
|
||||||
@ -27,7 +30,7 @@ docker run --rm -it \
|
|||||||
-p 8000:8000 \
|
-p 8000:8000 \
|
||||||
-v ./config.toml:/app/config.toml \
|
-v ./config.toml:/app/config.toml \
|
||||||
-e "RUST_LOG=info" \
|
-e "RUST_LOG=info" \
|
||||||
voidic/void-cat-rs
|
voidic/route96
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
listen = "0.0.0.0:8000"
|
listen = "0.0.0.0:8000"
|
||||||
|
|
||||||
# Database connection string (MYSQL)
|
# Database connection string (MYSQL)
|
||||||
database = "mysql://root:root@db:3306/void_cat"
|
database = "mysql://root:root@db:3306/route96"
|
||||||
|
|
||||||
# Directory to store uploads
|
# Directory to store uploads
|
||||||
storage_dir = "/app/data"
|
storage_dir = "/app/data"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
listen = "127.0.0.1:8000"
|
listen = "127.0.0.1:8000"
|
||||||
|
|
||||||
# Database connection string (MYSQL)
|
# Database connection string (MYSQL)
|
||||||
database = "mysql://root:root@localhost:3366/void_cat"
|
database = "mysql://root:root@localhost:3366/route96"
|
||||||
|
|
||||||
# Directory to store uploads
|
# Directory to store uploads
|
||||||
storage_dir = "./data"
|
storage_dir = "./data"
|
||||||
@ -20,4 +20,4 @@ public_url = "http://localhost:8000"
|
|||||||
# vit_model_path = "model.safetennsors"
|
# vit_model_path = "model.safetennsors"
|
||||||
|
|
||||||
# Webhook api endpoint
|
# Webhook api endpoint
|
||||||
webhook_url = "https://api.snort.social/api/v1/media/webhook"
|
# webhook_url = "https://api.snort.social/api/v1/media/webhook"
|
@ -6,11 +6,11 @@ services:
|
|||||||
image: mariadb
|
image: mariadb
|
||||||
environment:
|
environment:
|
||||||
- "MARIADB_ROOT_PASSWORD=root"
|
- "MARIADB_ROOT_PASSWORD=root"
|
||||||
- "MARIADB_DATABASE=void_cat"
|
- "MARIADB_DATABASE=route96"
|
||||||
volumes:
|
volumes:
|
||||||
- "db:/var/lib/mysql"
|
- "db:/var/lib/mysql"
|
||||||
app:
|
app:
|
||||||
image: voidic/void-cat-rs
|
image: voidic/route96
|
||||||
#build: .
|
#build: .
|
||||||
environment:
|
environment:
|
||||||
- "RUST_LOG=info"
|
- "RUST_LOG=info"
|
||||||
|
@ -5,7 +5,7 @@ services:
|
|||||||
image: mariadb
|
image: mariadb
|
||||||
environment:
|
environment:
|
||||||
- "MARIADB_ROOT_PASSWORD=root"
|
- "MARIADB_ROOT_PASSWORD=root"
|
||||||
- "MARIADB_DATABASE=void_cat"
|
- "MARIADB_DATABASE=route96"
|
||||||
ports:
|
ports:
|
||||||
- "3366:3306"
|
- "3366:3306"
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -7,6 +7,9 @@ use rocket::{async_trait, Request};
|
|||||||
|
|
||||||
pub struct BlossomAuth {
|
pub struct BlossomAuth {
|
||||||
pub content_type: Option<String>,
|
pub content_type: Option<String>,
|
||||||
|
pub x_content_type: Option<String>,
|
||||||
|
pub x_sha_256: Option<String>,
|
||||||
|
pub x_content_length: Option<u64>,
|
||||||
pub event: Event,
|
pub event: Event,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +68,27 @@ impl<'r> FromRequest<'r> for BlossomAuth {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
x_sha_256: request.headers().iter().find_map(|h| {
|
||||||
|
if h.name == "x-sha-256" {
|
||||||
|
Some(h.value.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
x_content_length: request.headers().iter().find_map(|h| {
|
||||||
|
if h.name == "x-content-length" {
|
||||||
|
Some(h.value.parse().unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
x_content_type: request.headers().iter().find_map(|h| {
|
||||||
|
if h.name == "x-content-type" {
|
||||||
|
Some(h.value.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Outcome::Error((Status::new(403), "Auth scheme must be Nostr"))
|
Outcome::Error((Status::new(403), "Auth scheme must be Nostr"))
|
||||||
|
@ -9,7 +9,7 @@ use rocket::request::{FromRequest, Outcome};
|
|||||||
|
|
||||||
pub struct Nip98Auth {
|
pub struct Nip98Auth {
|
||||||
pub content_type: Option<String>,
|
pub content_type: Option<String>,
|
||||||
pub content_length: Option<usize>,
|
pub content_length: Option<u64>,
|
||||||
pub event: Event,
|
pub event: Event,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
src/blob.rs
27
src/blob.rs
@ -1,27 +0,0 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::db::FileUpload;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
pub struct BlobDescriptor {
|
|
||||||
pub url: String,
|
|
||||||
pub sha256: String,
|
|
||||||
pub size: u64,
|
|
||||||
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
|
|
||||||
pub mime_type: Option<String>,
|
|
||||||
pub created: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlobDescriptor {
|
|
||||||
pub fn from_upload(value: &FileUpload, public_url: &String) -> Self {
|
|
||||||
let id_hex = hex::encode(&value.id);
|
|
||||||
Self {
|
|
||||||
url: format!("{}/{}", public_url, &id_hex),
|
|
||||||
sha256: id_hex,
|
|
||||||
size: value.size,
|
|
||||||
mime_type: Some(value.mime_type.clone()),
|
|
||||||
created: value.created.timestamp() as u64,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,6 @@ use crate::settings::Settings;
|
|||||||
use crate::webhook::Webhook;
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
mod blob;
|
|
||||||
mod cors;
|
mod cors;
|
||||||
mod db;
|
mod db;
|
||||||
mod filesystem;
|
mod filesystem;
|
||||||
@ -55,7 +54,7 @@ async fn main() -> Result<(), Error> {
|
|||||||
.limit("file", upload_limit)
|
.limit("file", upload_limit)
|
||||||
.limit("data-form", upload_limit)
|
.limit("data-form", upload_limit)
|
||||||
.limit("form", upload_limit);
|
.limit("form", upload_limit);
|
||||||
config.ident = Ident::try_new("void-cat-rs").unwrap();
|
config.ident = Ident::try_new("route96").unwrap();
|
||||||
|
|
||||||
let mut rocket = rocket::Rocket::custom(config)
|
let mut rocket = rocket::Rocket::custom(config)
|
||||||
.manage(FileStore::new(settings.clone()))
|
.manage(FileStore::new(settings.clone()))
|
||||||
|
@ -180,7 +180,7 @@ impl WebpProcessor {
|
|||||||
AVMEDIA_TYPE_AUDIO => {
|
AVMEDIA_TYPE_AUDIO => {
|
||||||
(*encoder_ctx).sample_rate = (*(*in_stream).codecpar).sample_rate;
|
(*encoder_ctx).sample_rate = (*(*in_stream).codecpar).sample_rate;
|
||||||
(*encoder_ctx).sample_fmt = transmute((*(*in_stream).codecpar).format);
|
(*encoder_ctx).sample_fmt = transmute((*(*in_stream).codecpar).format);
|
||||||
(*encoder_ctx).ch_layout = (*(*in_stream).codecpar).ch_layout;
|
(*encoder_ctx).ch_layout = (*(*in_stream).codecpar).ch_layout.clone();
|
||||||
(*encoder_ctx).time_base = (*in_stream).time_base;
|
(*encoder_ctx).time_base = (*in_stream).time_base;
|
||||||
(*stream).time_base = (*encoder_ctx).time_base;
|
(*stream).time_base = (*encoder_ctx).time_base;
|
||||||
}
|
}
|
||||||
|
@ -4,27 +4,54 @@ use log::error;
|
|||||||
use nostr::prelude::hex;
|
use nostr::prelude::hex;
|
||||||
use nostr::{Alphabet, SingleLetterTag, TagKind};
|
use nostr::{Alphabet, SingleLetterTag, TagKind};
|
||||||
use rocket::data::ByteUnit;
|
use rocket::data::ByteUnit;
|
||||||
use rocket::http::Status;
|
use rocket::http::{Header, Status};
|
||||||
use rocket::response::Responder;
|
use rocket::response::Responder;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use rocket::{routes, Data, Route, State};
|
use rocket::{routes, Data, Request, Response, Route, State};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::auth::blossom::BlossomAuth;
|
use crate::auth::blossom::BlossomAuth;
|
||||||
use crate::blob::BlobDescriptor;
|
use crate::db::{Database, FileUpload};
|
||||||
use crate::db::Database;
|
|
||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
use crate::routes::delete_file;
|
use crate::routes::{delete_file, Nip94Event};
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::webhook::Webhook;
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct BlobDescriptor {
|
||||||
|
pub url: String,
|
||||||
|
pub sha256: String,
|
||||||
|
pub size: u64,
|
||||||
|
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub mime_type: Option<String>,
|
||||||
|
pub created: u64,
|
||||||
|
#[serde(rename = "nip94", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub nip94: Option<Nip94Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlobDescriptor {
|
||||||
|
pub fn from_upload(settings: &Settings, value: &FileUpload) -> Self {
|
||||||
|
let id_hex = hex::encode(&value.id);
|
||||||
|
Self {
|
||||||
|
url: format!("{}/{}", settings.public_url, &id_hex),
|
||||||
|
sha256: id_hex,
|
||||||
|
size: value.size,
|
||||||
|
mime_type: Some(value.mime_type.clone()),
|
||||||
|
created: value.created.timestamp() as u64,
|
||||||
|
nip94: Some(Nip94Event::from_upload(settings, value)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct BlossomError {
|
struct BlossomError {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blossom_routes() -> Vec<Route> {
|
pub fn blossom_routes() -> Vec<Route> {
|
||||||
routes![delete_blob, upload, list_files]
|
routes![delete_blob, upload, list_files, upload_head]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlossomError {
|
impl BlossomError {
|
||||||
@ -53,6 +80,26 @@ impl BlossomResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BlossomHead {
|
||||||
|
pub msg: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r> Responder<'r, 'static> for BlossomHead {
|
||||||
|
fn respond_to(self, _request: &'r Request<'_>) -> rocket::response::Result<'static> {
|
||||||
|
let mut response = Response::new();
|
||||||
|
match self.msg {
|
||||||
|
Some(m) => {
|
||||||
|
response.set_status(Status::InternalServerError);
|
||||||
|
response.set_header(Header::new("x-upload-message", m));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
response.set_status(Status::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_method(event: &nostr::Event, method: &str) -> bool {
|
fn check_method(event: &nostr::Event, method: &str) -> bool {
|
||||||
if let Some(t) = event.tags.iter().find_map(|t| {
|
if let Some(t) = event.tags.iter().find_map(|t| {
|
||||||
if t.kind() == TagKind::Method
|
if t.kind() == TagKind::Method
|
||||||
@ -103,7 +150,7 @@ async fn upload(
|
|||||||
});
|
});
|
||||||
let size = auth.event.tags.iter().find_map(|t| {
|
let size = auth.event.tags.iter().find_map(|t| {
|
||||||
if t.kind() == TagKind::Size {
|
if t.kind() == TagKind::Size {
|
||||||
t.content().and_then(|v| v.parse::<usize>().ok())
|
t.content().and_then(|v| v.parse::<u64>().ok())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -171,8 +218,8 @@ async fn upload(
|
|||||||
BlossomResponse::error(format!("Error saving file (db): {}", e))
|
BlossomResponse::error(format!("Error saving file (db): {}", e))
|
||||||
} else {
|
} else {
|
||||||
BlossomResponse::BlobDescriptor(Json(BlobDescriptor::from_upload(
|
BlossomResponse::BlobDescriptor(Json(BlobDescriptor::from_upload(
|
||||||
&blob.upload,
|
&settings,
|
||||||
&settings.public_url,
|
&blob.upload
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,9 +245,58 @@ async fn list_files(
|
|||||||
Ok((files, _count)) => BlossomResponse::BlobDescriptorList(Json(
|
Ok((files, _count)) => BlossomResponse::BlobDescriptorList(Json(
|
||||||
files
|
files
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| BlobDescriptor::from_upload(f, &settings.public_url))
|
.map(|f| BlobDescriptor::from_upload(&settings, f))
|
||||||
.collect(),
|
.collect(),
|
||||||
)),
|
)),
|
||||||
Err(e) => BlossomResponse::error(format!("Could not list files: {}", e)),
|
Err(e) => BlossomResponse::error(format!("Could not list files: {}", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rocket::head("/upload")]
|
||||||
|
async fn upload_head(
|
||||||
|
auth: BlossomAuth,
|
||||||
|
settings: &State<Settings>,
|
||||||
|
) -> BlossomHead {
|
||||||
|
if !check_method(&auth.event, "upload") {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("Invalid auth method tag")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(z) = auth.x_content_length {
|
||||||
|
if z > settings.max_upload_bytes {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("File too large")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("Missing x-content-length header")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let None = auth.x_sha_256 {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("Missing x-sha-256 header")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let None = auth.x_content_type {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("Missing x-content-type header")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whitelist
|
||||||
|
if let Some(wl) = &settings.whitelist {
|
||||||
|
if !wl.contains(&auth.event.pubkey.to_hex()) {
|
||||||
|
return BlossomHead {
|
||||||
|
msg: Some("Not on whitelist")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlossomHead {
|
||||||
|
msg: None
|
||||||
|
}
|
||||||
|
}
|
@ -2,19 +2,20 @@ use std::fs;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::Error;
|
|
||||||
use nostr::Event;
|
|
||||||
use rocket::{Request, State};
|
|
||||||
use rocket::fs::NamedFile;
|
|
||||||
use rocket::http::{ContentType, Header, Status};
|
|
||||||
use rocket::response::Responder;
|
|
||||||
|
|
||||||
use crate::db::{Database, FileUpload};
|
use crate::db::{Database, FileUpload};
|
||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
#[cfg(feature = "blossom")]
|
#[cfg(feature = "blossom")]
|
||||||
pub use crate::routes::blossom::blossom_routes;
|
pub use crate::routes::blossom::blossom_routes;
|
||||||
#[cfg(feature = "nip96")]
|
#[cfg(feature = "nip96")]
|
||||||
pub use crate::routes::nip96::nip96_routes;
|
pub use crate::routes::nip96::nip96_routes;
|
||||||
|
use crate::settings::Settings;
|
||||||
|
use anyhow::Error;
|
||||||
|
use nostr::Event;
|
||||||
|
use rocket::fs::NamedFile;
|
||||||
|
use rocket::http::{ContentType, Header, Status};
|
||||||
|
use rocket::response::Responder;
|
||||||
|
use rocket::serde::Serialize;
|
||||||
|
use rocket::{Request, State};
|
||||||
|
|
||||||
#[cfg(feature = "blossom")]
|
#[cfg(feature = "blossom")]
|
||||||
mod blossom;
|
mod blossom;
|
||||||
@ -26,6 +27,51 @@ pub struct FilePayload {
|
|||||||
pub info: FileUpload,
|
pub info: FileUpload,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Default)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
struct Nip94Event {
|
||||||
|
pub created_at: i64,
|
||||||
|
pub content: String,
|
||||||
|
pub tags: Vec<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Nip94Event {
|
||||||
|
pub fn from_upload(settings: &Settings, upload: &FileUpload) -> Self {
|
||||||
|
let hex_id = hex::encode(&upload.id);
|
||||||
|
let mut tags = vec![
|
||||||
|
vec![
|
||||||
|
"url".to_string(),
|
||||||
|
format!("{}/{}", &settings.public_url, &hex_id),
|
||||||
|
],
|
||||||
|
vec!["x".to_string(), hex_id],
|
||||||
|
vec!["m".to_string(), upload.mime_type.clone()],
|
||||||
|
vec!["size".to_string(), upload.size.to_string()],
|
||||||
|
];
|
||||||
|
if let Some(bh) = &upload.blur_hash {
|
||||||
|
tags.push(vec!["blurhash".to_string(), bh.clone()]);
|
||||||
|
}
|
||||||
|
if let (Some(w), Some(h)) = (upload.width, upload.height) {
|
||||||
|
tags.push(vec!["dim".to_string(), format!("{}x{}", w, h)])
|
||||||
|
}
|
||||||
|
#[cfg(feature = "labels")]
|
||||||
|
for l in &upload.labels {
|
||||||
|
let val = if l.label.contains(',') {
|
||||||
|
let split_val: Vec<&str> = l.label.split(',').collect();
|
||||||
|
split_val[0].to_string()
|
||||||
|
} else {
|
||||||
|
l.label.clone()
|
||||||
|
};
|
||||||
|
tags.push(vec!["t".to_string(), val])
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
content: upload.name.clone(),
|
||||||
|
created_at: upload.created.timestamp(),
|
||||||
|
tags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'r> Responder<'r, 'static> for FilePayload {
|
impl<'r> Responder<'r, 'static> for FilePayload {
|
||||||
fn respond_to(self, request: &'r Request<'_>) -> rocket::response::Result<'static> {
|
fn respond_to(self, request: &'r Request<'_>) -> rocket::response::Result<'static> {
|
||||||
let mut response = self.file.respond_to(request)?;
|
let mut response = self.file.respond_to(request)?;
|
||||||
|
@ -15,7 +15,7 @@ use rocket::{routes, FromForm, Responder, Route, State};
|
|||||||
use crate::auth::nip98::Nip98Auth;
|
use crate::auth::nip98::Nip98Auth;
|
||||||
use crate::db::{Database, FileUpload};
|
use crate::db::{Database, FileUpload};
|
||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
use crate::routes::delete_file;
|
use crate::routes::{delete_file, Nip94Event};
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::webhook::Webhook;
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ struct Nip96Plan {
|
|||||||
/// landing page for this plan
|
/// landing page for this plan
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
pub max_byte_size: usize,
|
pub max_byte_size: u64,
|
||||||
/// Range in days / 0 for no expiration
|
/// Range in days / 0 for no expiration
|
||||||
/// [7, 0] means it may vary from 7 days to unlimited persistence,
|
/// [7, 0] means it may vary from 7 days to unlimited persistence,
|
||||||
/// [0, 0] means it has no expiration
|
/// [0, 0] means it has no expiration
|
||||||
@ -119,58 +119,19 @@ struct Nip96UploadResult {
|
|||||||
|
|
||||||
impl Nip96UploadResult {
|
impl Nip96UploadResult {
|
||||||
pub fn from_upload(settings: &Settings, upload: &FileUpload) -> Self {
|
pub fn from_upload(settings: &Settings, upload: &FileUpload) -> Self {
|
||||||
let hex_id = hex::encode(&upload.id);
|
|
||||||
let mut tags = vec![
|
|
||||||
vec![
|
|
||||||
"url".to_string(),
|
|
||||||
format!("{}/{}", &settings.public_url, &hex_id),
|
|
||||||
],
|
|
||||||
vec!["x".to_string(), hex_id],
|
|
||||||
vec!["m".to_string(), upload.mime_type.clone()],
|
|
||||||
vec!["size".to_string(), upload.size.to_string()],
|
|
||||||
];
|
|
||||||
if let Some(bh) = &upload.blur_hash {
|
|
||||||
tags.push(vec!["blurhash".to_string(), bh.clone()]);
|
|
||||||
}
|
|
||||||
if let (Some(w), Some(h)) = (upload.width, upload.height) {
|
|
||||||
tags.push(vec!["dim".to_string(), format!("{}x{}", w, h)])
|
|
||||||
}
|
|
||||||
#[cfg(feature = "labels")]
|
|
||||||
for l in &upload.labels {
|
|
||||||
let val = if l.label.contains(',') {
|
|
||||||
let split_val: Vec<&str> = l.label.split(',').collect();
|
|
||||||
split_val[0].to_string()
|
|
||||||
} else {
|
|
||||||
l.label.clone()
|
|
||||||
};
|
|
||||||
tags.push(vec!["t".to_string(), val])
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
status: "success".to_string(),
|
status: "success".to_string(),
|
||||||
nip94_event: Some(Nip94Event {
|
nip94_event: Some(Nip94Event::from_upload(settings, upload)),
|
||||||
content: upload.name.clone(),
|
|
||||||
created_at: upload.created.timestamp(),
|
|
||||||
tags,
|
|
||||||
}),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Default)]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
struct Nip94Event {
|
|
||||||
pub created_at: i64,
|
|
||||||
pub content: String,
|
|
||||||
pub tags: Vec<Vec<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
struct Nip96Form<'r> {
|
struct Nip96Form<'r> {
|
||||||
file: TempFile<'r>,
|
file: TempFile<'r>,
|
||||||
expiration: Option<usize>,
|
expiration: Option<usize>,
|
||||||
size: usize,
|
size: u64,
|
||||||
alt: Option<&'r str>,
|
alt: Option<&'r str>,
|
||||||
caption: Option<&'r str>,
|
caption: Option<&'r str>,
|
||||||
media_type: Option<&'r str>,
|
media_type: Option<&'r str>,
|
||||||
@ -234,7 +195,7 @@ async fn upload(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// account for upload speeds as slow as 1MB/s (8 Mbps)
|
// account for upload speeds as slow as 1MB/s (8 Mbps)
|
||||||
let mbs = form.size / 1.megabytes().as_u64() as usize;
|
let mbs = form.size / 1.megabytes().as_u64();
|
||||||
let max_time = 60.max(mbs) as u64;
|
let max_time = 60.max(mbs) as u64;
|
||||||
if auth.event.created_at < Timestamp::now().sub(Duration::from_secs(max_time)) {
|
if auth.event.created_at < Timestamp::now().sub(Duration::from_secs(max_time)) {
|
||||||
return Nip96Response::error("Auth event timestamp out of range");
|
return Nip96Response::error("Auth event timestamp out of range");
|
||||||
|
@ -13,7 +13,7 @@ pub struct Settings {
|
|||||||
pub database: String,
|
pub database: String,
|
||||||
|
|
||||||
/// Maximum support filesize for uploading
|
/// Maximum support filesize for uploading
|
||||||
pub max_upload_bytes: usize,
|
pub max_upload_bytes: u64,
|
||||||
|
|
||||||
/// Public facing url
|
/// Public facing url
|
||||||
pub public_url: String,
|
pub public_url: String,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>void_cat_rs</title>
|
<title>route96</title>
|
||||||
<style>
|
<style>
|
||||||
html {
|
html {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
@ -144,7 +144,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>
|
<h1>
|
||||||
Welcome to void_cat_rs
|
Welcome to route96
|
||||||
</h1>
|
</h1>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div>
|
<div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user