feat(npf): prototype image support

This commit is contained in:
Gustavo "Guz" L. de Mello
2024-04-29 14:50:06 -03:00
parent 13425b31e4
commit 21e42dec52
4 changed files with 134 additions and 12 deletions

View File

@@ -1,4 +1,4 @@
use std::cell::RefCell;
use std::{borrow::Borrow, cell::RefCell, path, str::FromStr};
use comrak::{
arena_tree::{Children, Node},
@@ -13,12 +13,11 @@ pub mod text_formatting;
mod objects_post;
use content_blocks::{BlockText, BlockValue};
use content_blocks::{BlockImage, BlockText, BlockValue};
use objects::{BlogInfo, Media};
use text_formatting::{FormatTypeBold, FormatTypeItalic, FormatValue};
use text_formatting::{FormatTypeLink, FormatTypeStrikeThrough};
use self::{objects::BlogInfo, text_formatting::FormatTypeMention};
use text_formatting::{FormatTypeLink, FormatTypeMention, FormatTypeStrikeThrough};
#[derive(Debug)]
pub enum NPFConvertError {
@@ -164,6 +163,53 @@ impl<'a> TryFrom<&'a Node<'a, RefCell<Ast>>> for objects::Post {
post.content.push(BlockValue::Text(BlockText::from("\n")));
Ok(post)
}
NodeValue::Image(i) => {
let alt_text = Self::try_from(node.children())?.fold_content();
if let Some(p) = node.parent() {
if let NodeValue::Paragraph = p.data.borrow().value {
let alt_text = alt_text
.content
.iter()
.find(|b| {
if let BlockValue::Text(_) = b {
true
} else {
false
}
})
.unwrap_or(BlockValue::Text(BlockText::new("")).borrow())
.to_owned();
let alt_text = if let BlockValue::Text(t) = alt_text {
Some(t.text.clone())
} else {
None
};
let media = if let Ok(url) = url::Url::from_str(&i.url) {
Media::from(url)
} else if let Some(name) = path::Path::new(&i.url).file_name() {
if let Some(name) = name.to_str() {
Media::from(name)
} else {
Media::from(i.url.as_str())
}
} else {
Media::from(i.url.as_str())
};
let mut block = BlockImage::from(media);
block.alt_text = alt_text;
let mut post = Self::new(0);
post.content.push(BlockValue::Image(block));
Ok(post)
} else {
Ok(alt_text)
}
} else {
Ok(alt_text)
}
}
_ => Ok(Self::new(0)),
}
}
@@ -411,7 +457,7 @@ mod tests {
let markdown = "If **you** are reading this, thanks for giving a look\n\
and checking the ~~ugly~~ source code of this *little\n\
**personal** project*. It is heart warming to know that *at least*\n\
[someone](t:_YENQUPzd_oPpmVDqZQ-yw) found this interesting and maybe useful, even knowing\n\
[someone](t:_YENQUPzd_oPpmVDqZQ-yw) found this interesting and maybe useful, ![even knowing](image.png)\n\
how niched this whole project is.\\
- [Gustavo \"Guz\" L. de Mello](https://guz.one), Apr 16, 12.2024";

View File

@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};
pub use super::objects_post::Post;
use mime_serde_shim::Wrapper as Mime;
#[serde_with::skip_serializing_none]
#[derive(Debug, Deserialize, Serialize, Clone)]
@@ -78,8 +79,9 @@ pub struct Avatar {
#[serde_with::skip_serializing_none]
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Media {
pub r#type: Option<String>,
pub url: url::Url,
pub r#type: Option<Mime>,
pub url: Option<url::Url>,
pub identifier: Option<String>,
pub width: Option<u64>,
pub height: Option<u64>,
pub original_dimensions_missing: Option<bool>,
@@ -87,13 +89,17 @@ pub struct Media {
pub has_original_dimentions: Option<bool>,
}
impl Media {
pub fn new(url: url::Url) -> Self {
Self::from(url)
pub fn new(identifier: String) -> Self {
Self::from(identifier)
}
pub fn is_valid(&self) -> bool {
self.url.is_some() || self.identifier.is_some()
}
fn default() -> Self {
Self {
r#type: None,
url: url::Url::parse("https://tumblr.com").unwrap(),
url: None,
identifier: None,
width: None,
height: None,
original_dimensions_missing: None,
@@ -102,10 +108,35 @@ impl Media {
}
}
}
impl From<String> for Media {
fn from(value: String) -> Self {
let mime = if let Some(m) = mime_guess::from_path(&value).first() {
Some(Mime::from(m))
} else {
None
};
Self {
r#type: mime,
identifier: Some(value),
..Self::default()
}
}
}
impl From<&str> for Media {
fn from(value: &str) -> Self {
Self::from(String::from(value))
}
}
impl From<url::Url> for Media {
fn from(value: url::Url) -> Self {
let mime = if let Some(m) = mime_guess::from_path(&value.to_string()).first() {
Some(Mime::from(m))
} else {
None
};
Self {
url: value,
r#type: mime,
url: Some(value),
..Self::default()
}
}