aboutsummaryrefslogtreecommitdiff
path: root/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server.go')
-rw-r--r--server.go111
1 files changed, 49 insertions, 62 deletions
diff --git a/server.go b/server.go
index 3e2ebd0..673c211 100644
--- a/server.go
+++ b/server.go
@@ -1,41 +1,37 @@
-// Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+// Copyright 2020, Shulhan <ms@kilabit.info>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package kamusku
+package kamusd
import (
"context"
+ "encoding/json"
"fmt"
"log"
"math/rand"
- stdhttp "net/http"
+ "net/http"
"os"
"strings"
"sync"
"time"
+ "git.sr.ht/~shulhan/kamusku"
"github.com/shuLhan/share/lib/ascii"
"github.com/shuLhan/share/lib/debug"
- "github.com/shuLhan/share/lib/http"
-)
-
-const (
- envKbbiSandi = "KBBI_SANDI"
- envKbbiSurel = "KBBI_SUREL"
- defListen = ":3394"
- emptyResponse = "{}"
+ libhttp "github.com/shuLhan/share/lib/http"
+ "github.com/shuLhan/share/lib/memfs"
)
//
-// Server for KBBI with caching and spell checking functionalities.
+// Server for kamusku with caching and spell checking functionalities.
//
type Server struct {
- http *http.Server
- kamus *kamusCache
+ httpd *libhttp.Server
+ kamus *dictionary
// The client that forward request to official KBBI server.
- forwardc *directClient
+ kbbic *kamusku.KbbiClient
stopped chan bool
wg sync.WaitGroup
@@ -49,53 +45,53 @@ type Server struct {
// NewServer create and initialize the server with optional path to dictionary
// storage.
//
-func NewServer(kamusStorage string) (server *Server, err error) {
+func NewServer(dictionaryStorage string) (server *Server, err error) {
address := defListen
port := os.Getenv(envPort)
if len(port) > 0 {
address = ":" + port
}
- opts := &http.ServerOptions{
- Root: "",
+ httpdOpts := &libhttp.ServerOptions{
+ Options: memfs.Options{
+ Root: "_www",
+ Development: debug.Value >= 2,
+ },
+ Memfs: memfsWWW,
Address: address,
}
- if debug.Value > 0 {
- opts.Development = true
- }
-
server = &Server{
stopped: make(chan bool, 1),
}
- server.kamus, err = newKamusCache(kamusStorage)
+ server.kamus, err = newDictionary(dictionaryStorage)
if err != nil {
- return nil, fmt.Errorf("http.NewServer: %w", err)
+ return nil, fmt.Errorf("NewServer: %w", err)
}
- server.http, err = http.NewServer(opts)
+ server.httpd, err = libhttp.NewServer(httpdOpts)
if err != nil {
- return nil, fmt.Errorf("http.NewServer: %w", err)
+ return nil, fmt.Errorf("NewServer: %w", err)
}
- server.forwardc, err = newDirectClient()
+ server.kbbic, err = kamusku.NewKbbiClient()
if err != nil {
- return nil, fmt.Errorf("http.NewServer: %w", err)
+ return nil, fmt.Errorf("NewServer: %w", err)
}
err = server.registerEndpoints()
if err != nil {
- return nil, fmt.Errorf("http.NewServer: %w", err)
+ return nil, fmt.Errorf("NewServer: %w", err)
}
- if !server.forwardc.isAuthenticated() {
+ if !server.kbbic.IsAuthenticated() {
surel := os.Getenv(envKbbiSurel)
sandi := os.Getenv(envKbbiSandi)
if len(surel) > 0 && len(sandi) > 0 {
- err = server.forwardc.login(surel, sandi)
+ err = server.kbbic.Login(surel, sandi)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("NewServer: %w", err)
}
}
}
@@ -108,16 +104,17 @@ func NewServer(kamusStorage string) (server *Server, err error) {
//
func (server *Server) Start() (err error) {
go server.dumpCacheJob()
+
server.wg.Add(1)
- return server.http.Start()
+ return server.httpd.Start()
}
//
// Shutdown the HTTP server and save the cache for future use.
//
func (server *Server) Shutdown() (err error) {
- err = server.http.Shutdown(context.TODO())
+ err = server.httpd.Shutdown(context.TODO())
server.stopped <- true
@@ -162,25 +159,21 @@ func (server *Server) dumpCache() {
// handleAdmin is endpoint to manage dictionary cache on the web.
//
func (server *Server) handleAdmin(
- httpRes stdhttp.ResponseWriter,
- httpReq *stdhttp.Request,
- reqBody []byte,
+ _ http.ResponseWriter, _ *http.Request, _ []byte,
) (resBody []byte, err error) {
return resBody, nil
}
func (server *Server) handleDefinisi(
- httpRes stdhttp.ResponseWriter,
- httpReq *stdhttp.Request,
- reqBody []byte,
+ _ http.ResponseWriter, httpReq *http.Request, _ []byte,
) (resBody []byte, err error) {
paramKata := httpReq.Form.Get(paramNameKata)
if len(paramKata) == 0 {
- return []byte(emptyResponse), nil
+ return []byte(jsonEmptyObject), nil
}
inputs := strings.Split(paramKata, ",")
- res := make(DefinisiResponse, len(inputs))
+ res := make(kamusku.LookupResponse, len(inputs))
for _, in := range inputs {
in = strings.TrimSpace(in)
@@ -188,7 +181,7 @@ func (server *Server) handleDefinisi(
continue
}
- kata := server.kamus.get(in)
+ kata := server.kamus.lookup(in)
if kata != nil {
res[in] = kata
continue
@@ -200,9 +193,8 @@ func (server *Server) handleDefinisi(
// The word does not exist in cache, retrieve it from official
// website.
- fwRes, err := server.forwardc.CariDefinisi([]string{in})
+ fwRes, err := server.kbbic.Lookup([]string{in})
if err != nil {
- kata.err = err
continue
}
@@ -217,30 +209,25 @@ func (server *Server) handleDefinisi(
}
if len(res) == 0 {
- return []byte(emptyResponse), nil
+ return []byte(jsonEmptyObject), nil
}
- resBody, err = res.pack()
- if err != nil {
- return nil, err
- }
-
- return resBody, nil
+ return json.Marshal(res)
}
//
// registerEndpoints register the API endpoints.
//
func (server *Server) registerEndpoints() (err error) {
- epDefinisi := &http.Endpoint{
- Method: http.RequestMethodGet,
+ epDefinisi := &libhttp.Endpoint{
+ Method: libhttp.RequestMethodGet,
Path: pathAPIDefinisi,
- RequestType: http.RequestTypeQuery,
- ResponseType: http.ResponseTypeJSON,
+ RequestType: libhttp.RequestTypeQuery,
+ ResponseType: libhttp.ResponseTypeJSON,
Call: server.handleDefinisi,
}
- err = server.http.RegisterEndpoint(epDefinisi)
+ err = server.httpd.RegisterEndpoint(epDefinisi)
if err != nil {
return fmt.Errorf("registerEndpoints %q: %w", pathAPIDefinisi,
err)
@@ -249,15 +236,15 @@ func (server *Server) registerEndpoints() (err error) {
rand.Seed(time.Now().Unix())
pathAdmin := string(ascii.Random([]byte(ascii.LettersNumber), 16))
- epAdmin := &http.Endpoint{
- Method: http.RequestMethodGet,
+ epAdmin := &libhttp.Endpoint{
+ Method: libhttp.RequestMethodGet,
Path: pathAdmin,
- RequestType: http.RequestTypeQuery,
- ResponseType: http.ResponseTypeHTML,
+ RequestType: libhttp.RequestTypeQuery,
+ ResponseType: libhttp.ResponseTypeHTML,
Call: server.handleAdmin,
}
- err = server.http.RegisterEndpoint(epAdmin)
+ err = server.httpd.RegisterEndpoint(epAdmin)
if err != nil {
return fmt.Errorf("registerEndpoints %q: %w", pathAdmin, err)
}