start implementing images

This commit is contained in:
SadlyNotSappho 2024-02-20 11:56:18 -08:00
parent 3fc9ea19eb
commit 951372a60a
5 changed files with 117 additions and 1 deletions

10
Cargo.lock generated
View File

@ -525,6 +525,7 @@ dependencies = [
"rocket_db_pools",
"sha256",
"sqlx",
"uuid",
]
[[package]]
@ -2425,6 +2426,15 @@ version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "uuid"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
]
[[package]]
name = "valuable"
version = "0.1.0"

View File

@ -14,4 +14,5 @@ rocket = {version="0.5.0",features=["secrets","json"]}
rocket_db_pools = {version="0.1.0",features=["sqlx_postgres"]}
sha256 = "1.5.0"
sqlx = { version = "0.7.3", features = ["macros", "postgres"] }
uuid = { version = "1.7.0", features = ["v4"] }
# rocket_sync_db_pools = { version = "0.1.0", features = ["diesel_postgres_pool", "diesel"] }

14
imagesplan.txt Normal file
View File

@ -0,0 +1,14 @@
GET /images/uuid.filetype
-> returns the image with the correct filetype - uuid.png would return the image in png format, etc
GET /images/by-user {user: "username"}
-> gets all of the images made by {user}, if you are {user}, unless you have admin.
POST /images/create {image: "image data"}
-> returns the uuid of the image, which it saves to the folder and database
DELETE /images/uuid
-> if you're the owner of the image or an admin, deletes the image. returns basic success/faliure
images are stored in /images/uuid.png. Image::get_by_uuid(uuid) just gets the image from the folder, verifies that it is an image, and returns it. Image::get_by_username(username) gets all database images from the database and returns the uuids. the client is responsible for getting the images.

View File

@ -347,6 +347,12 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
))
.await;
let _ = conn.execute(sqlx::query(
"ALTER TABLE images
DELETE COLUMN IF EXISTS image"
))
.await;
rocket
}

View File

@ -1,6 +1,7 @@
use base64::{engine::general_purpose, Engine};
use rand::{RngCore, SeedableRng};
use regex::Regex;
use rocket::fs::TempFile;
use rocket::http::Cookie;
use rocket_db_pools::sqlx::Executor;
use rocket_db_pools::Connection;
@ -236,5 +237,89 @@ pub struct Image {
pub id: i32,
pub uuid: String,
pub owner_name: String,
pub image: String,
}
impl Image {
pub async fn create(db: &mut Connection<Db>, mut image: TempFile<'_>, user: User) -> Status<String> {
let uuid = uuid::Uuid::new_v4().to_string();
// this is bad. see any of maia arson crimew's articles as to why.
image.persist_to(format!("/images/{uuid}.png")).await.unwrap();
match db
.execute(
sqlx::query(
r#"
INSERT INTO images (uuid, owner_name)
VALUES ($1, $2,);
"#,
)
.bind(uuid)
.bind(user.username),
)
.await
{
Ok(_) => Status {
status: StatusTypes::Success,
data: "Created image successfully.".to_string()
},
Err(why) => {
eprintln!("Couldn't create database entry: {why:?}");
Status {
status: StatusTypes::Faliure,
data: "Couldn't create image.".to_string()
}
}
}
}
pub async fn get_by_uuid(db: &mut Connection<Db>, uuid: &String) -> Result<Image, String> {
match db
.fetch_one(sqlx::query("SELECT * FROM images WHERE uuid = $1;").bind(uuid))
.await
{
Ok(img) => Ok(Image {
id: img.get::<i32, _>("id"),
uuid: img.get::<String, _>("uuid"),
owner_name: img.get::<String, _>("owner_name"),
}),
Err(_) => Err("Couldn't get image.".to_string()),
}
}
pub async fn get_by_username(db: &mut Connection<Db>, owner_name: &String) -> Result<Vec<Image>, String> {
match db
.fetch_all(sqlx::query("SELECT * FROM images WHERE owner_name = $1;").bind(owner_name))
.await
{
Ok(imgs) => {
let mut res = vec![];
for img in imgs {
res.push(Image {
id: img.get::<i32, _>("id"),
uuid: img.get::<String, _>("uuid"),
owner_name: img.get::<String, _>("owner_name"),
})
}
Ok(res)
},
Err(_) => Err("Couldn't get image.".to_string()),
}
}
pub async fn delete(db: &mut Connection<Db>, uuid: &String) -> Status<String> {
match db.execute(sqlx::query("DELETE FROM images WHERE uuid = $1").bind(uuid)).await {
Ok(rows_gone) => {
eprintln!("Deleted {rows_gone:?} rows.");
Status {
status: StatusTypes::Success,
data: "Successfully deleted the image.".to_string()
}
},
Err(why) => {
eprintln!("Couldn't remove database entry: {why:?}");
Status {
status: StatusTypes::Faliure,
data: "Couldn't delete the image.".to_string()
}
}
}
}
}