diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/format.rs | 40 | ||||
-rw-r--r-- | src/server.rs | 79 |
2 files changed, 98 insertions, 21 deletions
diff --git a/src/format.rs b/src/format.rs index 801611d..b9da487 100644 --- a/src/format.rs +++ b/src/format.rs @@ -156,7 +156,22 @@ pub fn format_batch_to<'a>( buf, r#"<p><strong>Extra examples (reading practice)</strong></p>"# )?; - // TODO + writeln!( + buf, + r#"<form method="POST" action="gen.html"> + <p>practice levels<p> + <p><select name="first_level" value="0"> + "# + )?; + for val in 0..=i { + write!(buf, r#"<option value="{}">{:03}</option>"#, val, val)?; + } + writeln!( + buf, + r#"</select> - <input type="hidden" name="last_level" value="{}" />{:03}</p> + <p><input type="submit" value="practice random sentences" /></p></form>"#, + i, i + )?; writeln!(buf, "<hr />")?; writeln!(buf, "<p>\(≧▽≦)/</p>")?; @@ -266,6 +281,29 @@ pub fn format_index_to( writeln!(buf, "<hr />")?; + writeln!(buf, r#"<p><strong>Extra reading practice</strong></p>"#)?; + writeln!( + buf, + r#"<form method="POST" action="gen.html"> + <p>practice levels<p> + <p><select name="first_level" value="0"> + "# + )?; + for val in 0..batches.len() { + write!(buf, r#"<option value="{}">{:03}</option>"#, val, val)?; + } + writeln!(buf, r#"</select> - <select name="last_level" value="0">"#)?; + for val in 0..batches.len() { + write!(buf, r#"<option value="{}">{:03}</option>"#, val, val)?; + } + writeln!( + buf, + r#"</select></p> + <p><input type="submit" value="practice random sentences" /></p></form>"# + )?; + + writeln!(buf, "<hr />")?; + let all_chars = Charset::from_iter( batches .iter() diff --git a/src/server.rs b/src/server.rs index c90ee40..774cff4 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,16 +1,16 @@ use std::fs; -use std::io::Write; -use futures::stream::TryStreamExt; use anyhow::{anyhow, Result}; +use futures::stream::TryStreamExt; use rand::prelude::*; +use serde::Deserialize; use http_types::mime; use tide::Request; use crate::datafiles::*; -use crate::format::*; use crate::example::*; +use crate::format::*; use crate::*; pub async fn server_main() -> tide::Result<()> { @@ -85,7 +85,7 @@ pub async fn server_main() -> tide::Result<()> { app.at("/script.js").serve_file("static/script.js")?; app.at("/jquery.js").serve_file("static/jquery.js")?; app.at("/about.html").get(about_page); - app.at("/ex/:start/:end").get(gen_examples_page); + app.at("/gen.html").post(gen_examples_page); app.at("/:batch").get(batch_page); // ---- serve actual http ---- @@ -152,9 +152,16 @@ async fn batch_page(req: Request<State>) -> tide::Result { .build()) } -async fn gen_examples_page(req: Request<State>) -> tide::Result { - let first_level: usize = req.param("start")?.parse()?; - let last_level: usize = req.param("end")?.parse()?; +#[derive(Deserialize)] +struct GenParam { + first_level: usize, + last_level: usize, +} + +async fn gen_examples_page(mut req: Request<State>) -> tide::Result { + let param: GenParam = req.body_form().await?; + let first_level = std::cmp::min(param.first_level, param.last_level); + let last_level = std::cmp::max(param.first_level, param.last_level); let allowed_chars = Charset::from_iter( req.state() @@ -179,15 +186,16 @@ async fn gen_examples_page(req: Request<State>) -> tide::Result { let state: State = req.state(); std::thread::spawn(move || { - tx.send_blocking(Ok(format!(r#" + tx.send_blocking(Ok(format!( + r#" <!DOCTYPE html> <html> <head> <meta charset=\"UTF-8\" /> <title>{:03} - {:03} practice</title> - <link rel="stylesheet" type="text/css" href="/style.css" /> - <script src="/jquery.js"></script> - <script src="/script.js"></script> + <link rel="stylesheet" type="text/css" href="style.css" /> + <script src="jquery.js"></script> + <script src="script.js"></script> </head> <body> <div class="batch_page"> @@ -206,7 +214,10 @@ async fn gen_examples_page(req: Request<State>) -> tide::Result { </div> </div> </body> - "#, first_level, last_level, first_level, last_level).into_bytes()))?; + "#, + first_level, last_level, first_level, last_level + ) + .into_bytes()))?; gen_examples(state, &allowed_chars, &needed_chars, 50, |mut ex| { ex.gen_furigana(&req.state().jmdict_idx, &req.state().furigana_overrides); @@ -221,12 +232,18 @@ async fn gen_examples_page(req: Request<State>) -> tide::Result { if let Some(ents) = state.jmdict_idx.get(keb) { for ent in ents.iter() { let ent_r_ele = ent.children().find(|x| x.has_tag_name("r_ele")).unwrap(); - let ent_reb = ent_r_ele.children().find(|x| x.has_tag_name("reb")).unwrap(); + let ent_reb = ent_r_ele + .children() + .find(|x| x.has_tag_name("reb")) + .unwrap(); let ent_reb = ent_reb.text().unwrap().trim(); if reb.map(|x| x != ent_reb).unwrap_or(false) { continue; } - expl += &format!(r#"<tr><td style="word-break: keep-all"> <span class="tab_large font_ja">{}</span> </td><td width="50%">"#, keb); + expl += &format!( + r#"<tr><td style="word-break: keep-all"> <span class="tab_large font_ja">{}</span> </td><td width="50%">"#, + keb + ); for sense in ent.children().filter(|x| x.has_tag_name("sense")) { if let Some(s) = sense.children().find(|x| x.has_tag_name("gloss")) { @@ -236,7 +253,10 @@ async fn gen_examples_page(req: Request<State>) -> tide::Result { expl += s.text().unwrap().trim(); } } - expl += &format!(r#"</td><td style="word-break: keep-all" class="tab_large font_ja">{}</td></tr>"#, ent_reb); + expl += &format!( + r#"</td><td style="word-break: keep-all" class="tab_large font_ja">{}</td></tr>"#, + ent_reb + ); } } } @@ -247,20 +267,28 @@ async fn gen_examples_page(req: Request<State>) -> tide::Result { "furi": ex.furigana_markup(), "vocab": expl + "</table>", }); - tx.send_blocking(Ok(format!("<script> add_example({}); </script>\n", serde_json::to_string(&item)?).into_bytes()))?; + tx.send_blocking(Ok(format!( + "<script> add_example({}); </script>\n", + serde_json::to_string(&item)? + ) + .into_bytes()))?; Ok(()) })?; tx.send_blocking(Ok(br#" </body> </html> - "#.to_vec()))?; + "# + .to_vec()))?; Ok::<_, anyhow::Error>(()) }); Ok(tide::Response::builder(200) - .body(tide::Body::from_reader(Box::pin(rx).into_async_read(), None)) + .body(tide::Body::from_reader( + Box::pin(rx).into_async_read(), + None, + )) .content_type(mime::HTML) .build()) } @@ -284,7 +312,9 @@ fn gen_examples<F>( count: usize, mut callback: F, ) -> Result<()> -where F: FnMut(Example) -> Result<()> { +where + F: FnMut(Example) -> Result<()>, +{ let mut rng = thread_rng(); let mut generated = 0; @@ -292,7 +322,16 @@ where F: FnMut(Example) -> Result<()> { .examples .iter() .filter(|x| x.chars.diff(&allowed_chars).is_empty() && x.chars.intersects(&needed_chars)) - .map(|ex| (ex, *ex.chars.iter().filter_map(|x| data.example_freq.get(&x)).min().unwrap())) + .map(|ex| { + ( + ex, + *ex.chars + .iter() + .filter_map(|x| data.example_freq.get(&x)) + .min() + .unwrap(), + ) + }) .collect::<Vec<_>>(); let mut remaining_needed = needed_chars.clone(); |