mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-22 11:21:24 +00:00
Update actix-form-data, impl Store & Repo for Data<T>
This commit is contained in:
parent
6673049238
commit
7f49af58fe
5 changed files with 585 additions and 236 deletions
233
Cargo.lock
generated
233
Cargo.lock
generated
|
@ -16,14 +16,13 @@ dependencies = [
|
|||
"memchr",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-form-data"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd2788a4c359a372371292ef9903cf26759abf3ddf00ed710061808b1414fc75"
|
||||
version = "0.7.0-beta.0"
|
||||
source = "git+https://git.asonix.dog/asonix/actix-form-data?branch=v0.7.x#3525bcd09cd030df3f2ed7684f2aad1bcc42d68b"
|
||||
dependencies = [
|
||||
"actix-multipart",
|
||||
"actix-rt",
|
||||
|
@ -168,7 +167,7 @@ dependencies = [
|
|||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio-rustls",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
|
@ -247,9 +246,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -265,9 +264,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.62"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
|
||||
checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7"
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
|
@ -320,9 +319,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||
|
||||
[[package]]
|
||||
name = "awc"
|
||||
version = "3.0.0"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65c60c44fbf3c8cee365e86b97d706e513b733c4eeb16437b45b88d2fffe889a"
|
||||
checksum = "80ca7ff88063086d2e2c70b9f3b29b2fcd999bac68ac21731e66781970d68519"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-http",
|
||||
|
@ -377,9 +376,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.5.15"
|
||||
version = "0.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9de18bc5f2e9df8f52da03856bf40e29b747de5a84e43aefff90e3dc4a21529b"
|
||||
checksum = "c9e3356844c4d6a6d6467b8da2cffb4a2820be256f50a3a386c9d152bab31043"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
|
@ -406,9 +405,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635"
|
||||
checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
|
@ -416,6 +415,8 @@ dependencies = [
|
|||
"http",
|
||||
"http-body",
|
||||
"mime",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -447,9 +448,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.2"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
|
||||
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
@ -495,9 +496,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.17"
|
||||
version = "3.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
|
||||
checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
@ -512,9 +513,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.17"
|
||||
version = "3.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
|
||||
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
|
||||
dependencies = [
|
||||
"heck 0.4.0",
|
||||
"proc-macro-error",
|
||||
|
@ -586,15 +587,15 @@ checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86"
|
|||
dependencies = [
|
||||
"prost 0.11.0",
|
||||
"prost-types 0.11.1",
|
||||
"tonic 0.8.0",
|
||||
"tonic 0.8.1",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-subscriber"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e933c43a5db3779b3600cdab18856af2411ca2237e33ba8ab476d5d5b1a6c1e7"
|
||||
checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be"
|
||||
dependencies = [
|
||||
"console-api",
|
||||
"crossbeam-channel",
|
||||
|
@ -608,7 +609,7 @@ dependencies = [
|
|||
"thread_local",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tonic 0.8.0",
|
||||
"tonic 0.8.1",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
|
@ -622,9 +623,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
|||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.3"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1079fb8528d9f9c888b1e8aa651e6e079ade467323d58f75faf1d30b1808f540"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -684,13 +685,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.3.4"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f"
|
||||
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core 0.9.3",
|
||||
]
|
||||
|
||||
|
@ -808,11 +810,10 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
|
@ -828,9 +829,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa"
|
||||
checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -842,9 +843,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1"
|
||||
checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -852,15 +853,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
|
||||
checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528"
|
||||
checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -869,15 +870,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5"
|
||||
checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d"
|
||||
checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -886,21 +887,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
|
||||
checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306"
|
||||
checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.23"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
|
||||
checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -965,7 +966,7 @@ dependencies = [
|
|||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -1066,9 +1067,9 @@ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
|
|||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.7.1"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
|
@ -1133,11 +1134,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
@ -1169,9 +1169,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.5.3"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "427496d698429d86ff947537dff68facb83fe753b7abea4fab4ac1c4b7a4b94b"
|
||||
checksum = "5a645fd8e7048c2f54050f7d0d4de8f624ada437e043bc7d72609bd08d70120b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -1262,9 +1262,9 @@ checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
|
|||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||
checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
|
@ -1288,12 +1288,6 @@ dependencies = [
|
|||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.5.0"
|
||||
|
@ -1346,9 +1340,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.3"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
@ -1420,9 +1414,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.1"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
|
@ -1481,9 +1475,9 @@ checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
|||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.4.0"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
|
@ -1535,9 +1529,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.8"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22"
|
||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
|
@ -1547,15 +1541,15 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
|||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.2.1"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69486e2b8c2d2aeb9762db7b4e00b0331156393555cff467f4163ff06821eef8"
|
||||
checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
|
@ -1563,9 +1557,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.2.1"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b13570633aff33c6d22ce47dd566b10a3b9122c2fe9d8e7501895905be532b91"
|
||||
checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
|
@ -1573,9 +1567,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.2.1"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3c567e5702efdc79fb18859ea74c3eb36e14c43da7b8c1f098a4ed6514ec7a0"
|
||||
checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
|
@ -1586,9 +1580,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.2.1"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eb32be5ee3bbdafa8c7a18b0a8a8d962b66cfa2ceee4037f49267a50ee821fe"
|
||||
checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
|
@ -1641,7 +1635,7 @@ dependencies = [
|
|||
"time",
|
||||
"tokio",
|
||||
"tokio-uring",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
|
@ -1936,7 +1930,7 @@ dependencies = [
|
|||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
|
@ -2092,9 +2086,9 @@ checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.143"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
@ -2123,9 +2117,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.143"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2134,9 +2128,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.83"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -2168,9 +2162,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.1"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f"
|
||||
checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
|
@ -2179,9 +2173,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.2"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
|
||||
checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
|
@ -2240,9 +2234,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
|||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.4"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
|
@ -2320,18 +2314,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.32"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
|
||||
checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.32"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
|
||||
checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2349,9 +2343,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45"
|
||||
checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"libc",
|
||||
|
@ -2383,9 +2377,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.20.1"
|
||||
version = "1.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581"
|
||||
checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
|
@ -2477,9 +2471,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
|
||||
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
@ -2531,9 +2525,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "498f271adc46acce75d66f639e4d35b31b2394c295c82496727dafa16d465dd2"
|
||||
checksum = "11cd56bdb54ef93935a6a79dbd1d91f1ebd4c64150fd61654031fd6b8b775c91"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
|
@ -2553,7 +2547,7 @@ dependencies = [
|
|||
"prost-derive 0.11.0",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
|
@ -2587,7 +2581,7 @@ dependencies = [
|
|||
"rand",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util 0.7.4",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -2790,9 +2784,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
|||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c"
|
||||
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||
|
||||
[[package]]
|
||||
name = "unchecked-index"
|
||||
|
@ -2835,13 +2829,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
@ -2981,13 +2974,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.2.5"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
|
||||
checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
|
||||
dependencies = [
|
||||
"either",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -19,7 +19,7 @@ io-uring = [
|
|||
]
|
||||
|
||||
[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-server = "2.0.0"
|
||||
actix-web = { version = "4.0.0", default-features = false }
|
||||
|
|
314
src/main.rs
314
src/main.rs
|
@ -1,8 +1,8 @@
|
|||
use actix_form_data::{Field, Form, Value};
|
||||
use actix_form_data::{Field, Form, FormData, Multipart, Value};
|
||||
use actix_web::{
|
||||
guard,
|
||||
http::header::{CacheControl, CacheDirective, LastModified, Range, ACCEPT_RANGES},
|
||||
web, App, HttpResponse, HttpResponseBuilder, HttpServer,
|
||||
web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer,
|
||||
};
|
||||
use awc::Client;
|
||||
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
|
||||
#[instrument(name = "Uploaded files", skip(value))]
|
||||
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>>,
|
||||
repo: web::Data<R>,
|
||||
store: web::Data<S>,
|
||||
|
@ -129,7 +256,7 @@ async fn upload<R: FullRepo, S: Store + 'static>(
|
|||
info!("Uploaded {} as {:?}", image.filename, alias);
|
||||
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!({
|
||||
"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))]
|
||||
async fn upload_backgrounded<R: FullRepo, S: Store>(
|
||||
value: Value<Backgrounded<R, S>>,
|
||||
Multipart(BackgroundedUpload(value)): Multipart<BackgroundedUpload<R, S>>,
|
||||
repo: web::Data<R>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let images = value
|
||||
|
@ -174,7 +350,7 @@ async fn upload_backgrounded<R: FullRepo, S: Store>(
|
|||
.expect("Identifier exists")
|
||||
.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!({
|
||||
"upload_id": upload_id.to_string(),
|
||||
|
@ -212,7 +388,7 @@ async fn claim_upload<R: FullRepo, S: Store + 'static>(
|
|||
|
||||
match upload_result {
|
||||
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!({
|
||||
"msg": "ok",
|
||||
|
@ -277,12 +453,12 @@ async fn do_download_inline<R: FullRepo + 'static, S: Store + 'static>(
|
|||
store: web::Data<S>,
|
||||
is_cached: bool,
|
||||
) -> 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 delete_token = session.delete_token().await?;
|
||||
|
||||
let details = ensure_details(&**repo, &**store, &alias).await?;
|
||||
let details = ensure_details(&repo, &store, &alias).await?;
|
||||
|
||||
session.disarm();
|
||||
|
||||
|
@ -311,7 +487,7 @@ async fn do_download_backgrounded<R: FullRepo + 'static, S: Store + 'static>(
|
|||
.expect("Identifier exists")
|
||||
.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();
|
||||
|
||||
|
@ -334,7 +510,7 @@ async fn delete<R: FullRepo>(
|
|||
let token = DeleteToken::from_existing(&token);
|
||||
let alias = Alias::from_existing(&alias);
|
||||
|
||||
queue::cleanup_alias(&**repo, alias, token).await?;
|
||||
queue::cleanup_alias(&repo, alias, token).await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().finish())
|
||||
}
|
||||
|
@ -440,12 +616,12 @@ async fn process<R: FullRepo, S: Store + 'static>(
|
|||
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(
|
||||
&**repo,
|
||||
&**store,
|
||||
&repo,
|
||||
&store,
|
||||
format,
|
||||
alias,
|
||||
thumbnail_path,
|
||||
|
@ -524,7 +700,7 @@ async fn process_head<R: FullRepo, S: Store + 'static>(
|
|||
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())
|
||||
|
@ -549,7 +725,7 @@ async fn process_backgrounded<R: FullRepo, S: Store>(
|
|||
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())
|
||||
}
|
||||
|
@ -563,7 +739,7 @@ async fn details<R: FullRepo, S: Store + 'static>(
|
|||
) -> Result<HttpResponse, Error> {
|
||||
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))
|
||||
}
|
||||
|
@ -582,9 +758,9 @@ async fn serve<R: FullRepo, S: Store + 'static>(
|
|||
|
||||
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))]
|
||||
|
@ -600,9 +776,9 @@ async fn serve_head<R: FullRepo, S: Store + 'static>(
|
|||
|
||||
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>(
|
||||
|
@ -733,7 +909,7 @@ fn srv_head(
|
|||
|
||||
#[instrument(name = "Spawning variant cleanup", skip(repo))]
|
||||
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())
|
||||
}
|
||||
|
||||
|
@ -751,7 +927,7 @@ async fn purge<R: FullRepo>(
|
|||
let aliases = repo.aliases_from_alias(&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!({
|
||||
"msg": "ok",
|
||||
|
@ -806,92 +982,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
|
|||
) -> color_eyre::Result<()> {
|
||||
repo.requeue_in_progress(CONFIG.server.worker_id.as_bytes().to_vec())
|
||||
.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 || {
|
||||
let store = store.clone();
|
||||
|
@ -923,7 +1013,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
|
|||
.service(
|
||||
web::resource("")
|
||||
.guard(guard::Post())
|
||||
.wrap(form.clone())
|
||||
.route(web::post().to(upload::<R, S>)),
|
||||
)
|
||||
.service(
|
||||
|
@ -931,7 +1020,6 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
|
|||
.service(
|
||||
web::resource("")
|
||||
.guard(guard::Post())
|
||||
.wrap(backgrounded_form.clone())
|
||||
.route(web::post().to(upload_backgrounded::<R, S>)),
|
||||
)
|
||||
.service(
|
||||
|
@ -975,11 +1063,7 @@ async fn launch<R: FullRepo + Clone + 'static, S: Store + Clone + 'static>(
|
|||
.wrap(Internal(
|
||||
CONFIG.server.api_key.as_ref().map(|s| s.to_owned()),
|
||||
))
|
||||
.service(
|
||||
web::resource("/import")
|
||||
.wrap(import_form.clone())
|
||||
.route(web::post().to(upload::<R, S>)),
|
||||
)
|
||||
.service(web::resource("/import").route(web::post().to(import::<R, S>)))
|
||||
.service(
|
||||
web::resource("/variants").route(web::delete().to(clean_variants::<R>)),
|
||||
)
|
||||
|
|
224
src/repo.rs
224
src/repo.rs
|
@ -102,10 +102,19 @@ pub(crate) trait FullRepo:
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> FullRepo for actix_web::web::Data<T> where T: FullRepo {}
|
||||
|
||||
pub(crate) trait BaseRepo {
|
||||
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)]
|
||||
pub(crate) trait CachedRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait UploadRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait QueueRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait SettingsRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait IdentifierRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait HashRepo: BaseRepo {
|
||||
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_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)]
|
||||
pub(crate) trait AliasRepo: BaseRepo {
|
||||
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_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 {
|
||||
pub(crate) fn open(config: config::Repo) -> color_eyre::Result<Self> {
|
||||
match config {
|
||||
|
|
48
src/store.rs
48
src/store.rs
|
@ -46,6 +46,54 @@ pub(crate) trait Store: Send + Sync + Clone + Debug {
|
|||
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)]
|
||||
impl<'a, T> Store for &'a T
|
||||
where
|
||||
|
|
Loading…
Reference in a new issue