aboutsummaryrefslogtreecommitdiff
path: root/code/src/main.rs
blob: c20d1371e8ea8bd9730211e603663510271c9e61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
pub mod atom;
pub mod html;
pub mod markdown;
pub mod syntax_highlight;

use atom::generate_atom;
use clap::{Parser, Subcommand};
use html::{article, index};
use laby::{internal::Buffer, Render};
use std::{
    fs::File,
    io::{BufRead, BufReader, Write},
    path::PathBuf,
    process::{Command, Stdio},
};

pub const BLOG_BASE: &'static str = "s.metamuffin.org/temp/blog-preview";

#[derive(Parser)]
pub struct Args {
    #[clap(short, long)]
    root: Option<String>,
    #[clap(short, long)]
    output: Option<String>,
    #[clap(subcommand)]
    action: ArgAction,
}

#[derive(Subcommand)]
pub enum ArgAction {
    RenderArticle { input: String },
    RenderIndex,
    GenerateAtom,
}

fn main() {
    let args = Args::parse();
    match &args.action {
        ArgAction::RenderArticle { input } => {
            let mut out = Buffer::new();
            article(input.to_owned()).render(&mut out);
            write_output(&args, out.into_string());
        }
        ArgAction::RenderIndex => {
            let mut out = Buffer::new();
            index(&args.root.as_ref().unwrap()).render(&mut out);
            write_output(&args, out.into_string());
        }
        ArgAction::GenerateAtom => {
            write_output(&args, generate_atom(&args));
        }
    }
}

fn write_output(t: &Args, o: String) {
    if let Some(f) = &t.output {
        let mut f = File::create(f).unwrap();
        f.write_fmt(format_args!("{o}")).unwrap()
    } else {
        println!("{o}")
    }
}

pub fn get_articles(root: &str) -> Vec<ArticleMeta> {
    let mut a = std::fs::read_dir(root)
        .unwrap()
        .map(|e| e.unwrap())
        .map(|e| article_metadata(e.path()))
        .collect::<Vec<_>>();
    a.sort_by_cached_key(|e| -match e.date {
        iso8601::Date::YMD { year, month, day } => day as i32 + month as i32 * 40 + year * 37,
        _ => unreachable!(),
    });
    a
}

pub fn file_history(filename: &str) -> String {
    String::from_utf8(
        Command::new("/usr/bin/git")
            .args(&["log", "--follow", "--pretty=tformat:%as %h %s", filename])
            .stdout(Stdio::piped())
            .output()
            .unwrap()
            .stdout,
    )
    .unwrap()
}

pub struct ArticleMeta {
    title: String,
    canonical_name: String,
    date: iso8601::Date,
}
fn article_metadata(path: PathBuf) -> ArticleMeta {
    let f = File::open(&path).unwrap();
    let mut f = BufReader::new(f);
    let mut buf = String::new();
    f.read_line(&mut buf).unwrap(); // assume the 1st line has the title
    ArticleMeta {
        title: String::from(buf[2..].trim()),
        canonical_name: path.file_stem().unwrap().to_str().unwrap().to_string(),
        date: iso8601::date(&path.file_name().unwrap().to_str().unwrap()[0..10]).unwrap(),
    }
}