Browse Source

Sort by date

index-subcmd
Vincent Prouillet 7 years ago
parent
commit
4acce865b4
7 changed files with 75 additions and 6 deletions
  1. +1
    -0
      Cargo.lock
  2. +1
    -0
      Cargo.toml
  3. +1
    -2
      src/cmd/serve.rs
  4. +45
    -0
      src/front_matter.rs
  5. +1
    -0
      src/main.rs
  6. +25
    -4
      src/page.rs
  7. +1
    -0
      src/site.rs

+ 1
- 0
Cargo.lock View File

@@ -2,6 +2,7 @@
name = "gutenberg" name = "gutenberg"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",


+ 1
- 0
Cargo.toml View File

@@ -24,6 +24,7 @@ serde_derive = "0.9"
tera = "0.8" tera = "0.8"
slug = "0.1" slug = "0.1"
syntect = "1" syntect = "1"
chrono = "0.3"


# Below is for the serve cmd # Below is for the serve cmd
staticfile = "0.4" staticfile = "0.4"


+ 1
- 2
src/cmd/serve.rs View File

@@ -5,7 +5,6 @@ use std::time::Duration;
use std::thread; use std::thread;


use iron::{Iron, Request, IronResult, Response, status}; use iron::{Iron, Request, IronResult, Response, status};
use iron::modifiers::Header;
use mount::Mount; use mount::Mount;
use staticfile::Static; use staticfile::Static;
use notify::{Watcher, RecursiveMode, watcher}; use notify::{Watcher, RecursiveMode, watcher};
@@ -17,7 +16,7 @@ use errors::{Result};
const LIVE_RELOAD: &'static [u8; 37809] = include_bytes!("livereload.js"); const LIVE_RELOAD: &'static [u8; 37809] = include_bytes!("livereload.js");




fn livereload_handler(req: &mut Request) -> IronResult<Response> {
fn livereload_handler(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Ok, String::from_utf8(LIVE_RELOAD.to_vec()).unwrap()))) Ok(Response::with((status::Ok, String::from_utf8(LIVE_RELOAD.to_vec()).unwrap())))
} }




+ 45
- 0
src/front_matter.rs View File

@@ -3,6 +3,7 @@ use std::collections::HashMap;


use toml; use toml;
use tera::Value; use tera::Value;
use chrono::prelude::*;




use errors::{Result}; use errors::{Result};
@@ -67,6 +68,19 @@ impl FrontMatter {


Ok(f) Ok(f)
} }

pub fn parse_date(&self) -> Option<NaiveDateTime> {
match self.date {
Some(ref d) => {
if d.contains("T") {
DateTime::parse_from_rfc3339(d).ok().and_then(|s| Some(s.naive_local()))
} else {
NaiveDate::parse_from_str(d, "%Y-%m-%d").ok().and_then(|s| Some(s.and_hms(0,0,0)))
}
},
None => None,
}
}
} }




@@ -183,6 +197,7 @@ slug = """#;
let res = FrontMatter::parse(content); let res = FrontMatter::parse(content);
assert!(res.is_err()); assert!(res.is_err());
} }

#[test] #[test]
fn test_errors_on_present_but_empty_url() { fn test_errors_on_present_but_empty_url() {
let content = r#" let content = r#"
@@ -192,4 +207,34 @@ url = """#;
let res = FrontMatter::parse(content); let res = FrontMatter::parse(content);
assert!(res.is_err()); assert!(res.is_err());
} }

#[test]
fn test_parse_date_yyyy_mm_dd() {
let content = r#"
title = "Hello"
description = "hey there"
date = "2016-10-10""#;
let res = FrontMatter::parse(content).unwrap();
assert!(res.parse_date().is_some());
}

#[test]
fn test_parse_date_rfc3339() {
let content = r#"
title = "Hello"
description = "hey there"
date = "2002-10-02T15:00:00Z""#;
let res = FrontMatter::parse(content).unwrap();
assert!(res.parse_date().is_some());
}

#[test]
fn test_cant_parse_random_date_format() {
let content = r#"
title = "Hello"
description = "hey there"
date = "2002/10/12""#;
let res = FrontMatter::parse(content).unwrap();
assert!(res.parse_date().is_none());
}
} }

+ 1
- 0
src/main.rs View File

@@ -15,6 +15,7 @@ extern crate tera;
extern crate glob; extern crate glob;
extern crate syntect; extern crate syntect;
extern crate slug; extern crate slug;
extern crate chrono;


extern crate staticfile; extern crate staticfile;
extern crate iron; extern crate iron;


+ 25
- 4
src/page.rs View File

@@ -1,4 +1,5 @@
/// A page, can be a blog post or a basic page /// A page, can be a blog post or a basic page
use std::cmp::Ordering;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::path::Path; use std::path::Path;
@@ -176,10 +177,30 @@ impl ser::Serialize for Page {
} }
} }


// Order pages by date, no-op for now
// TODO: impl PartialOrd on Vec<Page> so we can use sort()?
pub fn order_pages(pages: Vec<Page>) -> Vec<Page> {
pages
impl PartialOrd for Page {
fn partial_cmp(&self, other: &Page) -> Option<Ordering> {
if self.meta.date.is_none() {
println!("No self data");
return Some(Ordering::Less);
}

if other.meta.date.is_none() {
println!("No other date");
return Some(Ordering::Greater);
}

let this_date = self.meta.parse_date().unwrap();
let other_date = other.meta.parse_date().unwrap();

if this_date > other_date {
return Some(Ordering::Less);
}
if this_date < other_date {
return Some(Ordering::Greater);
}

Some(Ordering::Equal)
}
} }






+ 1
- 0
src/site.rs View File

@@ -118,6 +118,7 @@ impl Site {


// And finally the index page // And finally the index page
let mut context = Context::new(); let mut context = Context::new();
pages.sort_by(|a, b| a.partial_cmp(b).unwrap());
context.add("pages", &pages); context.add("pages", &pages);
context.add("config", &self.config); context.add("config", &self.config);
let index = self.templates.render("index.html", &context)?; let index = self.templates.render("index.html", &context)?;


Loading…
Cancel
Save