package main import ( "encoding/json" "fmt" "log" "net/http" "os" "foosoft.net/projects/jmdict" "git.elnu.com/ElnuDev/jichanorg/httputils" "github.com/gorilla/mux" ) var dict jmdict.Jmdict func LoadDict() error { const jmdictFile = "JMdict.xml" reader, err := os.Open(jmdictFile) if err != nil { return err } dict, _, err = jmdict.LoadJmdict(reader) if err != nil { return err } return nil } type Entry struct { Kanji string Reading string Definitions []string } func ParseEntry(entry jmdict.JmdictEntry) Entry { kanji := "" if len(entry.Kanji) > 0 { kanji = entry.Kanji[0].Expression } reading := "" if len(entry.Readings) > 0 { reading = entry.Readings[0].Reading } var definitions []string if len(entry.Sense) > 0 && len(entry.Sense[0].Glossary) > 0 { definitions = make([]string, len(entry.Sense[0].Glossary)) for i, glossary := range entry.Sense[0].Glossary { definitions[i] = glossary.Content } } return Entry{ Kanji: kanji, Reading: reading, Definitions: definitions, } } func Search(query string) []Entry { entries := make([]Entry, 0) for _, jmdictEntry := range dict.Entries { for _, kanji := range jmdictEntry.Kanji { if kanji.Expression == query { goto match } } for _, reading := range jmdictEntry.Readings { if reading.Reading == query { goto match } } continue match: entry := ParseEntry(jmdictEntry) entries = append(entries, entry) } return entries } func main() { err := LoadDict() if err != nil { fmt.Println(err) return } fmt.Println("JMdict loaded!") r := mux.NewRouter() r.HandleFunc("/api/search", httputils.GenerateHandler( "search.html", func(w http.ResponseWriter, r *http.Request) bool { if r.Header.Get("Accept") != "application/json" { return true } w.Header().Set("Content-Type", "application/json; charset=utf-8") r.ParseMultipartForm(0) query := r.FormValue("q") entries := Search(query) jsonBytes, _ := json.Marshal(entries) fmt.Fprint(w, string(jsonBytes)) return false }, func(w http.ResponseWriter, r *http.Request) any { r.ParseMultipartForm(0) query := r.FormValue("q") entry := Search(query) return entry }, []string{http.MethodGet, http.MethodPost}, )) r.Handle("/", http.FileServer(http.Dir("static"))) log.Fatal(http.ListenAndServe(":3334", r)) }