// Command remote is a chromedp example demonstrating how to connect to an // existing Chrome DevTools instance using a remote WebSocket URL. package main import ( // Standard "embed" "encoding/json" "flag" "html/template" "io" "log" "net/http" "os" "os/exec" "strings" ) const VERSION = "v1" var ( flagVerbose bool flagWsURL string flagWatch string //go:embed static fs embed.FS ) func main() { flag.BoolVar(&flagVerbose, "v", false, "verbose") flag.StringVar(&flagWsURL, "ws", "ws://127.0.0.1:9222", "devtools url") flag.StringVar(&flagWatch, "watch", "", "Files to watch") flag.Parse() http.HandleFunc("/", pageIndex) http.HandleFunc("/css/main.css", pageCSS) http.HandleFunc("/browser/start", actionBrowserStart) http.HandleFunc("/start", actionStart) http.HandleFunc("/stop/{uuid}", actionStop) http.HandleFunc("/sites", actionSites) log.Println("Listen on [::]:5123") http.ListenAndServe("[::]:5123", nil) } func replaceTilde(str string) string {// {{{ homedir, err := os.UserHomeDir() if err != nil { log.Println(err) return str } if str[0] == '~' { str = strings.Replace(str, "~", homedir, 1) } return str }// }}} func pageIndex(w http.ResponseWriter, r *http.Request) { // {{{ var tmpl *template.Template var err error if false { tmpl, err = template.ParseFS(fs, "static/html/index.html") } tmpl, err = template.ParseFiles("static/html/index.html") if err != nil { w.Write([]byte(err.Error())) return } data := map[string]any{ "Sites": sites, "VERSION": VERSION, } tmpl.Execute(w, data) } // }}} func pageCSS(w http.ResponseWriter, r *http.Request) { // {{{ w.Header().Add("Content-Type", "text/css") //data, err := fs.ReadFile("static/css/main.css") data, err := os.ReadFile("static/css/main.css") if err != nil { w.Write([]byte(err.Error())) return } w.Write(data) } // }}} func actionSites(w http.ResponseWriter, r *http.Request) { // {{{ j, _ := json.Marshal(struct { OK bool Sites map[string]*Site }{ true, sites, }) w.Write(j) } // }}} func actionBrowserStart(w http.ResponseWriter, r *http.Request) {// {{{ body, _ := io.ReadAll(r.Body) userDataDir := replaceTilde(string(body)) browser := exec.Command("google-chrome", "--user-data-dir="+string(userDataDir), "--remote-debugging-port=9222") err := browser.Start() if err != nil { log.Println(err) } else { go browser.Wait() } }// }}} func actionStart(w http.ResponseWriter, r *http.Request) { // {{{ var req struct { URL string Watch string } body, _ := io.ReadAll(r.Body) err := json.Unmarshal(body, &req) if err != nil { j, _ := json.Marshal(struct { OK bool Error string }{ false, err.Error(), }) w.Write(j) return } var site Site expandedWatch := replaceTilde(req.Watch) site, err = NewSite(flagWsURL, req.URL, expandedWatch) if err != nil { log.Println(err) } j, _ := json.Marshal(struct { OK bool Site Site }{ true, site, }) w.Write(j) } // }}} func actionStop(w http.ResponseWriter, r *http.Request) { // {{{ siteUUID := r.PathValue("uuid") site, found := sites[siteUUID] if !found { j, _ := json.Marshal(struct { OK bool Error string }{ false, "Site not found", }) w.Write(j) return } site.StopLoop = true j, _ := json.Marshal(struct { OK bool }{ true, }) w.Write(j) } // }}}