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",
 | 
					 "fluent-resmgr",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "ovlach_data",
 | 
					 "ovlach_data",
 | 
				
			||||||
 | 
					 "phf",
 | 
				
			||||||
 "reqwest",
 | 
					 "reqwest",
 | 
				
			||||||
 "rocket",
 | 
					 "rocket",
 | 
				
			||||||
 "rocket_dyn_templates",
 | 
					 "rocket_dyn_templates",
 | 
				
			||||||
@ -1410,6 +1411,7 @@ version = "0.11.2"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
 | 
					checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "phf_macros",
 | 
				
			||||||
 "phf_shared",
 | 
					 "phf_shared",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1433,6 +1435,19 @@ dependencies = [
 | 
				
			|||||||
 "rand",
 | 
					 "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]]
 | 
					[[package]]
 | 
				
			||||||
name = "phf_shared"
 | 
					name = "phf_shared"
 | 
				
			||||||
version = "0.11.2"
 | 
					version = "0.11.2"
 | 
				
			||||||
 | 
				
			|||||||
@ -20,3 +20,4 @@ sha256 = "1.4.0"
 | 
				
			|||||||
fluent-bundle = "0.15.2"
 | 
					fluent-bundle = "0.15.2"
 | 
				
			||||||
fluent-resmgr = "0.0.6"
 | 
					fluent-resmgr = "0.0.6"
 | 
				
			||||||
unic-langid = "0.9.1"
 | 
					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::{*, fairing::AdHoc};
 | 
				
			||||||
use rocket_dyn_templates::{Template, tera::Value};
 | 
					use rocket_dyn_templates::Template;
 | 
				
			||||||
use ::serde::Deserialize;
 | 
					use ::serde::Deserialize;
 | 
				
			||||||
use tools::tera::{static_filter, translate_filter, calculate_age, insert_space_every, lang_entity, gravatar_link};
 | 
					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>()
 | 
					        AdHoc::config::<PresentationConfig>()
 | 
				
			||||||
    ).attach(
 | 
					    ).attach(
 | 
				
			||||||
        AdHoc::config::<CVBackendConfig>()
 | 
					        AdHoc::config::<CVBackendConfig>()
 | 
				
			||||||
 | 
					    ).attach(
 | 
				
			||||||
 | 
					        tools::rocket::RequestTimer
 | 
				
			||||||
    ).mount("/", routes![
 | 
					    ).mount("/", routes![
 | 
				
			||||||
        routes::root::index
 | 
					        routes::root::index,
 | 
				
			||||||
 | 
					        routes::root::index_without_lang
 | 
				
			||||||
    ])
 | 
					    ])
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
use log::error;
 | 
					use log::error;
 | 
				
			||||||
use ovlach_data::cv::cv::CV;
 | 
					use ovlach_data::cv::cv::CV;
 | 
				
			||||||
use rocket::{get, State, response::status::NotFound, http::Status};
 | 
					use rocket::{get, State, response::Redirect, http::Status};
 | 
				
			||||||
use rocket_dyn_templates::{Template, context};
 | 
					use rocket_dyn_templates::Template;
 | 
				
			||||||
use serde::Serialize;
 | 
					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)]
 | 
					#[derive(Serialize, Debug)]
 | 
				
			||||||
struct RootPage {
 | 
					struct RootPage {
 | 
				
