diff --git a/src/email.rs b/src/email.rs index 8ab6bae..826f7af 100644 --- a/src/email.rs +++ b/src/email.rs @@ -1,7 +1,7 @@ +use crate::util::env_var; use crate::Config; use anyhow::anyhow; use lettre::{Message, SmtpTransport, Transport}; -use std::env; pub struct SmtpConfig { address: String, @@ -21,9 +21,9 @@ impl SmtpConfig { } pub async fn from_env() -> anyhow::Result { - let address = env::var("SMTP_ADDRESS")?; - let username = env::var("SMTP_USERNAME")?; - let password = env::var("SMTP_PASSWORD")?; + let address = env_var("SMTP_ADDRESS")?; + let username = env_var("SMTP_USERNAME")?; + let password = env_var("SMTP_PASSWORD")?; let smtp = SmtpConfig { address, username, diff --git a/src/main.rs b/src/main.rs index 415039a..4afa9fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ mod email; mod scrape; mod storage; mod userdb; +mod util; mod workers; use data::*; @@ -30,6 +31,7 @@ use db::Db; use email::SmtpConfig; use storage::Storage; use userdb::{IsSpam, UserDb}; +use util::env_var; // Fetch user data from forgejo from time to time const FORGEJO_POLL_DELAY: Duration = Duration::from_secs(11 * 3600); // 11 hours @@ -63,16 +65,12 @@ pub struct Config { impl Config { async fn from_env() -> anyhow::Result { - let forge_url_s = - std::env::var("FORGE_URL").context("reading the FORGE_URL environment variable")?; - let forge_api_token = - std::env::var("FORGE_API_TOKEN").context("reading the FORGE_API_TOKEN environment variable")?; - let org_name = - std::env::var("ORG_NAME").context("reading the ORG_NAME environment variable")?; - let admin_contact_email = std::env::var("ADMIN_CONTACT_EMAIL") - .context("reading the ADMIN_CONTACT_EMAIL environment variable")?; + let forge_url_s = env_var("FORGE_URL")?; + let forge_api_token = env_var("FORGE_API_TOKEN")?; + let org_name = env_var("ORG_NAME")?; + let admin_contact_email = env_var("ADMIN_CONTACT_EMAIL")?; - let actually_ban = match std::env::var("ACTUALLY_BAN_USERS").as_deref() { + let actually_ban = match env_var("ACTUALLY_BAN_USERS").as_deref() { Ok("true") => ActuallyBan::Yes { smtp: SmtpConfig::from_env().await?, }, @@ -85,13 +83,12 @@ impl Config { Err(_) => ActuallyBan::No, }; - let listen_addr = std::env::var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0")); - let listen_port: u16 = - match std::env::var("LISTEN_PORT").map(|s| u16::from_str_radix(&s, 10)) { - Ok(Err(e)) => return Err(anyhow!("LISTEN_PORT: invalid value ({})", e)), - Ok(Ok(p)) => p, - Err(_) => 8080, - }; + let listen_addr = env_var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0")); + let listen_port: u16 = match env_var("LISTEN_PORT").map(|s| u16::from_str_radix(&s, 10)) { + Ok(Err(e)) => return Err(anyhow!("LISTEN_PORT: invalid value ({})", e)), + Ok(Ok(p)) => p, + Err(_) => 8080, + }; Ok(Config { forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?, @@ -448,15 +445,12 @@ async fn get_static_( Some(page) => { let mime = new_mime_guess::from_path(&filename).first_or_octet_stream(); ([(header::CONTENT_TYPE, mime.to_string())], page.contents()).into_response() - }, + } } } #[tokio::main] async fn main() -> anyhow::Result<()> { - eprintln!("Eval templates"); - let _ = *TEMPLATES; - let config = Arc::new(Config::from_env().await?); let storage = Arc::new(Storage::from_env().await?); let forge = Arc::new(Forgejo::new( @@ -464,6 +458,9 @@ async fn main() -> anyhow::Result<()> { config.forge_url.clone(), )?); + eprintln!("Eval templates"); + let _ = *TEMPLATES; + eprintln!("Load users and repos"); let db = load_db(&storage, &forge).await?; diff --git a/src/storage.rs b/src/storage.rs index e4b9450..f6909c0 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,3 +1,4 @@ +use crate::util::env_var; use anyhow::Context; use aws_sdk_s3 as s3; use std::fs::File; @@ -26,20 +27,16 @@ impl Storage { } pub async fn from_env() -> anyhow::Result { - match std::env::var("STORAGE_BACKEND") - .context("reading the STORAGE_BACKEND environment variable")? - .as_ref() - { + match env_var("STORAGE_BACKEND")?.as_ref() { "local" => { - let dir = match std::env::var("STORAGE_LOCAL_DIR") { + let dir = match env_var("STORAGE_LOCAL_DIR") { Ok(dir) => dir, Err(_) => ".".to_string(), }; Ok(Self::from_local_dir(PathBuf::from(dir))) } "s3" => { - let bucket = std::env::var("STORAGE_S3_BUCKET") - .context("reading the STORAGE_S3_BUCKET environment variable")?; + let bucket = env_var("STORAGE_S3_BUCKET")?; Ok(Self::from_s3(bucket).await) } other => { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..3a446fb --- /dev/null +++ b/src/util.rs @@ -0,0 +1,6 @@ +use anyhow::Context; + +pub fn env_var(name: &str) -> anyhow::Result { + let v = std::env::var(name).context(format!("reading the {} environment variable", name))?; + Ok(v) +}