128 lines
3.8 KiB
Rust
128 lines
3.8 KiB
Rust
|
#[cfg(not(target_env = "msvc"))]
|
||
|
use tikv_jemallocator::Jemalloc;
|
||
|
|
||
|
#[cfg(not(target_env = "msvc"))]
|
||
|
#[global_allocator]
|
||
|
static GLOBAL: Jemalloc = Jemalloc;
|
||
|
|
||
|
use anyhow::{bail, Result};
|
||
|
use chrono::prelude::*;
|
||
|
use clap::{Parser, Subcommand};
|
||
|
use diesel::prelude::*;
|
||
|
use scan_dir::ScanDir;
|
||
|
use serde::Deserialize;
|
||
|
use std::fs;
|
||
|
|
||
|
use backend::*;
|
||
|
|
||
|
#[derive(Debug, Parser)]
|
||
|
#[clap(author, version, about, long_about = None)]
|
||
|
struct Cli {
|
||
|
#[clap(subcommand)]
|
||
|
commands: Commands,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Subcommand)]
|
||
|
enum Commands {
|
||
|
#[clap(about = "Imports new posts")]
|
||
|
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)]
|
||
|
struct PostFrontmatter {
|
||
|
name: String,
|
||
|
slug: String,
|
||
|
description: String,
|
||
|
published_at: NaiveDate,
|
||
|
edited_at: Option<NaiveDate>,
|
||
|
active: bool,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
struct Post {
|
||
|
frontmatter: PostFrontmatter,
|
||
|
content: String,
|
||
|
}
|
||
|
|
||
|
fn main() -> Result<()> {
|
||
|
match Cli::parse().commands {
|
||
|
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"))?;
|
||
|
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(),
|
||
|
})
|
||
|
})
|
||
|
.collect::<Result<Vec<_>>>()
|
||
|
})??;
|
||
|
dbg!(&posts);
|
||
|
|
||
|
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)?;
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
}
|