Skip to content
Snippets Groups Projects
embed.rs 1.25 KiB
Newer Older
insert's avatar
insert committed
use actix_web::{
    web::{self, Query},
    Responder,
};
use serde::Deserialize;
insert's avatar
insert committed

use crate::structs::embed::Embed;
use crate::structs::metadata::Metadata;
use crate::util::request::{consume_metatags, fetch};
insert's avatar
insert committed
use crate::{
    structs::media::{Media, MediaSize},
    util::{request::consume_size, result::Error},
};
insert's avatar
insert committed

#[derive(Deserialize)]
pub struct Parameters {
    url: String,
}

pub async fn get(info: Query<Parameters>) -> Result<impl Responder, Error> {
    let url = info.into_inner().url;
    let (resp, mime) = fetch(&url).await?;

    if let mime::HTML = mime.subtype() {
        let properties = consume_metatags(resp).await?;
        let mut metadata = Metadata::from(properties);
        metadata.resolve_external().await;
insert's avatar
insert committed

        if metadata.is_none() {
insert's avatar
insert committed
            return Ok(web::Json(Embed::None));
insert's avatar
insert committed
        Ok(web::Json(Embed::Website(metadata)))
    } else if let mime::IMAGE = mime.type_() {
insert's avatar
insert committed
        if let Ok((width, height)) = consume_size(resp).await {
            Ok(web::Json(Embed::Image(Media {
                url,
                width,
                height,
                size: MediaSize::Large,
            })))
insert's avatar
insert committed
        } else {
            Ok(web::Json(Embed::None))
        }
    } else {
        Ok(web::Json(Embed::None))
    }
}