1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-13 05:50:27 +00:00
mycorrhiza/main.go
2020-06-17 20:19:52 +05:00

241 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"github.com/gorilla/mux"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
// "strconv"
"time"
)
func GetRevision(hyphae map[string]*Hypha, hyphaName string, rev string, w http.ResponseWriter) (Revision, bool) {
log.Println("Getting hypha", hyphaName, rev)
for name, hypha := range hyphae {
if name == hyphaName {
if rev == "0" {
rev = hypha.NewestRevision()
}
for id, r := range hypha.Revisions {
if rev == id {
return *r, true
}
}
}
}
return Revision{}, false
}
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)
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
if !ok {
return
}
fileContents, err := ioutil.ReadFile(rev.BinaryPath)
if err != nil {
log.Println("Failed to load binary data of", rev.FullName, rev.Id)
w.WriteHeader(http.StatusNotFound)
return
}
w.Header().Set("Content-Type", rev.BinaryMime)
w.WriteHeader(http.StatusOK)
w.Write(fileContents)
log.Println("Showing image of", rev.FullName, rev.Id)
}
func HandlerRaw(w http.ResponseWriter, r *http.Request) {
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
}
w.Header().Set("Content-Type", rev.TextMime)
w.WriteHeader(http.StatusOK)
w.Write(fileContents)
log.Println("Serving text data of", rev.FullName, rev.Id)
}
func HandlerZen(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
revno := RevInMap(vars)
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
if !ok {
return
}
html, err := rev.AsHtml(hyphae)
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)
}
func HandlerView(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
revno := RevInMap(vars)
rev, ok := GetRevision(hyphae, vars["hypha"], revno, w)
if !ok {
return
}
html, err := rev.AsHtml(hyphae)
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, 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) {
vars := mux.Vars(r)
ActionEdit(vars["hypha"], w)
}
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")
}
var rootWikiDir string
var hyphae map[string]*Hypha
func hyphaeAsMap(hyphae []*Hypha) map[string]*Hypha {
mh := make(map[string]*Hypha)
for _, h := range hyphae {
mh[h.Name()] = h
}
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)
}
log.Println("Welcome to MycorrhizaWiki α")
log.Println("Indexing hyphae...")
hyphae = recurFindHyphae(rootWikiDir)
log.Println("Indexed", len(hyphae), "hyphae. Ready to accept requests.")
// setRelations(hyphae)
// Start server code
r := mux.NewRouter()
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)
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 {
log.Println("Rendering latest revision of hypha", v.Name())
html, err := v.AsHtml(hyphae, "0")
if err != nil {
fmt.Fprintln(w, err)
}
fmt.Fprintln(w, html)
}
})
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())
}