diff options
Diffstat (limited to 'src/cache/font.rs')
| -rw-r--r-- | src/cache/font.rs | 58 | 
1 files changed, 58 insertions, 0 deletions
diff --git a/src/cache/font.rs b/src/cache/font.rs new file mode 100644 index 0000000..c17247d --- /dev/null +++ b/src/cache/font.rs @@ -0,0 +1,58 @@ +use std::sync::Arc; +use std::time::Duration; +use std::sync::LazyLock; + +use tokio::sync::RwLock; +use reqwest::{StatusCode, Client}; + +use super::{CacheFuture, CacheGetter, Cache, AsyncCache}; +use crate::CONFIG; + +#[derive(serde::Deserialize, Debug, Default)] +#[serde(default)] +#[serde(rename = "kebab-case")] +pub struct FontQuery { +  pub font: Option<Arc<str>>, +  pub include_font: Option<Arc<str>>, +  pub google_font: Option<Arc<str>>, +//  pub small_font: Option<()> +} + +pub type FontFuture = CacheFuture<Arc<str>>; +pub type FontGetter = CacheGetter<Arc<str>>; +pub type FontCache  = Cache<Arc<str>>; + +fn font_getter(fontname: &String) -> FontFuture { +  let fontname = urlencoding::encode(fontname.as_ref()).to_string(); +  Box::pin(async move { +    let Some(google_api_key) = CONFIG.google_api_key.clone() +    else { +      unreachable!(); +    }; + +    let fontreq = HTTP.get(format!("https://www.googleapis.com/webfonts/v1/webfonts?key={}&family={fontname}", google_api_key)) +      .send().await +      .map_err(|e| {log::error!("Failed to get info for font `{fontname}`: {e}"); (StatusCode::SERVICE_UNAVAILABLE, "Couldn't connect to Google Fonts!")})?; +    if fontreq.status() == StatusCode::NOT_FOUND { return Err((StatusCode::NOT_FOUND, "Font does not exist!")); } +    if fontreq.status() == StatusCode::FORBIDDEN { +      log::error!("Invalid Google API key in config!"); +      return Err((StatusCode::SERVICE_UNAVAILABLE, "This instance is not configured to support Google Fonts properly, please use a different font.")); +    } + +    let cssreq = HTTP.get(format!("https://fonts.googleapis.com/css2?family={fontname}")) +      .send().await +      .map_err(|e| {log::error!("Failed to get CSS for font `{fontname}`: {e}"); (StatusCode::SERVICE_UNAVAILABLE, "Couldn't download font CSS!")})?; + +    Ok(cssreq.text().await.unwrap().into()) +  }) +} + +static HTTP: LazyLock<Client> = crate::http::lazy(); + +static FONT_CACHE: LazyLock<FontCache> =  LazyLock::new(|| { +  Arc::new(RwLock::new(AsyncCache::new(Duration::from_secs(86400), font_getter as FontGetter))) +}); + +pub async fn get_fontinfo(font: &String) -> Result<Arc<str>, (StatusCode, &'static str)> { +  FONT_CACHE.write().await.get_owned(font).await +}  | 
