mirror of https://github.com/perkeep/perkeep.git
Add configuration discovery to publish handler.
This permits metadata edits on the publish page if the viewer is the owner. (e.g. tagging, titling photos...) Change-Id: I08b098eaae92f5b629b02707d67bec23a705c29f
This commit is contained in:
parent
711bcfbd44
commit
16cc888842
|
@ -31,6 +31,8 @@ type Loader interface {
|
||||||
|
|
||||||
// Returns either a Storage or an http.Handler
|
// Returns either a Storage or an http.Handler
|
||||||
GetHandler(prefix string) (interface{}, os.Error)
|
GetHandler(prefix string) (interface{}, os.Error)
|
||||||
|
|
||||||
|
FindHandlerByTypeIfLoaded(htype string) (prefix string, handler interface{}, err os.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, os.Error)
|
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, os.Error)
|
||||||
|
|
|
@ -226,6 +226,15 @@ func main() {
|
||||||
ws.Serve()
|
ws.Serve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hl *handlerLoader) FindHandlerByTypeIfLoaded(htype string) (prefix string, handler interface{}, err os.Error) {
|
||||||
|
for prefix, config := range hl.config {
|
||||||
|
if config.htype == htype {
|
||||||
|
return prefix, hl.handler[prefix], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil, os.ENOENT
|
||||||
|
}
|
||||||
|
|
||||||
func (hl *handlerLoader) setupAll() {
|
func (hl *handlerLoader) setupAll() {
|
||||||
for prefix := range hl.config {
|
for prefix := range hl.config {
|
||||||
hl.setupHandler(prefix)
|
hl.setupHandler(prefix)
|
||||||
|
|
|
@ -46,6 +46,7 @@ type PublishHandler struct {
|
||||||
|
|
||||||
JSFiles, CSSFiles []string
|
JSFiles, CSSFiles []string
|
||||||
|
|
||||||
|
bsLoader blobserver.Loader
|
||||||
staticHandler http.Handler
|
staticHandler http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +55,9 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, err os.Error) {
|
func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, err os.Error) {
|
||||||
ph := &PublishHandler{}
|
ph := &PublishHandler{
|
||||||
|
bsLoader: ld,
|
||||||
|
}
|
||||||
ph.RootName = conf.RequiredString("rootName")
|
ph.RootName = conf.RequiredString("rootName")
|
||||||
ph.JSFiles = conf.OptionalList("js")
|
ph.JSFiles = conf.OptionalList("js")
|
||||||
ph.CSSFiles = conf.OptionalList("css")
|
ph.CSSFiles = conf.OptionalList("css")
|
||||||
|
@ -138,7 +141,29 @@ func (ph *PublishHandler) lookupPathTarget(root *blobref.BlobRef, suffix string)
|
||||||
return path.Target, nil
|
return path.Target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ph *PublishHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
if !ph.ViewerIsOwner(req) {
|
||||||
|
discoveryHelper(rw, req, map[string]interface{}{
|
||||||
|
"error": "viewer isn't owner",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, handler, err := ph.bsLoader.FindHandlerByTypeIfLoaded("ui")
|
||||||
|
if err != nil {
|
||||||
|
discoveryHelper(rw, req, map[string]interface{}{
|
||||||
|
"error": "no admin handler running",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ui := handler.(*UIHandler)
|
||||||
|
ui.serveDiscovery(rw, req)
|
||||||
|
}
|
||||||
|
|
||||||
func (ph *PublishHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
func (ph *PublishHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.URL.Query().Get("camli.mode") == "config" {
|
||||||
|
ph.serveDiscovery(rw, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
preq := ph.NewRequest(rw, req)
|
preq := ph.NewRequest(rw, req)
|
||||||
preq.serveHTTP()
|
preq.serveHTTP()
|
||||||
}
|
}
|
||||||
|
@ -184,6 +209,16 @@ func (ph *PublishHandler) NewRequest(rw http.ResponseWriter, req *http.Request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ph *PublishHandler) ViewerIsOwner(req *http.Request) bool {
|
||||||
|
// TODO: better check later
|
||||||
|
return strings.HasPrefix(req.RemoteAddr, "127.") ||
|
||||||
|
strings.HasPrefix(req.RemoteAddr, "localhost:")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *publishRequest) ViewerIsOwner() bool {
|
||||||
|
return pr.ph.ViewerIsOwner(pr.req)
|
||||||
|
}
|
||||||
|
|
||||||
func (pr *publishRequest) Debug() bool {
|
func (pr *publishRequest) Debug() bool {
|
||||||
return pr.req.FormValue("debug") == "1"
|
return pr.req.FormValue("debug") == "1"
|
||||||
}
|
}
|
||||||
|
@ -359,8 +394,12 @@ func (pr *publishRequest) serveSubject() {
|
||||||
}
|
}
|
||||||
for _, filename := range pr.ph.JSFiles {
|
for _, filename := range pr.ph.JSFiles {
|
||||||
pr.pf(" <script src='%s'></script>\n", pr.staticPath(filename))
|
pr.pf(" <script src='%s'></script>\n", pr.staticPath(filename))
|
||||||
|
if filename == "camli.js" && pr.ViewerIsOwner() {
|
||||||
|
pr.pf(" <script src='%s'></script>\n", pr.base+"?camli.mode=config&cb=onConfiguration")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pr.pf(" <script>\n")
|
pr.pf(" <script>\n")
|
||||||
|
pr.pf("var camliViewIsOwner = %v;\n", pr.ViewerIsOwner())
|
||||||
pr.pf("var camliPagePermanode = %q;\n", pr.subject)
|
pr.pf("var camliPagePermanode = %q;\n", pr.subject)
|
||||||
pr.pf("var camliPageMeta = \n")
|
pr.pf("var camliPageMeta = \n")
|
||||||
json, _ := json.MarshalIndent(jm, "", " ")
|
json, _ := json.MarshalIndent(jm, "", " ")
|
||||||
|
|
|
@ -213,14 +213,21 @@ func (ui *UIHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *UIHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
|
func discoveryHelper(rw http.ResponseWriter, req *http.Request, m map[string]interface{}) {
|
||||||
rw.Header().Set("Content-Type", "text/javascript")
|
rw.Header().Set("Content-Type", "text/javascript")
|
||||||
inCb := false
|
inCb := false
|
||||||
if cb := req.FormValue("cb"); identPattern.MatchString(cb) {
|
if cb := req.FormValue("cb"); identPattern.MatchString(cb) {
|
||||||
fmt.Fprintf(rw, "%s(", cb)
|
fmt.Fprintf(rw, "%s(", cb)
|
||||||
inCb = true
|
inCb = true
|
||||||
}
|
}
|
||||||
|
bytes, _ := json.MarshalIndent(m, "", " ")
|
||||||
|
rw.Write(bytes)
|
||||||
|
if inCb {
|
||||||
|
rw.Write([]byte{')'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ui *UIHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
|
||||||
pubRoots := map[string]interface{}{}
|
pubRoots := map[string]interface{}{}
|
||||||
for key, pubh := range ui.PublishRoots {
|
for key, pubh := range ui.PublishRoots {
|
||||||
m := map[string]interface{}{
|
m := map[string]interface{}{
|
||||||
|
@ -237,7 +244,7 @@ func (ui *UIHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
|
||||||
pubRoots[pubh.RootName] = m
|
pubRoots[pubh.RootName] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, _ := json.Marshal(map[string]interface{}{
|
discoveryHelper(rw, req, map[string]interface{}{
|
||||||
"blobRoot": ui.BlobRoot,
|
"blobRoot": ui.BlobRoot,
|
||||||
"searchRoot": ui.SearchRoot,
|
"searchRoot": ui.SearchRoot,
|
||||||
"jsonSignRoot": ui.JSONSignRoot,
|
"jsonSignRoot": ui.JSONSignRoot,
|
||||||
|
@ -245,10 +252,6 @@ func (ui *UIHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) {
|
||||||
"downloadHelper": "./download/",
|
"downloadHelper": "./download/",
|
||||||
"publishRoots": pubRoots,
|
"publishRoots": pubRoots,
|
||||||
})
|
})
|
||||||
rw.Write(bytes)
|
|
||||||
if inCb {
|
|
||||||
rw.Write([]byte{')'})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *UIHandler) serveDownload(rw http.ResponseWriter, req *http.Request) {
|
func (ui *UIHandler) serveDownload(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
|
Loading…
Reference in New Issue