Wire kage pack and kage open into the CLI
pack packs a mirror to a zim file or a runnable viewer, accepting a bare host that it resolves against the default output directory. open serves a zim over http like serve does for a folder. Execute checks for an appended archive first, so a packed kage runs as an offline viewer on an ephemeral port and ignores its arguments.
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/tamnd/kage/pack"
|
||||
"github.com/tamnd/kage/zim"
|
||||
)
|
||||
|
||||
func newOpenCmd() *cobra.Command {
|
||||
var addr string
|
||||
var openBrowser bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "open <file.zim>",
|
||||
Short: "Serve a ZIM archive in your browser for offline reading",
|
||||
Long: "open serves a packed ZIM file over a local HTTP server so you can browse the\n" +
|
||||
"site exactly as it was cloned. It is the read side of kage pack --format zim.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runOpen(cmd.Context(), args[0], addr, openBrowser)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&addr, "addr", "a", "127.0.0.1:8800", "address to listen on")
|
||||
cmd.Flags().BoolVar(&openBrowser, "open", true, "open the default browser")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runOpen(ctx context.Context, path, addr string, openBrowser bool) error {
|
||||
r, err := zim.Open(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot open %q: %w", path, err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot listen on %s: %w", addr, err)
|
||||
}
|
||||
url := "http://" + ln.Addr().String()
|
||||
|
||||
fmt.Fprintln(os.Stderr, styleTitle.Render("kage open")+" "+styleDim.Render(path))
|
||||
fmt.Fprintln(os.Stderr, " open "+styleAccent.Render(url))
|
||||
fmt.Fprintln(os.Stderr, styleDim.Render(" press Ctrl-C to stop"))
|
||||
if openBrowser {
|
||||
_ = pack.OpenInBrowser(url)
|
||||
}
|
||||
|
||||
srv := &http.Server{Handler: pack.Handler(r)}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
_ = srv.Close()
|
||||
}()
|
||||
if err := srv.Serve(ln); err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user