2020-06-12 16:22:02 +00:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2020-06-13 11:18:11 +00:00
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"log"
|
|
|
|
|
"net/http"
|
2020-06-12 16:22:02 +00:00
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2020-06-13 11:18:11 +00:00
|
|
|
|
// "strconv"
|
|
|
|
|
"time"
|
2020-06-12 16:22:02 +00:00
|
|
|
|
)
|
|
|
|
|
|
2020-06-16 18:35:52 +00:00
|
|
|
|
func GetRevision(hyphae map[string]*Hypha, hyphaName string, rev string, w http.ResponseWriter) (Revision, bool) {
|
2020-06-17 09:40:51 +00:00
|
|
|
|
log.Println("Getting hypha", hyphaName, rev)
|
|
|
|
|
for name, hypha := range hyphae {
|
2020-06-16 18:35:52 +00:00
|
|
|
|
if name == hyphaName {
|
2020-06-17 09:40:51 +00:00
|
|
|
|
if rev == "0" {
|
|
|
|
|
rev = hypha.NewestRevision()
|
|
|
|
|
}
|
|
|
|
|
for id, r := range hypha.Revisions {
|
2020-06-16 18:35:52 +00:00
|
|
|
|
if rev == id {
|
|
|
|
|
return *r, true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Revision{}, false
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-14 08:12:22 +00:00
|
|
|
|
func RevInMap(m map[string]string) string {
|
|
|
|
|
if val, ok := m["rev"]; ok {
|
|
|
|
|
return val
|
|
|
|
|
}
|
|
|
|
|
return "0"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// handlers
|
|
|
|
|
func HandlerGetBinary(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
|
revno := RevInMap(vars)
|
2020-06-14 08:43:49 +00:00
|
|
|
|
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
2020-06-14 08:12:22 +00:00
|
|
|
|
}
|
|
|
|
|
fileContents, err := ioutil.ReadFile(rev.BinaryPath)
|
|
|
|
|
if err != nil {
|
2020-06-14 08:43:49 +00:00
|
|
|
|
log.Println("Failed to load binary data of", rev.FullName, rev.Id)
|
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
|
return
|
2020-06-14 08:12:22 +00:00
|
|
|
|
}
|
2020-06-16 18:35:52 +00:00
|
|
|
|
w.Header().Set("Content-Type", rev.BinaryMime)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
w.Write(fileContents)
|
2020-06-14 08:43:49 +00:00
|
|
|
|
log.Println("Showing image of", rev.FullName, rev.Id)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerRaw(w http.ResponseWriter, r *http.Request) {
|
2020-06-14 08:43:49 +00:00
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
|
revno := RevInMap(vars)
|
|
|
|
|
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
fileContents, err := ioutil.ReadFile(rev.TextPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println("Failed to load text data of", rev.FullName, rev.Id)
|
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-06-17 09:40:51 +00:00
|
|
|
|
w.Header().Set("Content-Type", rev.TextMime)
|
2020-06-14 08:43:49 +00:00
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
w.Write(fileContents)
|
|
|
|
|
log.Println("Serving text data of", rev.FullName, rev.Id)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerZen(w http.ResponseWriter, r *http.Request) {
|
2020-06-14 08:43:49 +00:00
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
|
revno := RevInMap(vars)
|
|
|
|
|
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-06-16 18:35:52 +00:00
|
|
|
|
html, err := rev.AsHtml(hyphae)
|
2020-06-14 08:43:49 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println("Failed to render", rev.FullName)
|
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
fmt.Fprint(w, html)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerView(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
vars := mux.Vars(r)
|
2020-06-14 08:43:49 +00:00
|
|
|
|
revno := RevInMap(vars)
|
|
|
|
|
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
|
|
|
|
|
if !ok {
|
2020-06-14 08:12:22 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2020-06-16 18:35:52 +00:00
|
|
|
|
html, err := rev.AsHtml(hyphae)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
if err != nil {
|
2020-06-14 08:43:49 +00:00
|
|
|
|
log.Println("Failed to render", rev.FullName)
|
2020-06-14 08:12:22 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-06-14 08:43:49 +00:00
|
|
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
2020-06-14 08:12:22 +00:00
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
fmt.Fprint(w, HyphaPage(hyphae, rev, html))
|
|
|
|
|
log.Println("Rendering", rev.FullName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerHistory(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerEdit(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerRewind(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerDelete(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerRename(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HandlerUpdate(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.WriteHeader(http.StatusNotImplemented)
|
|
|
|
|
log.Println("Attempt to access an unimplemented thing")
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-12 16:22:02 +00:00
|
|
|
|
var rootWikiDir string
|
2020-06-14 08:12:22 +00:00
|
|
|
|
var hyphae map[string]*Hypha
|
2020-06-12 16:22:02 +00:00
|
|
|
|
|
|
|
|
|
func hyphaeAsMap(hyphae []*Hypha) map[string]*Hypha {
|
|
|
|
|
mh := make(map[string]*Hypha)
|
|
|
|
|
for _, h := range hyphae {
|
2020-06-16 18:35:52 +00:00
|
|
|
|
mh[h.Name()] = h
|
2020-06-12 16:22:02 +00:00
|
|
|
|
}
|
|
|
|
|
return mh
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
if len(os.Args) == 1 {
|
|
|
|
|
panic("Expected a root wiki pages directory")
|
|
|
|
|
}
|
|
|
|
|
// Required so the rootWikiDir hereinbefore does not get redefined.
|
|
|
|
|
var err error
|
|
|
|
|
rootWikiDir, err = filepath.Abs(os.Args[1])
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-17 09:40:51 +00:00
|
|
|
|
log.Println("Welcome to MycorrhizaWiki α")
|
|
|
|
|
log.Println("Indexing hyphae...")
|
2020-06-16 18:35:52 +00:00
|
|
|
|
hyphae = recurFindHyphae(rootWikiDir)
|
2020-06-17 09:40:51 +00:00
|
|
|
|
log.Println("Indexed", len(hyphae), "hyphae. Ready to accept requests.")
|
2020-06-16 18:35:52 +00:00
|
|
|
|
// setRelations(hyphae)
|
2020-06-12 16:22:02 +00:00
|
|
|
|
|
2020-06-13 11:18:11 +00:00
|
|
|
|
// Start server code
|
|
|
|
|
r := mux.NewRouter()
|
2020-06-14 08:12:22 +00:00
|
|
|
|
|
|
|
|
|
r.Queries("action", "getBinary", "rev", revQuery).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerGetBinary)
|
|
|
|
|
r.Queries("action", "getBinary").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerGetBinary)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "raw", "rev", revQuery).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerRaw)
|
|
|
|
|
r.Queries("action", "raw").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerRaw)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "zen", "rev", revQuery).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerZen)
|
|
|
|
|
r.Queries("action", "zen").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerZen)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "view", "rev", revQuery).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerView)
|
|
|
|
|
r.Queries("action", "view").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerView)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "history").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerHistory)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "edit").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerEdit)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "rewind", "rev", revQuery).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerRewind)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "delete").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerDelete)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "rename", "to", hyphaPattern).Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerRename)
|
|
|
|
|
|
|
|
|
|
r.Queries("action", "update").Path(hyphaUrl).
|
|
|
|
|
HandlerFunc(HandlerUpdate)
|
|
|
|
|
|
|
|
|
|
r.HandleFunc(hyphaUrl, HandlerView)
|
2020-06-13 16:42:43 +00:00
|
|
|
|
|
2020-06-13 11:18:11 +00:00
|
|
|
|
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
for _, v := range hyphae {
|
2020-06-16 18:35:52 +00:00
|
|
|
|
log.Println("Rendering latest revision of hypha", v.Name())
|
|
|
|
|
html, err := v.AsHtml(hyphae, "0")
|
2020-06-13 11:18:11 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintln(w, err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Fprintln(w, html)
|
|
|
|
|
}
|
|
|
|
|
})
|
2020-06-14 08:12:22 +00:00
|
|
|
|
|
2020-06-13 11:18:11 +00:00
|
|
|
|
http.Handle("/", r)
|
|
|
|
|
|
|
|
|
|
srv := &http.Server{
|
|
|
|
|
Handler: r,
|
|
|
|
|
Addr: "127.0.0.1:8000",
|
|
|
|
|
// Good practice: enforce timeouts for servers you create!
|
|
|
|
|
WriteTimeout: 15 * time.Second,
|
|
|
|
|
ReadTimeout: 15 * time.Second,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.Fatal(srv.ListenAndServe())
|
2020-06-12 16:22:02 +00:00
|
|
|
|
}
|