diff --git a/build.gradle.kts b/build.gradle.kts index dd7970e..cc2cec8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -100,10 +100,13 @@ dependencies { implementation("io.github.eb4j:mdict4j:0.2.0") implementation("org.jsoup:jsoup:1.14.3") + // for oxford-api + implementation("tokyo.northside:java-oxford-dictionaries:0.3.1") + // for video replay implementation("uk.co.caprica:vlcj:4.7.1") - implementation("com.formdev:flatlaf:1.6.4") + implementation("com.formdev:flatlaf:1.6.5") // for projector support implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) diff --git a/src/main/java/io/github/eb4j/ebview/dictionary/DictionariesManager.java b/src/main/java/io/github/eb4j/ebview/dictionary/DictionariesManager.java index e124c25..48ad7a0 100644 --- a/src/main/java/io/github/eb4j/ebview/dictionary/DictionariesManager.java +++ b/src/main/java/io/github/eb4j/ebview/dictionary/DictionariesManager.java @@ -20,6 +20,7 @@ import io.github.eb4j.ebview.data.DictionaryEntry; import io.github.eb4j.ebview.data.IDictionary; +import io.github.eb4j.ebview.dictionary.oxford.OxfordDriver; import io.github.eb4j.ebview.utils.Stemmer; import io.github.eb4j.ebview.utils.FileUtils; import org.slf4j.Logger; @@ -55,6 +56,7 @@ public DictionariesManager() { factories.add(new StarDict()); factories.add(new PDic()); factories.add(new MDict()); + dictionaries.add(new OxfordDriver()); stemmer = new Stemmer(); } diff --git a/src/main/java/io/github/eb4j/ebview/dictionary/oxford/HTMLFormatter.java b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/HTMLFormatter.java new file mode 100644 index 0000000..e39942d --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/HTMLFormatter.java @@ -0,0 +1,84 @@ +package io.github.eb4j.ebview.dictionary.oxford; + +import io.github.eb4j.ebview.data.DictionaryEntry; +import tokyo.northside.oxfordapi.dtd.Entry; +import tokyo.northside.oxfordapi.dtd.Example; +import tokyo.northside.oxfordapi.dtd.LexicalEntry; +import tokyo.northside.oxfordapi.dtd.Pronunciation; +import tokyo.northside.oxfordapi.dtd.Sense; +import tokyo.northside.oxfordapi.dtd.Translation; + +import java.util.List; + +public final class HTMLFormatter { + + private HTMLFormatter() { + } + + public static DictionaryEntry formatTranslations(final LexicalEntry lexicalEntry) { + String title = lexicalEntry.getText(); + StringBuilder sb = new StringBuilder("
    "); + for (Entry entry : lexicalEntry.getEntries()) { + for (Sense sense : entry.getSenses()) { + if (sense.getTranslations() == null) { + continue; + } + for (Translation translation : sense.getTranslations()) { + sb.append("
  1. ").append(translation.getText()).append("
  2. "); + } + } + } + sb.append("
"); + return new DictionaryEntry(title, sb.toString(), "oxford"); + } + + public static DictionaryEntry formatDefinitions(final LexicalEntry lexicalEntry) { + String title = lexicalEntry.getText(); + String category = lexicalEntry.getLexicalCategory().getText(); + StringBuilder sb = new StringBuilder("[").append(category).append("] "); + for (Entry entry : lexicalEntry.getEntries()) { + List pronunciations = entry.getPronunciations(); + if (pronunciations != null) { + sb.append(""); + for (Pronunciation pron: pronunciations) { + if (pron.getAudioFile() != null) { + sb.append(""); + } + sb.append("[").append(pron.getPhoneticSpelling()).append("]"); + if (pron.getAudioFile() != null) { + sb.append(""); + } + } + sb.append(" "); + } + List etymologies = entry.getEtymologies(); + if (etymologies != null) { + sb.append(""); + for (String etymology : etymologies) { + sb.append(etymology); + } + sb.append(""); + } + sb.append("
    "); + for (Sense sense : entry.getSenses()) { + if (sense.getDefinitions() == null) { + continue; + } + for (String text : sense.getDefinitions()) { + sb.append("
  1. ").append(text).append("
  2. "); + } + + List examples = sense.getExamples(); + if (examples != null) { + sb.append("
      "); + for (Example ex : examples) { + sb.append("
    • ").append(ex.getText()).append("
    • "); + } + sb.append("
    "); + } + } + sb.append("
"); + } + return new DictionaryEntry(title, sb.toString(), "oxford"); + } +} diff --git a/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java new file mode 100644 index 0000000..8de8669 --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java @@ -0,0 +1,79 @@ +package io.github.eb4j.ebview.dictionary.oxford; + +import io.github.eb4j.ebview.data.DictionaryEntry; +import io.github.eb4j.ebview.data.IDictionary; +import tokyo.northside.oxfordapi.OxfordClient; +import tokyo.northside.oxfordapi.OxfordClientException; +import tokyo.northside.oxfordapi.dtd.LexicalEntry; +import tokyo.northside.oxfordapi.dtd.Result; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OxfordDriver implements IDictionary { + + private final OxfordClient client; + private final String source; + private static final String APPID = ""; // FIXME + private static final String APPKEY = ""; // FIXME: add GUI to set and store encrypted + private final Map> cache = new HashMap<>(); + + public OxfordDriver() { + source = "en-gb"; + client = new OxfordClient(APPID, APPKEY); + } + + @Override + public String getDictionaryName() { + return "Oxford Dictionaries"; + } + + /** + * Read article's text. + * + * @param word The word to look up in the dictionary + * @return List of entries. May be empty, but cannot be null. + */ + @Override + public List readArticles(final String word) { + return queryArticle(word, true); + } + + /** + * Read article's text. Matching is predictive, so e.g. supplying "term" + * will return articles for "term", "terminology", "termite", etc. + * + * @param word The word to look up in the dictionary + * @return List of entries. May be empty, but cannot be null. + */ + @Override + public List readArticlesPredictive(final String word) { + return queryArticle(word, false); + } + + private List queryArticle(final String word, final boolean strict) { + if (!cache.containsKey(word)) { + List dictionaryEntries = new ArrayList<>(); + try { + for (Result result: client.queryEntry(word, source, strict)) { + for (LexicalEntry lexicalEntry : result.getLexicalEntries()) { + dictionaryEntries.add(HTMLFormatter.formatDefinitions(lexicalEntry)); + } + } + } catch (OxfordClientException oce) { + // when got connection/query error, return without any content. + return Collections.emptyList(); + } + cache.put(word, dictionaryEntries); + } + return cache.get(word); + } + + + @Override + public void close() { + } +}