tuwunel_service/admin/
attach.rs1use ruma::{
2 Mxc,
3 events::room::{
4 MediaSource,
5 message::{FileInfo, FileMessageEventContent, MessageType, RoomMessageEventContent},
6 },
7};
8use tuwunel_core::{
9 Result, implement,
10 utils::{
11 content_disposition::make_content_disposition, math::ruma_from_usize, random_string,
12 time::now_secs,
13 },
14};
15
16use super::CommandOutput;
17use crate::media::MXC_LENGTH;
18
19#[implement(super::Service)]
22pub(super) async fn attach(&self, output: &CommandOutput) -> Result<RoomMessageEventContent> {
23 let (mime, ext) = match output {
24 | CommandOutput::Markdown(_) => ("text/markdown", "md"),
25 | CommandOutput::Plain(_) => ("text/plain", "txt"),
26 };
27
28 let text = output.as_str();
29 let filename = format!("admin-output-{}.{ext}", now_secs());
30 let media_id = random_string(MXC_LENGTH);
31 let mxc = Mxc {
32 server_name: self.services.globals.server_name(),
33 media_id: &media_id,
34 };
35
36 let content_disposition = make_content_disposition(None, Some(mime), Some(&filename));
37
38 self.services
39 .media
40 .create(
41 &mxc,
42 Some(&self.services.globals.server_user),
43 Some(&content_disposition),
44 Some(mime),
45 text.as_bytes(),
46 )
47 .await?;
48
49 let file = FileMessageEventContent {
50 body: filename.clone(),
51 formatted: None,
52 filename: Some(filename),
53 source: MediaSource::Plain(mxc.to_string().into()),
54 info: Some(Box::new(FileInfo {
55 mimetype: Some(mime.to_owned()),
56 size: Some(ruma_from_usize(text.len())),
57 ..Default::default()
58 })),
59 };
60
61 Ok(RoomMessageEventContent::new(MessageType::File(file)))
62}