2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-12-22 19:31:35 +00:00

Update actix-form-data, impl Store & Repo for Data<T>

This commit is contained in:
asonix 2022-09-10 19:29:22 -05:00
parent 6673049238
commit 7f49af58fe
5 changed files with 585 additions and 236 deletions

233
Cargo.lock generated
View file

@ -16,14 +16,13 @@ dependencies = [
"memchr", "memchr",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
"tokio-util 0.7.3", "tokio-util 0.7.4",
] ]
[[package]] [[package]]
name = "actix-form-data" name = "actix-form-data"
version = "0.6.2" version = "0.7.0-beta.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://git.asonix.dog/asonix/actix-form-data?branch=v0.7.x#3525bcd09cd030df3f2ed7684f2aad1bcc42d68b"
checksum = "dd2788a4c359a372371292ef9903cf26759abf3ddf00ed710061808b1414fc75"
dependencies = [ dependencies = [
"actix-multipart", "actix-multipart",
"actix-rt", "actix-rt",
@ -168,7 +167,7 @@ dependencies = [
"log", "log",
"pin-project-lite", "pin-project-lite",
"tokio-rustls", "tokio-rustls",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"webpki-roots", "webpki-roots",
] ]
@ -247,9 +246,9 @@ dependencies = [
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.18" version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -265,9 +264,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.62" version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7"
[[package]] [[package]]
name = "async-stream" name = "async-stream"
@ -320,9 +319,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "awc" name = "awc"
version = "3.0.0" 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 = "65c60c44fbf3c8cee365e86b97d706e513b733c4eeb16437b45b88d2fffe889a" checksum = "80ca7ff88063086d2e2c70b9f3b29b2fcd999bac68ac21731e66781970d68519"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -377,9 +376,9 @@ dependencies = [
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.5.15" version = "0.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9de18bc5f2e9df8f52da03856bf40e29b747de5a84e43aefff90e3dc4a21529b" checksum = "c9e3356844c4d6a6d6467b8da2cffb4a2820be256f50a3a386c9d152bab31043"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core", "axum-core",
@ -406,9 +405,9 @@ dependencies = [
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.2.7" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -416,6 +415,8 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"mime", "mime",
"tower-layer",
"tower-service",
] ]
[[package]] [[package]]
@ -447,9 +448,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.2" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
dependencies = [ dependencies = [
"generic-array", "generic-array",
] ]
@ -495,9 +496,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.2.17" version = "3.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
@ -512,9 +513,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.2.17" version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [ dependencies = [
"heck 0.4.0", "heck 0.4.0",
"proc-macro-error", "proc-macro-error",
@ -586,15 +587,15 @@ checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86"
dependencies = [ dependencies = [
"prost 0.11.0", "prost 0.11.0",
"prost-types 0.11.1", "prost-types 0.11.1",
"tonic 0.8.0", "tonic 0.8.1",
"tracing-core", "tracing-core",
] ]
[[package]] [[package]]
name = "console-subscriber" name = "console-subscriber"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e933c43a5db3779b3600cdab18856af2411ca2237e33ba8ab476d5d5b1a6c1e7" checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be"
dependencies = [ dependencies = [
"console-api", "console-api",
"crossbeam-channel", "crossbeam-channel",
@ -608,7 +609,7 @@ dependencies = [
"thread_local", "thread_local",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tonic 0.8.0", "tonic 0.8.1",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-subscriber", "tracing-subscriber",
@ -622,9 +623,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.3" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1079fb8528d9f9c888b1e8aa651e6e079ade467323d58f75faf1d30b1808f540" checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -684,13 +685,14 @@ dependencies = [
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "5.3.4" version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"hashbrown", "hashbrown",
"lock_api", "lock_api",
"once_cell",
"parking_lot_core 0.9.3", "parking_lot_core 0.9.3",
] ]
@ -808,11 +810,10 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.0.1" 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 = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [ dependencies = [
"matches",
"percent-encoding", "percent-encoding",
] ]
@ -828,9 +829,9 @@ dependencies = [
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -842,9 +843,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -852,15 +853,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -869,15 +870,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -886,21 +887,21 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.23" version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -965,7 +966,7 @@ dependencies = [
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tracing", "tracing",
] ]
@ -1066,9 +1067,9 @@ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.7.1" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
@ -1133,11 +1134,10 @@ dependencies = [
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.2.3" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [ dependencies = [
"matches",
"unicode-bidi", "unicode-bidi",
"unicode-normalization", "unicode-normalization",
] ]
@ -1169,9 +1169,9 @@ dependencies = [
[[package]] [[package]]
name = "io-uring" name = "io-uring"
version = "0.5.3" version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427496d698429d86ff947537dff68facb83fe753b7abea4fab4ac1c4b7a4b94b" checksum = "5a645fd8e7048c2f54050f7d0d4de8f624ada437e043bc7d72609bd08d70120b"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
@ -1262,9 +1262,9 @@ checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.7" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
@ -1288,12 +1288,6 @@ dependencies = [
"regex-automata", "regex-automata",
] ]
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "matchit" name = "matchit"
version = "0.5.0" version = "0.5.0"
@ -1346,9 +1340,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.5.3" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
dependencies = [ dependencies = [
"adler", "adler",
] ]
@ -1420,9 +1414,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.1" version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
[[package]] [[package]]
name = "opentelemetry" name = "opentelemetry"
@ -1481,9 +1475,9 @@ checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
[[package]] [[package]]
name = "owo-colors" name = "owo-colors"
version = "3.4.0" version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
@ -1535,9 +1529,9 @@ dependencies = [
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.8" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
[[package]] [[package]]
name = "pathdiff" name = "pathdiff"
@ -1547,15 +1541,15 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.2.1" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69486e2b8c2d2aeb9762db7b4e00b0331156393555cff467f4163ff06821eef8" checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4"
dependencies = [ dependencies = [
"thiserror", "thiserror",
"ucd-trie", "ucd-trie",
@ -1563,9 +1557,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_derive" name = "pest_derive"
version = "2.2.1" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b13570633aff33c6d22ce47dd566b10a3b9122c2fe9d8e7501895905be532b91" checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91"
dependencies = [ dependencies = [
"pest", "pest",
"pest_generator", "pest_generator",
@ -1573,9 +1567,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_generator" name = "pest_generator"
version = "2.2.1" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3c567e5702efdc79fb18859ea74c3eb36e14c43da7b8c1f098a4ed6514ec7a0" checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad"
dependencies = [ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
@ -1586,9 +1580,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_meta" name = "pest_meta"
version = "2.2.1" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eb32be5ee3bbdafa8c7a18b0a8a8d962b66cfa2ceee4037f49267a50ee821fe" checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"pest", "pest",
@ -1641,7 +1635,7 @@ dependencies = [
"time", "time",
"tokio", "tokio",
"tokio-uring", "tokio-uring",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"toml", "toml",
"tracing", "tracing",
"tracing-actix-web", "tracing-actix-web",
@ -1936,7 +1930,7 @@ dependencies = [
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
@ -2092,9 +2086,9 @@ checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.143" version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -2123,9 +2117,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.143" version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2134,9 +2128,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.83" version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -2168,9 +2162,9 @@ dependencies = [
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.1" version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f" checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
@ -2179,9 +2173,9 @@ dependencies = [
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.2" version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
@ -2240,9 +2234,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.4" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
dependencies = [ dependencies = [
"libc", "libc",
"winapi", "winapi",
@ -2320,18 +2314,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.32" version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.32" version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2349,9 +2343,9 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
dependencies = [ dependencies = [
"itoa", "itoa",
"libc", "libc",
@ -2383,9 +2377,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.20.1" version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
@ -2477,9 +2471,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.3" 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 = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@ -2531,9 +2525,9 @@ dependencies = [
[[package]] [[package]]
name = "tonic" name = "tonic"
version = "0.8.0" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "498f271adc46acce75d66f639e4d35b31b2394c295c82496727dafa16d465dd2" checksum = "11cd56bdb54ef93935a6a79dbd1d91f1ebd4c64150fd61654031fd6b8b775c91"
dependencies = [ dependencies = [
"async-stream", "async-stream",
"async-trait", "async-trait",
@ -2553,7 +2547,7 @@ dependencies = [
"prost-derive 0.11.0", "prost-derive 0.11.0",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tower", "tower",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
@ -2587,7 +2581,7 @@ dependencies = [
"rand", "rand",
"slab", "slab",
"tokio", "tokio",
"tokio-util 0.7.3", "tokio-util 0.7.4",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@ -2790,9 +2784,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]] [[package]]
name = "ucd-trie" name = "ucd-trie"
version = "0.1.4" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
[[package]] [[package]]
name = "unchecked-index" name = "unchecked-index"
@ -2835,13 +2829,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]] [[package]]
name = "url" name = "url"
version = "2.2.2" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna",
"matches",
"percent-encoding", "percent-encoding",
"serde", "serde",
] ]
@ -2981,13 +2974,13 @@ dependencies = [
[[package]] [[package]]
name = "which" name = "which"
version = "4.2.5" version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
dependencies = [ dependencies = [
"either", "either",
"lazy_static",
"libc", "libc",
"once_cell",
] ]
[[package]] [[package]]

View file

@ -19,7 +19,7 @@ io-uring = [
] ]
[dependencies] [dependencies]
actix-form-data = "0.6.0" actix-form-data = { version = "0.7.0-beta.0", git = "https://git.asonix.dog/asonix/actix-form-data", branch = "v0.7.x" }
actix-rt = { version = "2.7.0", default-features = false } actix-rt = { version = "2.7.0", default-features = false }
actix-server = "2.0.0" actix-server = "2.0.0"
actix-web = { version = "4.0.0", default-features = false } actix-web = { version = "4.0.0", default-features = false }

View file

@ -1,8 +1,8 @@
use actix_form_data::{Field, Form, Value}; use actix_form_data::{Field, Form, FormData, Multipart, Value};
use actix_web::{ use actix_web::{
guard, guard,
http::header::{CacheControl, CacheDirective, LastModified, Range, ACCEPT_RANGES}, http::header::{CacheControl, CacheDirective, LastModified, Range, ACCEPT_RANGES},
web, App, HttpResponse, HttpResponseBuilder, HttpServer, web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer,
}; };
use awc::Client; use awc::Client;
use futures_util::{ use futures_util::{
@ -105,9 +105,136 @@ async fn ensure_details<R: FullRepo, S: Store + 'static>(
} }
} }
struct Upload<R: FullRepo + 'static, S: Store + 'static>(Value<Session<R, S>>);
impl<R: FullRepo, S: Store + 'static> FormData for Upload<R, S> {
type Item = Session<R, S>;
type Error = Error;
fn form(req: &HttpRequest) -> Form<Self::Item, Self::Error> {
// Create a new Multipart Form validator
//
// This form is expecting a single array field, 'images' with at most 10 files in it
let repo = req
.app_data::<web::Data<R>>()
.expect("No repo in request")
.clone();
let store = req
.app_data::<web::Data<S>>()
.expect("No store in request")
.clone();
Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = repo.clone();
let store = store.clone();
let span = tracing::info_span!("file-upload", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move {
ingest::ingest(&**repo, &**store, stream, None, true, false).await
}
.instrument(span),
)
})),
)
}
fn extract(value: Value<Session<R, S>>) -> Result<Self, Self::Error> {
Ok(Upload(value))
}
}
struct Import<R: FullRepo + 'static, S: Store + 'static>(Value<Session<R, S>>);
impl<R: FullRepo, S: Store + 'static> FormData for Import<R, S> {
type Item = Session<R, S>;
type Error = Error;
fn form(req: &actix_web::HttpRequest) -> Form<Self::Item, Self::Error> {
let repo = req
.app_data::<web::Data<R>>()
.expect("No repo in request")
.clone();
let store = req
.app_data::<web::Data<S>>()
.expect("No store in request")
.clone();
// Create a new Multipart Form validator for internal imports
//
// This form is expecting a single array field, 'images' with at most 10 files in it
Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = repo.clone();
let store = store.clone();
let span = tracing::info_span!("file-import", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move {
ingest::ingest(
&**repo,
&**store,
stream,
Some(Alias::from_existing(&filename)),
!CONFIG.media.skip_validate_imports,
false,
)
.await
}
.instrument(span),
)
})),
)
}
fn extract(value: Value<Self::Item>) -> Result<Self, Self::Error>
where
Self: Sized,
{
Ok(Import(value))
}
}
/// Handle responding to succesful uploads /// Handle responding to succesful uploads
#[instrument(name = "Uploaded files", skip(value))] #[instrument(name = "Uploaded files", skip(value))]
async fn upload<R: FullRepo, S: Store + 'static>( async fn upload<R: FullRepo, S: Store + 'static>(
Multipart(Upload(value)): Multipart<Upload<R, S>>,
repo: web::Data<R>,
store: web::Data<S>,
) -> Result<HttpResponse, Error> {
handle_upload(value, repo, store).await
}
/// Handle responding to succesful uploads
#[instrument(name = "Imported files", skip(value))]
async fn import<R: FullRepo, S: Store + 'static>(
Multipart(Import(value)): Multipart<Import<R, S>>,
repo: web::Data<R>,
store: web::Data<S>,
) -> Result<HttpResponse, Error> {
handle_upload(value, repo, store).await
}
/// Handle responding to succesful uploads
#[instrument(name = "Uploaded files", skip(value))]
async fn handle_upload<R: FullRepo, S: Store + 'static>(
value: Value<Session<R, S>>, value: Value<Session<R, S>>,
repo: web::Data<R>, repo: web::Data<R>,
store: web::Data<S>, store: web::Data<S>,
@ -129,7 +256,7 @@ async fn upload<R: FullRepo, S: Store + 'static>(
info!("Uploaded {} as {:?}", image.filename, alias); info!("Uploaded {} as {:?}", image.filename, alias);
let delete_token = image.result.delete_token().await?; let delete_token = image.result.delete_token().await?;
let details = ensure_details(&**repo, &**store, alias).await?; let details = ensure_details(&repo, &store, alias).await?;
files.push(serde_json::json!({ files.push(serde_json::json!({
"file": alias.to_string(), "file": alias.to_string(),
@ -149,9 +276,58 @@ async fn upload<R: FullRepo, S: Store + 'static>(
}))) })))
} }
struct BackgroundedUpload<R: FullRepo + 'static, S: Store + 'static>(Value<Backgrounded<R, S>>);
impl<R: FullRepo, S: Store + 'static> FormData for BackgroundedUpload<R, S> {
type Item = Backgrounded<R, S>;
type Error = Error;
fn form(req: &actix_web::HttpRequest) -> Form<Self::Item, Self::Error> {
// Create a new Multipart Form validator for backgrounded uploads
//
// This form is expecting a single array field, 'images' with at most 10 files in it
let repo = req
.app_data::<web::Data<R>>()
.expect("No repo in request")
.clone();
let store = req
.app_data::<web::Data<S>>()
.expect("No store in request")
.clone();
Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = (**repo).clone();
let store = (**store).clone();
let span = tracing::info_span!("file-proxy", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move { Backgrounded::proxy(repo, store, stream).await }
.instrument(span),
)
})),
)
}
fn extract(value: Value<Self::Item>) -> Result<Self, Self::Error>
where
Self: Sized,
{
Ok(BackgroundedUpload(value))
}
}
#[instrument(name = "Uploaded files", skip(value))] #[instrument(name = "Uploaded files", skip(value))]
async fn upload_backgrounded<R: FullRepo, S: Store>( async fn upload_backgrounded<R: FullRepo, S: Store>(
value: Value<Backgrounded<R, S>>, Multipart(BackgroundedUpload(value)): Multipart<BackgroundedUpload<R, S>>,
repo: web::Data<R>, repo: web::Data<R>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let images = value let images = value
@ -174,7 +350,7 @@ async fn upload_backgrounded<R: FullRepo, S: Store>(
.expect("Identifier exists") .expect("Identifier exists")
.to_bytes()?; .to_bytes()?;
queue::queue_ingest(&**repo, identifier, upload_id, None, true, false).await?; queue::queue_ingest(&repo, identifier, upload_id, None, true, false).await?;
files.push(serde_json::json!({ files.push(serde_json::json!({
"upload_id": upload_id.to_string(), "upload_id": upload_id.to_string(),
@ -212,7 +388,7 @@ async fn claim_upload<R: FullRepo, S: Store + 'static>(
match upload_result { match upload_result {
UploadResult::Success { alias, token } => { UploadResult::Success { alias, token } => {
let details = ensure_details(&**repo, &**store, &alias).await?; let details = ensure_details(&repo, &store, &alias).await?;
Ok(HttpResponse::Ok().json(&serde_json::json!({ Ok(HttpResponse::Ok().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
@ -277,12 +453,12 @@ async fn do_download_inline<R: FullRepo + 'static, S: Store + 'static>(
store: web::Data<S>, store: web::Data<S>,
is_cached: bool, is_cached: bool,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let mut session = ingest::ingest(&**repo, &**store, stream, None, true, is_cached).await?; let mut session = ingest::ingest(&repo, &store, stream, None, true, is_cached).await?;
let alias = session.alias().expect("alias should exist").to_owned(); let alias = session.alias().expect("alias should exist").to_owned();
let delete_token = session.delete_token().await?; let delete_token = session.delete_token().await?;
let details = ensure_details(&**repo, &**store, &alias).await?; let details = ensure_details(&repo, &store, &alias).await?;
session.disarm(); session.disarm();
@ -311,7 +487,7 @@ async fn do_download_backgrounded<R: FullRepo + 'static, S: Store + 'static>(
.expect("Identifier exists") .expect("Identifier exists")
.to_bytes()?; .to_bytes()?;
queue::queue_ingest(&**repo, identifier, upload_id, None, true, is_cached).await?; queue::queue_ingest(&repo, identifier, upload_id, None, true, is_cached).await?;
backgrounded.disarm(); backgrounded.disarm();
@ -334,7 +510,7 @@ async fn delete<R: FullRepo>(
let token = DeleteToken::from_existing(&token); let token = DeleteToken::from_existing(&token);
let alias = Alias::from_existing(&alias); let alias = Alias::from_existing(&alias);
queue::cleanup_alias(&**repo, alias, token).await?; queue::cleanup_alias(&repo, alias, token).await?;
Ok(HttpResponse::NoContent().finish()) Ok(HttpResponse::NoContent().finish())
} }
@ -440,12 +616,12 @@ async fn process<R: FullRepo, S: Store + 'static>(
new_details new_details
}; };
return ranged_file_resp(&**store, identifier, range, details).await; return ranged_file_resp(&store, identifier, range, details).await;
} }
let (details, bytes) = generate::generate( let (details, bytes) = generate::generate(
&**repo, &repo,
&**store, &store,
format, format,
alias, alias,
thumbnail_path, thumbnail_path,
@ -524,7 +700,7 @@ async fn process_head<R: FullRepo, S: Store + 'static>(
new_details new_details
}; };
return ranged_file_head_resp(&**store, identifier, range, details).await; return ranged_file_head_resp(&store, identifier, range, details).await;
} }
Ok(HttpResponse::NotFound().finish()) Ok(HttpResponse::NotFound().finish())
@ -549,7 +725,7 @@ async fn process_backgrounded<R: FullRepo, S: Store>(
return Ok(HttpResponse::Accepted().finish()); return Ok(HttpResponse::Accepted().finish());
} }
queue_generate(&**repo, target_format, source, process_path, process_args).await?; queue_generate(&repo, target_format, source, process_path, process_args).await?;
Ok(HttpResponse::Accepted().finish()) Ok(HttpResponse::Accepted().finish())
} }
@ -563,7 +739,7 @@ async fn details<R: FullRepo, S: Store + 'static>(
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let alias = alias.into_inner(); let alias = alias.into_inner();
let details = ensure_details(&**repo, &**store, &alias).await?; let details = ensure_details(&repo, &store, &alias).await?;
Ok(HttpResponse::Ok().json(&details)) Ok(HttpResponse::Ok().json(&details))
} }
@ -582,9 +758,9 @@ async fn serve<R: FullRepo, S: Store + 'static>(
let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?; let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?;
let details = ensure_details(&**repo, &**store, &alias).await?; let details = ensure_details(&repo, &store, &alias).await?;
ranged_file_resp(&**store, identifier, range, details).await ranged_file_resp(&store, identifier, range, details).await
} }
#[instrument(name = "Serving file headers", skip(repo))] #[instrument(name = "Serving file headers", skip(repo))]
@ -600,9 +776,9 @@ async fn serve_head<R: FullRepo, S: Store + 'static>(
let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?; let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?;
let details = ensure_details(&**repo, &**store, &alias).await?; let details = ensure_details(&repo, &store, &alias).await?;
ranged_file_head_resp(&**store, identifier, range, details).await ranged_file_head_resp(&store, identifier, range, details).await
} }
async fn ranged_file_head_resp<S: Store + 'static>( async fn ranged_file_head_resp<S: Store + 'static>(
@ -733,7 +909,7 @@ fn srv_head(
#[instrument(name = "Spawning variant cleanup", skip(repo))] #[instrument(name = "Spawning variant cleanup", skip(repo))]
async fn clean_variants<R: FullRepo>(repo: web::Data<R>) -> Result<HttpResponse, Error> { async fn clean_variants<R: FullRepo>(repo: web::Data<R>) -> Result<HttpResponse, Error> {
queue::cleanup_all_variants(&**repo).await?; queue::cleanup_all_variants(&repo).await?;
Ok(HttpResponse::NoContent().finish()) Ok(HttpResponse::NoContent().finish())
} }
@ -751,7 +927,7 @@ async fn purge<R: FullRepo>(
let aliases = repo.aliases_from_alias(&alias).await?; let aliases = repo.aliases_from_alias(&alias).await?;
let hash = repo.hash(&alias).await?; let hash = repo.hash(&alias).await?;
queue::cleanup_hash(&**repo, hash).await?; queue::cleanup_hash(&repo, hash).await?;
Ok(HttpResponse::Ok().json(&serde_json::json!({ Ok(HttpResponse::Ok().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
@ -806,92 +982,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
) -> color_eyre::Result<()> { ) -> color_eyre::Result<()> {
repo.requeue_in_progress(CONFIG.server.worker_id.as_bytes().to_vec()) repo.requeue_in_progress(CONFIG.server.worker_id.as_bytes().to_vec())
.await?; .await?;
// Create a new Multipart Form validator
//
// This form is expecting a single array field, 'images' with at most 10 files in it
let repo2 = repo.clone();
let store2 = store.clone();
let form = Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = repo2.clone();
let store = store2.clone();
let span = tracing::info_span!("file-upload", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move { ingest::ingest(&repo, &store, stream, None, true, false).await }
.instrument(span),
)
})),
);
// Create a new Multipart Form validator for internal imports
//
// This form is expecting a single array field, 'images' with at most 10 files in it
let repo2 = repo.clone();
let store2 = store.clone();
let import_form = Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = repo2.clone();
let store = store2.clone();
let span = tracing::info_span!("file-import", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move {
ingest::ingest(
&repo,
&store,
stream,
Some(Alias::from_existing(&filename)),
!CONFIG.media.skip_validate_imports,
false,
)
.await
}
.instrument(span),
)
})),
);
// Create a new Multipart Form validator for backgrounded uploads
//
// This form is expecting a single array field, 'images' with at most 10 files in it
let repo2 = repo.clone();
let store2 = store.clone();
let backgrounded_form = Form::new()
.max_files(10)
.max_file_size(CONFIG.media.max_file_size * MEGABYTES)
.transform_error(transform_error)
.field(
"images",
Field::array(Field::file(move |filename, _, stream| {
let repo = repo2.clone();
let store = store2.clone();
let span = tracing::info_span!("file-proxy", ?filename);
let stream = stream.map_err(Error::from);
Box::pin(
async move { Backgrounded::proxy(repo, store, stream).await }.instrument(span),
)
})),
);
HttpServer::new(move || { HttpServer::new(move || {
let store = store.clone(); let store = store.clone();
@ -923,7 +1013,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
.service( .service(
web::resource("") web::resource("")
.guard(guard::Post()) .guard(guard::Post())
.wrap(form.clone())
.route(web::post().to(upload::<R, S>)), .route(web::post().to(upload::<R, S>)),
) )
.service( .service(
@ -931,7 +1020,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
.service( .service(
web::resource("") web::resource("")
.guard(guard::Post()) .guard(guard::Post())
.wrap(backgrounded_form.clone())
.route(web::post().to(upload_backgrounded::<R, S>)), .route(web::post().to(upload_backgrounded::<R, S>)),
) )
.service( .service(
@ -975,11 +1063,7 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
.wrap(Internal( .wrap(Internal(
CONFIG.server.api_key.as_ref().map(|s| s.to_owned()), CONFIG.server.api_key.as_ref().map(|s| s.to_owned()),
)) ))
.service( .service(web::resource("/import").route(web::post().to(import::<R, S>)))
web::resource("/import")
.wrap(import_form.clone())
.route(web::post().to(upload::<R, S>)),
)
.service( .service(
web::resource("/variants").route(web::delete().to(clean_variants::<R>)), web::resource("/variants").route(web::delete().to(clean_variants::<R>)),
) )

View file

@ -102,10 +102,19 @@ pub(crate) trait FullRepo:
} }
} }
impl<T> FullRepo for actix_web::web::Data<T> where T: FullRepo {}
pub(crate) trait BaseRepo { pub(crate) trait BaseRepo {
type Bytes: AsRef<[u8]> + From<Vec<u8>> + Clone; type Bytes: AsRef<[u8]> + From<Vec<u8>> + Clone;
} }
impl<T> BaseRepo for actix_web::web::Data<T>
where
T: BaseRepo,
{
type Bytes = T::Bytes;
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait CachedRepo: BaseRepo { pub(crate) trait CachedRepo: BaseRepo {
async fn mark_cached(&self, alias: &Alias) -> Result<(), Error>; async fn mark_cached(&self, alias: &Alias) -> Result<(), Error>;
@ -113,6 +122,20 @@ pub(crate) trait CachedRepo: BaseRepo {
async fn update(&self, alias: &Alias) -> Result<Vec<Alias>, Error>; async fn update(&self, alias: &Alias) -> Result<Vec<Alias>, Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> CachedRepo for actix_web::web::Data<T>
where
T: CachedRepo,
{
async fn mark_cached(&self, alias: &Alias) -> Result<(), Error> {
T::mark_cached(&self, alias).await
}
async fn update(&self, alias: &Alias) -> Result<Vec<Alias>, Error> {
T::update(&self, alias).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait UploadRepo: BaseRepo { pub(crate) trait UploadRepo: BaseRepo {
async fn create(&self, upload_id: UploadId) -> Result<(), Error>; async fn create(&self, upload_id: UploadId) -> Result<(), Error>;
@ -124,6 +147,28 @@ pub(crate) trait UploadRepo: BaseRepo {
async fn complete(&self, upload_id: UploadId, result: UploadResult) -> Result<(), Error>; async fn complete(&self, upload_id: UploadId, result: UploadResult) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> UploadRepo for actix_web::web::Data<T>
where
T: UploadRepo,
{
async fn create(&self, upload_id: UploadId) -> Result<(), Error> {
T::create(&self, upload_id).await
}
async fn wait(&self, upload_id: UploadId) -> Result<UploadResult, Error> {
T::wait(&self, upload_id).await
}
async fn claim(&self, upload_id: UploadId) -> Result<(), Error> {
T::claim(&self, upload_id).await
}
async fn complete(&self, upload_id: UploadId, result: UploadResult) -> Result<(), Error> {
T::complete(&self, upload_id, result).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait QueueRepo: BaseRepo { pub(crate) trait QueueRepo: BaseRepo {
async fn requeue_in_progress(&self, worker_prefix: Vec<u8>) -> Result<(), Error>; async fn requeue_in_progress(&self, worker_prefix: Vec<u8>) -> Result<(), Error>;
@ -133,6 +178,24 @@ pub(crate) trait QueueRepo: BaseRepo {
async fn pop(&self, queue: &'static str, worker_id: Vec<u8>) -> Result<Self::Bytes, Error>; async fn pop(&self, queue: &'static str, worker_id: Vec<u8>) -> Result<Self::Bytes, Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> QueueRepo for actix_web::web::Data<T>
where
T: QueueRepo,
{
async fn requeue_in_progress(&self, worker_prefix: Vec<u8>) -> Result<(), Error> {
T::requeue_in_progress(&self, worker_prefix).await
}
async fn push(&self, queue: &'static str, job: Self::Bytes) -> Result<(), Error> {
T::push(&self, queue, job).await
}
async fn pop(&self, queue: &'static str, worker_id: Vec<u8>) -> Result<Self::Bytes, Error> {
T::pop(&self, queue, worker_id).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait SettingsRepo: BaseRepo { pub(crate) trait SettingsRepo: BaseRepo {
async fn set(&self, key: &'static str, value: Self::Bytes) -> Result<(), Error>; async fn set(&self, key: &'static str, value: Self::Bytes) -> Result<(), Error>;
@ -140,6 +203,24 @@ pub(crate) trait SettingsRepo: BaseRepo {
async fn remove(&self, key: &'static str) -> Result<(), Error>; async fn remove(&self, key: &'static str) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> SettingsRepo for actix_web::web::Data<T>
where
T: SettingsRepo,
{
async fn set(&self, key: &'static str, value: Self::Bytes) -> Result<(), Error> {
T::set(&self, key, value).await
}
async fn get(&self, key: &'static str) -> Result<Option<Self::Bytes>, Error> {
T::get(&self, key).await
}
async fn remove(&self, key: &'static str) -> Result<(), Error> {
T::remove(&self, key).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait IdentifierRepo: BaseRepo { pub(crate) trait IdentifierRepo: BaseRepo {
async fn relate_details<I: Identifier>( async fn relate_details<I: Identifier>(
@ -152,6 +233,28 @@ pub(crate) trait IdentifierRepo: BaseRepo {
async fn cleanup<I: Identifier>(&self, identifier: &I) -> Result<(), Error>; async fn cleanup<I: Identifier>(&self, identifier: &I) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> IdentifierRepo for actix_web::web::Data<T>
where
T: IdentifierRepo,
{
async fn relate_details<I: Identifier>(
&self,
identifier: &I,
details: &Details,
) -> Result<(), Error> {
T::relate_details(&self, identifier, details).await
}
async fn details<I: Identifier>(&self, identifier: &I) -> Result<Option<Details>, Error> {
T::details(&self, identifier).await
}
async fn cleanup<I: Identifier>(&self, identifier: &I) -> Result<(), Error> {
T::cleanup(&self, identifier).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait HashRepo: BaseRepo { pub(crate) trait HashRepo: BaseRepo {
type Stream: Stream<Item = Result<Self::Bytes, Error>>; type Stream: Stream<Item = Result<Self::Bytes, Error>>;
@ -201,6 +304,93 @@ pub(crate) trait HashRepo: BaseRepo {
async fn cleanup(&self, hash: Self::Bytes) -> Result<(), Error>; async fn cleanup(&self, hash: Self::Bytes) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> HashRepo for actix_web::web::Data<T>
where
T: HashRepo,
{
type Stream = T::Stream;
async fn hashes(&self) -> Self::Stream {
T::hashes(&self).await
}
async fn create(&self, hash: Self::Bytes) -> Result<Result<(), AlreadyExists>, Error> {
T::create(&self, hash).await
}
async fn relate_alias(&self, hash: Self::Bytes, alias: &Alias) -> Result<(), Error> {
T::relate_alias(&self, hash, alias).await
}
async fn remove_alias(&self, hash: Self::Bytes, alias: &Alias) -> Result<(), Error> {
T::remove_alias(&self, hash, alias).await
}
async fn aliases(&self, hash: Self::Bytes) -> Result<Vec<Alias>, Error> {
T::aliases(&self, hash).await
}
async fn relate_identifier<I: Identifier>(
&self,
hash: Self::Bytes,
identifier: &I,
) -> Result<(), Error> {
T::relate_identifier(&self, hash, identifier).await
}
async fn identifier<I: Identifier + 'static>(&self, hash: Self::Bytes) -> Result<I, Error> {
T::identifier(&self, hash).await
}
async fn relate_variant_identifier<I: Identifier>(
&self,
hash: Self::Bytes,
variant: String,
identifier: &I,
) -> Result<(), Error> {
T::relate_variant_identifier(&self, hash, variant, identifier).await
}
async fn variant_identifier<I: Identifier + 'static>(
&self,
hash: Self::Bytes,
variant: String,
) -> Result<Option<I>, Error> {
T::variant_identifier(&self, hash, variant).await
}
async fn variants<I: Identifier + 'static>(
&self,
hash: Self::Bytes,
) -> Result<Vec<(String, I)>, Error> {
T::variants(&self, hash).await
}
async fn remove_variant(&self, hash: Self::Bytes, variant: String) -> Result<(), Error> {
T::remove_variant(&self, hash, variant).await
}
async fn relate_motion_identifier<I: Identifier>(
&self,
hash: Self::Bytes,
identifier: &I,
) -> Result<(), Error> {
T::relate_motion_identifier(&self, hash, identifier).await
}
async fn motion_identifier<I: Identifier + 'static>(
&self,
hash: Self::Bytes,
) -> Result<Option<I>, Error> {
T::motion_identifier(&self, hash).await
}
async fn cleanup(&self, hash: Self::Bytes) -> Result<(), Error> {
T::cleanup(&self, hash).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub(crate) trait AliasRepo: BaseRepo { pub(crate) trait AliasRepo: BaseRepo {
async fn create(&self, alias: &Alias) -> Result<Result<(), AlreadyExists>, Error>; async fn create(&self, alias: &Alias) -> Result<Result<(), AlreadyExists>, Error>;
@ -218,6 +408,40 @@ pub(crate) trait AliasRepo: BaseRepo {
async fn cleanup(&self, alias: &Alias) -> Result<(), Error>; async fn cleanup(&self, alias: &Alias) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> AliasRepo for actix_web::web::Data<T>
where
T: AliasRepo,
{
async fn create(&self, alias: &Alias) -> Result<Result<(), AlreadyExists>, Error> {
T::create(&self, alias).await
}
async fn relate_delete_token(
&self,
alias: &Alias,
delete_token: &DeleteToken,
) -> Result<Result<(), AlreadyExists>, Error> {
T::relate_delete_token(&self, alias, delete_token).await
}
async fn delete_token(&self, alias: &Alias) -> Result<DeleteToken, Error> {
T::delete_token(&self, alias).await
}
async fn relate_hash(&self, alias: &Alias, hash: Self::Bytes) -> Result<(), Error> {
T::relate_hash(&self, alias, hash).await
}
async fn hash(&self, alias: &Alias) -> Result<Self::Bytes, Error> {
T::hash(&self, alias).await
}
async fn cleanup(&self, alias: &Alias) -> Result<(), Error> {
T::cleanup(&self, alias).await
}
}
impl Repo { impl Repo {
pub(crate) fn open(config: config::Repo) -> color_eyre::Result<Self> { pub(crate) fn open(config: config::Repo) -> color_eyre::Result<Self> {
match config { match config {

View file

@ -46,6 +46,54 @@ pub(crate) trait Store: Send + Sync + Clone + Debug {
async fn remove(&self, identifier: &Self::Identifier) -> Result<(), Error>; async fn remove(&self, identifier: &Self::Identifier) -> Result<(), Error>;
} }
#[async_trait::async_trait(?Send)]
impl<T> Store for actix_web::web::Data<T>
where
T: Store,
{
type Identifier = T::Identifier;
type Stream = T::Stream;
async fn save_async_read<Reader>(&self, reader: &mut Reader) -> Result<Self::Identifier, Error>
where
Reader: AsyncRead + Unpin,
{
T::save_async_read(&self, reader).await
}
async fn save_bytes(&self, bytes: Bytes) -> Result<Self::Identifier, Error> {
T::save_bytes(&self, bytes).await
}
async fn to_stream(
&self,
identifier: &Self::Identifier,
from_start: Option<u64>,
len: Option<u64>,
) -> Result<Self::Stream, Error> {
T::to_stream(&self, identifier, from_start, len).await
}
async fn read_into<Writer>(
&self,
identifier: &Self::Identifier,
writer: &mut Writer,
) -> Result<(), std::io::Error>
where
Writer: AsyncWrite + Send + Unpin,
{
T::read_into(&self, identifier, writer).await
}
async fn len(&self, identifier: &Self::Identifier) -> Result<u64, Error> {
T::len(&self, identifier).await
}
async fn remove(&self, identifier: &Self::Identifier) -> Result<(), Error> {
T::remove(&self, identifier).await
}
}
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl<'a, T> Store for &'a T impl<'a, T> Store for &'a T
where where