libQuotient
A Qt library for building matrix clients
content-repo.h
Go to the documentation of this file.
1 // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 
3 #pragma once
4 
5 #include <Quotient/jobs/basejob.h>
6 
7 #include <QtCore/QIODevice>
8 #include <QtNetwork/QNetworkReply>
9 
10 namespace Quotient {
11 
12 //! \brief Upload some content to the content repository.
13 class QUOTIENT_API UploadContentJob : public BaseJob {
14 public:
15  //!
16  //! \param filename
17  //! The name of the file being uploaded
18  //!
19  //! \param contentType
20  //! **Optional.** The content type of the file being uploaded.
21  //!
22  //! Clients SHOULD always supply this header.
23  //!
24  //! Defaults to `application/octet-stream` if it is not set.
25  explicit UploadContentJob(QIODevice* content, const QString& filename = {},
26  const QString& contentType = {});
27 
28  // Result properties
29 
30  //! The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to the uploaded content.
31  QUrl contentUri() const { return loadFromJson<QUrl>("content_uri"_L1); }
32 };
33 
34 inline auto collectResponse(const UploadContentJob* job) { return job->contentUri(); }
35 
36 //! \brief Upload content to an `mxc://` URI that was created earlier.
37 //!
38 //! This endpoint permits uploading content to an `mxc://` URI that was created
39 //! earlier via [POST /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create).
40 class QUOTIENT_API UploadContentToMXCJob : public BaseJob {
41 public:
42  //! \param serverName
43  //! The server name from the `mxc://` URI (the authority component).
44  //!
45  //! \param mediaId
46  //! The media ID from the `mxc://` URI (the path component).
47  //!
48  //!
49  //! \param filename
50  //! The name of the file being uploaded
51  //!
52  //! \param contentType
53  //! **Optional.** The content type of the file being uploaded.
54  //!
55  //! Clients SHOULD always supply this header.
56  //!
57  //! Defaults to `application/octet-stream` if it is not set.
58  explicit UploadContentToMXCJob(const QString& serverName, const QString& mediaId,
59  QIODevice* content, const QString& filename = {},
60  const QString& contentType = {});
61 };
62 
63 //! \brief Create a new `mxc://` URI without uploading the content.
64 //!
65 //! Creates a new `mxc://` URI, independently of the content being uploaded. The content must be
66 //! provided later via [`PUT
67 //! /_matrix/media/v3/upload/{serverName}/{mediaId}`](/client-server-api/#put_matrixmediav3uploadservernamemediaid).
68 //!
69 //! The server may optionally enforce a maximum age for unused IDs,
70 //! and delete media IDs when the client doesn't start the upload in time,
71 //! or when the upload was interrupted and not resumed in time. The server
72 //! should include the maximum POSIX millisecond timestamp to complete the
73 //! upload in the `unused_expires_at` field in the response JSON. The
74 //! recommended default expiration is 24 hours which should be enough time
75 //! to accommodate users on poor connection who find a better connection to
76 //! complete the upload.
77 //!
78 //! As well as limiting the rate of requests to create `mxc://` URIs, the server
79 //! should limit the number of concurrent *pending media uploads* a given
80 //! user can have. A pending media upload is a created `mxc://` URI where (a)
81 //! the media has not yet been uploaded, and (b) has not yet expired (the
82 //! `unused_expires_at` timestamp has not yet passed). In both cases, the
83 //! server should respond with an HTTP 429 error with an errcode of
84 //! `M_LIMIT_EXCEEDED`.
85 class QUOTIENT_API CreateContentJob : public BaseJob {
86 public:
87  explicit CreateContentJob();
88 
89  //! \brief Construct a URL without creating a full-fledged job object
90  //!
91  //! This function can be used when a URL for CreateContentJob
92  //! is necessary but the job itself isn't.
93  static QUrl makeRequestUrl(const HomeserverData& hsData);
94 
95  // Result properties
96 
97  //! The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at
98  //! which the content will be available, once it is uploaded.
99  QUrl contentUri() const { return loadFromJson<QUrl>("content_uri"_L1); }
100 
101  //! The timestamp (in milliseconds since the unix epoch) when the
102  //! generated media id will expire, if media is not uploaded.
103  std::optional<qint64> unusedExpiresAt() const
104  {
105  return loadFromJson<std::optional<qint64>>("unused_expires_at"_L1);
106  }
107 
108  struct Response {
109  //! The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at
110  //! which the content will be available, once it is uploaded.
111  QUrl contentUri{};
112 
113  //! The timestamp (in milliseconds since the unix epoch) when the
114  //! generated media id will expire, if media is not uploaded.
115  std::optional<qint64> unusedExpiresAt{};
116  };
117 };
118 
119 template <std::derived_from<CreateContentJob> JobT>
120 constexpr inline auto doCollectResponse<JobT> =
121  [](JobT* j) -> CreateContentJob::Response { return { j->contentUri(), j->unusedExpiresAt() }; };
122 
123 //! \brief Download content from the content repository.
124 //!
125 //! \note
126 //! Replaced by [`GET
127 //! /_matrix/client/v1/media/download/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid)
128 //! (requires authentication).
129 //!
130 //! \warning
131 //! <strong>[Changed in v1.11]</strong> This endpoint MAY return `404 M_NOT_FOUND`
132 //! for media which exists, but is after the server froze unauthenticated
133 //! media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more
134 //! information.
135 class [[deprecated("Check the documentation for details")]] QUOTIENT_API GetContentJob
136  : public BaseJob {
137 public:
138  //! \param serverName
139  //! The server name from the `mxc://` URI (the authority component).
140  //!
141  //! \param mediaId
142  //! The media ID from the `mxc://` URI (the path component).
143  //!
144  //! \param allowRemote
145  //! Indicates to the server that it should not attempt to fetch the media if
146  //! it is deemed remote. This is to prevent routing loops where the server
147  //! contacts itself.
148  //!
149  //! Defaults to `true` if not provided.
150  //!
151  //! \param timeoutMs
152  //! The maximum number of milliseconds that the client is willing to wait to
153  //! start receiving data, in the case that the content has not yet been
154  //! uploaded. The default value is 20000 (20 seconds). The content
155  //! repository SHOULD impose a maximum value for this parameter. The
156  //! content repository MAY respond before the timeout.
157  //!
158  //! \param allowRedirect
159  //! Indicates to the server that it may return a 307 or 308 redirect
160  //! response that points at the relevant media content. When not explicitly
161  //! set to `true` the server must return the media content itself.
162  explicit GetContentJob(const QString& serverName, const QString& mediaId,
163  bool allowRemote = true, qint64 timeoutMs = 20000,
164  bool allowRedirect = false);
165 
166  //! \brief Construct a URL without creating a full-fledged job object
167  //!
168  //! This function can be used when a URL for GetContentJob
169  //! is necessary but the job itself isn't.
170  static QUrl makeRequestUrl(const HomeserverData& hsData, const QString& serverName,
171  const QString& mediaId, bool allowRemote = true,
172  qint64 timeoutMs = 20000, bool allowRedirect = false);
173 
174  // Result properties
175 
176  //! The content type of the file that was previously uploaded.
177  //!
178  //! The server MUST return a `Content-Type` which is either exactly the same
179  //! as the original upload, or reasonably close. The bounds of "reasonable"
180  //! are:
181  //!
182  //! * Adding a charset to `text/*` content types.
183  //! * Detecting HTML and using `text/html` instead of `text/plain`.
184  //! * Using `application/octet-stream` when the server determines the
185  //! content type is obviously wrong. For example, an encrypted file being
186  //! claimed as `image/png`.
187  //! * Returning `application/octet-stream` when the media has an
188  //! unknown/unprovided `Content-Type`. For example, being uploaded before
189  //! the server tracked content types or when the remote server is
190  //! non-compliantly omitting the header entirely.
191  //!
192  //! Actions not in the spirit of the above are not considered "reasonable".
193  QString contentType() const { return QString::fromUtf8(reply()->rawHeader("Content-Type")); }
194 
195  //! The
196  //! [disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
197  //! of the returned content. MUST be one of `inline` or `attachment`,
198  //! and SHOULD contain a file name.
199  //!
200  //! If the `Content-Type` is allowed in the [restrictions for serving
201  //! inline content](/client-server-api/#serving-inline-content),
202  //! servers SHOULD use `inline`, otherwise they SHOULD use
203  //! `attachment`.
204  //!
205  //! If the upload was made with a `filename`, this header MUST
206  //! contain the same `filename`. Otherwise, `filename` is excluded
207  //! from the header. If the media being downloaded is remote, the
208  //! remote server's `filename` in the `Content-Disposition` header
209  //! is used as the `filename` instead. When the header is not
210  //! supplied, or does not supply a `filename`, the local download
211  //! response does not include a `filename`.
212  QString contentDisposition() const
213  {
214  return QString::fromUtf8(reply()->rawHeader("Content-Disposition"));
215  }
216 
217  //! The content that was previously uploaded.
218  QIODevice* data() { return reply(); }
219 };
220 
221 //! \brief Download content from the content repository overriding the file name
222 //!
223 //! \note
224 //! Replaced by [`GET
225 //! /_matrix/client/v1/media/download/{serverName}/{mediaId}/{fileName}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename)
226 //! (requires authentication).
227 //!
228 //! This will download content from the content repository (same as
229 //! the previous endpoint) but replace the target file name with the one
230 //! provided by the caller.
231 //!
232 //! \warning
233 //! <strong>[Changed in v1.11]</strong> This endpoint MAY return `404 M_NOT_FOUND`
234 //! for media which exists, but is after the server froze unauthenticated
235 //! media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more
236 //! information.
237 class [[deprecated("Check the documentation for details")]] QUOTIENT_API GetContentOverrideNameJob
238  : public BaseJob {
239 public:
240  //! \param serverName
241  //! The server name from the `mxc://` URI (the authority component).
242  //!
243  //! \param mediaId
244  //! The media ID from the `mxc://` URI (the path component).
245  //!
246  //! \param fileName
247  //! A filename to give in the `Content-Disposition` header.
248  //!
249  //! \param allowRemote
250  //! Indicates to the server that it should not attempt to fetch the media if
251  //! it is deemed remote. This is to prevent routing loops where the server
252  //! contacts itself.
253  //!
254  //! Defaults to `true` if not provided.
255  //!
256  //! \param timeoutMs
257  //! The maximum number of milliseconds that the client is willing to wait to
258  //! start receiving data, in the case that the content has not yet been
259  //! uploaded. The default value is 20000 (20 seconds). The content
260  //! repository SHOULD impose a maximum value for this parameter. The
261  //! content repository MAY respond before the timeout.
262  //!
263  //! \param allowRedirect
264  //! Indicates to the server that it may return a 307 or 308 redirect
265  //! response that points at the relevant media content. When not explicitly
266  //! set to `true` the server must return the media content itself.
267  explicit GetContentOverrideNameJob(const QString& serverName, const QString& mediaId,
268  const QString& fileName, bool allowRemote = true,
269  qint64 timeoutMs = 20000, bool allowRedirect = false);
270 
271  //! \brief Construct a URL without creating a full-fledged job object
272  //!
273  //! This function can be used when a URL for GetContentOverrideNameJob
274  //! is necessary but the job itself isn't.
275  static QUrl makeRequestUrl(const HomeserverData& hsData, const QString& serverName,
276  const QString& mediaId, const QString& fileName,
277  bool allowRemote = true, qint64 timeoutMs = 20000,
278  bool allowRedirect = false);
279 
280  // Result properties
281 
282  //! The content type of the file that was previously uploaded.
283  //!
284  //! The server MUST return a `Content-Type` which is either exactly the same
285  //! as the original upload, or reasonably close. The bounds of "reasonable"
286  //! are:
287  //!
288  //! * Adding a charset to `text/*` content types.
289  //! * Detecting HTML and using `text/html` instead of `text/plain`.
290  //! * Using `application/octet-stream` when the server determines the
291  //! content type is obviously wrong. For example, an encrypted file being
292  //! claimed as `image/png`.
293  //! * Returning `application/octet-stream` when the media has an
294  //! unknown/unprovided `Content-Type`. For example, being uploaded before
295  //! the server tracked content types or when the remote server is
296  //! non-compliantly omitting the header entirely.
297  //!
298  //! Actions not in the spirit of the above are not considered "reasonable".
299  QString contentType() const { return QString::fromUtf8(reply()->rawHeader("Content-Type")); }
300 
301  //! The
302  //! [disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
303  //! of the returned content. MUST be one of `inline` or `attachment`,
304  //! and MUST contain the file name requested in the path.
305  //!
306  //! If the `Content-Type` is allowed in the [restrictions for serving
307  //! inline content](/client-server-api/#serving-inline-content),
308  //! servers SHOULD use `inline`, otherwise they SHOULD use
309  //! `attachment`.
310  QString contentDisposition() const
311  {
312  return QString::fromUtf8(reply()->rawHeader("Content-Disposition"));
313  }
314 
315  //! The content that was previously uploaded.
316  QIODevice* data() { return reply(); }
317 };
318 
319 //! \brief Download a thumbnail of content from the content repository
320 //!
321 //! \note
322 //! Replaced by [`GET
323 //! /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid)
324 //! (requires authentication).
325 //!
326 //! Download a thumbnail of content from the content repository.
327 //! See the [Thumbnails](/client-server-api/#thumbnails) section for more information.
328 //!
329 //! \warning
330 //! <strong>[Changed in v1.11]</strong> This endpoint MAY return `404 M_NOT_FOUND`
331 //! for media which exists, but is after the server froze unauthenticated
332 //! media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more
333 //! information.
334 class [[deprecated("Check the documentation for details")]] QUOTIENT_API GetContentThumbnailJob
335  : public BaseJob {
336 public:
337  //! \param serverName
338  //! The server name from the `mxc://` URI (the authority component).
339  //!
340  //! \param mediaId
341  //! The media ID from the `mxc://` URI (the path component).
342  //!
343  //! \param width
344  //! The *desired* width of the thumbnail. The actual thumbnail may be
345  //! larger than the size specified.
346  //!
347  //! \param height
348  //! The *desired* height of the thumbnail. The actual thumbnail may be
349  //! larger than the size specified.
350  //!
351  //! \param method
352  //! The desired resizing method. See the [Thumbnails](/client-server-api/#thumbnails)
353  //! section for more information.
354  //!
355  //! \param allowRemote
356  //! Indicates to the server that it should not attempt to fetch the media if
357  //! it is deemed remote. This is to prevent routing loops where the server
358  //! contacts itself.
359  //!
360  //! Defaults to `true` if not provided.
361  //!
362  //! \param timeoutMs
363  //! The maximum number of milliseconds that the client is willing to wait to
364  //! start receiving data, in the case that the content has not yet been
365  //! uploaded. The default value is 20000 (20 seconds). The content
366  //! repository SHOULD impose a maximum value for this parameter. The
367  //! content repository MAY respond before the timeout.
368  //!
369  //! \param allowRedirect
370  //! Indicates to the server that it may return a 307 or 308 redirect
371  //! response that points at the relevant media content. When not explicitly
372  //! set to `true` the server must return the media content itself.
373  //!
374  //! \param animated
375  //! Indicates preference for an animated thumbnail from the server, if possible. Animated
376  //! thumbnails typically use the content types `image/gif`, `image/png` (with APNG format),
377  //! `image/apng`, and `image/webp` instead of the common static `image/png` or `image/jpeg`
378  //! content types.
379  //!
380  //! When `true`, the server SHOULD return an animated thumbnail if possible and supported.
381  //! When `false`, the server MUST NOT return an animated thumbnail. For example, returning a
382  //! static `image/png` or `image/jpeg` thumbnail. When not provided, the server SHOULD NOT
383  //! return an animated thumbnail.
384  //!
385  //! Servers SHOULD prefer to return `image/webp` thumbnails when supporting animation.
386  //!
387  //! When `true` and the media cannot be animated, such as in the case of a JPEG or PDF, the
388  //! server SHOULD behave as though `animated` is `false`.
389  explicit GetContentThumbnailJob(const QString& serverName, const QString& mediaId, int width,
390  int height, const QString& method = {}, bool allowRemote = true,
391  qint64 timeoutMs = 20000, bool allowRedirect = false,
392  std::optional<bool> animated = std::nullopt);
393 
394  //! \brief Construct a URL without creating a full-fledged job object
395  //!
396  //! This function can be used when a URL for GetContentThumbnailJob
397  //! is necessary but the job itself isn't.
398  static QUrl makeRequestUrl(const HomeserverData& hsData, const QString& serverName,
399  const QString& mediaId, int width, int height,
400  const QString& method = {}, bool allowRemote = true,
401  qint64 timeoutMs = 20000, bool allowRedirect = false,
402  std::optional<bool> animated = std::nullopt);
403 
404  // Result properties
405 
406  //! The
407  //! [disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
408  //! of the returned content. MUST be `inline`, and SHOULD contain a file name (e.g.
409  //! `thumbnail.png`).
410  //!
411  //! Servers should note the [Content-Type restrictions for serving inline
412  //! content](/client-server-api/#serving-inline-content), as these limitations imply which
413  //! formats should be used for thumbnail generation.
414  QString contentDisposition() const
415  {
416  return QString::fromUtf8(reply()->rawHeader("Content-Disposition"));
417  }
418 
419  //! The content type of the thumbnail.
420  QString contentType() const { return QString::fromUtf8(reply()->rawHeader("Content-Type")); }
421 
422  //! A thumbnail of the requested content.
423  QIODevice* data() { return reply(); }
424 };
425 
426 //! \brief Get information about a URL for a client
427 //!
428 //! \note
429 //! Replaced by [`GET
430 //! /_matrix/client/v1/media/preview_url`](/client-server-api/#get_matrixclientv1mediapreview_url).
431 //!
432 //! Get information about a URL for the client. Typically this is called when a
433 //! client sees a URL in a message and wants to render a preview for the user.
434 //!
435 //! **Note:**
436 //! Clients should consider avoiding this endpoint for URLs posted in encrypted
437 //! rooms. Encrypted rooms often contain more sensitive information the users
438 //! do not want to share with the homeserver, and this can mean that the URLs
439 //! being shared should also not be shared with the homeserver.
440 class [[deprecated("Check the documentation for details")]] QUOTIENT_API GetUrlPreviewJob
441  : public BaseJob {
442 public:
443  //! \param url
444  //! The URL to get a preview of.
445  //!
446  //! \param ts
447  //! The preferred point in time to return a preview for. The server may
448  //! return a newer version if it does not have the requested version
449  //! available.
450  explicit GetUrlPreviewJob(const QUrl& url, std::optional<qint64> ts = std::nullopt);
451 
452  //! \brief Construct a URL without creating a full-fledged job object
453  //!
454  //! This function can be used when a URL for GetUrlPreviewJob
455  //! is necessary but the job itself isn't.
456  static QUrl makeRequestUrl(const HomeserverData& hsData, const QUrl& url,
457  std::optional<qint64> ts = std::nullopt);
458 
459  // Result properties
460 
461  //! The byte-size of the image. Omitted if there is no image attached.
462  std::optional<qint64> matrixImageSize() const
463  {
464  return loadFromJson<std::optional<qint64>>("matrix:image:size"_L1);
465  }
466 
467  //! An [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to the image. Omitted if
468  //! there is no image.
469  QUrl ogImage() const { return loadFromJson<QUrl>("og:image"_L1); }
470 
471  struct Response {
472  //! The byte-size of the image. Omitted if there is no image attached.
473  std::optional<qint64> matrixImageSize{};
474 
475  //! An [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to the image. Omitted if
476  //! there is no image.
477  QUrl ogImage{};
478  };
479 };
480 
481 QT_WARNING_PUSH
482 QT_WARNING_DISABLE_DEPRECATED
483 template <std::derived_from<GetUrlPreviewJob> JobT>
484 constexpr inline auto doCollectResponse<JobT> =
485  [](JobT* j) -> GetUrlPreviewJob::Response { return { j->matrixImageSize(), j->ogImage() }; };
486 QT_WARNING_POP
487 
488 //! \brief Get the configuration for the content repository.
489 //!
490 //! \note
491 //! Replaced by [`GET
492 //! /_matrix/client/v1/media/config`](/client-server-api/#get_matrixclientv1mediaconfig).
493 //!
494 //! This endpoint allows clients to retrieve the configuration of the content
495 //! repository, such as upload limitations.
496 //! Clients SHOULD use this as a guide when using content repository endpoints.
497 //! All values are intentionally left optional. Clients SHOULD follow
498 //! the advice given in the field description when the field is not available.
499 //!
500 //! **NOTE:** Both clients and server administrators should be aware that proxies
501 //! between the client and the server may affect the apparent behaviour of content
502 //! repository APIs, for example, proxies may enforce a lower upload size limit
503 //! than is advertised by the server on this endpoint.
504 class [[deprecated("Check the documentation for details")]] QUOTIENT_API GetConfigJob
505  : public BaseJob {
506 public:
507  explicit GetConfigJob();
508 
509  //! \brief Construct a URL without creating a full-fledged job object
510  //!
511  //! This function can be used when a URL for GetConfigJob
512  //! is necessary but the job itself isn't.
513  static QUrl makeRequestUrl(const HomeserverData& hsData);
514 
515  // Result properties
516 
517  //! The maximum size an upload can be in bytes.
518  //! Clients SHOULD use this as a guide when uploading content.
519  //! If not listed or null, the size limit should be treated as unknown.
520  std::optional<qint64> uploadSize() const
521  {
522  return loadFromJson<std::optional<qint64>>("m.upload.size"_L1);
523  }
524 };
525 
526 QT_WARNING_PUSH
527 QT_WARNING_DISABLE_DEPRECATED
528 inline auto collectResponse(const GetConfigJob* job) { return job->uploadSize(); }
529 QT_WARNING_POP
530 
531 } // namespace Quotient