]> luflow.net public git repositories - flow-web.git/blob - src/site/core.rs
Initial commit.
[flow-web.git] / src / site / core.rs
1 // luflow.net web site
2 // AGPL-3.0 License (see LICENSE)
3
4 use log::info;
5 use sailfish::Template;
6 use sailfish::TemplateSimple;
7 use std::path::Path;
8 use std::sync::{Arc, Mutex};
9
10 use crate::site::blog_post::BlogPost;
11 use crate::site::helper::Helper;
12 use crate::site::screenshot::Screenshot;
13
14 pub struct CoreShared {
15 state: Mutex<CoreState>,
16 }
17
18 impl CoreShared {
19 pub fn new() -> Self {
20 Self {
21 state: Mutex::new(CoreState::new()),
22 }
23 }
24
25 pub fn shared(self) -> Arc<Self> {
26 Arc::new(self)
27 }
28
29 pub fn set_core_index_data(
30 &self,
31 blog_base_dir: String,
32 blog_posts: Vec<BlogPost>,
33 screenshots: Vec<Screenshot>,
34 ) {
35 let mut lock = self.state.lock().unwrap();
36 lock.blog_base_dir = blog_base_dir;
37 lock.blog_posts = blog_posts;
38 lock.screenshots = screenshots;
39 }
40 }
41
42 #[derive(Template)]
43 #[template(path = "index.stpl")]
44 struct CoreState {
45 pub blog_posts: Vec<BlogPost>,
46 pub screenshots: Vec<Screenshot>,
47 pub hfge_url: String,
48 pub blog_base_dir: String,
49 }
50
51 impl CoreState {
52 pub fn new() -> Self {
53 Self {
54 blog_posts: Vec::new(),
55 screenshots: Vec::new(),
56 hfge_url: String::from("projects/hfge"),
57 blog_base_dir: String::new(),
58 }
59 }
60 }
61
62 pub async fn generate_core() {
63 // create output dirs needed:
64 create_output_dirs();
65
66 let mut tasks = Vec::with_capacity(4);
67
68 // copy all static related files:
69 tasks.push(tokio::spawn(copy_static_dirs()));
70
71 // generate all core pages (core index will be done as the very
72 // last thing as screenshot and blog generation must be done first):
73 tasks.push(tokio::spawn(generate_error_pages()));
74 tasks.push(tokio::spawn(generate_project_pages()));
75 tasks.push(tokio::spawn(generate_contact_page()));
76
77 // wait until all taks are done:
78 for task in tasks {
79 task.await.unwrap();
80 }
81 }
82
83 fn create_output_dirs() {
84 Helper::create_dir_all(&Helper::get_output_dir().join("contact"));
85 Helper::create_dir_all(&Helper::get_output_dir().join("projects/hfge"));
86 }
87
88 async fn copy_static_dirs() {
89 // copy static and static_root to output folder:
90 Helper::copy_dir_all(Path::new("static"), Helper::get_output_dir().join("static"))
91 .await
92 .unwrap();
93 info!(
94 "Copied dir 'static' recursively to '{}'",
95 Helper::get_output_dir().join("static").display()
96 );
97
98 Helper::copy_dir_all(Path::new("static_root"), Helper::get_output_dir())
99 .await
100 .unwrap();
101 info!(
102 "Copied dir 'static_root' recursively to '{}'",
103 Helper::get_output_dir().display()
104 );
105 }
106
107 async fn generate_error_pages() {
108 // 404:
109 #[derive(TemplateSimple)]
110 #[template(path = "404.stpl")]
111 struct Err404Template {}
112
113 let ctx = Err404Template {};
114 Helper::write_file(
115 &Helper::get_output_dir().join("404.html"),
116 &ctx.render_once().unwrap().as_bytes(),
117 )
118 .await
119 .unwrap();
120
121 // 500:
122 #[derive(TemplateSimple)]
123 #[template(path = "500.stpl")]
124 struct Err500Template {}
125
126 let ctx = Err500Template {};
127 Helper::write_file(
128 &Helper::get_output_dir().join("500.html"),
129 &ctx.render_once().unwrap().as_bytes(),
130 )
131 .await
132 .unwrap();
133 }
134
135 async fn generate_project_pages() {
136 // projects/hfge:
137 #[derive(TemplateSimple)]
138 #[template(path = "hfge.stpl")]
139 struct HFGETemplate {}
140
141 let ctx = HFGETemplate {};
142 Helper::write_file(
143 &Helper::get_output_dir().join("projects/hfge/index.html"),
144 &ctx.render_once().unwrap().as_bytes(),
145 )
146 .await
147 .unwrap();
148 }
149
150 async fn generate_contact_page() {
151 // contact:
152 #[derive(TemplateSimple)]
153 #[template(path = "contact.stpl")]
154 struct ContactTemplate {}
155
156 let ctx = ContactTemplate {};
157 Helper::write_file(
158 &Helper::get_output_dir().join("contact/index.html"),
159 &ctx.render_once().unwrap().as_bytes(),
160 )
161 .await
162 .unwrap();
163 }
164
165 pub async fn generate_root_index(shared: Arc<CoreShared>) {
166 let lock = shared.state.lock().unwrap();
167
168 // write page to disk:
169 Helper::write_file_sync(
170 &Helper::get_output_dir().join("index.html"),
171 &lock.render().unwrap().as_bytes(),
172 )
173 .unwrap();
174 }