about summary refs log tree commit diff
path: root/splorm/src/handler/quark/index.rs
blob: 314e9dc5f0193cacc17cd953bedc595720f8d31c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! quark index page

use std::{str::FromStr, sync::Arc};

use axum::{
	Extension,
	body::Body,
	extract::RawQuery,
	http::{StatusCode, header},
	response::Response,
};
use sessionhash::RequestContext;
use somethings::auth::Session;
use wikarden::Wikarden;

use crate::{
	Query, RuntimeError,
	config::Settings,
	extractor::Wrap,
	fs::RequestPath,
	handler::{
		quark::{markup::PageTemplate, open_template_path},
		temporary_redirect,
	},
};

/// GET `/quark` and GET `/quark?create`
///
/// Returns the index page as set in [`Settings`].
///
/// Redirects requests with the `"edit"` query boolean-parameter to the page
/// editing path
pub async fn index(
	Extension(wikarden): Extension<Arc<Wikarden>>,
	Extension(settings): Extension<Settings>,
	maybe_session: Option<Wrap<Session>>,
	ctx: RequestContext,
	RawQuery(rquery): RawQuery,
) -> Result<Response, RuntimeError> {
	tracing::info!("{ctx} GET /quark");

	if let Some(rq) = rquery {
		if let Ok(q) = Query::from_str(&rq) {
			if maybe_session.is_none() {
				return Err(RuntimeError::Generic403);
			}

			if q.has("create") {
				return index_page_create(settings, &wikarden).await;
			}

			if q.has("edit") {
				let index = settings.wikarden_index();
				return temporary_redirect(format!("{index}?edit")).await;
			}
		}
	}

	let quark_index = settings.wikarden_index();
	PageTemplate::new(&settings, &wikarden, quark_index)
		.set_with_tools(maybe_session.is_some())
		.set_can_be_deleted(false)
		.rendered_response()
		.await
}

/// page creation handler
///
/// [`index()`] calls this if the `"create"` query boolean-parameter is set
async fn index_page_create(settings: Settings, wik: &Wikarden) -> Result<Response, RuntimeError> {
	let template_path = settings.quark_template_dir().join("minimal.html");
	let mut template = super::open_template_path(template_path, &settings).await?;

	let template_path = RequestPath::verify_safe(settings.root(), "quark/create.html")?;
	let mut create_template = open_template_path(*template_path.system_path(), &settings).await?;

	let sections = wik.sections().await;
	if !sections.is_empty() {
		if let Some(data_pat) = create_template.get_pattern("sections-data") {
			let list_pat = create_template.get_pattern("sections-list").unwrap();

			for section in sections {
				let mut data = data_pat.clone();
				data.set("section", format!("{section}/"));
				create_template.set_pattern(data);

				let mut list = list_pat.clone();
				list.set("section", section);
				create_template.set_pattern(list);
			}
		}
	} else {
		let mut list_pat = create_template.get_pattern("sections-list").unwrap();
		list_pat.set("section", "no sections");
		create_template.set_pattern(list_pat);
	}

	template.set("mainClass", "main-create");
	template.set("quarkForm", "true");
	template.set("main", create_template.compile());

	Response::builder()
		.status(StatusCode::OK)
		.header(header::CONTENT_TYPE, "text/html")
		.body(Body::from(template.compile()))
		.map_err(|_| RuntimeError::Unknown)
}