// Basic router for that server's general website page. // All new servers come with this as a default so that use rocket_contrib::templates::Template; use rocket::response::NamedFile; use std::path::Path; use std::fs::read_to_string; use serde_derive::Deserialize; // Purely for backend purposes #[derive(Serialize, Deserialize, Debug)] pub struct WebsiteConfig { url: Option, // default is freechat.io - clean url of domain favicon: Option, // uri path to the favicon i.e. /media/static/favicon.png motto: Option, opengraph: Option } #[derive(Serialize, Deserialize, Debug)] struct OpenGraph { title: Option, og_type: Option, // prefixing this because type is a keyword in rust smh url: Option, description: Option, image: Option, } pub static mut CTX: WebsiteConfig = WebsiteConfig { url: None, favicon: None, motto: None, opengraph: None, }; // Pages themselves pub fn init() { // Sets up ctx so before the rest of the dispatchers are called let default_path = "configs/website.toml"; let default_config = r#" url="freechat.io" favicon="/static/media/favicon.png" motto="Freely chat with freechat!" # NOTE: discord/slack/linked(especially) love caching things so make sure you # write something that yo're proud of the first time lest u doom yourself to have the # wrong things cahced for a few months # Used to help sites embed some information about your site # Especially when the server's site is linked in another freechat/slack/discord server [opengraph] title="Freechat" # again this has a prefix because `type` is a keyword in rust so just yea og_type="Decentralized chat" url="freechat.io" description="Free and open chat platform" image="/static/media/logo.png" "#; // TODO: when we read from the file we should elegantly say there are errors in the config // instead of going through the basic panic if let Ok(file) = read_to_string(default_path) { // This is the only time we should ever write to CTX thus the unsafe is mostly fine let config: WebsiteConfig = toml::from_str(&file).unwrap(); println!("file contents: {:?}", config); unsafe { CTX.url = config.url; CTX.favicon = config.favicon; CTX.motto = config.motto; if let Some(og) = config.opengraph { CTX.opengraph = Some(OpenGraph { title: config.opengraph.title, config.opengraph_type: config.opengraph.config.opengraph_type, url: config.opengraph.url, description: config.opengraph.description, image: config.opengraph.image, }); } } } else { // No check because default_config is hardcoded into place let config: WebsiteConfig = toml::from_str(default_config).unwrap(); unsafe { CTX.url = config.url; CTX.favicon = config.favicon; CTX.motto = config.motto; } } } #[get("/")] pub fn homepage() -> Template { unsafe { Template::render("index", &CTX) } } #[get("/about")] pub fn about_page() -> Template { unsafe { Template::render("about", &CTX) } } #[get("/servers")] pub fn server_info() -> Template { unsafe { Template::render("servers", &CTX) } } #[get("/static/css/")] pub fn static_css(file: String) -> Option { let mut f = file; f = f.replace("..", ""); f = f.replace("%2e", ""); NamedFile::open(Path::new("static/css/").join(f)).ok() } #[get("/static/js/")] pub fn static_js(file: String) -> Option { let mut f = file; f = f.replace("..", ""); f = f.replace("%2e", ""); NamedFile::open(Path::new("static/js/").join(f)).ok() } #[get("/static/media/")] pub fn static_media(file: String) -> Option { let mut f = file; f = f.replace("..", ""); f = f.replace("%2e", ""); NamedFile::open(Path::new("static/media/").join(f)).ok() }