rocket-pinboard/src/models/note.rs

146 lines
4.3 KiB
Rust
Raw Normal View History

use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::time::SystemTime;
use comrak;
use glob::glob;
use inflector::Inflector;
use rocket::serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
/// Structure for representing a wish note
pub struct Note {
/// The ID of the note (unique string)
pub id: String,
/// The index of the note (unique number)
2022-10-17 19:18:35 +02:00
pub index: usize,
/// The raw note data
pub data: String,
/// The time the note was last modified
pub mtime: SystemTime,
/// The name of the note, i.e. the person it is for
pub name: String,
/// The path to the note file
2018-02-15 20:49:42 +01:00
path: PathBuf,
}
impl Note {
pub fn to_html(&self) -> String {
let mut options = comrak::ComrakOptions::default();
2022-10-17 19:18:35 +02:00
options.extension.strikethrough = true;
options.extension.tagfilter = true;
options.extension.autolink = true;
options.extension.tasklist = true;
comrak::markdown_to_html(&self.data, &options)
}
2018-02-15 20:49:42 +01:00
pub fn update_data(&mut self, data: &String) {
let mut file = File::create(&self.path).expect(&format!(
2018-03-09 22:25:54 +01:00
"Cannot open note file: {}",
2018-02-15 20:49:42 +01:00
self.path.to_str().unwrap()
));
file.write_all(data.as_bytes()).expect(&format!(
2018-03-09 22:25:54 +01:00
"Cannot write note file: {}",
2018-02-15 20:49:42 +01:00
self.path.to_str().unwrap()
));
self.data = data.clone();
let metadata = file.metadata().unwrap();
self.mtime = metadata.modified().unwrap();
}
pub fn load_all(note_path: Option<&str>) -> Vec<Self> {
2018-02-15 20:49:42 +01:00
let mut notes: Vec<Note> = vec![];
let mut index = 0;
let path_glob = match note_path {
Some(dir) => format!("{}/notes/*.note", dir),
2018-02-15 20:49:42 +01:00
None => format!("notes/*.note"),
};
for entry in glob(path_glob.as_str()).unwrap().filter_map(Result::ok) {
let file_name = entry.file_name().unwrap().to_str().unwrap();
let name = match file_name.find('.') {
Some(index) => &file_name[0..index],
2018-02-15 20:49:42 +01:00
None => "unknown",
};
let mut data = String::new();
2018-02-15 20:49:42 +01:00
let mut file =
2018-03-09 22:25:54 +01:00
File::open(&entry).expect(&format!("Cannot open note file: {}", file_name));
file.read_to_string(&mut data)
2018-03-09 22:25:54 +01:00
.expect(&format!("Cannot read note file: {}", file_name));
2018-12-18 15:48:45 +01:00
let metadata = file
.metadata()
2018-03-09 22:25:54 +01:00
.expect(&format!("Cannot get metadata of note file: {}", file_name));
2020-02-03 21:15:38 +01:00
let note = Note {
id: String::from(name),
2018-02-15 20:49:42 +01:00
index: index,
data: data,
mtime: metadata.modified().unwrap(),
name: String::from(name).to_title_case(),
2018-02-15 20:49:42 +01:00
path: entry.clone(),
};
notes.push(note);
index += 1;
}
notes
}
}
2018-01-01 21:44:12 +01:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn loads_all_notes() {
let notes = Note::load_all(Some("test"));
2018-02-15 20:49:42 +01:00
let note_ids: Vec<&str> = notes.iter().map(|note| note.id.as_ref()).collect();
assert_eq!(note_ids, vec!["test", "updatable"]);
2018-01-01 21:44:12 +01:00
}
#[test]
fn converts_to_html() {
let notes = Note::load_all(Some("test"));
2018-02-15 20:49:42 +01:00
let note = notes.iter().find(|note| note.id == "test").unwrap();
assert_eq!(
note.to_html(),
r#"<p>This is a test note</p>
2018-01-01 21:44:12 +01:00
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
2018-02-15 20:49:42 +01:00
"#
);
2018-01-01 21:44:12 +01:00
}
#[test]
fn updates_data() {
let mut notes = Note::load_all(Some("test"));
2018-02-15 20:49:42 +01:00
let note = notes
.iter_mut()
.find(|note| note.id == "updatable")
2018-01-01 21:44:12 +01:00
.unwrap();
assert_eq!(note.data, "Some content");
2018-01-01 21:44:12 +01:00
// Update the data van verify it has changed
let new_data = "New content";
note.update_data(&String::from(new_data));
assert_eq!(note.data, new_data);
2018-01-01 21:44:12 +01:00
// Verify that the data is written to the file of the note by
2018-01-01 21:44:12 +01:00
// loading them again
let mut notes = Note::load_all(Some("test"));
2018-02-15 20:49:42 +01:00
let note = notes
.iter_mut()
.find(|note| note.id == "updatable")
2018-01-01 21:44:12 +01:00
.unwrap();
assert_eq!(note.data, new_data);
// ... and change it back again
note.update_data(&String::from("Some content"));
2018-01-01 21:44:12 +01:00
}
}