aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client.go108
-rw-r--r--client_test.go16
-rw-r--r--cmd/kbbi/main.go16
-rw-r--r--definisi_response.go2
-rw-r--r--kata.go69
5 files changed, 108 insertions, 103 deletions
diff --git a/client.go b/client.go
index 3301ff1..d90eb4a 100644
--- a/client.go
+++ b/client.go
@@ -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
diff --git a/kata.go b/kata.go
index 1fb8eeb..94b23b4 100644
--- a/kata.go
+++ b/kata.go
@@ -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
}
//