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