From e7844763443d44202fdd9553de4488374b99e182 Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 2 Feb 2023 12:38:02 +0000 Subject: [PATCH] Add /api/v1/custom_emojis endpoint --- CHANGELOG.md | 1 + docs/openapi.yaml | 16 +++++++++++++++ src/main.rs | 2 ++ src/mastodon_api/custom_emojis/mod.rs | 2 ++ src/mastodon_api/custom_emojis/types.rs | 25 +++++++++++++++++++++++ src/mastodon_api/custom_emojis/views.rs | 27 +++++++++++++++++++++++++ src/mastodon_api/mod.rs | 1 + src/mastodon_api/statuses/types.rs | 26 +++++------------------- src/models/emojis/queries.rs | 17 ++++++++++++++++ 9 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 src/mastodon_api/custom_emojis/mod.rs create mode 100644 src/mastodon_api/custom_emojis/types.rs create mode 100644 src/mastodon_api/custom_emojis/views.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index cb6f759..03ba53a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Replace post attachments and other related objects when processing `Update(Note)` activity. - Append attachment URL to post content if attachment size exceeds limit. +- Added `/api/v1/custom_emojis` endpoint. ### Changed diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 5fdd27d..f833d85 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -584,6 +584,19 @@ paths: $ref: '#/components/schemas/Relationship' 404: description: Profile not found + /api/v1/custom_emojis: + get: + summary: Returns custom emojis that are available on the server. + responses: + 200: + description: Successful operation + content: + application/json: + schema: + description: Emoji list + type: array + items: + $ref: '#/components/schemas/CustomEmoji' /api/v1/directory: get: summary: List profiles visible in the directory. @@ -1373,6 +1386,9 @@ components: url: description: A link to the custom emoji. type: string + static_url: + description: A link to a static copy of the custom emoji. + type: string visible_in_picker: description: Whether this Emoji should be visible in the picker or unlisted. type: boolean diff --git a/src/main.rs b/src/main.rs index e7e0b22..ae469c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use mitra::http::json_error_handler; use mitra::job_queue::scheduler; use mitra::logger::configure_logger; use mitra::mastodon_api::accounts::views::account_api_scope; +use mitra::mastodon_api::custom_emojis::views::custom_emoji_api_scope; use mitra::mastodon_api::directory::views::directory_api_scope; use mitra::mastodon_api::instance::views::instance_api_scope; use mitra::mastodon_api::markers::views::marker_api_scope; @@ -144,6 +145,7 @@ async fn main() -> std::io::Result<()> { )) .service(oauth_api_scope()) .service(account_api_scope()) + .service(custom_emoji_api_scope()) .service(directory_api_scope()) .service(instance_api_scope()) .service(marker_api_scope()) diff --git a/src/mastodon_api/custom_emojis/mod.rs b/src/mastodon_api/custom_emojis/mod.rs new file mode 100644 index 0000000..a964b01 --- /dev/null +++ b/src/mastodon_api/custom_emojis/mod.rs @@ -0,0 +1,2 @@ +pub mod types; +pub mod views; diff --git a/src/mastodon_api/custom_emojis/types.rs b/src/mastodon_api/custom_emojis/types.rs new file mode 100644 index 0000000..749ca94 --- /dev/null +++ b/src/mastodon_api/custom_emojis/types.rs @@ -0,0 +1,25 @@ +use serde::Serialize; + +use crate::models::emojis::types::DbEmoji; +use crate::utils::files::get_file_url; + +/// https://docs.joinmastodon.org/entities/CustomEmoji/ +#[derive(Serialize)] +pub struct CustomEmoji { + shortcode: String, + url: String, + static_url: String, + visible_in_picker: bool, +} + +impl CustomEmoji { + pub fn from_db(instance_url: &str, emoji: DbEmoji) -> Self { + let image_url = get_file_url(instance_url, &emoji.image.file_name); + Self { + shortcode: emoji.emoji_name, + url: image_url.clone(), + static_url: image_url, + visible_in_picker: true, + } + } +} diff --git a/src/mastodon_api/custom_emojis/views.rs b/src/mastodon_api/custom_emojis/views.rs new file mode 100644 index 0000000..b412d0a --- /dev/null +++ b/src/mastodon_api/custom_emojis/views.rs @@ -0,0 +1,27 @@ +use actix_web::{get, web, HttpResponse, Scope}; + +use crate::config::Config; +use crate::database::{get_database_client, DbPool}; +use crate::errors::HttpError; +use crate::models::emojis::queries::get_local_emojis; +use super::types::CustomEmoji; + +/// https://docs.joinmastodon.org/methods/custom_emojis/ +#[get("")] +async fn custom_emoji_list( + config: web::Data, + db_pool: web::Data, +) -> Result { + let db_client = &**get_database_client(&db_pool).await?; + let instance = config.instance(); + let emojis: Vec = get_local_emojis(db_client).await? + .into_iter() + .map(|db_emoji| CustomEmoji::from_db(&instance.url(), db_emoji)) + .collect(); + Ok(HttpResponse::Ok().json(emojis)) +} + +pub fn custom_emoji_api_scope() -> Scope { + web::scope("/api/v1/custom_emojis") + .service(custom_emoji_list) +} diff --git a/src/mastodon_api/mod.rs b/src/mastodon_api/mod.rs index 455679a..37e7b23 100644 --- a/src/mastodon_api/mod.rs +++ b/src/mastodon_api/mod.rs @@ -1,4 +1,5 @@ pub mod accounts; +pub mod custom_emojis; pub mod directory; pub mod instance; pub mod markers; diff --git a/src/mastodon_api/statuses/types.rs b/src/mastodon_api/statuses/types.rs index 411dda3..598c50a 100644 --- a/src/mastodon_api/statuses/types.rs +++ b/src/mastodon_api/statuses/types.rs @@ -3,14 +3,16 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::activitypub::identifiers::local_tag_collection; -use crate::mastodon_api::accounts::types::Account; -use crate::mastodon_api::media::types::Attachment; +use crate::mastodon_api::{ + accounts::types::Account, + custom_emojis::types::CustomEmoji, + media::types::Attachment, +}; use crate::models::{ emojis::types::DbEmoji, posts::types::{Post, Visibility}, profiles::types::DbActorProfile, }; -use crate::utils::files::get_file_url; /// https://docs.joinmastodon.org/entities/mention/ #[derive(Serialize)] @@ -49,24 +51,6 @@ impl Tag { } } -/// https://docs.joinmastodon.org/entities/CustomEmoji/ -#[derive(Serialize)] -pub struct CustomEmoji { - shortcode: String, - url: String, - visible_in_picker: bool, -} - -impl CustomEmoji { - fn from_db(instance_url: &str, emoji: DbEmoji) -> Self { - Self { - shortcode: emoji.emoji_name, - url: get_file_url(instance_url, &emoji.image.file_name), - visible_in_picker: true, - } - } -} - /// https://docs.joinmastodon.org/entities/status/ #[derive(Serialize)] pub struct Status { diff --git a/src/models/emojis/queries.rs b/src/models/emojis/queries.rs index 324a7e9..4fa89ec 100644 --- a/src/models/emojis/queries.rs +++ b/src/models/emojis/queries.rs @@ -111,6 +111,23 @@ pub async fn get_local_emojis_by_names( Ok(emojis) } +pub async fn get_local_emojis( + db_client: &impl DatabaseClient, +) -> Result, DatabaseError> { + let rows = db_client.query( + " + SELECT emoji + FROM emoji + WHERE hostname IS NULL + ", + &[], + ).await?; + let emojis = rows.iter() + .map(|row| row.try_get("emoji")) + .collect::>()?; + Ok(emojis) +} + pub async fn get_emoji_by_name_and_hostname( db_client: &impl DatabaseClient, emoji_name: &str,