uploads: centralise via ChatHubApi::save_upload, refactor handlers
Nightly Build / build (push) Successful in 6m41s
Nightly Build / build (push) Successful in 6m41s
Extract shared upload seam in skald-core, move Telegram and web handlers to use it. Simplify media attachment routing. Clean up unused deps and dead code.
This commit is contained in:
@@ -5,7 +5,7 @@ use tokio::sync::broadcast;
|
||||
|
||||
use crate::events::GlobalEvent;
|
||||
use crate::interface_tool::InterfaceTool;
|
||||
use crate::message_meta::MessageMetadata;
|
||||
use crate::message_meta::{Attachment, MessageMetadata};
|
||||
|
||||
// ── SendMessageOptions ────────────────────────────────────────────────────────
|
||||
|
||||
@@ -59,6 +59,20 @@ pub trait ChatHubApi: Send + Sync {
|
||||
opts: SendMessageOptions,
|
||||
) -> anyhow::Result<()>;
|
||||
|
||||
/// Persist an uploaded file for `source_id` into the owner's
|
||||
/// `~/uploads/{session}/` and return its [`Attachment`] (home-relative agent
|
||||
/// path). Channel adapters (e.g. the Telegram plugin) call this instead of
|
||||
/// writing files themselves, so the core owns *where* uploads land and every
|
||||
/// surface produces a path the agent can actually reach. The recognized
|
||||
/// magic-byte MIME wins over the caller-claimed `client_mime`.
|
||||
async fn save_upload(
|
||||
&self,
|
||||
source_id: &str,
|
||||
file_name: &str,
|
||||
client_mime: Option<String>,
|
||||
bytes: &[u8],
|
||||
) -> anyhow::Result<Attachment>;
|
||||
|
||||
/// Create a new session for the source, discarding the previous one.
|
||||
async fn clear(&self, source_id: &str) -> anyhow::Result<i64>;
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// One file attached by the user to a message. `path` is relative to the project
|
||||
/// root (e.g. `data/uploads/123/file.pdf`) so it is both servable under `/data/…`
|
||||
/// and resolvable by the filesystem tools.
|
||||
/// One file attached by the user to a message. `path` is a home-relative agent
|
||||
/// path (e.g. `uploads/123/file.pdf`) — the caller's container home is its root,
|
||||
/// so the fs-tools, `execute_cmd`, the file viewer (`/api/file`) and the media
|
||||
/// inliner all resolve it to the same physical file.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Attachment {
|
||||
pub path: String,
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
/// The subdirectory of a user's home where chat uploads are saved
|
||||
/// (`{home}/uploads/{session_id}/…`, reachable by the agent as `uploads/…`).
|
||||
/// Shared by the upload handler (write path) and the media inliner (containment
|
||||
/// root) so the two anchors can never drift.
|
||||
pub const UPLOADS_SUBDIR: &str = "uploads";
|
||||
|
||||
/// One shared folder mounted into a user's container.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SharedMount {
|
||||
|
||||
Reference in New Issue
Block a user