add code download route
This commit is contained in:
parent
480e16d070
commit
dddc4b4081
6 changed files with 131 additions and 2 deletions
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -299,6 +299,16 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
|
@ -1118,6 +1128,19 @@ version = "0.31.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.10"
|
||||
|
@ -1447,6 +1470,22 @@ dependencies = [
|
|||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"globset",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex-automata 0.4.9",
|
||||
"same-file",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
|
@ -1747,6 +1786,7 @@ dependencies = [
|
|||
"axum",
|
||||
"clap",
|
||||
"futures",
|
||||
"ignore",
|
||||
"lopdf",
|
||||
"quick-xml",
|
||||
"rayon",
|
||||
|
|
|
@ -29,3 +29,7 @@ utoipa-swagger-ui = { version = "9.0.2", features = ["axum", "vendored"] }
|
|||
uuid = { version = "1.17.0", features = ["v4"] }
|
||||
walkdir = "2.5.0"
|
||||
zip = "4.2.0"
|
||||
|
||||
[build-dependencies]
|
||||
ignore = "0.4.23"
|
||||
zip = { version = "4.2.0", default-features = false, features = ["deflate"] }
|
||||
|
|
46
build.rs
Normal file
46
build.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use std::{
|
||||
env,
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use ignore::Walk;
|
||||
use zip::{CompressionMethod, write::SimpleFileOptions};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let out_dir = env::var("OUT_DIR")?;
|
||||
let src_dir = ".";
|
||||
|
||||
let zip_path = Path::new(&out_dir).join("archive.zip");
|
||||
let zip_file = File::create(zip_path)?;
|
||||
|
||||
let walkdir = Walk::new(src_dir);
|
||||
let it = walkdir.into_iter();
|
||||
|
||||
let mut zip = zip::ZipWriter::new(zip_file);
|
||||
|
||||
let options = SimpleFileOptions::default()
|
||||
.compression_method(CompressionMethod::Deflated)
|
||||
.unix_permissions(0o755);
|
||||
|
||||
for entry in it {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let name = path.strip_prefix(Path::new(src_dir))?;
|
||||
|
||||
if path.is_file() {
|
||||
zip.start_file(name.to_str().unwrap(), options)?;
|
||||
let mut f = File::open(path)?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer)?;
|
||||
zip.write_all(&buffer)?;
|
||||
} else if !name.as_os_str().is_empty() {
|
||||
zip.add_directory(name.to_str().unwrap(), options)?;
|
||||
}
|
||||
}
|
||||
zip.finish()?;
|
||||
println!("cargo:rerun-if-changed={}", src_dir);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -15,6 +15,7 @@ use utoipa_swagger_ui::SwaggerUi;
|
|||
|
||||
use crate::{storage::Postgres, text_encoder::TextEncoder, tokenize::Tokenizer};
|
||||
|
||||
pub mod code;
|
||||
pub mod error;
|
||||
pub mod query;
|
||||
pub mod routes;
|
||||
|
|
38
src/api/code.rs
Normal file
38
src/api/code.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use axum::{
|
||||
http::{StatusCode, header},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
|
||||
use super::TAG;
|
||||
|
||||
const SOURCE_ARCHIVE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/archive.zip"));
|
||||
|
||||
/// Serve the source code archive as a downloadable zip file.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/code",
|
||||
tag = TAG,
|
||||
responses(
|
||||
(status = 200,
|
||||
description = "Source code archive as zip file",
|
||||
content_type = "application/zip",
|
||||
headers(
|
||||
("content-disposition" = String, description = "Attachment filename"),
|
||||
("content-length" = String, description = "File size in bytes")
|
||||
)
|
||||
),
|
||||
)
|
||||
)]
|
||||
pub async fn route() -> Result<Response, StatusCode> {
|
||||
let content_length = SOURCE_ARCHIVE.len().to_string();
|
||||
let headers = [
|
||||
(header::CONTENT_TYPE, "application/zip"),
|
||||
(
|
||||
header::CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"source.zip\"",
|
||||
),
|
||||
(header::CONTENT_LENGTH, content_length.as_str()),
|
||||
];
|
||||
|
||||
Ok((headers, SOURCE_ARCHIVE).into_response())
|
||||
}
|
|
@ -6,13 +6,13 @@ use tower_http::trace::TraceLayer;
|
|||
use utoipa_axum::{router::OpenApiRouter, routes};
|
||||
|
||||
use super::state::AppState;
|
||||
use crate::api::query;
|
||||
use crate::api::{code, query};
|
||||
|
||||
/// Create the main API router with all endpoints and middleware.
|
||||
pub fn router(state: AppState) -> OpenApiRouter {
|
||||
let store = Arc::new(state);
|
||||
OpenApiRouter::new()
|
||||
.routes(routes!(query::route))
|
||||
.routes(routes!(query::route, code::route))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.with_state(store)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue