translations #2
This commit is contained in:
		
							parent
							
								
									07c02052fd
								
							
						
					
					
						commit
						6efbfc0e9c
					
				
							
								
								
									
										15
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										15
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -1288,6 +1288,7 @@ dependencies = [
 | 
			
		||||
 "fluent-resmgr",
 | 
			
		||||
 "log",
 | 
			
		||||
 "ovlach_data",
 | 
			
		||||
 "phf",
 | 
			
		||||
 "reqwest",
 | 
			
		||||
 "rocket",
 | 
			
		||||
 "rocket_dyn_templates",
 | 
			
		||||
@ -1410,6 +1411,7 @@ version = "0.11.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_macros",
 | 
			
		||||
 "phf_shared",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1433,6 +1435,19 @@ dependencies = [
 | 
			
		||||
 "rand",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf_macros"
 | 
			
		||||
version = "0.11.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_generator",
 | 
			
		||||
 "phf_shared",
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf_shared"
 | 
			
		||||
version = "0.11.2"
 | 
			
		||||
 | 
			
		||||
@ -20,3 +20,4 @@ sha256 = "1.4.0"
 | 
			
		||||
fluent-bundle = "0.15.2"
 | 
			
		||||
fluent-resmgr = "0.0.6"
 | 
			
		||||
unic-langid = "0.9.1"
 | 
			
		||||
phf = { version = "0.11.2", features = ["macros"] }
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
use rocket::{*, fairing::AdHoc};
 | 
			
		||||
use rocket_dyn_templates::{Template, tera::Value};
 | 
			
		||||
use rocket_dyn_templates::Template;
 | 
			
		||||
use ::serde::Deserialize;
 | 
			
		||||
use tools::tera::{static_filter, translate_filter, calculate_age, insert_space_every, lang_entity, gravatar_link};
 | 
			
		||||
 | 
			
		||||
@ -44,7 +42,10 @@ pub fn rocket_builder() -> Rocket<Build> {
 | 
			
		||||
        AdHoc::config::<PresentationConfig>()
 | 
			
		||||
    ).attach(
 | 
			
		||||
        AdHoc::config::<CVBackendConfig>()
 | 
			
		||||
    ).attach(
 | 
			
		||||
        tools::rocket::RequestTimer
 | 
			
		||||
    ).mount("/", routes![
 | 
			
		||||
        routes::root::index
 | 
			
		||||
        routes::root::index,
 | 
			
		||||
        routes::root::index_without_lang
 | 
			
		||||
    ])
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
use log::error;
 | 
			
		||||
use ovlach_data::cv::cv::CV;
 | 
			
		||||
use rocket::{get, State, response::status::NotFound, http::Status};
 | 
			
		||||
use rocket_dyn_templates::{Template, context};
 | 
			
		||||
use rocket::{get, State, response::Redirect, http::Status};
 | 
			
		||||
use rocket_dyn_templates::Template;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
 | 
			
		||||
use crate::{PresentationConfig, services::cv::fetch_cv_data_from_backend, CVBackendConfig};
 | 
			
		||||
use crate::{PresentationConfig, services::cv::fetch_cv_data_from_backend, CVBackendConfig, tools::rocket::RequestLanguage};
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Debug)]
 | 
			
		||||
struct RootPage {
 | 
			
