Add API method for generating post previews

https://codeberg.org/silverpill/mitra/issues/12
This commit is contained in:
silverpill 2022-12-19 22:06:18 +00:00
parent f7d9173cce
commit a23a555a05
3 changed files with 88 additions and 4 deletions

View file

@ -710,9 +710,7 @@ paths:
type: object
properties:
status:
description: |
Text content of the post.
Allowed HTML tags: a, br, pre, code, strong, em, p.
description: Text content of the post.
type: string
content_type:
description: Media type of the post content.
@ -751,6 +749,42 @@ paths:
$ref: '#/components/schemas/Status'
400:
description: Invalid post data
/api/v1/statuses/preview:
post:
summary: Preview new post.
security:
- tokenAuth: []
requestBody:
content:
application/json:
schema:
type: object
properties:
status:
description: Text content of the post.
type: string
content_type:
description: Media type of the post content.
type: string
default: text/html
enum:
- text/html
- text/markdown
required:
- status
responses:
200:
description: Preview generated.
content:
application/json:
schema:
type: object
properties:
content:
description: HTML-encoded post content.
type: string
400:
description: Invalid post data.
/api/v1/statuses/{status_id}:
delete:
summary: Delete post

View file

@ -149,6 +149,19 @@ pub struct StatusData {
pub content_type: String,
}
#[derive(Deserialize)]
pub struct StatusPreviewData {
pub status: String,
#[serde(default = "default_post_content_type")]
pub content_type: String,
}
#[derive(Serialize)]
pub struct StatusPreview {
pub content: String,
}
#[derive(Deserialize)]
pub struct TransactionData {
pub transaction_id: String,

View file

@ -47,7 +47,13 @@ use super::helpers::{
parse_microsyntaxes,
PostContent,
};
use super::types::{Status, StatusData, TransactionData};
use super::types::{
Status,
StatusData,
StatusPreview,
StatusPreviewData,
TransactionData,
};
#[post("")]
async fn create_status(
@ -161,6 +167,36 @@ async fn create_status(
Ok(HttpResponse::Created().json(status))
}
#[post("/preview")]
async fn preview_status(
auth: BearerAuth,
config: web::Data<Config>,
db_pool: web::Data<DbPool>,
status_data: web::Json<StatusPreviewData>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
get_current_user(db_client, auth.token()).await?;
let status_data = status_data.into_inner();
let content = match status_data.content_type.as_str() {
"text/html" => status_data.status,
"text/markdown" => {
markdown_lite_to_html(&status_data.status)
.map_err(|_| ValidationError("invalid markdown"))?
},
_ => return Err(ValidationError("unsupported content type").into()),
};
let PostContent { mut content, .. } = parse_microsyntaxes(
db_client,
&config.instance(),
content,
).await?;
// Clean content
content = clean_content(&content)?;
// Return preview
let preview = StatusPreview { content };
Ok(HttpResponse::Ok().json(preview))
}
#[get("/{status_id}")]
async fn get_status(
auth: Option<BearerAuth>,
@ -524,6 +560,7 @@ pub fn status_api_scope() -> Scope {
web::scope("/api/v1/statuses")
// Routes without status ID
.service(create_status)
.service(preview_status)
// Routes with status ID
.service(get_status)
.service(delete_status)