Allow GUI development with standard binary

This commit is contained in:
Jakob Borg 2014-05-22 16:12:19 +02:00
parent 52d8e4c691
commit 04130fcb15
5 changed files with 45 additions and 56 deletions

View File

@ -88,7 +88,8 @@ case "$1" in
;; ;;
guidev) guidev)
build -tags guidev echo "Syncthing is already built for GUI developments. Try:"
echo " STGUIASSETS=~/someDir/gui syncthing"
;; ;;
test) test)

View File

@ -4,17 +4,21 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand" "math/rand"
"mime"
"net" "net"
"net/http" "net/http"
"path/filepath"
"runtime" "runtime"
"sync" "sync"
"time" "time"
"crypto/tls" "crypto/tls"
"code.google.com/p/go.crypto/bcrypt" "code.google.com/p/go.crypto/bcrypt"
"github.com/calmh/syncthing/auto"
"github.com/calmh/syncthing/config" "github.com/calmh/syncthing/config"
"github.com/calmh/syncthing/logger" "github.com/calmh/syncthing/logger"
"github.com/calmh/syncthing/model" "github.com/calmh/syncthing/model"
@ -31,8 +35,7 @@ var (
configInSync = true configInSync = true
guiErrors = []guiError{} guiErrors = []guiError{}
guiErrorsMut sync.Mutex guiErrorsMut sync.Mutex
static = embeddedStatic() static func(http.ResponseWriter, *http.Request, *log.Logger)
staticFunc = static.(func(http.ResponseWriter, *http.Request, *log.Logger))
) )
const ( const (
@ -43,7 +46,7 @@ func init() {
l.AddHandler(logger.LevelWarn, showGuiError) l.AddHandler(logger.LevelWarn, showGuiError)
} }
func startGUI(cfg config.GUIConfiguration, m *model.Model) error { func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) error {
var listener net.Listener var listener net.Listener
var err error var err error
if cfg.UseTLS { if cfg.UseTLS {
@ -70,6 +73,12 @@ func startGUI(cfg config.GUIConfiguration, m *model.Model) error {
} }
} }
if len(assetDir) > 0 {
static = martini.Static(assetDir).(func(http.ResponseWriter, *http.Request, *log.Logger))
} else {
static = embeddedStatic()
}
router := martini.NewRouter() router := martini.NewRouter()
router.Get("/", getRoot) router.Get("/", getRoot)
router.Get("/rest/version", restGetVersion) router.Get("/rest/version", restGetVersion)
@ -108,7 +117,7 @@ func startGUI(cfg config.GUIConfiguration, m *model.Model) error {
func getRoot(w http.ResponseWriter, r *http.Request) { func getRoot(w http.ResponseWriter, r *http.Request) {
r.URL.Path = "/index.html" r.URL.Path = "/index.html"
staticFunc(w, r, nil) static(w, r, nil)
} }
func restMiddleware(w http.ResponseWriter, r *http.Request) { func restMiddleware(w http.ResponseWriter, r *http.Request) {
@ -340,3 +349,29 @@ func basic(username string, passhash string) http.HandlerFunc {
} }
} }
} }
func embeddedStatic() func(http.ResponseWriter, *http.Request, *log.Logger) {
var modt = time.Now().UTC().Format(http.TimeFormat)
return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
file := req.URL.Path
if file[0] == '/' {
file = file[1:]
}
bs, ok := auto.Assets[file]
if !ok {
return
}
mtype := mime.TypeByExtension(filepath.Ext(req.URL.Path))
if len(mtype) != 0 {
res.Header().Set("Content-Type", mtype)
}
res.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs)))
res.Header().Set("Last-Modified", modt)
res.Write(bs)
}
}

View File

@ -1,9 +0,0 @@
//+build guidev
package main
import "github.com/codegangsta/martini"
func embeddedStatic() interface{} {
return martini.Static("gui")
}

View File

@ -1,40 +0,0 @@
//+build !guidev
package main
import (
"fmt"
"log"
"mime"
"net/http"
"path/filepath"
"time"
"github.com/calmh/syncthing/auto"
)
func embeddedStatic() interface{} {
var modt = time.Now().UTC().Format(http.TimeFormat)
return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
file := req.URL.Path
if file[0] == '/' {
file = file[1:]
}
bs, ok := auto.Assets[file]
if !ok {
return
}
mtype := mime.TypeByExtension(filepath.Ext(req.URL.Path))
if len(mtype) != 0 {
res.Header().Set("Content-Type", mtype)
}
res.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs)))
res.Header().Set("Last-Modified", modt)
res.Write(bs)
}
}

View File

@ -84,7 +84,9 @@ const (
- "xdr" (the xdr package) - "xdr" (the xdr package)
- "all" (all of the above) - "all" (all of the above)
STCPUPROFILE Write CPU profile to the specified file.` STCPUPROFILE Write CPU profile to the specified file.
STGUIASSETS Directory to load GUI assets from. Overrides compiled in assets.`
) )
func main() { func main() {
@ -279,7 +281,7 @@ func main() {
} }
l.Infof("Starting web GUI on %s://%s:%d/", proto, hostShow, addr.Port) l.Infof("Starting web GUI on %s://%s:%d/", proto, hostShow, addr.Port)
err := startGUI(cfg.GUI, m) err := startGUI(cfg.GUI, os.Getenv("STGUIASSETS"), m)
if err != nil { if err != nil {
l.Fatalln("Cannot start GUI:", err) l.Fatalln("Cannot start GUI:", err)
} }