		||||
@ -14,14 +14,14 @@ struct RootPage {
 | 
			
		||||
    lang: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/")]
 | 
			
		||||
pub async fn index(presentation_config: &State<PresentationConfig>, cv_config: &State<CVBackendConfig>) -> Result<Template, Status> {
 | 
			
		||||
#[get("/<language>")]
 | 
			
		||||
pub async fn index(presentation_config: &State<PresentationConfig>, cv_config: &State<CVBackendConfig>, language: RequestLanguage) -> Result<Template, Status> {
 | 
			
		||||
    let context = match fetch_cv_data_from_backend(cv_config.cv_backend_path.clone()).await {
 | 
			
		||||
        Ok(cv) => RootPage {
 | 
			
		||||
            static_host: presentation_config.static_route.clone(),
 | 
			
		||||
            cv,
 | 
			
		||||
            download_cv_url: "FIXME!".to_string(),
 | 
			
		||||
            lang: "en".to_string(),
 | 
			
		||||
            lang: language.language,
 | 
			
		||||
        },
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("Can't fetch CV data from backend {:?}", e);
 | 
			
		||||
@ -29,7 +29,12 @@ pub async fn index(presentation_config: &State<PresentationConfig>, cv_config: &
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //return Templ;
 | 
			
		||||
 | 
			
		||||
    Ok(Template::render("default", &context))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[get("/")]
 | 
			
		||||
pub fn index_without_lang() -> Redirect {
 | 
			
		||||
    // Default language is czech (TODO: config)
 | 
			
		||||
    Redirect::to(format!("{}/{}", "", "cs"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1 +1,2 @@
 | 
			
		||||
pub mod tera;
 | 
			
		||||
pub mod rocket;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										83
									
								
								src/tools/rocket.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/tools/rocket.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
			
		||||
use std::time::SystemTime;
 | 
			
		||||
use log::info;
 | 
			
		||||
use rocket::{Request, Response, Data, fairing::{Kind, Info, Fairing}, request::{self, FromRequest, FromParam}, http::Status};
 | 
			
		||||
use phf::phf_map;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub struct RequestLanguage {
 | 
			
		||||
    pub language: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static LANG_TO_CODES: phf::Map<&'static str, &'static str> = phf_map! {
 | 
			
		||||
    "cs" => "cs-CZ",
 | 
			
		||||
    "en" => "en-US",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
impl<'r> FromParam<'r> for RequestLanguage {
 | 
			
		||||
    type Error = &'r str;
 | 
			
		||||
 | 
			
		||||
    fn from_param(param: &'r str) -> Result<Self, Self::Error> {
 | 
			
		||||
        match LANG_TO_CODES.get(param) {
 | 
			
		||||
            Some(val) => Ok(RequestLanguage {
 | 
			
		||||
                language: val.to_string(),
 | 
			
		||||
            }),
 | 
			
		||||
            None => Ok(RequestLanguage {
 | 
			
		||||
                language: LANG_TO_CODES["en"].to_string(),
 | 
			
		||||
            }),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Fairing for timing requests.
 | 
			
		||||
pub struct RequestTimer;
 | 
			
		||||
 | 
			
		||||
/// Value stored in request-local state.
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
struct TimerStart(Option<SystemTime>);
 | 
			
		||||
 | 
			
		||||
#[rocket::async_trait]
 | 
			
		||||
impl Fairing for RequestTimer {
 | 
			
		||||
    fn info(&self) -> Info {
 | 
			
		||||
        Info {
 | 
			
		||||
            name: "Request Timer",
 | 
			
		||||
            kind: Kind::Request | Kind::Response
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Stores the start time of the request in request-local state.
 | 
			
		||||
    async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) {
 | 
			
		||||
        // Store a `TimerStart` instead of directly storing a `SystemTime`
 | 
			
		||||
        // to ensure that this usage doesn't conflict with anything else
 | 
			
		||||
        // that might store a `SystemTime` in request-local cache.
 | 
			
		||||
        request.local_cache(|| TimerStart(Some(SystemTime::now())));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Adds a header to the response indicating how long the server took to
 | 
			
		||||
    /// process the request.
 | 
			
		||||
    async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
 | 
			
		||||
        let start_time = req.local_cache(|| TimerStart(None));
 | 
			
		||||
        if let Some(Ok(duration)) = start_time.0.map(|st| st.elapsed()) {
 | 
			
		||||
            let ms = duration.as_secs() * 1000 + duration.subsec_millis() as u64;
 | 
			
		||||
            res.set_raw_header("X-Response-Time", format!("{} ms", ms));
 | 
			
		||||
            info!("Response time: {} ms", ms);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Request guard used to retrieve the start time of a request.
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
pub struct StartTime(pub SystemTime);
 | 
			
		||||
 | 
			
		||||
// Allows a route to access the time a request was initiated.
 | 
			
		||||
#[rocket::async_trait]
 | 
			
		||||
impl<'r> FromRequest<'r> for StartTime {
 | 
			
		||||
    type Error = ();
 | 
			
		||||
 | 
			
		||||
    async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
 | 
			
		||||
        match *request.local_cache(|| TimerStart(None)) {
 | 
			
		||||
            TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
 | 
			
		||||
            TimerStart(None) => request::Outcome::Error((Status::InternalServerError, ())),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -4,9 +4,8 @@ use chrono::{Utc, Datelike};
 | 
			
		||||
use log::error;
 | 
			
		||||
use rocket_dyn_templates::tera::{Value, Error};
 | 
			
		||||
use ovlach_data::cv::chrono::from_string;
 | 
			
		||||
use sha256::{digest, try_digest};
 | 
			
		||||
use sha256::digest;
 | 
			
		||||
use fluent_resmgr::resource_manager::ResourceManager;
 | 
			
		||||
use tokio::sync::broadcast::error;
 | 
			
		||||
use unic_langid::LanguageIdentifier;
 | 
			
		||||
 | 
			
		||||
// TODO: tenhle modul je trochu prasacky..
 | 
			
		||||
@ -23,9 +22,10 @@ pub fn translate_filter(
 | 
			
		||||
    value: &Value,
 | 
			
		||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    // TODO: prepis me!
 | 
			
		||||
    let mgr = ResourceManager::new("./resources/{locale}/{res_id}".into());
 | 
			
		||||
    let locales = vec![LanguageIdentifier::from_str("en-US").unwrap()];
 | 
			
		||||
    let val_id = vec![value.as_str().unwrap().to_string()];
 | 
			
		||||
    let lang = args["lang"].as_str().unwrap();
 | 
			
		||||
    let locales = vec![LanguageIdentifier::from_str(lang).unwrap()];
 | 
			
		||||
    let val = value.as_str().unwrap().to_string();
 | 
			
		||||
    
 | 
			
		||||
    let bundle = mgr.get_bundle(locales, vec!["ovlach_frontend".to_string()]);
 | 
			
		||||
@ -54,7 +54,7 @@ pub fn translate_filter(
 | 
			
		||||
 | 
			
		||||
pub fn lang_entity(
 | 
			
		||||
    value: &Value,
 | 
			
		||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    error!("{:?}", value); // TODO: rewrite me!!!
 | 
			
		||||
    return Ok(rocket_dyn_templates::tera::Value::String(format!("{}", value["en"].as_str().unwrap()))); // TODO: fix-me here!
 | 
			
		||||
@ -62,7 +62,7 @@ pub fn lang_entity(
 | 
			
		||||
 | 
			
		||||
pub fn gravatar_link(
 | 
			
		||||
    value: &Value,
 | 
			
		||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    let val = digest(value.as_str().unwrap());
 | 
			
		||||
    return Ok(rocket_dyn_templates::tera::Value::String(format!("https://gravatar.com/avatar/{}", val))); // TODO: fix-me here!
 | 
			
		||||
@ -72,7 +72,7 @@ pub fn insert_space_every(
 | 
			
		||||
        value: &Value,
 | 
			
		||||
        args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    let mut input = value.as_u64().unwrap().to_string();
 | 
			
		||||
    let input = value.as_u64().unwrap().to_string();
 | 
			
		||||
    let times = args.get("times").unwrap().as_u64().unwrap();
 | 
			
		||||
    let mut result = String::new();
 | 
			
		||||
    
 | 
			
		||||
@ -88,7 +88,7 @@ pub fn insert_space_every(
 | 
			
		||||
 | 
			
		||||
pub fn calculate_age(
 | 
			
		||||
    value: &Value,
 | 
			
		||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    error!("{:?}", value.as_str());
 | 
			
		||||
    //let s = value.to_string().trim_matches('"'); // TODO: unwrap here!
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user