feat: blossom media uploads
fix: file extensions in URLs
This commit is contained in:
parent
bf19607c07
commit
a113056817
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@ -2016,6 +2016,12 @@ version = "0.3.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime2ext"
|
||||||
|
version = "0.1.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "515a63dc9666c865e848b043ab52fe9a5c713ae89cde4b5fbaae67cfd614b93a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -2989,6 +2995,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"mime2ext",
|
||||||
"nostr",
|
"nostr",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
@ -50,4 +50,5 @@ ffmpeg-rs-raw = { git = "https://git.v0l.io/Kieran/ffmpeg-rs-raw.git", rev = "df
|
|||||||
candle-core = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
candle-core = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
||||||
candle-nn = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
candle-nn = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
||||||
candle-transformers = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
candle-transformers = { git = "https://git.v0l.io/huggingface/candle.git", tag = "0.7.2", optional = true }
|
||||||
sqlx-postgres = { version = "0.8.2", optional = true, features = ["chrono", "uuid"] }
|
sqlx-postgres = { version = "0.8.2", optional = true, features = ["chrono", "uuid"] }
|
||||||
|
mime2ext = "0.1.53"
|
||||||
|
@ -34,7 +34,14 @@ impl BlobDescriptor {
|
|||||||
pub fn from_upload(settings: &Settings, value: &FileUpload) -> Self {
|
pub fn from_upload(settings: &Settings, value: &FileUpload) -> Self {
|
||||||
let id_hex = hex::encode(&value.id);
|
let id_hex = hex::encode(&value.id);
|
||||||
Self {
|
Self {
|
||||||
url: format!("{}/{}", settings.public_url, &id_hex),
|
url: format!(
|
||||||
|
"{}/{}{}",
|
||||||
|
settings.public_url,
|
||||||
|
&id_hex,
|
||||||
|
mime2ext::mime2ext(&value.mime_type)
|
||||||
|
.map(|m| format!(".{m}"))
|
||||||
|
.unwrap_or("".to_string())
|
||||||
|
),
|
||||||
sha256: id_hex,
|
sha256: id_hex,
|
||||||
size: value.size,
|
size: value.size,
|
||||||
mime_type: Some(value.mime_type.clone()),
|
mime_type: Some(value.mime_type.clone()),
|
||||||
|
@ -57,7 +57,14 @@ impl Nip94Event {
|
|||||||
let mut tags = vec![
|
let mut tags = vec![
|
||||||
vec![
|
vec![
|
||||||
"url".to_string(),
|
"url".to_string(),
|
||||||
format!("{}/{}", &settings.public_url, &hex_id),
|
format!(
|
||||||
|
"{}/{}{}",
|
||||||
|
&settings.public_url,
|
||||||
|
&hex_id,
|
||||||
|
mime2ext::mime2ext(&upload.mime_type)
|
||||||
|
.map(|m| format!(".{m}"))
|
||||||
|
.unwrap_or("".to_string())
|
||||||
|
),
|
||||||
],
|
],
|
||||||
vec!["x".to_string(), hex_id],
|
vec!["x".to_string(), hex_id],
|
||||||
vec!["m".to_string(), upload.mime_type.clone()],
|
vec!["m".to_string(), upload.mime_type.clone()],
|
||||||
|
@ -34,6 +34,22 @@ export class Blossom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async media(file: File) {
|
||||||
|
const hash = await window.crypto.subtle.digest(
|
||||||
|
"SHA-256",
|
||||||
|
await file.arrayBuffer(),
|
||||||
|
);
|
||||||
|
const tags = [["x", bytesToString("hex", new Uint8Array(hash))]];
|
||||||
|
|
||||||
|
const rsp = await this.#req("/media", "PUT", file, tags);
|
||||||
|
if (rsp.ok) {
|
||||||
|
return (await rsp.json()) as BlobDescriptor;
|
||||||
|
} else {
|
||||||
|
const text = await rsp.text();
|
||||||
|
throw new Error(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async #req(
|
async #req(
|
||||||
path: string,
|
path: string,
|
||||||
method: "GET" | "POST" | "DELETE" | "PUT",
|
method: "GET" | "POST" | "DELETE" | "PUT",
|
||||||
@ -42,7 +58,7 @@ export class Blossom {
|
|||||||
) {
|
) {
|
||||||
throwIfOffline();
|
throwIfOffline();
|
||||||
|
|
||||||
const url = `${this.url}upload`;
|
const url = `${this.url}${path}`;
|
||||||
const now = unixNow();
|
const now = unixNow();
|
||||||
const auth = async (url: string, method: string) => {
|
const auth = async (url: string, method: string) => {
|
||||||
const auth = await this.publisher.generic((eb) => {
|
const auth = await this.publisher.generic((eb) => {
|
||||||
|
@ -31,7 +31,7 @@ export default function Upload() {
|
|||||||
setError(undefined);
|
setError(undefined);
|
||||||
if (type === "blossom") {
|
if (type === "blossom") {
|
||||||
const uploader = new Blossom(url, pub);
|
const uploader = new Blossom(url, pub);
|
||||||
const result = await uploader.upload(toUpload);
|
const result = noCompress ? await uploader.upload(toUpload) : await uploader.media(toUpload);
|
||||||
setResults((s) => [...s, result]);
|
setResults((s) => [...s, result]);
|
||||||
}
|
}
|
||||||
if (type === "nip96") {
|
if (type === "nip96") {
|
||||||
@ -128,15 +128,13 @@ export default function Upload() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{type === "nip96" && (
|
<div
|
||||||
<div
|
className="flex gap-2 cursor-pointer"
|
||||||
className="flex gap-2 cursor-pointer"
|
onClick={() => setNoCompress((s) => !s)}
|
||||||
onClick={() => setNoCompress((s) => !s)}
|
>
|
||||||
>
|
Disable Compression
|
||||||
Disable Compression
|
<input type="checkbox" checked={noCompress} />
|
||||||
<input type="checkbox" checked={noCompress} />
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user