aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2020-04-06 03:00:22 +0700
committerShulhan <m.shulhan@gmail.com>2020-04-06 03:00:22 +0700
commitdb5b35cd5052d47c81bb63f78f7781513be22fd2 (patch)
treec393a2aa937a0b576a9f25c10b76dd8967a90b02
parent5ea27bffa9020ddcdc62774a29e399e76ae5997c (diff)
downloadkamusku-db5b35cd5052d47c81bb63f78f7781513be22fd2.tar.xz
www-kbbi: add content page for "/project/kbbi"
The content page show the definition and capabilities of the API.
-rw-r--r--.gitignore3
-rw-r--r--Makefile11
-rw-r--r--_content/index.html33
-rw-r--r--_content/index.js106
-rw-r--r--_content/kbbiclient.js35
-rw-r--r--generate.go7
-rw-r--r--internal/generate/main.go31
-rw-r--r--kbbi.go1
-rw-r--r--server.go12
9 files changed, 235 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index f426802..135b2f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
+/cmd/www-kbbi/static.go
/internal/cmd/mergedic/id_ID.dic
/internal/cmd/mergedic/id_ID.dic.new
+/kamus.gob
+/kamus.gob.new
/kbbi
/testdata/kamus.gob
/testdata/kamus.gob.new
diff --git a/Makefile b/Makefile
index 0f4812c..8cc8884 100644
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,14 @@
## Use of this source code is governed by a BSD-style
## license that can be found in the LICENSE file.
-.PHONY: all build lint test install deploy
+.PHONY: all build lint test install generate deploy
LINT_OPTS =
+GENERATE_INPUTS = _content/index.html \
+ _content/index.js \
+ _content/kbbiclient.js
+
all: build lint test
build:
@@ -27,7 +31,10 @@ test:
install:
go install ./cmd/kbbi/
-deploy:
+cmd/www-kbbi/static.go: $(GENERATE_INPUTS)
+ go generate
+
+deploy: cmd/www-kbbi/static.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -o www-kbbi-linux-amd64 ./cmd/www-kbbi/
rsync --progress ./www-kbbi-linux-amd64 www-kbbi:~/bin/www-kbbi
diff --git a/_content/index.html b/_content/index.html
new file mode 100644
index 0000000..328e00a
--- /dev/null
+++ b/_content/index.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Project KBBI</title>
+
+ <script type="text/javascript" src="kbbiclient.js"></script>
+ <script type="text/javascript" src="index.js"></script>
+ <style>
+ .kelas-kata,
+ .contoh {
+ margin-left: 2em;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>Proyek KBBI</h1>
+ <p>
+ Proyek implementasi API untuk Kamus Besar Bahasa Indonesia.
+ </p>
+
+ <h2>Definisi kata</h2>
+ <label>
+ Daftar kata:
+ <input type="text" id="kata" maxlength="64" />
+ </label>
+ <button onclick="cariDefinisi()">Cari definisi</button>
+ <p class="note">
+ Catatan: gunakan koma untuk mencari lebih dari satu kata.
+ </p>
+
+ <div id="definisi-result"></div>
+ </body>
+</html>
diff --git a/_content/index.js b/_content/index.js
new file mode 100644
index 0000000..72482e9
--- /dev/null
+++ b/_content/index.js
@@ -0,0 +1,106 @@
+/**
+ * Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+let kbbiClient = new KBBIClient("")
+
+function cariDefinisi() {
+ let kata = document.getElementById("kata").value
+ kbbiClient.getDefinitions(kata, cariDefinisiCallback)
+}
+
+function cariDefinisiCallback(res) {
+ let out = document.getElementById("definisi-result")
+ out.innerHTML = ""
+
+ for (let kata in res) {
+ let root = document.createElement("div")
+ printResultKata(root, kata, res[kata])
+ out.appendChild(root)
+ }
+}
+
+function printResultKata(out, kata, defKata) {
+ let el = document.createElement("b")
+ el.appendChild(document.createTextNode(kata))
+ out.appendChild(el)
+
+ printKataDasar(out, defKata.dasar)
+ printDefinitions(out, defKata.definisi)
+}
+
+function printKataDasar(out, kataDasar) {
+ let root = document.createElement("div")
+ root.appendChild(document.createTextNode("Kata dasar: "))
+
+ if (kataDasar === "") {
+ root.appendChild(document.createTextNode("-"))
+ } else {
+ let italic = document.createElement("i")
+ italic.appendChild(document.createTextNode(kataDasar))
+ root.appendChild(italic)
+ }
+
+ out.appendChild(root)
+}
+
+function printDefinitions(out, definitions) {
+ for (let x = 0; x < definitions.length; x++) {
+ let def = definitions[x]
+
+ let root = document.createElement("div")
+ let el = document.createElement("p")
+ el.classList.add("definisi")
+ el.appendChild(
+ document.createTextNode(
+ "Definisi #" + (x + 1) + ": " + def.isi + ".",
+ ),
+ )
+ root.appendChild(el)
+
+ printKelasKata(root, def.kelas)
+ printContoh(root, def.contoh)
+ out.appendChild(root)
+ }
+}
+
+function printKelasKata(out, daftarKelas) {
+ if (typeof daftarKelas === "undefined") {
+ return
+ }
+
+ let root = document.createElement("div")
+ root.classList.add("kelas-kata")
+ root.appendChild(document.createTextNode("Kelas,"))
+
+ let el = document.createElement("ul")
+ for (let x = 0; x < daftarKelas.length; x++) {
+ let li = document.createElement("li")
+ li.appendChild(document.createTextNode(daftarKelas[x]))
+ el.appendChild(li)
+ }
+ root.appendChild(el)
+ out.appendChild(root)
+}
+
+function printContoh(out, examples) {
+ if (typeof examples === "undefined") {
+ return
+ }
+
+ let root = document.createElement("div")
+ root.classList.add("contoh")
+ root.appendChild(document.createTextNode("Contoh,"))
+
+ let ul = document.createElement("ul")
+
+ for (let x = 0; x < examples.length; x++) {
+ let li = document.createElement("li")
+ li.appendChild(document.createTextNode(examples[x]))
+ ul.appendChild(li)
+ }
+ root.appendChild(ul)
+ out.appendChild(root)
+}
diff --git a/_content/kbbiclient.js b/_content/kbbiclient.js
new file mode 100644
index 0000000..ab35633
--- /dev/null
+++ b/_content/kbbiclient.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+class KBBIClient {
+ constructor(baseURL) {
+ if (baseURL.length === 0) {
+ baseURL = "https://kilabit.info/project/kbbi"
+ }
+ this.baseURL = baseURL
+ }
+
+ getDefinitions(words, cb) {
+ if (words.length === 0) {
+ return
+ }
+
+ let params = "kata=" + words
+ let xhr = new XMLHttpRequest()
+
+ xhr.addEventListener("load", function() {
+ cb(JSON.parse(xhr.responseText))
+ })
+
+ xhr.open("GET", this.baseURL + "/api/definisi?" + params)
+ xhr.setRequestHeader(
+ "Content-Type",
+ "application/x-www-form-urlencoded",
+ )
+
+ xhr.send(null)
+ }
+}
diff --git a/generate.go b/generate.go
new file mode 100644
index 0000000..05137b0
--- /dev/null
+++ b/generate.go
@@ -0,0 +1,7 @@
+// Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run ./internal/generate
+
+package kbbi
diff --git a/internal/generate/main.go b/internal/generate/main.go
new file mode 100644
index 0000000..cb12ccf
--- /dev/null
+++ b/internal/generate/main.go
@@ -0,0 +1,31 @@
+// Copyright 2020, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "log"
+
+ "github.com/shuLhan/share/lib/memfs"
+)
+
+func main() {
+ includes := []string{
+ "index.html",
+ "index.js",
+ "kbbiclient.js",
+ }
+
+ mfs, err := memfs.New(includes, nil, true)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ err = mfs.Mount("./_content")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ mfs.GoGenerate("main", "./cmd/www-kbbi/static.go", memfs.EncodingGzip)
+}
diff --git a/kbbi.go b/kbbi.go
index ffecd30..897e96d 100644
--- a/kbbi.go
+++ b/kbbi.go
@@ -27,6 +27,7 @@ const (
attrValueRootWord = "rootword"
+ headerNameACAO = "Access-Control-Allow-Origin"
headerNameContentType = "Content-Type"
headerValueContentType = "application/x-www-form-urlencoded"
diff --git a/server.go b/server.go
index e0e6b9c..7969ca2 100644
--- a/server.go
+++ b/server.go
@@ -12,6 +12,7 @@ import (
"sync"
"time"
+ "github.com/shuLhan/share/lib/debug"
"github.com/shuLhan/share/lib/http"
)
@@ -44,9 +45,14 @@ type Server struct {
//
func NewServer(kamusStorage string) (server *Server, err error) {
opts := &http.ServerOptions{
+ Root: "_content",
Address: defListen,
}
+ if debug.Value > 0 {
+ opts.Development = true
+ }
+
server = &Server{
stopped: make(chan bool, 1),
}
@@ -78,7 +84,7 @@ func NewServer(kamusStorage string) (server *Server, err error) {
// Start the HTTP server.
//
func (server *Server) Start() (err error) {
- go server.dumpCache()
+ go server.dumpCacheJob()
server.wg.Add(1)
return server.http.Start()
@@ -88,7 +94,7 @@ func (server *Server) Start() (err error) {
// Shutdown the HTTP server and save the cache for future use.
//
func (server *Server) Shutdown() (err error) {
- err = server.Shutdown()
+ err = server.http.Shutdown(nil)
server.stopped <- true
@@ -134,6 +140,8 @@ func (server *Server) handleDefinisi(
httpReq *stdhttp.Request,
reqBody []byte,
) (resBody []byte, err error) {
+ httpRes.Header().Set(headerNameACAO, "*")
+
paramKata := httpReq.Form.Get(paramNameKata)
if len(paramKata) == 0 {
return []byte(emptyResponse), nil