]>
Commit | Line | Data |
---|---|---|
606f82c7 | 1 | use std::fs::{copy, create_dir_all, read_dir, remove_dir_all, write}; |
a9c6be41 RBR |
2 | use std::io::{Result, Error, ErrorKind}; |
3 | use std::path::PathBuf; | |
5f81d796 | 4 | use super::{sync_down::SyncDown, generate::Generate, sync_up::SyncUp}; |
a9c6be41 RBR |
5 | use crate::configuration::Configuration; |
6 | use crate::constants::METADATA_FILENAME; | |
7 | use crate::metadata::Metadata; | |
f6a545b0 | 8 | use serde_json; |
d620665f RBR |
9 | |
10 | pub struct Update; | |
11 | ||
12 | impl Update { | |
13 | pub fn new() -> Self { | |
14 | Update | |
15 | } | |
a9c6be41 | 16 | |
606f82c7 RBR |
17 | fn copy_post(&self, source: &PathBuf, target: &PathBuf) -> Result<()> { |
18 | let post_name = source.file_name() | |
19 | .ok_or_else(|| Error::new(ErrorKind::InvalidInput, "Could not get post filename."))?; | |
20 | ||
21 | let target_post = target.join(post_name); | |
22 | copy(source, target_post)?; | |
23 | Ok(()) | |
a9c6be41 RBR |
24 | } |
25 | ||
606f82c7 | 26 | fn write_metadata(&self, metadata: &Metadata, metadata_location: &PathBuf) -> Result<()> { |
f6a545b0 | 27 | let serialized_metadata = serde_json::to_string(&metadata)?; |
606f82c7 RBR |
28 | write(metadata_location, serialized_metadata)?; |
29 | Ok(()) | |
a9c6be41 RBR |
30 | } |
31 | ||
606f82c7 RBR |
32 | fn archive(&self, source: &PathBuf, target: &PathBuf) -> Result<()> { |
33 | let entries = read_dir(source)?; | |
34 | for entry in entries { | |
35 | let entry = entry?; | |
36 | let entry_type = entry.file_type()?; | |
37 | let entry_name = entry.file_name(); | |
38 | let entry_source = entry.path(); | |
39 | let entry_target = target.join(entry_name); | |
40 | ||
41 | if entry_type.is_dir() { | |
42 | self.archive(&entry_source, &entry_target)?; | |
43 | } else { | |
44 | copy(&entry_source, &entry_target)?; | |
45 | } | |
46 | } | |
47 | ||
48 | Ok(()) | |
a9c6be41 | 49 | } |
d620665f RBR |
50 | } |
51 | ||
52 | impl super::Command for Update { | |
53 | fn before_dependencies(&self) -> Vec<Box<dyn super::Command>> { | |
5f81d796 | 54 | vec![Box::new(SyncDown::new())] |
d620665f RBR |
55 | } |
56 | ||
a9c6be41 RBR |
57 | fn execute(&self, input: Option<&String>, configuration: &Configuration, _: &String) -> Result<()> { |
58 | let input = input.expect("You must provide a path to a post"); | |
59 | let post_location = PathBuf::from(input); | |
60 | if !post_location.exists() { | |
61 | return Err(Error::new(ErrorKind::NotFound, "The path provided does not exist")); | |
62 | } | |
63 | ||
606f82c7 RBR |
64 | // Step 1. Write into the ephemeral posts |
65 | ||
a9c6be41 RBR |
66 | create_dir_all(&configuration.posts_directory)?; |
67 | ||
606f82c7 RBR |
68 | let first_post_path = configuration.posts_directory.join("0"); |
69 | let metadata_file_path = first_post_path.join(METADATA_FILENAME); | |
a9c6be41 RBR |
70 | let metadata = Metadata::read_or_create(&metadata_file_path); |
71 | ||
606f82c7 RBR |
72 | let _ = remove_dir_all(&first_post_path); |
73 | create_dir_all(&first_post_path)?; | |
74 | ||
75 | self.copy_post(&post_location, &first_post_path)?; | |
76 | self.write_metadata(&metadata, &metadata_file_path)?; | |
77 | ||
78 | // Step 2. Write into the archive | |
79 | ||
80 | create_dir_all(&configuration.archive_directory)?; | |
81 | ||
82 | let post_archive_path = configuration.archive_directory.join(metadata.id); | |
83 | let _ = remove_dir_all(&post_archive_path); | |
84 | create_dir_all(&post_archive_path)?; | |
85 | ||
86 | self.archive(&first_post_path, &post_archive_path)?; | |
d620665f RBR |
87 | return Ok(()) |
88 | } | |
89 | ||
90 | fn after_dependencies(&self) -> Vec<Box<dyn super::Command>> { | |
5f81d796 RBR |
91 | vec![ |
92 | Box::new(Generate::new()), | |
93 | Box::new(SyncUp::new()) | |
94 | ] | |
d620665f RBR |
95 | } |
96 | ||
97 | fn command(&self) -> &'static str { | |
98 | "update" | |
99 | } | |
100 | ||
101 | fn help(&self) -> &'static str { | |
102 | "<path_to_post>\t\tUpdates latest blog post" | |
103 | } | |
104 | } | |
105 |