asklyphe/asklyphe-frontend/src/routes/announcement.rs
2025-03-19 20:58:23 -07:00

119 lines
4.5 KiB
Rust

/*
* asklyphe-frontend routes/announcement.rs
* - http routes for announcements
*
* Copyright (C) 2025 Real Microsoft, LLC
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::sync::Arc;
use askama::Template;
use asklyphe_common::nats::authservice::{AuthServiceQuery, AuthServiceRequest, AuthServiceResponse};
use asklyphe_common::nats::authservice::announcements::{AnnouncementFullRequest, AnnouncementFullResponse, LatestAnnouncementRequest, LatestAnnouncementResponse};
use asklyphe_common::nats::comms;
use asklyphe_common::nats::comms::ServiceResponse;
use async_nats::jetstream;
use axum::Extension;
use axum::extract::Path;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use serde::Serialize;
use tracing::{debug, error};
use tracing::log::warn;
use crate::{Opts, ALPHA, BUILT_ON, GIT_COMMIT, VERSION, YEAR};
use crate::routes::index::FrontpageAnnouncement;
use crate::routes::Themes;
#[derive(Serialize, Debug)]
struct FullAnnouncement {
title: String,
date: String,
creator: String,
full: String
}
async fn announcement(nats: Arc<jetstream::Context>, slug: String) -> Option<FullAnnouncement> {
let response = comms::query_service(
comms::Query::AuthService(AuthServiceQuery {
request: AuthServiceRequest::AnnouncementFullRequest(AnnouncementFullRequest { slug }),
replyto: "".to_string(),
}),
&nats,
false,
).await;
if let Err(e) = response {
error!("nats error: {:?}", e);
None
} else {
let response = response.unwrap();
match response {
ServiceResponse::SearchService(_) => {
error!("sent search service response when asking for auth service!! investigate ASAP!!!");
None
}
ServiceResponse::BingService(_) => {
error!("sent bing service response when asking for auth service!! investigate ASAP!!!");
None
}
ServiceResponse::AuthService(r) => match r {
AuthServiceResponse::AnnouncementFullResponse(v) => {
match v {
AnnouncementFullResponse::Some(v) => {
Some(FullAnnouncement {
title: v.title,
date: chrono::DateTime::from_timestamp(v.created_on, 0).unwrap().to_rfc2822(),
creator: v.creator,
full: v.markdown_text.replace("\n", "<br/>"),
})
}
AnnouncementFullResponse::NotFound => {
None
}
AnnouncementFullResponse::InternalServerError(e) => {
warn!("internal server error while getting announcement: {}", e);
None
}
}
}
x => {
error!("auth service gave {} to our user info request!", x);
None
}
},
}
}
}
#[derive(Template)]
#[template(path = "announcement.html")]
pub struct AnnouncementTemplate {
version: String,
git_commit: String,
built_on: String,
year: String,
alpha: bool,
theme: Themes,
announcement: FullAnnouncement,
}
pub async fn announcement_full(Extension(nats): Extension<Arc<jetstream::Context>>, Extension(opts): Extension<Opts>, Path(slug): Path<String>) -> impl IntoResponse {
debug!("looking up {slug}");
if let Some(announcement) = announcement(nats.clone(), slug.clone()).await {
AnnouncementTemplate {
version: VERSION.to_string(),
git_commit: GIT_COMMIT.to_string(),
built_on: BUILT_ON.to_string(),
year: YEAR.to_string(),
alpha: ALPHA,
theme: Themes::Default,
announcement,
}.into_response()
} else {
StatusCode::NOT_FOUND.into_response()
}
}