|
1 |
| -use std::{ |
2 |
| - error::Error, |
3 |
| - fs::{self, File}, |
4 |
| - io::Write, |
5 |
| - path::PathBuf, |
6 |
| -}; |
7 |
| - |
8 |
| -use comrak::ComrakOptions; |
| 1 | +mod posts; |
9 | 2 |
|
| 3 | +use crate::posts::Post; |
10 | 4 | use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContext, RenderError};
|
11 |
| - |
12 |
| -use serde_derive::{Deserialize, Serialize}; |
13 |
| -use serde_json::json; |
14 |
| - |
15 | 5 | use sass_rs::{compile_file, Options};
|
| 6 | +use serde_derive::Serialize; |
| 7 | +use serde_json::json; |
| 8 | +use std::error::Error; |
| 9 | +use std::fs::{self, File}; |
| 10 | +use std::io::Write; |
| 11 | +use std::path::PathBuf; |
16 | 12 |
|
17 | 13 | struct Blog {
|
18 | 14 | handlebars: Handlebars,
|
19 | 15 | posts: Vec<Post>,
|
20 | 16 | out_directory: PathBuf,
|
21 | 17 | }
|
22 | 18 |
|
23 |
| -#[derive(Debug, Serialize, Deserialize, Clone)] |
24 |
| -struct Post { |
25 |
| - filename: String, |
26 |
| - title: String, |
27 |
| - author: String, |
28 |
| - year: String, |
29 |
| - show_year: bool, |
30 |
| - month: String, |
31 |
| - day: String, |
32 |
| - contents: String, |
33 |
| - url: String, |
34 |
| - published: String, |
35 |
| - release: bool, |
36 |
| -} |
37 |
| - |
38 |
| -#[derive(Debug, PartialEq, Serialize, Deserialize)] |
39 |
| -struct YamlHeader { |
40 |
| - title: String, |
41 |
| - author: String, |
42 |
| - #[serde(default)] |
43 |
| - release: bool, |
44 |
| -} |
45 |
| - |
46 | 19 | #[derive(Debug, Serialize)]
|
47 | 20 | struct Releases {
|
48 | 21 | releases: Vec<ReleasePost>,
|
@@ -115,91 +88,19 @@ impl Blog {
|
115 | 88 | let mut posts = Vec::new();
|
116 | 89 |
|
117 | 90 | for entry in fs::read_dir(dir)? {
|
118 |
| - let entry = entry?; |
119 |
| - let path = entry.path(); |
120 |
| - |
121 |
| - // yeah this might blow up, but it won't |
122 |
| - let filename = path.file_name().unwrap().to_str().unwrap(); |
| 91 | + let path = entry?.path(); |
123 | 92 |
|
124 | 93 | // ignore vim temporary files
|
| 94 | + let filename = path.file_name().unwrap().to_str().unwrap(); |
125 | 95 | if filename.starts_with(".") && filename.ends_with(".swp") {
|
126 | 96 | continue;
|
127 | 97 | }
|
128 | 98 |
|
129 |
| - // we need to get the metadata out of the url |
130 |
| - let mut split = filename.splitn(4, "-"); |
131 |
| - |
132 |
| - let year = split.next().unwrap().to_string(); |
133 |
| - let month = split.next().unwrap().to_string(); |
134 |
| - let day = split.next().unwrap().to_string(); |
135 |
| - let filename = split.next().unwrap().to_string(); |
136 |
| - |
137 |
| - let contents = fs::read_to_string(path)?; |
138 |
| - |
139 |
| - // yaml headers.... we know the first four bytes of each file are "---\n" |
140 |
| - // so we need to find the end. we need the fours to adjust for those first bytes |
141 |
| - let end_of_yaml = contents[4..].find("---").unwrap() + 4; |
142 |
| - let yaml = &contents[..end_of_yaml]; |
143 |
| - let YamlHeader { |
144 |
| - author, |
145 |
| - title, |
146 |
| - release, |
147 |
| - } = serde_yaml::from_str(yaml)?; |
148 |
| - // next, the contents. we add + to get rid of the final "---\n\n" |
149 |
| - let options = ComrakOptions { |
150 |
| - ext_header_ids: Some(String::new()), |
151 |
| - ..ComrakOptions::default() |
152 |
| - }; |
153 |
| - |
154 |
| - let contents = comrak::markdown_to_html(&contents[end_of_yaml + 5..], &options); |
155 |
| - |
156 |
| - // finally, the url. |
157 |
| - let mut url = PathBuf::from(&*filename); |
158 |
| - url.set_extension("html"); |
159 |
| - |
160 |
| - // this is fine |
161 |
| - let url = format!("{}/{}/{}/{}", year, month, day, url.to_str().unwrap()); |
162 |
| - |
163 |
| - // build the published time. this is only approximate, which is fine. |
164 |
| - // we do some unwraps because these need to be valid |
165 |
| - let published = time::Tm { |
166 |
| - tm_sec: 0, |
167 |
| - tm_min: 0, |
168 |
| - tm_hour: 0, |
169 |
| - tm_mday: day.parse::<i32>().unwrap(), |
170 |
| - tm_mon: month.parse::<i32>().unwrap() - 1, // 0-11 not 1-12 |
171 |
| - tm_year: year.parse::<i32>().unwrap() - 1900, // from the year 1900, not the actual year |
172 |
| - // these next two fields are wrong but we never use them to generate our times |
173 |
| - tm_wday: 1, |
174 |
| - tm_yday: 1, |
175 |
| - tm_isdst: 0, |
176 |
| - tm_utcoff: 0, |
177 |
| - tm_nsec: 0, |
178 |
| - }; |
179 |
| - |
180 |
| - let published = published.rfc3339().to_string(); |
181 |
| - |
182 |
| - let post = Post { |
183 |
| - filename, |
184 |
| - title, |
185 |
| - author, |
186 |
| - year, |
187 |
| - show_year: false, |
188 |
| - month, |
189 |
| - day, |
190 |
| - contents, |
191 |
| - url, |
192 |
| - published, |
193 |
| - release, |
194 |
| - }; |
195 |
| - |
196 |
| - posts.push(post); |
| 99 | + posts.push(Post::open(&path)?); |
197 | 100 | }
|
198 | 101 |
|
199 | 102 | // finally, sort the posts. oldest first.
|
200 |
| - |
201 | 103 | posts.sort_by_key(|post| post.url.clone());
|
202 |
| - |
203 | 104 | posts.reverse();
|
204 | 105 |
|
205 | 106 | for i in 1..posts.len() {
|
|
0 commit comments