From b3d8a06fdf6b413cb3708ac02f7b25612a387feb Mon Sep 17 00:00:00 2001 From: Hiers Date: Sat, 16 Dec 2023 19:42:38 +0000 Subject: [PATCH] Working sentence searching. It's working, but the code is not very polished. Will clean it up later. --- src/main.rs | 39 ++++++++++++++++++++++++-- src/sentence_search.rs | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/sentence_search.rs diff --git a/src/main.rs b/src/main.rs index 33c5157..748482e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod word_search; mod kanji_search; +mod sentence_search; mod aux; use std::{ io::{stdin, stdout, Write}, @@ -9,6 +10,7 @@ use std::{ use word_search::word_search; use kanji_search::search_by_radical; +use sentence_search::sentence_search; use argparse::{ArgumentParser, List, Print, Store, StoreTrue}; @@ -20,7 +22,13 @@ macro_rules! JISHO_URL { "https://jisho.org/api/v1/search/words?keyword={}" }; } - +macro_rules! TATOEBA_URL_ENG_QUERY { () => { + "https://tatoeba.org/en/api_v0/search?from=eng&orphans=no&to=jpn&unapproved=no&query={}" + }; +} +macro_rules! TATOEBA_URL_JPN_QUERY { () => { + "https://tatoeba.org/en/api_v0/search?from=jpn&orphans=no&to=eng&unapproved=no&query={}" + }; } fn main() -> Result<(), ureq::Error> { @@ -60,7 +68,34 @@ fn main() -> Result<(), ureq::Error> { if query.starts_with(':') || query.starts_with(':') { /* Kanji search */ search_by_radical(&mut query); - } else { + + } else if query.starts_with('_') || query.starts_with('_'){ /* Sentence search */ + /* Do API eng->jpn request */ + let body: Value = ureq::get(&format!(TATOEBA_URL_ENG_QUERY!(), &query[1..])) + .call()?.into_json()?; + + match sentence_search(&options, body, &mut output) { + Ok(r) => lines_output += r, + Err(e) => match e { + -1 => { + eprintln!("error: invalid json returned"); + return Ok(()); + }, + _ => { /* Valid response, but nothing useful */ + /* Do a jpn->eng request in case input is in japansese */ + let body: Value = ureq::get(&format!(TATOEBA_URL_JPN_QUERY!(), &query[1..])) + .call()?.into_json()?; + + match sentence_search(&options, body, &mut output) { + Ok(r) => lines_output += r, + Err(e) => if e == -1 { + eprintln!("Error: invalid json returned"); + return Ok(()); + } + } + } + } + } } else { /* Word search */ // Do API request let body: Value = ureq::get(&format!(JISHO_URL!(), query)) diff --git a/src/sentence_search.rs b/src/sentence_search.rs new file mode 100644 index 0000000..27b7e4e --- /dev/null +++ b/src/sentence_search.rs @@ -0,0 +1,63 @@ +use crate::aux::*; + +use serde_json::Value; +use colored::*; + +pub fn sentence_search(options: &Options, body: Value, output: &mut String) -> Result{ + + let mut lines = 0; + let body = value_to_arr({ + let body = body.get("results"); + + if body.is_none() { + return Err(-1); + } + + body.unwrap() + }); + + let mut i = 1; + + /* + * Each entry is an english or japanese sentence and we're pairing it up with the equivalents in + * the translations array + */ + for entry in body.iter() { + if i >= options.limit && options.limit != 0 { + break; + } + + let translations = value_to_arr({ + let translations = entry.get("translations"); + + if translations.is_none() { + return Err(-1); + } + let translations = value_to_arr(translations.unwrap()).get(0); + if translations.is_none() { + return Err(-1); + } + translations.unwrap() + }); + + + for translation in translations.iter() { + let index_str = format!("{}.", i).bright_black(); + + /* prefer to keep japanese sentences on top */ + if entry.get("lang").unwrap() == "eng" { + *output += &format!("{} {}\n {}\n\n", index_str, value_to_str(translation.get("text").unwrap()).replace("\"", ""), value_to_str(entry.get("text").unwrap()).replace("\"", "")); + } else { + *output += &format!("{} {}\n {}\n\n", index_str, value_to_str(entry.get("text").unwrap()).replace("\"", ""), value_to_str(translation.get("text").unwrap()).replace("\"", "")); + } + + i += 1; + lines += 3; + } + + } + if !output.is_empty() { + return Ok(lines) + } + Err(1) +}