ruma_federation_api/authenticated_media/
get_content_thumbnail.rs

1//! `GET /_matrix/federation/*/media/thumbnail/{mediaId}`
2//!
3//! Get a thumbnail of content from the media repository.
4
5pub mod v1 {
6    //! `/v1/` ([spec])
7    //!
8    //! [spec]: https://spec.matrix.org/latest/server-server-api/#get_matrixfederationv1mediathumbnailmediaid
9
10    use std::time::Duration;
11
12    use js_int::UInt;
13    use ruma_common::{
14        api::{request, Metadata},
15        media::Method,
16        metadata,
17    };
18
19    use crate::authenticated_media::{ContentMetadata, FileOrLocation};
20
21    const METADATA: Metadata = metadata! {
22        method: GET,
23        rate_limited: true,
24        authentication: ServerSignatures,
25        history: {
26            unstable => "/_matrix/federation/unstable/org.matrix.msc3916.v2/media/thumbnail/:media_id",
27            1.11 => "/_matrix/federation/v1/media/thumbnail/:media_id",
28        }
29    };
30
31    /// Request type for the `get_content_thumbnail` endpoint.
32    #[request]
33    pub struct Request {
34        /// The media ID from the `mxc://` URI (the path component).
35        #[ruma_api(path)]
36        pub media_id: String,
37
38        /// The desired resizing method.
39        #[ruma_api(query)]
40        #[serde(skip_serializing_if = "Option::is_none")]
41        pub method: Option<Method>,
42
43        /// The *desired* width of the thumbnail.
44        ///
45        /// The actual thumbnail may not match the size specified.
46        #[ruma_api(query)]
47        pub width: UInt,
48
49        /// The *desired* height of the thumbnail.
50        ///
51        /// The actual thumbnail may not match the size specified.
52        #[ruma_api(query)]
53        pub height: UInt,
54
55        /// The maximum duration that the client is willing to wait to start receiving data, in the
56        /// case that the content has not yet been uploaded.
57        ///
58        /// The default value is 20 seconds.
59        #[ruma_api(query)]
60        #[serde(
61            with = "ruma_common::serde::duration::ms",
62            default = "ruma_common::media::default_download_timeout",
63            skip_serializing_if = "ruma_common::media::is_default_download_timeout"
64        )]
65        pub timeout_ms: Duration,
66
67        /// Whether the server should return an animated thumbnail.
68        ///
69        /// When `Some(true)`, the server should return an animated thumbnail if possible and
70        /// supported. When `Some(false)`, the server must not return an animated
71        /// thumbnail. When `None`, the server should not return an animated thumbnail.
72        #[ruma_api(query)]
73        #[serde(skip_serializing_if = "Option::is_none")]
74        pub animated: Option<bool>,
75    }
76
77    impl Request {
78        /// Creates a new `Request` with the given media ID, desired thumbnail width
79        /// and desired thumbnail height.
80        pub fn new(media_id: String, width: UInt, height: UInt) -> Self {
81            Self {
82                media_id,
83                method: None,
84                width,
85                height,
86                timeout_ms: ruma_common::media::default_download_timeout(),
87                animated: None,
88            }
89        }
90    }
91
92    /// Response type for the `get_content_thumbnail` endpoint.
93    #[derive(Debug, Clone)]
94    #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
95    pub struct Response {
96        /// The metadata of the thumbnail.
97        pub metadata: ContentMetadata,
98
99        /// The content of the thumbnail.
100        pub content: FileOrLocation,
101    }
102
103    impl Response {
104        /// Creates a new `Response` with the given metadata and content.
105        pub fn new(metadata: ContentMetadata, content: FileOrLocation) -> Self {
106            Self { metadata, content }
107        }
108    }
109
110    #[cfg(feature = "client")]
111    impl ruma_common::api::IncomingResponse for Response {
112        type EndpointError = ruma_common::api::error::MatrixError;
113
114        fn try_from_http_response<T: AsRef<[u8]>>(
115            http_response: http::Response<T>,
116        ) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
117        {
118            use ruma_common::api::EndpointError;
119
120            if http_response.status().as_u16() < 400 {
121                let (metadata, content) =
122                    crate::authenticated_media::try_from_multipart_mixed_response(http_response)?;
123                Ok(Self { metadata, content })
124            } else {
125                Err(ruma_common::api::error::FromHttpResponseError::Server(
126                    ruma_common::api::error::MatrixError::from_http_response(http_response),
127                ))
128            }
129        }
130    }
131
132    #[cfg(feature = "server")]
133    impl ruma_common::api::OutgoingResponse for Response {
134        fn try_into_http_response<T: Default + bytes::BufMut>(
135            self,
136        ) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
137            crate::authenticated_media::try_into_multipart_mixed_response(
138                &self.metadata,
139                &self.content,
140            )
141        }
142    }
143}