summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2020-03-29 02:35:24 +0700
committerShulhan <m.shulhan@gmail.com>2020-03-29 02:35:24 +0700
commit81695a6ba830374fe1b7335d67ea6f22122af1f6 (patch)
treed0f89093391db87f8dadefd7149d816bd86e1d71
parentcea97a6f997afccfb4eca3a7f1672ea5a8da8a8c (diff)
downloadkamusku-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.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
}
//