feat: updated to newest notion-client version

This commit is contained in:
Bram Dingelstad 2023-11-06 20:54:29 +01:00
parent 0966a27e99
commit 5b4ab0302c

View file

@ -1,109 +1,114 @@
use async_recursion::async_recursion; use async_recursion::async_recursion;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {}
}
use notion; use notion;
use notion::BlockType; use notion::BlockType;
pub fn convert_rich_text(text: &notion::RichText) -> String { pub fn convert_rich_text(text: &notion::RichText) -> String {
match text { match text {
notion::RichText::Text(text, _) => { notion::RichText::Text {
text, annotations, ..
} => {
let mut string = text.content.to_owned(); let mut string = text.content.to_owned();
if text.annotations.bold { if annotations.bold {
string = format!("**{string}**"); string = format!("**{string}**");
} }
if text.annotations.italic { if annotations.italic {
string = format!("*{string}*"); string = format!("*{string}*");
} }
if text.annotations.code { if annotations.code {
string = format!("`{string}`"); string = format!("`{string}`");
} }
string string
}, }
_ => "".to_string() _ => "".to_string(),
} }
} }
#[async_recursion] #[async_recursion]
pub async fn convert_blocks(notion: &notion::Client, blocks: &Vec<notion::Block>) -> Result<String, Error> { pub async fn convert_blocks(
notion: &notion::Client,
blocks: &Vec<notion::Block>,
) -> Result<String, Error> {
let mut output = vec![]; let mut output = vec![];
for block in blocks.iter() { for block in blocks.iter() {
let string = match &block.value { let string = match &block.block {
BlockType::Heading1(heading) | BlockType::Heading1 { heading }
BlockType::Heading2(heading) | | BlockType::Heading2 { heading }
BlockType::Heading3(heading) => { | BlockType::Heading3 { heading } => {
let content = heading.rich_text let content = heading
.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
let markdown_heading = match &block.value { let markdown_heading = match &block.block {
BlockType::Heading1(_) => "#", BlockType::Heading1 { .. } => "#",
BlockType::Heading2(_) => "##", BlockType::Heading2 { .. } => "##",
BlockType::Heading3(_) | _ => "###", BlockType::Heading3 { .. } | _ => "###",
}; };
Some(format!("{markdown_heading} {content}")) Some(format!("{markdown_heading} {content}"))
}, }
BlockType::Paragraph(paragraph) => { BlockType::Paragraph { paragraph, .. } => Some(
Some( paragraph
paragraph.rich_text .rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>() .collect::<String>(),
) ),
}, BlockType::Code { code, .. } => {
BlockType::Code(code) => {
let language = serde_variant::to_variant_name(&code.language).unwrap(); let language = serde_variant::to_variant_name(&code.language).unwrap();
let content = code.rich_text let content = code
.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
Some( Some(format!("```{language}\n{content}\n```"))
format!("```{language}\n{content}\n```") }
) BlockType::BulletedListItem {
}, bulleted_list_item, ..
BlockType::BulletedListItem(list_item) => { } => {
let content = list_item.rich_text let content = bulleted_list_item
.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
// TODO: Recurse down to `children` // TODO: Recurse down to `children`
Some( Some(format!("* {content}"))
format!("* {content}") }
) BlockType::NumberedListItem {
}, numbered_list_item, ..
BlockType::NumberedListItem(list_item) => { } => {
// TODO: Hold state for numbering // TODO: Hold state for numbering
let content = list_item.rich_text let content = numbered_list_item
.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
// TODO: Recurse down to `children` // TODO: Recurse down to `children`
Some( Some(format!("1. {content}"))
format!("1. {content}") }
) BlockType::ToDo { to_do, .. } => {
}, let content = to_do
BlockType::ToDo(todo_item) => { .rich_text
let content = todo_item.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
let checked = if todo_item.checked.unwrap_or(false) { let checked = if to_do.checked.unwrap_or(false) {
"x" "x"
} else { } else {
" " " "
@ -111,32 +116,30 @@ pub async fn convert_blocks(notion: &notion::Client, blocks: &Vec<notion::Block>
// TODO: Recurse down to `children` // TODO: Recurse down to `children`
Some( Some(format!("[{checked}] {content}"))
format!("[{checked}] {content}") }
) BlockType::Quote { quote, .. } => {
}, let content = quote
BlockType::Quote(quote) => { .rich_text
let content = quote.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
// TODO: Recurse down to `children` // TODO: Recurse down to `children`
Some( Some(format!("> {content}"))
format!("> {content}") }
) BlockType::Callout { callout, .. } => {
}, let content = callout
BlockType::Callout(callout) => { .rich_text
let content = callout.rich_text
.iter() .iter()
.map(|text| convert_rich_text(text)) .map(|text| convert_rich_text(text))
.collect::<String>(); .collect::<String>();
let icon = if let Some(value) = &callout.icon { let icon = if let Some(value) = &callout.icon {
match value { match value {
notion::Icon::Emoji(emoji) => emoji, notion::Icon::Emoji { emoji, .. } => emoji,
_ => "" _ => "",
} }
} else { } else {
"" ""
@ -144,42 +147,53 @@ pub async fn convert_blocks(notion: &notion::Client, blocks: &Vec<notion::Block>
// TODO: Recurse down to `children` // TODO: Recurse down to `children`
Some( Some(format!("> {icon} {content}"))
format!("> {icon} {content}") }
) BlockType::Image { image, .. } => {
}, match &image {
BlockType::Image(image) => { notion::File::External { external, .. } => {
match &image.image { let url = &external.url;
notion::File::External(url) => Some(format!(r#"<img style="margin: 0 auto" src="{url}">"#)), Some(format!(r#"<img style="margin: 0 auto" src="{url}">"#))
}
// TODO: Implement reupload of Notion file type // TODO: Implement reupload of Notion file type
_ => None _ => None,
} }
}, }
BlockType::Video(video) => { BlockType::Video { video, .. } => {
match &video.video { match &video {
notion::File::External(url) => Some(format!(r#"<video controls src="{url}" />"#)), notion::File::External { external, .. } => {
let url = &external.url;
Some(format!(r#"<video controls src="{url}" />"#))
}
// TODO: Implement reupload of Notion file type // TODO: Implement reupload of Notion file type
_ => None _ => None,
} }
}, }
BlockType::Divider => Some("---".to_string()), BlockType::Divider => Some("---".to_string()),
BlockType::Unsupported(string) => { BlockType::Unsupported => {
println!("Did not catch {string}"); // println!("Did not catch {string}");
None None
}, }
BlockType::ColumnList(_) => { BlockType::ColumnList { .. } => {
if block.has_children { if block.has_children {
let columns = notion let columns = notion
.blocks() .blocks
.children() .children()
.list(notion::BlockChildrenListOptions { block_id: &block.id }) .list(notion::BlockChildrenListOptions {
block_id: &block.id,
})
.await .await
.unwrap() .unwrap()
.results; .results;
let mut content = vec![]; let mut content = vec![];
for column in columns.iter() { for column in columns.iter() {
let children = notion.blocks().children().list(notion::BlockChildrenListOptions { block_id: &column.id }) let children = notion
.blocks
.children()
.list(notion::BlockChildrenListOptions {
block_id: &column.id,
})
.await .await
.unwrap() .unwrap()
.results; .results;
@ -187,35 +201,36 @@ pub async fn convert_blocks(notion: &notion::Client, blocks: &Vec<notion::Block>
content.push(convert_blocks(&notion, &children).await.unwrap()); content.push(convert_blocks(&notion, &children).await.unwrap());
} }
Some( Some(format!(
format!( r#"<div style="display: flex;">{content}</div>"#,
r#"<div style="display: flex;">{content}</div>"#, content = content
content = content .iter()
.iter() .map(|column| format!(r#"<div style="margin: 0 16px">{column}</div>"#))
.map( .collect::<Vec<String>>()
|column| format!(r#"<div style="margin: 0 16px">{column}</div>"#) .join("\n")
) ))
.collect::<Vec<String>>()
.join("\n")
)
)
} else { } else {
None None
} }
}, }
BlockType::Column(_) | BlockType::Column { .. }
BlockType::Table | | BlockType::Table
BlockType::Bookmark | | BlockType::Bookmark { .. }
BlockType::File(_) | BlockType::PDF(_) | | BlockType::File { .. }
| BlockType::Pdf { .. }
BlockType::TableOfContents | | BlockType::TableOfContents
BlockType::ChildPage(_) | | BlockType::ChildPage { .. }
BlockType::ChildDatabase(_) | | BlockType::ChildDatabase { .. }
BlockType::SyncedBlock | | BlockType::SyncedBlock
BlockType::Template | | BlockType::Template
BlockType::Toggle => None | BlockType::Toggle
| BlockType::Breadcrumb
| BlockType::Embed { .. }
| BlockType::Equation { .. }
| BlockType::LinkPreview { .. }
| BlockType::TableRow
| BlockType::LinkToPage { .. } => None,
}; };
if let Some(string) = string { if let Some(string) = string {
@ -225,4 +240,3 @@ pub async fn convert_blocks(notion: &notion::Client, blocks: &Vec<notion::Block>
Ok(output.join("\n\n")) Ok(output.join("\n\n"))
} }