From b0571efcb32ed3ed5b0683f11c87fac2bbc0f9bc Mon Sep 17 00:00:00 2001 From: kieran Date: Mon, 16 Dec 2024 13:34:30 +0000 Subject: [PATCH] feat: serve legacy void.cat uploads --- config.yaml | 5 ++++- src/bin/void_cat_migrate.rs | 11 +++++++---- src/lib.rs | 1 + src/routes/mod.rs | 30 +++++++++++++----------------- src/settings.rs | 3 +++ src/void_db.rs | 37 +------------------------------------ src/void_file.rs | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 66 insertions(+), 58 deletions(-) create mode 100644 src/void_file.rs diff --git a/config.yaml b/config.yaml index d1e7a1a..e55bd69 100644 --- a/config.yaml +++ b/config.yaml @@ -28,4 +28,7 @@ vit_model: # plausible_url: "https://plausible.com/" # Support legacy void -# void_cat_database: "postgres://postgres:postgres@localhost:41911/void" \ No newline at end of file +# void_cat_database: "postgres://postgres:postgres@localhost:41911/void" + +# Legacy file path for void.cat uploads +# void_cat_files: "/my/void.cat/data" \ No newline at end of file diff --git a/src/bin/void_cat_migrate.rs b/src/bin/void_cat_migrate.rs index 2c24edc..0a4dfb3 100644 --- a/src/bin/void_cat_migrate.rs +++ b/src/bin/void_cat_migrate.rs @@ -6,7 +6,8 @@ use nostr::bitcoin::base58; use route96::db::{Database, FileUpload}; use route96::filesystem::FileStore; use route96::settings::Settings; -use route96::void_db::{VoidCatDb, VoidFile}; +use route96::void_db::VoidCatDb; +use route96::void_file::VoidFile; use std::path::PathBuf; use tokio::io::{AsyncWriteExt, BufWriter}; @@ -54,7 +55,7 @@ async fn main() -> Result<(), Error> { let mut page = 0; loop { let files = db_void.list_files(page).await?; - if files.len() == 0 { + if files.is_empty() { break; } for f in files { @@ -73,7 +74,7 @@ async fn main() -> Result<(), Error> { let mut page = 0; loop { let files = db_void.list_files(page).await?; - if files.len() == 0 { + if files.is_empty() { break; } for f in files { @@ -99,7 +100,9 @@ async fn migrate_file( let id_vec = hex::decode(&f.digest)?; // copy file - let src_path = PathBuf::new().join(&args.data_path).join(f.map_to_path()); + let src_path = PathBuf::new() + .join(&args.data_path) + .join(VoidFile::map_to_path(&f.id)); let dst_path = fs.map_path(&id_vec); if src_path.exists() && !dst_path.exists() { info!( diff --git a/src/lib.rs b/src/lib.rs index 4f3947f..57ac69d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,4 +10,5 @@ pub mod routes; pub mod settings; #[cfg(any(feature = "void-cat-redirects", feature = "bin-void-cat-migrate"))] pub mod void_db; +pub mod void_file; pub mod webhook; diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 6819b8d..0e0fa59 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -6,16 +6,13 @@ pub use crate::routes::blossom::blossom_routes; #[cfg(feature = "nip96")] pub use crate::routes::nip96::nip96_routes; use crate::settings::Settings; -#[cfg(feature = "void-cat-redirects")] -use crate::void_db::VoidCatDb; +use crate::void_file::VoidFile; use anyhow::Error; use http_range_header::{parse_range_header, EndPosition, StartPosition}; use log::warn; use nostr::Event; use rocket::fs::NamedFile; use rocket::http::{ContentType, Header, Status}; -#[cfg(feature = "void-cat-redirects")] -use rocket::response::Redirect; use rocket::response::Responder; use rocket::serde::Serialize; use rocket::{Request, Response, State}; @@ -355,25 +352,24 @@ pub async fn head_blob(sha256: &str, fs: &State) -> Status { } } -#[cfg(feature = "void-cat-redirects")] +/// Legacy URL redirect for void.cat uploads #[rocket::get("/d/")] -pub async fn void_cat_redirect( - id: &str, - settings: &State, - vdb: &State, -) -> Option { +pub async fn void_cat_redirect(id: &str, settings: &State) -> Option { let id = if id.contains(".") { id.split('.').next().unwrap() } else { id }; - let uuid = - uuid::Uuid::from_slice_le(nostr::bitcoin::base58::decode(id).unwrap().as_slice()).unwrap(); - if let Ok(Some(d)) = vdb.get_digest(&uuid).await { - Some(Redirect::permanent(format!( - "{}/{}", - &settings.public_url, &d - ))) + if let Some(base) = &settings.void_cat_files { + let uuid = + uuid::Uuid::from_slice_le(nostr::bitcoin::base58::decode(id).unwrap().as_slice()) + .unwrap(); + let f = base.join(VoidFile::map_to_path(&uuid)); + if let Ok(f) = NamedFile::open(f).await { + Some(f) + } else { + None + } } else { None } diff --git a/src/settings.rs b/src/settings.rs index f369847..bb6abce 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -32,6 +32,9 @@ pub struct Settings { #[cfg(feature = "void-cat-redirects")] pub void_cat_database: Option, + + /// Path to void.cat uploads (files-v2) + pub void_cat_files: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/void_db.rs b/src/void_db.rs index 538a247..a06522c 100644 --- a/src/void_db.rs +++ b/src/void_db.rs @@ -1,42 +1,7 @@ -use chrono::{DateTime, Utc}; -use sqlx::FromRow; +use crate::void_file::VoidFile; use sqlx_postgres::{PgPool, PgPoolOptions}; -use std::path::PathBuf; use uuid::Uuid; -#[derive(FromRow)] -pub struct VoidFile { - #[sqlx(rename = "Id")] - pub id: Uuid, - #[sqlx(rename = "Name")] - pub name: Option, - #[sqlx(rename = "Size")] - pub size: i64, - #[sqlx(rename = "Uploaded")] - pub uploaded: DateTime, - #[sqlx(rename = "Description")] - pub description: Option, - #[sqlx(rename = "MimeType")] - pub mime_type: String, - #[sqlx(rename = "Digest")] - pub digest: String, - #[sqlx(rename = "MediaDimensions")] - pub media_dimensions: Option, - #[sqlx(rename = "Email")] - pub email: String, -} - -impl VoidFile { - pub fn map_to_path(&self) -> PathBuf { - let id_str = self.id.as_hyphenated().to_string(); - PathBuf::new() - .join("files-v2/") - .join(&id_str[..2]) - .join(&id_str[2..4]) - .join(&id_str) - } -} - pub struct VoidCatDb { pub pool: PgPool, } diff --git a/src/void_file.rs b/src/void_file.rs new file mode 100644 index 0000000..f67fbd8 --- /dev/null +++ b/src/void_file.rs @@ -0,0 +1,37 @@ +use chrono::{DateTime, Utc}; +use sqlx::FromRow; +use std::path::PathBuf; +use uuid::Uuid; + +#[derive(FromRow)] +pub struct VoidFile { + #[sqlx(rename = "Id")] + pub id: Uuid, + #[sqlx(rename = "Name")] + pub name: Option, + #[sqlx(rename = "Size")] + pub size: i64, + #[sqlx(rename = "Uploaded")] + pub uploaded: DateTime, + #[sqlx(rename = "Description")] + pub description: Option, + #[sqlx(rename = "MimeType")] + pub mime_type: String, + #[sqlx(rename = "Digest")] + pub digest: String, + #[sqlx(rename = "MediaDimensions")] + pub media_dimensions: Option, + #[sqlx(rename = "Email")] + pub email: String, +} + +impl VoidFile { + pub fn map_to_path(id: &Uuid) -> PathBuf { + let id_str = id.as_hyphenated().to_string(); + PathBuf::new() + .join("files-v2/") + .join(&id_str[..2]) + .join(&id_str[2..4]) + .join(&id_str) + } +}