ENH: Drop filesystem (#1)

This commit is contained in:
Matthew Ryan Dillon 2016-10-17 15:26:20 -07:00 committed by GitHub
parent bd93fd22bb
commit 18b61a9532

127
main.go
View file

@ -2,66 +2,63 @@ package main
import ( import (
"archive/zip" "archive/zip"
"bytes"
"fmt" "fmt"
"github.com/pkg/browser" "github.com/pkg/browser"
"io" "io/ioutil"
"mime/multipart"
"net/http" "net/http"
"os" "path"
"path/filepath"
"regexp" "regexp"
"strings" "time"
) )
func rootHandler(w http.ResponseWriter, r *http.Request) { type dataMap map[string]*bytes.Reader
type zipContext struct {
Data dataMap
}
func (z *zipContext) rootHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, index) fmt.Fprintf(w, index)
} }
func uploadHandler(w http.ResponseWriter, r *http.Request) { func (z *zipContext) uploadHandler(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(32 << 20) r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("artifact") file, _, err := r.FormFile("artifact")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
defer file.Close() if err := unzip(file, z.Data); err != nil {
os.RemoveAll("tmp")
os.Mkdir("tmp", 0755)
filename := filepath.Join("tmp", handler.Filename)
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
err = unzip(filename, filepath.Join("tmp", "serve"))
if err != nil {
panic(err) panic(err)
} }
var vizpath string var vizpath string
for k := range z.Data {
filepath.Walk("tmp", func(path string, f os.FileInfo, _ error) error { r, err := regexp.MatchString("index.", k)
if !f.IsDir() { if err == nil && r {
r, err := regexp.MatchString("index.", f.Name()) vizpath = k
if err == nil && r {
vizpath = path
}
} }
return nil }
})
http.Redirect(w, r, filepath.ToSlash(vizpath), 301) http.Redirect(w, r, path.Join("tmp", vizpath), 301)
}
func (z *zipContext) ServeHTTP(w http.ResponseWriter, r *http.Request) {
filename := r.URL.Path
http.ServeContent(w, r, filename, time.Now(), z.Data[filename])
} }
func main() { func main() {
http.HandleFunc("/", rootHandler) zipServer := &zipContext{
http.HandleFunc("/upload", uploadHandler) Data: make(dataMap),
http.Handle("/tmp/", http.StripPrefix("/tmp", http.FileServer(http.Dir("tmp")))) }
http.HandleFunc("/", zipServer.rootHandler)
http.HandleFunc("/upload", zipServer.uploadHandler)
http.Handle("/tmp/", http.StripPrefix("/tmp/", zipServer))
err := browser.OpenURL("http://localhost:8282") err := browser.OpenURL("http://localhost:8282")
if err != nil { if err != nil {
@ -71,64 +68,28 @@ func main() {
http.ListenAndServe(":8282", nil) http.ListenAndServe(":8282", nil)
} }
// Modified from http://stackoverflow.com/a/24792688 func unzip(source multipart.File, unzipped dataMap) error {
func unzip(src, dest string) error { var buff bytes.Buffer
r, err := zip.OpenReader(src) sourceSize, err := buff.ReadFrom(source)
if err != nil {
return err
}
r, err := zip.NewReader(source, sourceSize)
if err != nil { if err != nil {
return err return err
} }
defer func() {
if err := r.Close(); err != nil {
panic(err)
}
}()
os.MkdirAll(dest, 0755) for _, f := range r.File {
// Closure to address file descriptors issue with all the deferred .Close() methods
extractAndWriteFile := func(f *zip.File) error {
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
return err return err
} }
defer func() { b, err := ioutil.ReadAll(rc)
if err := rc.Close(); err != nil {
panic(err)
}
}()
components := strings.Split(f.Name, "/")
path := filepath.Join(append([]string{dest}, components...)...)
if f.FileInfo().IsDir() {
os.MkdirAll(path, 0755)
} else {
os.MkdirAll(filepath.Dir(path), 0755)
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()
_, err = io.Copy(f, rc)
if err != nil {
return err
}
}
return nil
}
for _, f := range r.File {
err := extractAndWriteFile(f)
if err != nil { if err != nil {
return err return err
} }
unzipped[f.Name] = bytes.NewReader(b)
} }
return nil return nil
} }
@ -136,7 +97,7 @@ var index = `
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>dnd binary upload</title> <title>qiime qzv viewer</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style> <style>
/*! /*!