| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- package main
- import (
- "encoding/json"
- "fmt"
- "io"
- "log"
- "mime"
- "net/http"
- "path/filepath"
- "bitbucket.org/tebeka/nrsc"
- "github.com/codegangsta/martini"
- )
- func startGUI(addr string, m *Model) {
- router := martini.NewRouter()
- router.Get("/", getRoot)
- router.Get("/rest/version", restGetVersion)
- router.Get("/rest/model", restGetModel)
- router.Get("/rest/connections", restGetConnections)
- router.Get("/rest/config", restGetConfig)
- router.Get("/rest/need", restGetNeed)
- go func() {
- mr := martini.New()
- mr.Use(nrscStatic("gui"))
- mr.Use(martini.Recovery())
- mr.Action(router.Handle)
- mr.Map(m)
- http.ListenAndServe(addr, mr)
- }()
- }
- func getRoot(w http.ResponseWriter, r *http.Request) {
- http.Redirect(w, r, "/index.html", 302)
- }
- func restGetVersion() string {
- return Version
- }
- func restGetModel(m *Model, w http.ResponseWriter) {
- var res = make(map[string]interface{})
- globalFiles, globalDeleted, globalBytes := m.GlobalSize()
- res["globalFiles"], res["globalDeleted"], res["globalBytes"] = globalFiles, globalDeleted, globalBytes
- localFiles, localDeleted, localBytes := m.LocalSize()
- res["localFiles"], res["localDeleted"], res["localBytes"] = localFiles, localDeleted, localBytes
- inSyncFiles, inSyncBytes := m.InSyncSize()
- res["inSyncFiles"], res["inSyncBytes"] = inSyncFiles, inSyncBytes
- files, total := m.NeedFiles()
- res["needFiles"], res["needBytes"] = len(files), total
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(res)
- }
- func restGetConnections(m *Model, w http.ResponseWriter) {
- var res = m.ConnectionStats()
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(res)
- }
- func restGetConfig(w http.ResponseWriter) {
- var res = make(map[string]interface{})
- res["repository"] = config.OptionMap("repository")
- res["nodes"] = config.OptionMap("nodes")
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(res)
- }
- func restGetNeed(m *Model, w http.ResponseWriter) {
- files, _ := m.NeedFiles()
- if files == nil {
- // We don't want the empty list to serialize as "null\n"
- files = make([]FileInfo, 0)
- }
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(files)
- }
- func nrscStatic(path string) interface{} {
- if err := nrsc.Initialize(); err != nil {
- panic("Unable to initialize nrsc: " + err.Error())
- }
- return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
- file := req.URL.Path
- // nrsc expects there not to be a leading slash
- if file[0] == '/' {
- file = file[1:]
- }
- f := nrsc.Get(file)
- if f == nil {
- return
- }
- rdr, err := f.Open()
- if err != nil {
- http.Error(res, "Internal Server Error", http.StatusInternalServerError)
- }
- defer rdr.Close()
- mtype := mime.TypeByExtension(filepath.Ext(req.URL.Path))
- if len(mtype) != 0 {
- res.Header().Set("Content-Type", mtype)
- }
- res.Header().Set("Content-Size", fmt.Sprintf("%d", f.Size()))
- res.Header().Set("Last-Modified", f.ModTime().UTC().Format(http.TimeFormat))
- io.Copy(res, rdr)
- }
- }
|