forked from MightyPork/elefren-fork
feat(media): Add support for media alt text
This commit is contained in:
committed by
Paul Woolcock
parent
4afb3c3d74
commit
44da726d08
+35
-1
@@ -122,6 +122,7 @@ pub use crate::data::Data;
|
|||||||
pub use crate::errors::{ApiError, Error, Result};
|
pub use crate::errors::{ApiError, Error, Result};
|
||||||
pub use isolang::Language;
|
pub use isolang::Language;
|
||||||
pub use crate::mastodon_client::{MastodonClient, MastodonUnauthenticated};
|
pub use crate::mastodon_client::{MastodonClient, MastodonUnauthenticated};
|
||||||
|
pub use crate::media_builder::MediaBuilder;
|
||||||
pub use crate::registration::Registration;
|
pub use crate::registration::Registration;
|
||||||
pub use crate::requests::{
|
pub use crate::requests::{
|
||||||
AddFilterRequest,
|
AddFilterRequest,
|
||||||
@@ -145,6 +146,8 @@ pub mod helpers;
|
|||||||
/// Contains trait for converting `reqwest::Request`s to `reqwest::Response`s
|
/// Contains trait for converting `reqwest::Request`s to `reqwest::Response`s
|
||||||
pub mod http_send;
|
pub mod http_send;
|
||||||
mod mastodon_client;
|
mod mastodon_client;
|
||||||
|
/// Constructing media attachments for a status.
|
||||||
|
pub mod media_builder;
|
||||||
/// Handling multiple pages of entities.
|
/// Handling multiple pages of entities.
|
||||||
pub mod page;
|
pub mod page;
|
||||||
/// Registering your app.
|
/// Registering your app.
|
||||||
@@ -239,7 +242,6 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
(post (id: &str,)) reject_follow_request: "accounts/follow_requests/reject" => Empty,
|
(post (id: &str,)) reject_follow_request: "accounts/follow_requests/reject" => Empty,
|
||||||
(get (q: &'a str, resolve: bool,)) search: "search" => SearchResult,
|
(get (q: &'a str, resolve: bool,)) search: "search" => SearchResult,
|
||||||
(post (uri: Cow<'static, str>,)) follows: "follows" => Account,
|
(post (uri: Cow<'static, str>,)) follows: "follows" => Account,
|
||||||
(post multipart (file: Cow<'static, str>,)) media: "media" => Attachment,
|
|
||||||
(post) clear_notifications: "notifications/clear" => Empty,
|
(post) clear_notifications: "notifications/clear" => Empty,
|
||||||
(post (id: &str,)) dismiss_notification: "notifications/dismiss" => Empty,
|
(post (id: &str,)) dismiss_notification: "notifications/dismiss" => Empty,
|
||||||
(get) get_push_subscription: "push/subscription" => Subscription,
|
(get) get_push_subscription: "push/subscription" => Subscription,
|
||||||
@@ -627,6 +629,38 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
|
|
||||||
Ok(EventReader(WebSocket(client)))
|
Ok(EventReader(WebSocket(client)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Equivalent to /api/v1/media
|
||||||
|
fn media(&self, media_builder: MediaBuilder) -> Result<Attachment> {
|
||||||
|
use reqwest::multipart::Form;
|
||||||
|
|
||||||
|
let mut form_data = Form::new().file("file", media_builder.file.as_ref())?;
|
||||||
|
|
||||||
|
if let Some(description) = media_builder.description {
|
||||||
|
form_data = form_data.text("description", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(focus) = media_builder.focus {
|
||||||
|
let string = format!("{},{}", focus.0, focus.1);
|
||||||
|
form_data = form_data.text("focus", string);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = self.send(
|
||||||
|
self.client
|
||||||
|
.post(&self.route("/api/v1/media"))
|
||||||
|
.multipart(form_data),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let status = response.status().clone();
|
||||||
|
|
||||||
|
if status.is_client_error() {
|
||||||
|
return Err(Error::Client(status));
|
||||||
|
} else if status.is_server_error() {
|
||||||
|
return Err(Error::Server(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialise(response)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -144,41 +144,6 @@ macro_rules! route_v2 {
|
|||||||
|
|
||||||
macro_rules! route {
|
macro_rules! route {
|
||||||
|
|
||||||
((post multipart ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
|
||||||
doc_comment! {
|
|
||||||
concat!(
|
|
||||||
"Equivalent to `post /api/v1/",
|
|
||||||
$url,
|
|
||||||
"`\n# Errors\nIf `access_token` is not set."),
|
|
||||||
fn $name(&self, $($param: $typ,)*) -> Result<$ret> {
|
|
||||||
use reqwest::multipart::Form;
|
|
||||||
|
|
||||||
let form_data = Form::new()
|
|
||||||
$(
|
|
||||||
.file(stringify!($param), $param.as_ref())?
|
|
||||||
)*;
|
|
||||||
|
|
||||||
let response = self.send(
|
|
||||||
self.client
|
|
||||||
.post(&self.route(concat!("/api/v1/", $url)))
|
|
||||||
.multipart(form_data)
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let status = response.status().clone();
|
|
||||||
|
|
||||||
if status.is_client_error() {
|
|
||||||
return Err(Error::Client(status));
|
|
||||||
} else if status.is_server_error() {
|
|
||||||
return Err(Error::Server(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
deserialise(response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
route!{$($rest)*}
|
|
||||||
};
|
|
||||||
|
|
||||||
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
((get ($($param:ident: $typ:ty,)*)) $name:ident: $url:expr => $ret:ty, $($rest:tt)*) => {
|
||||||
doc_comment! {
|
doc_comment! {
|
||||||
concat!(
|
concat!(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::borrow::Cow;
|
|||||||
use crate::entities::prelude::*;
|
use crate::entities::prelude::*;
|
||||||
use crate::errors::Result;
|
use crate::errors::Result;
|
||||||
use crate::http_send::{HttpSend, HttpSender};
|
use crate::http_send::{HttpSend, HttpSender};
|
||||||
|
use crate::media_builder::MediaBuilder;
|
||||||
use crate::page::Page;
|
use crate::page::Page;
|
||||||
use crate::requests::{
|
use crate::requests::{
|
||||||
AddFilterRequest,
|
AddFilterRequest,
|
||||||
@@ -113,7 +114,7 @@ pub trait MastodonClient<H: HttpSend = HttpSender> {
|
|||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// POST /api/v1/media
|
/// POST /api/v1/media
|
||||||
fn media(&self, file: Cow<'static, str>) -> Result<Attachment> {
|
fn media(&self, media_builder: MediaBuilder) -> Result<Attachment> {
|
||||||
unimplemented!("This method was not implemented");
|
unimplemented!("This method was not implemented");
|
||||||
}
|
}
|
||||||
/// POST /api/v1/notifications/clear
|
/// POST /api/v1/notifications/clear
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
/// A builder pattern struct for constructing a media attachment.
|
||||||
|
#[derive(Debug, Default, Clone, Serialize)]
|
||||||
|
pub struct MediaBuilder {
|
||||||
|
/// The file name of the attachment to be uploaded.
|
||||||
|
pub file: Cow<'static, str>,
|
||||||
|
/// The alt text of the attachment.
|
||||||
|
pub description: Option<Cow<'static, str>>,
|
||||||
|
/// The focus point for images.
|
||||||
|
pub focus: Option<(f32, f32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MediaBuilder {
|
||||||
|
/// Create a new attachment from a file name.
|
||||||
|
pub fn new(file: Cow<'static, str>) -> Self {
|
||||||
|
MediaBuilder {
|
||||||
|
file,
|
||||||
|
description: None,
|
||||||
|
focus: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Set an alt text description for the attachment.
|
||||||
|
pub fn description(mut self, description: Cow<'static, str>) -> Self {
|
||||||
|
self.description = Some(description);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a focus point for an image attachment.
|
||||||
|
pub fn focus(mut self, f1: f32, f2: f32) -> Self {
|
||||||
|
self.focus = Some((f1, f2));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience helper so that the mastodon.media() method can be called with a
|
||||||
|
// file name only (owned string).
|
||||||
|
impl From<String> for MediaBuilder {
|
||||||
|
fn from(file: String) -> MediaBuilder {
|
||||||
|
MediaBuilder {
|
||||||
|
file: file.into(),
|
||||||
|
description: None,
|
||||||
|
focus: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience helper so that the mastodon.media() method can be called with a
|
||||||
|
// file name only (borrowed string).
|
||||||
|
impl From<&'static str> for MediaBuilder {
|
||||||
|
fn from(file: &'static str) -> MediaBuilder {
|
||||||
|
MediaBuilder {
|
||||||
|
file: file.into(),
|
||||||
|
description: None,
|
||||||
|
focus: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience helper so that the mastodon.media() method can be called with a
|
||||||
|
// file name only (Cow string).
|
||||||
|
impl From<Cow<'static, str>> for MediaBuilder {
|
||||||
|
fn from(file: Cow<'static, str>) -> MediaBuilder {
|
||||||
|
MediaBuilder {
|
||||||
|
file,
|
||||||
|
description: None,
|
||||||
|
focus: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user