This commit is contained in:
Dominic Grimm 2023-02-08 22:13:11 +01:00
parent 94fb270008
commit 584c07ff23
No known key found for this signature in database
GPG key ID: 6F294212DEAAC530
22 changed files with 539 additions and 187 deletions

View file

@ -10,8 +10,9 @@ use chrono::prelude::*;
use clap::{Parser, Subcommand};
use diesel::prelude::*;
use scan_dir::ScanDir;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use backend::*;
@ -28,23 +29,9 @@ enum Commands {
Import,
}
#[derive(Deserialize, Debug)]
struct Blog {
name: String,
description: String,
copyright: String,
owner: BlogOwner,
}
#[derive(Deserialize, Debug)]
struct BlogOwner {
name: String,
email: String,
website: Option<String>,
}
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
struct PostFrontmatter {
id: Option<i32>,
name: String,
slug: String,
description: String,
@ -55,6 +42,7 @@ struct PostFrontmatter {
#[derive(Debug)]
struct Post {
path: PathBuf,
frontmatter: PostFrontmatter,
content: String,
}
@ -64,61 +52,86 @@ fn main() -> Result<()> {
Commands::Import => {
let conn = &mut db::establish_connection()?;
let blog: Blog = serde_yaml::from_str(&fs::read_to_string("/blog/blog.yml")?)?;
diesel::delete(db::schema::configs::table)
.filter(db::schema::configs::active.eq(true))
.execute(conn)?;
diesel::insert_into(db::schema::configs::table)
.values(db::models::NewConfig {
active: true,
name: &blog.name,
description: &blog.description,
copyright: &blog.copyright,
owner_name: &blog.owner.name,
owner_email: &blog.owner.email,
owner_website: blog.owner.website.as_deref(),
})
.execute(conn)?;
let posts = ScanDir::dirs().read("/blog/posts", |iter| {
iter.map(|(entry, name)| {
dbg!(&entry, &name);
let src = fs::read_to_string(entry.path().join("post.md"))?;
for post in ScanDir::dirs().read("/blog", |iter| {
iter.map(|(entry, _)| {
let path = entry.path().join("post.md");
let src = fs::read_to_string(&path)?;
let frontmatter = match fronma::parser::parse::<PostFrontmatter>(&src) {
Ok(x) => x,
Err(x) => bail!("Error parsing frontmatter: {:?}", x),
};
Ok(Post {
frontmatter: PostFrontmatter {
name: frontmatter.headers.name.trim().to_string(),
slug: frontmatter.headers.slug.trim().to_string(),
description: frontmatter.headers.description.trim().to_string(),
..frontmatter.headers
},
content: frontmatter.body.trim().to_string(),
path,
frontmatter: frontmatter.headers,
content: frontmatter.body.to_string(),
})
})
.collect::<Result<Vec<_>>>()
})??;
dbg!(&posts);
})?? {
let content = post.content.trim();
for post in posts {
diesel::delete(db::schema::posts::table)
.filter(db::schema::posts::slug.eq(&post.frontmatter.slug))
.execute(conn)?;
diesel::insert_into(db::schema::posts::table)
.values(db::models::NewPost {
name: &post.frontmatter.name,
slug: &post.frontmatter.slug,
description: &post.frontmatter.description,
content: &post.content,
published_at: post.frontmatter.published_at,
edited_at: post.frontmatter.edited_at,
active: post.frontmatter.active,
})
.execute(conn)?;
if let Some(id) = post.frontmatter.id {
diesel::update(db::schema::posts::table)
.filter(db::schema::posts::id.eq(id))
.set(db::models::UpdatePost {
name: Some(&post.frontmatter.name),
slug: Some(&post.frontmatter.slug),
description: Some(&post.frontmatter.description),
content: Some(content),
published_at: Some(post.frontmatter.published_at),
edited_at: Some(post.frontmatter.edited_at),
active: Some(post.frontmatter.active),
})
.execute(conn)?;
} else {
let id = if let Some(id) = db::schema::posts::table
.select(db::schema::posts::id)
.filter(db::schema::posts::slug.eq(&post.frontmatter.slug))
.first::<i32>(conn)
.optional()?
{
diesel::update(db::schema::posts::table)
.filter(db::schema::posts::id.eq(id))
.set(db::models::UpdatePost {
name: Some(&post.frontmatter.name),
slug: None,
description: Some(&post.frontmatter.description),
content: Some(content),
published_at: Some(post.frontmatter.published_at),
edited_at: Some(post.frontmatter.edited_at),
active: Some(post.frontmatter.active),
})
.execute(conn)?;
id
} else {
diesel::insert_into(db::schema::posts::table)
.values(db::models::NewPost {
name: &post.frontmatter.name,
slug: &post.frontmatter.slug,
description: &post.frontmatter.description,
content: content,
published_at: post.frontmatter.published_at,
edited_at: post.frontmatter.edited_at,
active: post.frontmatter.active,
})
.returning(db::schema::posts::id)
.get_result::<i32>(conn)?
};
fs::write(
post.path,
format!(
"---\n{}---\n{}",
serde_yaml::to_string(&PostFrontmatter {
id: Some(id),
..post.frontmatter
})?,
post.content
),
)?;
}
}
Ok(())