diff options
| author | Shulhan <m.shulhan@gmail.com> | 2020-03-29 02:35:24 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2020-03-29 02:35:24 +0700 |
| commit | 81695a6ba830374fe1b7335d67ea6f22122af1f6 (patch) | |
| tree | d0f89093391db87f8dadefd7149d816bd86e1d71 | |
| parent | cea97a6f997afccfb4eca3a7f1672ea5a8da8a8c (diff) | |
| download | kamusku-81695a6ba830374fe1b7335d67ea6f22122af1f6.tar.xz | |
client: ganti parameter CariDefinisi menjadi slice of string
Sebelumnya parameter untuk method CariDefinisi() hanya sebuah string.
Supaya dapat mencari lebih dari satu kata dalam satu kali panggil, maka
parameternya diganti menjadi slice of string.
Hal ini menyebabkan penambahan field internal "err" yang berisi kesalahan
pada saat pengambilan definisi yang dapat diperiksa dengan menggunakan
method Err().
Selain itu, pindahkan fungsi parseHTMLEntri menjadi method dari Kata.
| -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 } // |