			||||||
@ -14,14 +14,14 @@ struct RootPage {
 | 
				
			|||||||
    lang: String,
 | 
					    lang: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/")]
 | 
					#[get("/<language>")]
 | 
				
			||||||
pub async fn index(presentation_config: &State<PresentationConfig>, cv_config: &State<CVBackendConfig>) -> Result<Template, Status> {
 | 
					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 {
 | 
					    let context = match fetch_cv_data_from_backend(cv_config.cv_backend_path.clone()).await {
 | 
				
			||||||
        Ok(cv) => RootPage {
 | 
					        Ok(cv) => RootPage {
 | 
				
			||||||
            static_host: presentation_config.static_route.clone(),
 | 
					            static_host: presentation_config.static_route.clone(),
 | 
				
			||||||
            cv,
 | 
					            cv,
 | 
				
			||||||
            download_cv_url: "FIXME!".to_string(),
 | 
					            download_cv_url: "FIXME!".to_string(),
 | 
				
			||||||
            lang: "en".to_string(),
 | 
					            lang: language.language,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        Err(e) => {
 | 
					        Err(e) => {
 | 
				
			||||||
            error!("Can't fetch CV data from backend {:?}", 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))
 | 
					    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 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 log::error;
 | 
				
			||||||
use rocket_dyn_templates::tera::{Value, Error};
 | 
					use rocket_dyn_templates::tera::{Value, Error};
 | 
				
			||||||
use ovlach_data::cv::chrono::from_string;
 | 
					use ovlach_data::cv::chrono::from_string;
 | 
				
			||||||
use sha256::{digest, try_digest};
 | 
					use sha256::digest;
 | 
				
			||||||
use fluent_resmgr::resource_manager::ResourceManager;
 | 
					use fluent_resmgr::resource_manager::ResourceManager;
 | 
				
			||||||
use tokio::sync::broadcast::error;
 | 
					 | 
				
			||||||
use unic_langid::LanguageIdentifier;
 | 
					use unic_langid::LanguageIdentifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: tenhle modul je trochu prasacky..
 | 
					// TODO: tenhle modul je trochu prasacky..
 | 
				
			||||||
@ -23,9 +22,10 @@ pub fn translate_filter(
 | 
				
			|||||||
    value: &Value,
 | 
					    value: &Value,
 | 
				
			||||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
					    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
				
			||||||
) -> Result<Value, Error> {
 | 
					) -> Result<Value, Error> {
 | 
				
			||||||
 | 
					    // TODO: prepis me!
 | 
				
			||||||
    let mgr = ResourceManager::new("./resources/{locale}/{res_id}".into());
 | 
					    let mgr = ResourceManager::new("./resources/{locale}/{res_id}".into());
 | 
				
			||||||
    let locales = vec![LanguageIdentifier::from_str("en-US").unwrap()];
 | 
					    let lang = args["lang"].as_str().unwrap();
 | 
				
			||||||
    let val_id = vec![value.as_str().unwrap().to_string()];
 | 
					    let locales = vec![LanguageIdentifier::from_str(lang).unwrap()];
 | 
				
			||||||
    let val = value.as_str().unwrap().to_string();
 | 
					    let val = value.as_str().unwrap().to_string();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    let bundle = mgr.get_bundle(locales, vec!["ovlach_frontend".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(
 | 
					pub fn lang_entity(
 | 
				
			||||||
    value: &Value,
 | 
					    value: &Value,
 | 
				
			||||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
					    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
				
			||||||
) -> Result<Value, Error> {
 | 
					) -> Result<Value, Error> {
 | 
				
			||||||
    error!("{:?}", value); // TODO: rewrite me!!!
 | 
					    error!("{:?}", value); // TODO: rewrite me!!!
 | 
				
			||||||
    return Ok(rocket_dyn_templates::tera::Value::String(format!("{}", value["en"].as_str().unwrap()))); // TODO: fix-me here!
 | 
					    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(
 | 
					pub fn gravatar_link(
 | 
				
			||||||
    value: &Value,
 | 
					    value: &Value,
 | 
				
			||||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
					    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
				
			||||||
) -> Result<Value, Error> {
 | 
					) -> Result<Value, Error> {
 | 
				
			||||||
    let val = digest(value.as_str().unwrap());
 | 
					    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!
 | 
					    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,
 | 
					        value: &Value,
 | 
				
			||||||
        args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
					        args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
				
			||||||
) -> Result<Value, Error> {
 | 
					) -> 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 times = args.get("times").unwrap().as_u64().unwrap();
 | 
				
			||||||
    let mut result = String::new();
 | 
					    let mut result = String::new();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -88,7 +88,7 @@ pub fn insert_space_every(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub fn calculate_age(
 | 
					pub fn calculate_age(
 | 
				
			||||||
    value: &Value,
 | 
					    value: &Value,
 | 
				
			||||||
    args: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
					    _: &HashMap<String, rocket_dyn_templates::tera::Value>
 | 
				
			||||||
) -> Result<Value, Error> {
 | 
					) -> Result<Value, Error> {
 | 
				
			||||||
    error!("{:?}", value.as_str());
 | 
					    error!("{:?}", value.as_str());
 | 
				
			||||||
    //let s = value.to_string().trim_matches('"'); // TODO: unwrap here!
 | 
					    //let s = value.to_string().trim_matches('"'); // TODO: unwrap here!
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user