diff options
| -rw-r--r-- | client.go | 138 |
1 files changed, 64 insertions, 74 deletions
@@ -8,7 +8,6 @@ import ( "encoding/gob" "errors" "fmt" - "io" "log" "net/http" "net/http/cookiejar" @@ -25,12 +24,14 @@ import ( ) const ( - kbbiUrlBase = "https://kbbi.kemdikbud.go.id" - kbbiUrlLogin = kbbiUrlBase + "/Account/Login" + kbbiHost = `kbbi.kemdikbud.go.id` + kbbiUrlBase = `https://` + kbbiHost + kbbiUrlLogin = `/Account/Login` kbbiPathEntri = "/entri/" attrNameClass = "class" attrNameHref = "href" + attrNameName = `name` attrNameTitle = "title" attrNameValue = "value" @@ -64,7 +65,7 @@ const ( // Client for official KBBI web using HTTP. type Client struct { - httpc *http.Client + httpc *libhttp.Client cookieURL *url.URL baseDir string cookies []*http.Cookie @@ -87,14 +88,18 @@ func NewClient() (cl *Client, err error) { return nil, fmt.Errorf("New: %w", err) } + var clientOpts = libhttp.ClientOptions{ + ServerURL: kbbiUrlBase, + Timeout: defTimeout, + } + cl = &Client{ cookieURL: cookieURL, - httpc: &http.Client{ - Jar: jar, - Timeout: defTimeout, - }, + httpc: libhttp.NewClient(clientOpts), } + cl.httpc.Jar = jar + err = cl.loadCookies() if err != nil { return nil, fmt.Errorf("New: %w", err) @@ -120,22 +125,17 @@ func (cl *Client) Lookup(ins []string) (res LookupResponse, err error) { kata := &Word{} res[in] = kata - entriURL := kbbiUrlBase + kbbiPathEntri + in - httpRes, err := cl.httpc.Get(entriURL) - if err != nil { - kata.err = err - continue + var req = libhttp.ClientRequest{ + Path: kbbiPathEntri + in, } - - defer httpRes.Body.Close() - - body, err := io.ReadAll(httpRes.Body) + var resp *libhttp.ClientResponse + resp, err = cl.httpc.Get(req) if err != nil { kata.err = err continue } - err = kata.parseHTMLEntri(in, body) + err = kata.parseHTMLEntri(in, resp.Body) if err != nil { kata.err = err } @@ -158,6 +158,7 @@ func (cl *Client) ListRootWords(pageStart, pageEnd int) (rootWords Words, err er } var ( + logp = `ListRootWords` params = url.Values{ paramNameMasukan: []string{paramValueDasar}, paramNameMasukanLengkap: []string{paramValueDasar}, @@ -167,39 +168,36 @@ func (cl *Client) ListRootWords(pageStart, pageEnd int) (rootWords Words, err er n int ) - urlPage := kbbiUrlBase + "/Cari/Jenis?" + urlPage := `/Cari/Jenis` rootWords = make(Words) for ; pageStart <= pageEnd; pageStart++ { params.Set(paramNamePage, strconv.Itoa(pageStart)) - req, err := http.NewRequest(http.MethodGet, urlPage+params.Encode(), nil) - if err != nil { - return rootWords, err + var req = libhttp.ClientRequest{ + Method: http.MethodGet, + Path: urlPage, + Params: params, + Type: libhttp.RequestTypeQuery, } - - res, err := cl.httpc.Do(req) - if err != nil { - return rootWords, fmt.Errorf("ListRootWords: page %d: %w", pageStart, err) - } - - defer res.Body.Close() - - body, err := io.ReadAll(res.Body) + var resp *libhttp.ClientResponse + resp, err = cl.httpc.Get(req) if err != nil { - return rootWords, fmt.Errorf("ListRootWords: page %d: %w", pageStart, err) + err = fmt.Errorf(`%s: halaman %d: %w`, logp, pageStart, err) + return rootWords, err } - got, err = cl.parseHTMLRootWords(body) + got, err = cl.parseHTMLRootWords(resp.Body) if err != nil { - return rootWords, fmt.Errorf("ListRootWords: page %d: %w", pageStart, err) + err = fmt.Errorf(`%s: halaman %d: %w`, logp, pageStart, err) + return rootWords, err } if len(got) == 0 { break } - fmt.Printf("%d: got words: %v\n", pageStart, got) + log.Printf(`%s: halaman %d: daftar kata: %v`, logp, pageStart, got) n = rootWords.merge(got) if n == 0 { @@ -207,8 +205,8 @@ func (cl *Client) ListRootWords(pageStart, pageEnd int) (rootWords Words, err er break } - log.Printf("ListRootWords: halaman %d, jumlah kata %d, total kata %d", - pageStart, len(got), len(rootWords)) + log.Printf(`%s: halaman %d: jumlah kata %d, total kata %d`, + logp, pageStart, len(got), len(rootWords)) } return rootWords, nil @@ -222,9 +220,11 @@ func (cl *Client) IsAuthenticated() bool { // Login authenticate the client using user email and password. func (cl *Client) Login(email, pass string) (err error) { + var logp = `Login` + tokenLogin, err := cl.preLogin() if err != nil { - return fmt.Errorf("Login: %w", err) + return fmt.Errorf(`%s: %w`, logp, err) } params := url.Values{ @@ -234,29 +234,21 @@ func (cl *Client) Login(email, pass string) (err error) { paramNameIngatSaya: []string{paramValueFalse}, } - reqBody := strings.NewReader(params.Encode()) - - req, err := http.NewRequest(http.MethodPost, kbbiUrlLogin, reqBody) - if err != nil { - return fmt.Errorf("Login: %w", err) + var req = libhttp.ClientRequest{ + Method: http.MethodPost, + Path: kbbiUrlLogin, + Params: params, + Type: libhttp.RequestTypeForm, } - - req.Header.Set(libhttp.HeaderContentType, libhttp.ContentTypeForm) - - res, err := cl.httpc.Do(req) + var resp *libhttp.ClientResponse + resp, err = cl.httpc.PostForm(req) if err != nil { - return fmt.Errorf("Login: %w", err) + return fmt.Errorf(`%s: %w`, logp, err) } - defer res.Body.Close() - - resBody, err := io.ReadAll(res.Body) - if err != nil { - return fmt.Errorf("Login: %w", err) - } - - if res.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("login: %d %s", res.StatusCode, resBody) + if resp.HTTPResponse.StatusCode >= http.StatusBadRequest { + return fmt.Errorf(`%s: %d %s`, logp, + resp.HTTPResponse.StatusCode, resp.Body) } cl.cookies = cl.httpc.Jar.Cookies(cl.cookieURL) @@ -316,35 +308,33 @@ func (cl *Client) parseHTMLLogin(htmlBody []byte) ( continue } + var name = node.GetAttrValue(attrNameName) + if name != paramNameRequestVerificationToken { + continue + } + token := node.GetAttrValue(attrNameValue) if len(token) > 0 { return token, nil } } - return "", fmt.Errorf("token login not found") + return ``, errors.New(`token login not found`) } // preLogin initialize the client to get the first cookie. func (cl *Client) preLogin() (token string, err error) { - req, err := http.NewRequest(http.MethodGet, kbbiUrlLogin, nil) - if err != nil { - return "", err + var req = libhttp.ClientRequest{ + Method: http.MethodGet, + Path: kbbiUrlLogin, } - - res, err := cl.httpc.Do(req) - if err != nil { - return "", err - } - - defer res.Body.Close() - - body, err := io.ReadAll(res.Body) + var resp *libhttp.ClientResponse + resp, err = cl.httpc.Get(req) if err != nil { return "", err } - token, err = cl.parseHTMLLogin(body) + token, err = cl.parseHTMLLogin(resp.Body) if err != nil { return "", err } @@ -385,7 +375,7 @@ func (cl *Client) loadCookies() (err error) { func (cl *Client) saveCookies() { err := os.MkdirAll(filepath.Join(cl.baseDir, configDir), 0700) if err != nil { - log.Println("saveCookies:", err) + log.Println(`saveCookies:`, err) } f := filepath.Join(cl.baseDir, configDir, cookieFile) @@ -394,11 +384,11 @@ func (cl *Client) saveCookies() { enc := gob.NewEncoder(&buf) err = enc.Encode(cl.cookies) if err != nil { - log.Println("saveCookies: ", err) + log.Println(`saveCookies:`, err) } err = os.WriteFile(f, buf.Bytes(), 0600) if err != nil { - log.Println("saveCookies: ", err) + log.Println(`saveCookies:`, err) } } |
