Working template configuration file

This commit is contained in:
Slatian 2023-02-19 23:12:43 +01:00
parent d4caf1a77c
commit 2abc5844ad
5 changed files with 48 additions and 10 deletions

View File

@ -34,6 +34,7 @@ pub struct GeoIpConfig {
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct TemplateConfig { pub struct TemplateConfig {
pub template_location: String, pub template_location: String,
pub extra_config: Option<String>,
} }
impl Default for ServerConfig { impl Default for ServerConfig {
@ -69,6 +70,7 @@ impl Default for TemplateConfig {
fn default() -> Self { fn default() -> Self {
TemplateConfig { TemplateConfig {
template_location: "templates/".to_string(), template_location: "templates/".to_string(),
extra_config: None,
} }
} }
} }

View File

@ -72,7 +72,7 @@ struct ServiceSharedState {
} }
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, long_about="None")] #[command(author, version, long_about="A web service that tells you your ip-address and more …")]
struct CliArgs { struct CliArgs {
#[arg(short, long)] #[arg(short, long)]
config: Option<String>, config: Option<String>,
@ -80,6 +80,8 @@ struct CliArgs {
listen_on: Option<String>, listen_on: Option<String>,
#[arg(short, long)] #[arg(short, long)]
templates: Option<String>, templates: Option<String>,
#[arg(short,long)]
extra_config: Option<String>,
} }
fn match_domain_hidden_list(domain: &String, hidden_list: &Vec<String>) -> bool { fn match_domain_hidden_list(domain: &String, hidden_list: &Vec<String>) -> bool {
@ -93,6 +95,23 @@ fn match_domain_hidden_list(domain: &String, hidden_list: &Vec<String>) -> bool
return false; return false;
} }
fn read_toml_from_file<T: for<'de> serde::Deserialize<'de>>(path: &String) -> Option<T> {
let text = match fs::read_to_string(path) {
Ok(t) => t,
Err(e) => {
println!("Error while reading file '{path}': {e}");
return None;
}
};
match toml::from_str(&text) {
Ok(t) => Some(t),
Err(e) => {
println!("Unable to parse file '{path}':\n{e}");
return None;
}
}
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
// Parse Command line arguments // Parse Command line arguments
@ -101,12 +120,10 @@ async fn main() {
// Read configuration file // Read configuration file
let config: config::EchoIpServiceConfig = match cli_args.config { let config: config::EchoIpServiceConfig = match cli_args.config {
Some(config_path) => { Some(config_path) => {
let config_text = fs::read_to_string(config_path) match read_toml_from_file::<config::EchoIpServiceConfig>(&config_path) {
.expect("Can't read configuration file!"); Some(c) => c,
match toml::from_str(&config_text) { None => {
Ok(c) => c, println!("Could not read confuration file, exiting.");
Err(e) => {
println!("Unable to parse configuration file:\n{e}");
::std::process::exit(1); ::std::process::exit(1);
} }
} }
@ -114,13 +131,22 @@ async fn main() {
None => Default::default(), None => Default::default(),
}; };
// Initalize Tera templates // Initalize Tera templates
let mut template_base_dir = (&config.template.template_location).to_owned(); let mut template_base_dir = (&config.template.template_location).to_owned();
if !template_base_dir.ends_with("/") { if !template_base_dir.ends_with("/") {
template_base_dir = template_base_dir + "/"; template_base_dir = template_base_dir + "/";
} }
let template_extra_config = match &cli_args.extra_config {
Some(path) => read_toml_from_file(path),
None => match &config.template.extra_config {
Some(path) => read_toml_from_file(path),
None => {
println!("Trying to read default template configuration ...");
println!("(If this fails that may be ok, depending on your template)");
read_toml_from_file(&(template_base_dir.clone()+"extra.toml"))
},
},
};
let template_glob = template_base_dir+"*.html"; let template_glob = template_base_dir+"*.html";
println!("Parsing Templates from '{}' ...", &template_glob); println!("Parsing Templates from '{}' ...", &template_glob);
let res = Tera::new((template_glob).as_str()); let res = Tera::new((template_glob).as_str());
@ -174,6 +200,7 @@ async fn main() {
ServiceSharedState { ServiceSharedState {
templating_engine: templating_engine::Engine{ templating_engine: templating_engine::Engine{
tera: tera, tera: tera,
template_config: template_extra_config,
}, },
dns_resolver: dns_resolver, dns_resolver: dns_resolver,
asn_db: asn_db, asn_db: asn_db,
@ -196,7 +223,7 @@ async fn main() {
println!("Starting Server ..."); println!("Starting Server ...");
axum::Server::bind(&listen_on) axum::Server::bind(&listen_on)
.serve(app.into_make_service()) .serve(app.into_make_service_with_connect_info::<std::net::SocketAddr>())
.await .await
.unwrap(); .unwrap();
} }

View File

@ -11,6 +11,7 @@ use axum::{
response::Json, response::Json,
}; };
use tera::Tera; use tera::Tera;
use toml::Table;
use crate::simple_dns; use crate::simple_dns;
use crate::IpResult; use crate::IpResult;
@ -68,6 +69,7 @@ impl View {
pub struct Engine { pub struct Engine {
pub tera: Tera, pub tera: Tera,
pub template_config: Option<Table>,
} }
impl Engine { impl Engine {
@ -85,6 +87,7 @@ impl Engine {
//intented for shared macros //intented for shared macros
context.insert("format", &format.to_string()); context.insert("format", &format.to_string());
context.insert("data", &view); context.insert("data", &view);
context.insert("extra", &self.template_config);
match self.tera.render(&(template_name+".html"), &context) { match self.tera.render(&(template_name+".html"), &context) {
Ok(html) => Html(html).into_response(), Ok(html) => Html(html).into_response(),

1
templates/extra.toml Normal file
View File

@ -0,0 +1 @@
site_name="echoip-slatecave"

View File

@ -6,6 +6,11 @@
</head> </head>
<body> <body>
{% set r = data.result %} {% set r = data.result %}
<header>
<nav>
<a href="/" class="site-name">{{extra.site_name|default(val="echoip")}}</a>
</nav>
</header>
<h1>Your IP-Address is: {{ data.query.ip }}</h1> <h1>Your IP-Address is: {{ data.query.ip }}</h1>
<section> <section>
<h2>Network Information</h2> <h2>Network Information</h2>