fafa3dfa51
BuildZIM walks a cloned host directory, turns every file into a content entry with a MIME inferred from its extension, picks a main page, and adds the standard metadata plus a mainPage redirect. state.json is skipped. BuildBinary appends the archive to a copy of kage behind a KAGEPCK1 trailer, and Embedded detects that trailer at startup so the binary serves itself. Handler maps / to the main page and /path to a content entry, the same handler the embedded viewer uses.
63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
package pack
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/tamnd/kage/zim"
|
|
)
|
|
|
|
// Handler serves a ZIM archive over HTTP. "/" maps to the archive's main page;
|
|
// "/a/b.png" maps to the C/a/b.png content entry. Because the saved HTML's links
|
|
// are mirror-relative paths, and those are exactly the C urls, a click in a
|
|
// served page hits the right entry with no rewriting. A miss is a plain 404.
|
|
func Handler(r *zim.Reader) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
p := strings.TrimPrefix(req.URL.Path, "/")
|
|
if p == "" {
|
|
blob, err := r.MainPage()
|
|
if err != nil {
|
|
http.NotFound(w, req)
|
|
return
|
|
}
|
|
serveBlob(w, blob)
|
|
return
|
|
}
|
|
blob, err := r.Get(zim.NamespaceContent, p)
|
|
if errors.Is(err, zim.ErrNotFound) {
|
|
http.NotFound(w, req)
|
|
return
|
|
}
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
serveBlob(w, blob)
|
|
})
|
|
}
|
|
|
|
func serveBlob(w http.ResponseWriter, b zim.Blob) {
|
|
if b.MimeType != "" {
|
|
w.Header().Set("Content-Type", b.MimeType)
|
|
}
|
|
_, _ = w.Write(b.Data)
|
|
}
|
|
|
|
// OpenInBrowser launches the platform default browser at url. It is best-effort:
|
|
// callers print the url regardless and never treat a launch failure as fatal.
|
|
func OpenInBrowser(url string) error {
|
|
var cmd *exec.Cmd
|
|
switch runtime.GOOS {
|
|
case "darwin":
|
|
cmd = exec.Command("open", url)
|
|
case "windows":
|
|
cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
|
|
default:
|
|
cmd = exec.Command("xdg-open", url)
|
|
}
|
|
return cmd.Start()
|
|
}
|