diff options
| -rw-r--r-- | client.go | 108 | ||||
| -rw-r--r-- | client_test.go | 16 | ||||
| -rw-r--r-- | cmd/kbbi/main.go | 16 | ||||
| -rw-r--r-- | definisi_response.go | 2 | ||||
| -rw-r--r-- | kata.go | 69 |
5 files changed, 108 insertions, 103 deletions
@@ -68,32 +68,46 @@ func New(cookies []*http.Cookie) (cl *Client, err error) { } // -// CariDefinisi dari kata. +// CariDefinisi dari daftar kata. // -func (cl Client) CariDefinisi(in string) (kata *Kata, err error) { - entriURL := baseURL + entriPath + in - res, err := cl.httpc.Get(entriURL) - if err != nil { - return nil, fmt.Errorf("CariDefinisi %q: %w", in, err) - } +func (cl Client) CariDefinisi(ins []string) (res DefinisiResponse) { + res = make(DefinisiResponse, len(ins)) - defer res.Body.Close() + for _, in := range ins { + _, ok := res[in] + if ok { + continue + } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("Cari %q: %w", in, err) - } + kata := &Kata{} + res[in] = kata - if debug.Value >= 2 { - fmt.Printf(">>> HTML body for %s:\n%s", entriURL, body) - } + entriURL := baseURL + entriPath + in + httpRes, err := cl.httpc.Get(entriURL) + if err != nil { + kata.err = err + continue + } - kata, err = parseHTMLEntri(body) - if err != nil { - return nil, fmt.Errorf("CariDefinisi %q: %w", in, err) + defer httpRes.Body.Close() + + body, err := ioutil.ReadAll(httpRes.Body) + if err != nil { + kata.err = err + continue + } + + if debug.Value >= 2 { + fmt.Printf(">>> HTML body for %s:\n%s", entriURL, body) + } + + err = kata.parseHTMLEntri(body) + if err != nil { + kata.err = err + } } - return kata, nil + return res } // @@ -204,62 +218,6 @@ func (cl *Client) SetCookies(cookies []*http.Cookie) { } } -// -// parseHTMLEntri parse HTML body from "/entri/<kata>" page to find the -// definition of the word. -// -func parseHTMLEntri(htmlBody []byte) (kata *Kata, err error) { - node, err := html.Parse(bytes.NewReader(htmlBody)) - if err != nil { - return nil, err - } - - kata = new(Kata) - var prev *html.Node - - for { - switch { - case node.FirstChild != nil && node.FirstChild != prev && - node.LastChild != prev: - node = node.FirstChild - case node.NextSibling != nil: - node = node.NextSibling - default: - prev = node - node = node.Parent - } - if node == nil { - break - } - - if node.Type != html.ElementNode { - continue - } - - switch node.Data { - case tagNameHeader2: - kata.parseKataDasar(node) - - case tagNameOrderedList, tagNameUnorderedList: - li := getFirstChild(node) - for li != nil { - defKata := parseDefinisiKata(li) - if defKata == nil { - break - } - kata.Definisi = append(kata.Definisi, defKata) - li = getNextSibling(li) - } - node = node.NextSibling - - default: - continue - } - } - - return kata, nil -} - func (cl Client) parseHTMLKataDasar(htmlBody []byte) (kataDasar daftarKata, err error) { node, err := html.Parse(bytes.NewReader(htmlBody)) if err != nil { diff --git a/client_test.go b/client_test.go index 7373645..92f5fd4 100644 --- a/client_test.go +++ b/client_test.go @@ -9,22 +9,6 @@ import ( "testing" ) -func TestParseHTMLEntri(t *testing.T) { - htmlBody, err := ioutil.ReadFile("testdata/entri.html") - if err != nil { - t.Fatal(err) - } - - daftarDefinisi, err := parseHTMLEntri(htmlBody) - if err != nil { - t.Fatal(err) - } - - for _, defKata := range daftarDefinisi { - t.Logf("Definisi kata: %+v", defKata) - } -} - func TestClient_parseHTMLKataDasar(t *testing.T) { htmlBody, err := ioutil.ReadFile("testdata/kbbi_dasar.html") if err != nil { diff --git a/cmd/kbbi/main.go b/cmd/kbbi/main.go index 1a7f561..a036e13 100644 --- a/cmd/kbbi/main.go +++ b/cmd/kbbi/main.go @@ -73,20 +73,16 @@ func main() { return } - var ( - daftarKata []string = flag.Args() - ) - for _, in := range daftarKata { - kata, err := cl.CariDefinisi(in) + resDefinisi := cl.CariDefinisi(flag.Args()) + + for k, kata := range resDefinisi { + err = kata.Err() if err != nil { - log.Println(err) - } - if kata == nil { - fmt.Printf("!!! %s: %s\n\n", in, errKataNotFound) + fmt.Printf("!!! %s: %s\n", k, err) continue } - fmt.Println("===", in) + fmt.Println("===", k) if len(kata.Dasar) > 0 { fmt.Printf(" Kata dasar: %s\n", kata.Dasar) } diff --git a/definisi_response.go b/definisi_response.go index b7376aa..d842310 100644 --- a/definisi_response.go +++ b/definisi_response.go @@ -8,4 +8,4 @@ package kbbi // DefinisiResponse is a response from "/definisi" API. // Its contains mapping of words and their definitions. // -type DefinisiResponse map[string]Kata +type DefinisiResponse map[string]*Kata @@ -4,7 +4,18 @@ package kbbi -import "golang.org/x/net/html" +import ( + "bytes" + + "golang.org/x/net/html" +) + +// +// Err return an error from retrieving definition. +// +func (kata *Kata) Err() error { + return kata.err +} // // Kata store the single root word and its definitions. @@ -12,6 +23,62 @@ import "golang.org/x/net/html" type Kata struct { Dasar string `json:"dasar"` Definisi []*DefinisiKata `json:"definisi"` + err error +} + +// +// parseHTMLEntri parse HTML body from "/entri/<kata>" page to find the +// definition of the word. +// +func (kata *Kata) parseHTMLEntri(htmlBody []byte) (err error) { + node, err := html.Parse(bytes.NewReader(htmlBody)) + if err != nil { + return err + } + + var prev *html.Node + + for { + switch { + case node.FirstChild != nil && node.FirstChild != prev && + node.LastChild != prev: + node = node.FirstChild + case node.NextSibling != nil: + node = node.NextSibling + default: + prev = node + node = node.Parent + } + if node == nil { + break + } + + if node.Type != html.ElementNode { + continue + } + + switch node.Data { + case tagNameHeader2: + kata.parseKataDasar(node) + + case tagNameOrderedList, tagNameUnorderedList: + li := getFirstChild(node) + for li != nil { + defKata := parseDefinisiKata(li) + if defKata == nil { + break + } + kata.Definisi = append(kata.Definisi, defKata) + li = getNextSibling(li) + } + node = node.NextSibling + + default: + continue + } + } + + return nil } // |
