1use crate::{
2 auth::RequestExt as _, github::Release, AppState, LayoutData, Request, RequestExt as _,
3};
4use comrak::ComrakOptions;
5use serde::{Deserialize, Serialize};
6use std::sync::Arc;
7use tide::{http::mime, log, Server};
8
9pub fn add_routes(app: &mut Server<Arc<AppState>>) {
10 app.at("/").get(get_home);
11 app.at("/signups").post(post_signup);
12 app.at("/releases/:tag_name/:name").get(get_release_asset);
13}
14
15async fn get_home(mut request: Request) -> tide::Result {
16 #[derive(Serialize)]
17 struct HomeData {
18 #[serde(flatten)]
19 layout: Arc<LayoutData>,
20 releases: Option<Vec<Release>>,
21 }
22
23 let mut data = HomeData {
24 layout: request.layout_data().await?,
25 releases: None,
26 };
27
28 if let Some(user) = request.current_user().await? {
29 if user.is_insider {
30 data.releases = Some(
31 request
32 .state()
33 .repo_client
34 .releases()
35 .await?
36 .into_iter()
37 .filter_map(|mut release| {
38 if release.draft {
39 None
40 } else {
41 let mut options = ComrakOptions::default();
42 options.render.unsafe_ = true; // Allow raw HTML in the markup. We control these release notes anyway.
43 release.body = comrak::markdown_to_html(&release.body, &options);
44 Some(release)
45 }
46 })
47 .collect(),
48 );
49 }
50 }
51
52 Ok(tide::Response::builder(200)
53 .body(request.state().render_template("home.hbs", &data)?)
54 .content_type(mime::HTML)
55 .build())
56}
57
58async fn post_signup(mut request: Request) -> tide::Result {
59 #[derive(Debug, Deserialize)]
60 struct Form {
61 github_login: String,
62 email_address: String,
63 about: String,
64 #[serde(default)]
65 wants_releases: bool,
66 #[serde(default)]
67 wants_updates: bool,
68 #[serde(default)]
69 wants_community: bool,
70 }
71
72 let mut form: Form = request.body_form().await?;
73 form.github_login = form
74 .github_login
75 .strip_prefix("@")
76 .map(str::to_string)
77 .unwrap_or(form.github_login);
78
79 log::info!("Signup submitted: {:?}", form);
80
81 // Save signup in the database
82 request
83 .db()
84 .create_signup(
85 &form.github_login,
86 &form.email_address,
87 &form.about,
88 form.wants_releases,
89 form.wants_updates,
90 form.wants_community,
91 )
92 .await?;
93
94 let layout_data = request.layout_data().await?;
95 Ok(tide::Response::builder(200)
96 .body(
97 request
98 .state()
99 .render_template("signup.hbs", &layout_data)?,
100 )
101 .content_type(mime::HTML)
102 .build())
103}
104
105async fn get_release_asset(request: Request) -> tide::Result {
106 let body = request
107 .state()
108 .repo_client
109 .release_asset(request.param("tag_name")?, request.param("name")?)
110 .await?;
111
112 Ok(tide::Response::builder(200)
113 .header("Cache-Control", "no-transform")
114 .content_type(mime::BYTE_STREAM)
115 .body(body)
116 .build())
117}