sdk: Add get_media_file function
This commit is contained in:
Generated
+1
@@ -2755,6 +2755,7 @@ dependencies = [
|
||||
"matrix-sdk-sled",
|
||||
"matrix-sdk-test",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
|
||||
@@ -176,6 +176,13 @@ interface Client {
|
||||
|
||||
[Throws=ClientError]
|
||||
void login(string username, string password, string? initial_device_name, string? device_id);
|
||||
|
||||
[Throws=ClientError]
|
||||
MediaFileHandle get_media_file(MediaSource source, string mime_type);
|
||||
};
|
||||
|
||||
interface MediaFileHandle {
|
||||
string path();
|
||||
};
|
||||
|
||||
enum MembershipState {
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock};
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use matrix_sdk::{
|
||||
media::{MediaFormat, MediaRequest, MediaThumbnailSize},
|
||||
media::{MediaFileHandle as SdkMediaFileHandle, MediaFormat, MediaRequest, MediaThumbnailSize},
|
||||
ruma::{
|
||||
api::client::{
|
||||
account::whoami,
|
||||
@@ -181,6 +181,29 @@ impl Client {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_media_file(
|
||||
&self,
|
||||
media_source: Arc<MediaSource>,
|
||||
mime_type: String,
|
||||
) -> anyhow::Result<Arc<MediaFileHandle>> {
|
||||
let client = self.client.clone();
|
||||
let source = (*media_source).clone();
|
||||
let mime_type: mime::Mime = mime_type.parse()?;
|
||||
|
||||
RUNTIME.block_on(async move {
|
||||
let handle = client
|
||||
.media()
|
||||
.get_media_file(
|
||||
&MediaRequest { source, format: MediaFormat::File },
|
||||
&mime_type,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Arc::new(MediaFileHandle { inner: handle }))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
@@ -617,3 +640,16 @@ pub struct Session {
|
||||
fn gen_transaction_id() -> String {
|
||||
TransactionId::new().to_string()
|
||||
}
|
||||
|
||||
/// A file handle that takes ownership of a media file on disk. When the handle
|
||||
/// is dropped, the file will be removed from the disk.
|
||||
pub struct MediaFileHandle {
|
||||
inner: SdkMediaFileHandle,
|
||||
}
|
||||
|
||||
impl MediaFileHandle {
|
||||
/// Get the media file's path.
|
||||
pub fn path(&self) -> String {
|
||||
self.inner.path().to_str().unwrap().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,6 +589,7 @@ pub struct AudioInfo {
|
||||
// for that
|
||||
pub duration: Option<u64>,
|
||||
pub size: Option<u64>,
|
||||
pub mimetype: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
@@ -681,6 +682,7 @@ impl From<&matrix_sdk::ruma::events::room::message::AudioInfo> for AudioInfo {
|
||||
Self {
|
||||
duration: info.duration.map(|d| d.as_millis() as u64),
|
||||
size: info.size.map(Into::into),
|
||||
mimetype: info.mimetype.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ matrix-sdk-common = { version = "0.6.0", path = "../matrix-sdk-common" }
|
||||
matrix-sdk-indexeddb = { version = "0.2.0", path = "../matrix-sdk-indexeddb", default-features = false, optional = true }
|
||||
matrix-sdk-sled = { version = "0.2.0", path = "../matrix-sdk-sled", default-features = false, optional = true }
|
||||
mime = "0.3.16"
|
||||
mime_guess = "2.0.4"
|
||||
pin-project-lite = "0.2.9"
|
||||
rand = { version = "0.8.5", optional = true }
|
||||
reqwest = { version = "0.11.10", default_features = false }
|
||||
@@ -94,6 +95,7 @@ ruma = { workspace = true, features = ["rand", "unstable-msc2448", "unstable-msc
|
||||
serde = { workspace = true }
|
||||
serde_html_form = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tempfile = "3.3.0"
|
||||
thiserror = { workspace = true }
|
||||
tower = { version = "0.4.13", features = ["make"], optional = true }
|
||||
tracing = { workspace = true, features = ["attributes"] }
|
||||
@@ -137,7 +139,6 @@ dirs = "4.0.0"
|
||||
futures = { version = "0.3.21", default-features = false, features = ["executor"] }
|
||||
matrix-sdk-test = { version = "0.6.0", path = "../../testing/matrix-sdk-test" }
|
||||
once_cell = { workspace = true }
|
||||
tempfile = "3.3.0"
|
||||
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
|
||||
@@ -17,16 +17,24 @@
|
||||
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
use std::io::Read;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
pub use matrix_sdk_base::media::*;
|
||||
use mime::Mime;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use mime_guess;
|
||||
use ruma::{
|
||||
api::client::media::{create_content, get_content, get_content_thumbnail},
|
||||
assign,
|
||||
events::room::MediaSource,
|
||||
MxcUri,
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use tempfile::{Builder as TempFileBuilder, NamedTempFile};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use tokio::{fs::File as TokioFile, io::AsyncWriteExt};
|
||||
|
||||
use crate::{
|
||||
attachment::{AttachmentInfo, Thumbnail},
|
||||
@@ -45,6 +53,23 @@ pub struct Media {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
/// A file handle that takes ownership of a media file on disk. When the handle
|
||||
/// is dropped, the file will be removed from the disk.
|
||||
#[derive(Debug)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub struct MediaFileHandle {
|
||||
/// The temporary file that contains the media.
|
||||
file: NamedTempFile,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
impl MediaFileHandle {
|
||||
/// Get the media file's path.
|
||||
pub fn path(&self) -> &Path {
|
||||
self.file.path()
|
||||
}
|
||||
}
|
||||
|
||||
impl Media {
|
||||
pub(crate) fn new(client: Client) -> Self {
|
||||
Self { client }
|
||||
@@ -96,6 +121,43 @@ impl Media {
|
||||
Ok(self.client.send(request, Some(request_config)).await?)
|
||||
}
|
||||
|
||||
/// Gets a media file by copying it to a temporary location on disk.
|
||||
///
|
||||
/// The file won't be encrypted even if it is encrypted on the server.
|
||||
///
|
||||
/// Returns a `MediaFileHandle` which takes ownership of the file. When the
|
||||
/// handle is dropped, the file will be deleted from the temporary location.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `request` - The `MediaRequest` of the content.
|
||||
///
|
||||
/// * `content_type` - The type of the media, this will be used to set the
|
||||
/// temporary file's extension.
|
||||
///
|
||||
/// * `use_cache` - If we should use the media cache for this request.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub async fn get_media_file(
|
||||
&self,
|
||||
request: &MediaRequest,
|
||||
content_type: &Mime,
|
||||
use_cache: bool,
|
||||
) -> Result<MediaFileHandle> {
|
||||
let data = self.get_media_content(request, use_cache).await?;
|
||||
|
||||
let mut suffix = String::from("");
|
||||
if let Some(extension) =
|
||||
mime_guess::get_mime_extensions(content_type).and_then(|a| a.first())
|
||||
{
|
||||
suffix = String::from(".") + extension;
|
||||
}
|
||||
|
||||
let file = TempFileBuilder::new().suffix(&suffix).tempfile()?;
|
||||
TokioFile::from_std(file.reopen()?).write_all(&data).await?;
|
||||
|
||||
Ok(MediaFileHandle { file })
|
||||
}
|
||||
|
||||
/// Get a media file's content.
|
||||
///
|
||||
/// If the content is encrypted and encryption is enabled, the content will
|
||||
|
||||
Reference in New Issue
Block a user