Alt support (nip98)
This commit is contained in:
parent
7fa2633a1e
commit
d41d561fdc
2
migrations/20240908152548_alt.sql
Normal file
2
migrations/20240908152548_alt.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
alter table uploads
|
||||||
|
add column alt varchar(512);
|
@ -13,6 +13,7 @@ pub struct FileUpload {
|
|||||||
pub width: Option<u32>,
|
pub width: Option<u32>,
|
||||||
pub height: Option<u32>,
|
pub height: Option<u32>,
|
||||||
pub blur_hash: Option<String>,
|
pub blur_hash: Option<String>,
|
||||||
|
pub alt: Option<String>,
|
||||||
|
|
||||||
#[sqlx(skip)]
|
#[sqlx(skip)]
|
||||||
#[cfg(feature = "labels")]
|
#[cfg(feature = "labels")]
|
||||||
@ -88,14 +89,15 @@ impl Database {
|
|||||||
pub async fn add_file(&self, file: &FileUpload, user_id: u64) -> Result<(), Error> {
|
pub async fn add_file(&self, file: &FileUpload, user_id: u64) -> Result<(), Error> {
|
||||||
let mut tx = self.pool.begin().await?;
|
let mut tx = self.pool.begin().await?;
|
||||||
let q = sqlx::query("insert ignore into \
|
let q = sqlx::query("insert ignore into \
|
||||||
uploads(id,name,size,mime_type,blur_hash,width,height) values(?,?,?,?,?,?,?)")
|
uploads(id,name,size,mime_type,blur_hash,width,height,alt) values(?,?,?,?,?,?,?,?)")
|
||||||
.bind(&file.id)
|
.bind(&file.id)
|
||||||
.bind(&file.name)
|
.bind(&file.name)
|
||||||
.bind(file.size)
|
.bind(file.size)
|
||||||
.bind(&file.mime_type)
|
.bind(&file.mime_type)
|
||||||
.bind(&file.blur_hash)
|
.bind(&file.blur_hash)
|
||||||
.bind(file.width)
|
.bind(file.width)
|
||||||
.bind(file.height);
|
.bind(file.height)
|
||||||
|
.bind(&file.alt);
|
||||||
tx.execute(q).await?;
|
tx.execute(q).await?;
|
||||||
|
|
||||||
let q2 = sqlx::query("insert ignore into user_uploads(file,user_id) values(?,?)")
|
let q2 = sqlx::query("insert ignore into user_uploads(file,user_id) values(?,?)")
|
||||||
|
@ -154,6 +154,7 @@ impl FileStore {
|
|||||||
#[cfg(feature = "labels")]
|
#[cfg(feature = "labels")]
|
||||||
labels,
|
labels,
|
||||||
created: Utc::now(),
|
created: Utc::now(),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use nostr::Timestamp;
|
use nostr::Timestamp;
|
||||||
use rocket::{FromForm, Responder, Route, routes, State};
|
|
||||||
use rocket::data::ToByteUnit;
|
use rocket::data::ToByteUnit;
|
||||||
use rocket::form::Form;
|
use rocket::form::Form;
|
||||||
use rocket::fs::TempFile;
|
use rocket::fs::TempFile;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use rocket::serde::Serialize;
|
use rocket::serde::Serialize;
|
||||||
|
use rocket::{routes, FromForm, Responder, Route, State};
|
||||||
|
|
||||||
use crate::auth::nip98::Nip98Auth;
|
use crate::auth::nip98::Nip98Auth;
|
||||||
use crate::db::{Database, FileUpload};
|
use crate::db::{Database, FileUpload};
|
||||||
@ -227,15 +227,11 @@ async fn upload(
|
|||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(e) => return Nip96Response::error(&format!("Could not open file: {}", e)),
|
Err(e) => return Nip96Response::error(&format!("Could not open file: {}", e)),
|
||||||
};
|
};
|
||||||
let mime_type = form.media_type
|
let mime_type = form.media_type.unwrap_or("application/octet-stream");
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
|
|
||||||
if form.expiration.is_some() {
|
if form.expiration.is_some() {
|
||||||
return Nip96Response::error("Expiration not supported");
|
return Nip96Response::error("Expiration not supported");
|
||||||
}
|
}
|
||||||
if form.alt.is_some() {
|
|
||||||
return Nip96Response::error("\"alt\" is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// account for upload speeds as slow as 1MB/s (8 Mbps)
|
// account for upload speeds as slow as 1MB/s (8 Mbps)
|
||||||
let mbs = form.size / 1.megabytes().as_u64() as usize;
|
let mbs = form.size / 1.megabytes().as_u64() as usize;
|
||||||
@ -259,16 +255,25 @@ async fn upload(
|
|||||||
Some(c) => c.to_string(),
|
Some(c) => c.to_string(),
|
||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
};
|
};
|
||||||
|
blob.upload.alt = match &form.alt {
|
||||||
|
Some(s) => Some(s.to_string()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
||||||
if let Some(wh) = webhook.as_ref() {
|
if let Some(wh) = webhook.as_ref() {
|
||||||
match wh.store_file(&pubkey_vec, blob.clone()) {
|
match wh.store_file(&pubkey_vec, blob.clone()) {
|
||||||
Ok(store) => if !store {
|
Ok(store) => {
|
||||||
let _ = fs::remove_file(blob.path);
|
if !store {
|
||||||
return Nip96Response::error("Upload rejected");
|
let _ = fs::remove_file(blob.path);
|
||||||
|
return Nip96Response::error("Upload rejected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = fs::remove_file(blob.path);
|
let _ = fs::remove_file(blob.path);
|
||||||
return Nip96Response::error(&format!("Internal error, failed to call webhook: {}", e));
|
return Nip96Response::error(&format!(
|
||||||
|
"Internal error, failed to call webhook: {}",
|
||||||
|
e
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +295,10 @@ async fn upload(
|
|||||||
return Nip96Response::error(&format!("Could not save file (db): {}", e));
|
return Nip96Response::error(&format!("Could not save file (db): {}", e));
|
||||||
}
|
}
|
||||||
|
|
||||||
Nip96Response::UploadResult(Json(Nip96UploadResult::from_upload(settings, &blob.upload)))
|
Nip96Response::UploadResult(Json(Nip96UploadResult::from_upload(
|
||||||
|
settings,
|
||||||
|
&blob.upload,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("{}", e.to_string());
|
error!("{}", e.to_string());
|
||||||
@ -312,7 +320,6 @@ async fn delete(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[rocket::get("/n96?<page>&<count>")]
|
#[rocket::get("/n96?<page>&<count>")]
|
||||||
async fn list_files(
|
async fn list_files(
|
||||||
auth: Nip98Auth,
|
auth: Nip98Auth,
|
||||||
@ -323,17 +330,23 @@ async fn list_files(
|
|||||||
) -> Nip96Response {
|
) -> Nip96Response {
|
||||||
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
||||||
let server_count = count.min(5_000).max(1);
|
let server_count = count.min(5_000).max(1);
|
||||||
match db.list_files(&pubkey_vec, page * server_count, server_count).await {
|
match db
|
||||||
|
.list_files(&pubkey_vec, page * server_count, server_count)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok((files, total)) => Nip96Response::FileList(Json(Nip96FileListResults {
|
Ok((files, total)) => Nip96Response::FileList(Json(Nip96FileListResults {
|
||||||
count: server_count,
|
count: server_count,
|
||||||
page,
|
page,
|
||||||
total: total as u32,
|
total: total as u32,
|
||||||
files: files
|
files: files
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| Nip96UploadResult::from_upload(settings, f).nip94_event.unwrap())
|
.map(|f| {
|
||||||
|
Nip96UploadResult::from_upload(settings, f)
|
||||||
|
.nip94_event
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
})),
|
||||||
)),
|
|
||||||
Err(e) => Nip96Response::error(&format!("Could not list files: {}", e)),
|
Err(e) => Nip96Response::error(&format!("Could not list files: {}", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user