ruma_client_api/authenticated_media/get_content_thumbnail.rs
1//! `GET /_matrix/client/*/media/thumbnail/{serverName}/{mediaId}`
2//!
3//! Get a thumbnail of content from the media store.
4
5pub mod v1 {
6 //! `/v1/` ([spec])
7 //!
8 //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid
9
10 use std::time::Duration;
11
12 use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE};
13 use js_int::UInt;
14 use ruma_common::{
15 api::{request, response, Metadata},
16 http_headers::ContentDisposition,
17 media::Method,
18 metadata, IdParseError, MxcUri, OwnedServerName,
19 };
20
21 const METADATA: Metadata = metadata! {
22 method: GET,
23 rate_limited: true,
24 authentication: AccessToken,
25 history: {
26 unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/thumbnail/:server_name/:media_id",
27 1.11 => "/_matrix/client/v1/media/thumbnail/:server_name/:media_id",
28 }
29 };
30
31 /// Request type for the `get_content_thumbnail` endpoint.
32 #[request(error = crate::Error)]
33 pub struct Request {
34 /// The server name from the mxc:// URI (the authoritory component).
35 #[ruma_api(path)]
36 pub server_name: OwnedServerName,
37
38 /// The media ID from the mxc:// URI (the path component).
39 #[ruma_api(path)]
40 pub media_id: String,
41
42 /// The desired resizing method.
43 #[ruma_api(query)]
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub method: Option<Method>,
46
47 /// The *desired* width of the thumbnail.
48 ///
49 /// The actual thumbnail may not match the size specified.
50 #[ruma_api(query)]
51 pub width: UInt,
52
53 /// The *desired* height of the thumbnail.
54 ///
55 /// The actual thumbnail may not match the size specified.
56 #[ruma_api(query)]
57 pub height: UInt,
58
59 /// The maximum duration that the client is willing to wait to start receiving data, in the
60 /// case that the content has not yet been uploaded.
61 ///
62 /// The default value is 20 seconds.
63 #[ruma_api(query)]
64 #[serde(
65 with = "ruma_common::serde::duration::ms",
66 default = "ruma_common::media::default_download_timeout",
67 skip_serializing_if = "ruma_common::media::is_default_download_timeout"
68 )]
69 pub timeout_ms: Duration,
70
71 /// Whether the server should return an animated thumbnail.
72 ///
73 /// When `Some(true)`, the server should return an animated thumbnail if possible and
74 /// supported. When `Some(false)`, the server must not return an animated
75 /// thumbnail. When `None`, the server should not return an animated thumbnail.
76 #[ruma_api(query)]
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub animated: Option<bool>,
79 }
80
81 /// Response type for the `get_content_thumbnail` endpoint.
82 #[response(error = crate::Error)]
83 pub struct Response {
84 /// A thumbnail of the requested content.
85 #[ruma_api(raw_body)]
86 pub file: Vec<u8>,
87
88 /// The content type of the thumbnail.
89 #[ruma_api(header = CONTENT_TYPE)]
90 pub content_type: Option<String>,
91
92 /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
93 /// file that was previously uploaded.
94 ///
95 /// See [MDN] for the syntax.
96 ///
97 /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
98 #[ruma_api(header = CONTENT_DISPOSITION)]
99 pub content_disposition: Option<ContentDisposition>,
100 }
101
102 impl Request {
103 /// Creates a new `Request` with the given media ID, server name, desired thumbnail width
104 /// and desired thumbnail height.
105 pub fn new(
106 media_id: String,
107 server_name: OwnedServerName,
108 width: UInt,
109 height: UInt,
110 ) -> Self {
111 Self {
112 media_id,
113 server_name,
114 method: None,
115 width,
116 height,
117 timeout_ms: ruma_common::media::default_download_timeout(),
118 animated: None,
119 }
120 }
121
122 /// Creates a new `Request` with the given URI, desired thumbnail width and
123 /// desired thumbnail height.
124 pub fn from_uri(uri: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
125 let (server_name, media_id) = uri.parts()?;
126
127 Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height))
128 }
129 }
130
131 impl Response {
132 /// Creates a new `Response` with the given thumbnail.
133 pub fn new(
134 file: Vec<u8>,
135 content_type: String,
136 content_disposition: ContentDisposition,
137 ) -> Self {
138 Self {
139 file,
140 content_type: Some(content_type),
141 content_disposition: Some(content_disposition),
142 }
143 }
144 }
145}