iafan / goplayspace

Advanced Go Playground frontend written in Go, with syntax highlighting, turtle graphics mode, and more
https://goplay.space
Other
981 stars 63 forks source link

Help - code to download raw #21

Open golango opened 6 years ago

golango commented 6 years ago

Can you help me with adding a download button to get the raw files from play.golang.org?

iafan commented 6 years ago

I can't provide a detailed walkthrough, but I can give you some pointers: 1) https://stackoverflow.com/questions/3749231/download-file-using-javascript-jquery on how this can be done (you need to post current editor contents to the server, and the server needs to return the same payload with appropriate MIME Type and suggested filename). 2) use the "Share" button and code behind it as a template: duplicate the button in the UI, use code similar to this to send editor data back to the server (use a different server URL, e.g. /download instead of /share). On the server, implement the /download handler similar to this that would just return the data back with some headers as suggested above.

veganexe commented 6 years ago

I get this error when compiling, component/app/app.go:248:2: bodyBytes declared but not used

Where am I going wrong?

server.go

...
...
import (
        "fmt"
...
...
http.HandleFunc("/download", downloadHandler)
...
...
func runDownload(body io.Reader) ([]byte, error) {
        return doRequest("POST", "https://play.golang.org/share", "text/plain", body)
}
...
...
func downloadHandler(w http.ResponseWriter, r *http.Request) {
        defer r.Body.Close()

        if r.Method != http.MethodPost {
                http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
                return
        }

        bodyBytes, err := runDownload(r.Body)
        if err != nil {
                http.Error(w, "Failed to send download request", http.StatusInternalServerError)
                return
        }
        w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="code.go"`))
        w.Header().Set("Content-type", "text/plain")
        w.Write(bodyBytes)
}
...
...

app.go

...
...
func (a *Application) downloadButtonClick(e *vecty.Event) {
        a.doDownload()
}

func (a *Application) doDownload() {

        a.doFormat()
        bodyBytes, err := xhr.Send("POST", "/download", []byte(a.Input))
        if err != nil {
                a.err = err.Error()
                return
        }

}
...
...
        elem.Button(
                        vecty.UnsafeHTML("Download"),
                        event.Click(a.downloadButtonClick),
                ),
...
...
golango commented 6 years ago

That looks too complicated! Can there just be a simple download button that can download a shared snippet. Because if you add .go to the snippet id on play.golang.org, it returns the raw file, for example, https://play.golang.org/p/v3rrZLwEUC.go