vaguely working upload/download implementation
This commit is contained in:
commit
00f4dce4f9
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
db/punt.sqlite
|
||||||
|
uploads
|
1542
Cargo.lock
generated
Normal file
1542
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
Cargo.toml
Normal file
27
Cargo.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[package]
|
||||||
|
name = "punt"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = {version = "0.5.0-rc.1", features = ["json"]}
|
||||||
|
serde = {version = "1", features = ["derive"]}
|
||||||
|
tokio = {version = "1", features = ["fs"]}
|
||||||
|
serde_json = "1"
|
||||||
|
rand = "0.8"
|
||||||
|
|
||||||
|
[dependencies.libsqlite3-sys]
|
||||||
|
version = ">=0.17.2, <0.24.0"
|
||||||
|
features = ["bundled"]
|
||||||
|
|
||||||
|
[dependencies.diesel]
|
||||||
|
version = "1.4"
|
||||||
|
default-features = false
|
||||||
|
features = ["sqlite"]
|
||||||
|
|
||||||
|
[dependencies.rocket_sync_db_pools]
|
||||||
|
version = "0.1.0-rc.1"
|
||||||
|
default-features = false
|
||||||
|
features = ["diesel_sqlite_pool"]
|
4
Rocket.toml
Normal file
4
Rocket.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Temporary, will be replaced by env vars and hard-coded defaults eventually so that Punt can function as a single-binary application
|
||||||
|
|
||||||
|
[global.databases]
|
||||||
|
punt = {url = "db/punt.sqlite"}
|
1
db/migrations/2022-01-16-214545_initial/down.sql
Normal file
1
db/migrations/2022-01-16-214545_initial/down.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE uploads;
|
5
db/migrations/2022-01-16-214545_initial/up.sql
Normal file
5
db/migrations/2022-01-16-214545_initial/up.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
CREATE TABLE uploads (
|
||||||
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
|
name TEXT,
|
||||||
|
created_at INTEGER
|
||||||
|
);
|
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/schema.rs"
|
||||||
|
|
||||||
|
# this will start working whenever Diesel CLI gets around to releasing v1.4.4
|
||||||
|
# [migrations_directory]
|
||||||
|
# file = "db/migrations"
|
40
src/data.rs
Normal file
40
src/data.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use rocket_sync_db_pools::database;
|
||||||
|
use rocket::serde::Serialize;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
|
||||||
|
use crate::schema::uploads;
|
||||||
|
|
||||||
|
|
||||||
|
#[database("punt")]
|
||||||
|
pub struct DbConn(diesel::SqliteConnection);
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Queryable, Insertable, Serialize)]
|
||||||
|
#[table_name="uploads"]
|
||||||
|
pub struct FileInfo {
|
||||||
|
pub id: String,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub created_at: Option<i32> // figure out how to marshal this to a proper time type later
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_file_info(id: String, conn: DbConn) -> QueryResult<FileInfo> {
|
||||||
|
conn.run(|c| uploads::table.find(id).first(c)).await
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn put_file_info(id: &str, name: Option<&str>, conn: DbConn) -> QueryResult<()> {
|
||||||
|
let file_info = FileInfo {
|
||||||
|
id: id.to_owned(),
|
||||||
|
name: name.map(|n| n.to_owned()),
|
||||||
|
created_at: Some(1642371865),
|
||||||
|
};
|
||||||
|
|
||||||
|
conn.run(|c| {
|
||||||
|
diesel::insert_into(uploads::table)
|
||||||
|
.values(file_info)
|
||||||
|
.execute(c)
|
||||||
|
}).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
25
src/lib.rs
Normal file
25
src/lib.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use rand::{Rng, distributions::Alphanumeric};
|
||||||
|
use tokio::fs::create_dir;
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use rocket::fs::TempFile;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn gen_id() -> String {
|
||||||
|
rand::thread_rng()
|
||||||
|
.sample_iter(Alphanumeric)
|
||||||
|
.map(|c| c as char)
|
||||||
|
.take(16)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn persist_file(file: &mut TempFile<'_>, filename: &str) -> std::io::Result<()> {
|
||||||
|
let dst = format!("uploads/{filename}");
|
||||||
|
match file.persist_to(&dst).await {
|
||||||
|
Err(e) if e.kind() == ErrorKind::NotFound => {
|
||||||
|
create_dir("uploads").await?;
|
||||||
|
file.persist_to(&dst).await
|
||||||
|
},
|
||||||
|
other => other,
|
||||||
|
}
|
||||||
|
}
|
44
src/main.rs
Normal file
44
src/main.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use rocket::{get, post, routes, fs::TempFile};
|
||||||
|
use rocket::http::Status;
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
#[macro_use] extern crate diesel;
|
||||||
|
|
||||||
|
mod data;
|
||||||
|
mod lib;
|
||||||
|
mod schema;
|
||||||
|
use data::{DbConn, FileInfo};
|
||||||
|
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn test() -> &'static str {
|
||||||
|
return "Hello, world!";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[get("/<id>")]
|
||||||
|
async fn download(id: String, conn: DbConn) -> Result<Json<FileInfo>, Status> {
|
||||||
|
data::get_file_info(id, conn).await
|
||||||
|
.map(|info| Json(info))
|
||||||
|
.map_err(|_| Status::InternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[post("/upload", data = "<file>")]
|
||||||
|
async fn upload(mut file: TempFile<'_>, conn: DbConn) -> Result<String, Status> {
|
||||||
|
let id = lib::gen_id();
|
||||||
|
data::put_file_info(&id, file.name(), conn).await
|
||||||
|
.map_err(|_| Status::InternalServerError)?;
|
||||||
|
|
||||||
|
|
||||||
|
lib::persist_file(&mut file, &id).await
|
||||||
|
.map_err(|_| Status::InternalServerError)?;
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[rocket::launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
rocket::build()
|
||||||
|
.attach(DbConn::fairing())
|
||||||
|
.mount("/", routes![test, upload, download])
|
||||||
|
}
|
7
src/schema.rs
Normal file
7
src/schema.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
table! {
|
||||||
|
uploads (id) {
|
||||||
|
id -> Text,
|
||||||
|
name -> Nullable<Text>,
|
||||||
|
created_at -> Nullable<Integer>,
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user