mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-13 05:50:27 +00:00
Make it render all hyphae
This commit is contained in:
parent
14fe4acf6b
commit
de7b7faca2
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module github.com/bouncepaw/mycorrhiza
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725 // indirect
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
gopkg.in/ini.v1 v1.57.0
|
||||
|
3
go.sum
3
go.sum
@ -1,4 +1,6 @@
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725 h1:X6sZdr+t2E2jwajTy/FfXbmAKPFTYxEq9hiFgzMiuPQ=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -6,6 +8,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
|
||||
|
58
hypha.go
58
hypha.go
@ -1,7 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Hypha struct {
|
||||
@ -36,39 +38,29 @@ func (h Hypha) String() string {
|
||||
revbuf)
|
||||
}
|
||||
|
||||
type Revision struct {
|
||||
// Revision is hypha's state at some point in time. Future revisions are not really supported. Most data here is stored in m.ini.
|
||||
Id int
|
||||
// Name used at this revision
|
||||
Name string `json:"name"`
|
||||
// Present in every hypha. Stored in t.txt.
|
||||
TextPath string
|
||||
// In at least one markup. Supported ones are "myco", "html", "md", "plain"
|
||||
Markup string `json:"markup"`
|
||||
// Some hyphæ have binary contents such as images. Their presence change hypha's behavior in a lot of ways (see methods' implementations). If stored, it is stored in b (filename "b")
|
||||
BinaryPath string
|
||||
// To tell what is meaning of binary content, mimeType for them is stored. If the hypha has no binary content, this field must be "application/x-hypha"
|
||||
MimeType string `json:"mimeType"`
|
||||
// Every revision was created at some point. This field stores the creation time of the latest revision
|
||||
RevisionTime int `json:"createdAt"`
|
||||
// Every hypha has any number of tags
|
||||
Tags []string `json:"tags"`
|
||||
// Current revision is authored by someone
|
||||
RevisionAuthor string `json:"author"`
|
||||
// and has a comment in plain text
|
||||
RevisionComment string `json:"comment"`
|
||||
// Rest of fields are ignored
|
||||
func GetRevision(hyphae map[string]*Hypha, hyphaName string, rev string) (Revision, error) {
|
||||
for name, _ := range hyphae {
|
||||
if name == hyphaName {
|
||||
for _, r := range hyphae[name].Revisions {
|
||||
id, err := strconv.Atoi(rev)
|
||||
if err != nil {
|
||||
return Revision{}, err
|
||||
}
|
||||
if r.Id == id {
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Revision{}, errors.New("Some error idk")
|
||||
}
|
||||
|
||||
func (h Revision) String() string {
|
||||
return fmt.Sprintf(`Revision %v created at %v {
|
||||
name: %v
|
||||
textPath: %v
|
||||
markup: %v
|
||||
binaryPath: %v
|
||||
mimeType: %v
|
||||
tags: %v
|
||||
revisionAuthor: %v
|
||||
revisionComment: %v
|
||||
}`, h.Id, h.RevisionTime, h.Name, h.TextPath, h.Markup, h.BinaryPath, h.MimeType, h.Tags, h.RevisionAuthor, h.RevisionComment)
|
||||
// `rev` is the id of revision to render. If it = 0, the last one is rendered. If the revision is not found, an error is returned.
|
||||
func (h Hypha) Render(hyphae map[string]*Hypha, rev int) (ret string, err error) {
|
||||
for _, r := range h.Revisions {
|
||||
if r.Id == rev {
|
||||
return r.Render(hyphae)
|
||||
}
|
||||
}
|
||||
return "", errors.New("Revision was not found")
|
||||
}
|
||||
|
59
main.go
59
main.go
@ -2,8 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
// "strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var rootWikiDir string
|
||||
@ -30,5 +36,56 @@ func main() {
|
||||
hyphae := hyphaeAsMap(recurFindHyphae(rootWikiDir))
|
||||
setRelations(hyphae)
|
||||
|
||||
fmt.Println(hyphae)
|
||||
// Start server code
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/showHyphae", func(w http.ResponseWriter, r *http.Request) {
|
||||
for _, h := range hyphae {
|
||||
fmt.Fprintln(w, h)
|
||||
}
|
||||
})
|
||||
r.Queries(
|
||||
"action", "getBinary",
|
||||
"rev", "{rev:[\\d]+}",
|
||||
).Path("/{hypha:" + hyphaPattern + "}").
|
||||
HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
rev, err := GetRevision(hyphae, vars["hypha"], vars["rev"])
|
||||
if err != nil {
|
||||
log.Println("Failed to show image of", rev.FullName)
|
||||
}
|
||||
fileContents, err := ioutil.ReadFile(rev.BinaryPath)
|
||||
if err != nil {
|
||||
log.Println("Failed to show image of", rev.FullName)
|
||||
}
|
||||
log.Println("Contents:", fileContents[:10], "...")
|
||||
w.Header().Set("Content-Type", rev.MimeType)
|
||||
// w.Header().Set("Content-Length", strconv.Itoa(len(fileContents)))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(fileContents)
|
||||
log.Println("Showing image of", rev.FullName)
|
||||
})
|
||||
|
||||
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.Render(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())
|
||||
}
|
||||
|
79
revision.go
Normal file
79
revision.go
Normal file
@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gomarkdown/markdown"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type Revision struct {
|
||||
// Revision is hypha's state at some point in time. Future revisions are not really supported. Most data here is stored in m.ini.
|
||||
Id int
|
||||
// Name used at this revision
|
||||
Name string `json:"name"`
|
||||
// Name of hypha
|
||||
FullName string
|
||||
// Present in every hypha. Stored in t.txt.
|
||||
TextPath string
|
||||
// In at least one markup. Supported ones are "myco", "html", "md", "plain"
|
||||
Markup string `json:"markup"`
|
||||
// Some hyphæ have binary contents such as images. Their presence change hypha's behavior in a lot of ways (see methods' implementations). If stored, it is stored in b (filename "b")
|
||||
BinaryPath string
|
||||
BinaryRequest string
|
||||
// To tell what is meaning of binary content, mimeType for them is stored. If the hypha has no binary content, this field must be "application/x-hypha"
|
||||
MimeType string `json:"mimeType"`
|
||||
// Every revision was created at some point. This field stores the creation time of the latest revision
|
||||
RevisionTime int `json:"createdAt"`
|
||||
// Every hypha has any number of tags
|
||||
Tags []string `json:"tags"`
|
||||
// Current revision is authored by someone
|
||||
RevisionAuthor string `json:"author"`
|
||||
// and has a comment in plain text
|
||||
RevisionComment string `json:"comment"`
|
||||
}
|
||||
|
||||
func (h Revision) String() string {
|
||||
return fmt.Sprintf(`Revision %v created at %v {
|
||||
name: %v
|
||||
textPath: %v
|
||||
markup: %v
|
||||
binaryPath: %v
|
||||
mimeType: %v
|
||||
tags: %v
|
||||
revisionAuthor: %v
|
||||
revisionComment: %v
|
||||
}`, h.Id, h.RevisionTime, h.Name, h.TextPath, h.Markup, h.BinaryPath, h.MimeType, h.Tags, h.RevisionAuthor, h.RevisionComment)
|
||||
}
|
||||
|
||||
// This method is meant to be called only by Hypha#Render.
|
||||
func (r Revision) Render(hyphae map[string]*Hypha) (ret string, err error) {
|
||||
ret += `<article class="page">
|
||||
`
|
||||
// If it is a binary hypha (we support only images for now):
|
||||
// TODO: support things other than images.
|
||||
if r.MimeType != "application/x-hypha" {
|
||||
ret += fmt.Sprintf(`<img src="%s" class="page__image"/>`, r.BinaryRequest)
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadFile(r.TextPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// TODO: support more markups.
|
||||
// TODO: support mycorrhiza extensions like transclusion.
|
||||
switch r.Markup {
|
||||
case "plain":
|
||||
ret += fmt.Sprintf(`<pre>%s</pre>`, contents)
|
||||
case "md":
|
||||
html := markdown.ToHTML(contents, nil, nil)
|
||||
ret += string(html)
|
||||
default:
|
||||
return "", errors.New("Unsupported markup: " + r.Markup)
|
||||
}
|
||||
|
||||
ret += `
|
||||
</article>`
|
||||
return ret, nil
|
||||
}
|
7
walk.go
7
walk.go
@ -96,7 +96,7 @@ func recurFindHyphae(fullPath string) (hyphae []*Hypha) {
|
||||
|
||||
// Fill in every revision
|
||||
for _, possibleRevisionPath := range possibleRevisionPaths {
|
||||
rev, err := makeRevision(possibleRevisionPath)
|
||||
rev, err := makeRevision(possibleRevisionPath, h.Name)
|
||||
if err == nil {
|
||||
h.Revisions = append(h.Revisions, rev)
|
||||
}
|
||||
@ -119,7 +119,7 @@ func recurFindHyphae(fullPath string) (hyphae []*Hypha) {
|
||||
return hyphae
|
||||
}
|
||||
|
||||
func makeRevision(fullPath string) (r Revision, err error) {
|
||||
func makeRevision(fullPath string, fullName string) (r Revision, err error) {
|
||||
// fullPath is expected to be a path to a dir.
|
||||
// Revision directory must have at least `m.json` and `t.txt` files.
|
||||
var (
|
||||
@ -159,7 +159,7 @@ func makeRevision(fullPath string) (r Revision, err error) {
|
||||
return r, err
|
||||
}
|
||||
|
||||
r = Revision{}
|
||||
r = Revision{FullName: fullName}
|
||||
err = json.Unmarshal(mJsonContents, &r)
|
||||
if err != nil {
|
||||
fmt.Println(fullPath, ">\tError:", err)
|
||||
@ -174,6 +174,7 @@ func makeRevision(fullPath string) (r Revision, err error) {
|
||||
// Do not check for binary file presence, attempt to read it will fail anyway
|
||||
if bPresent {
|
||||
r.BinaryPath = filepath.Join(fullPath, "b")
|
||||
r.BinaryRequest = fmt.Sprintf("%s?rev=%d&action=getBinary", r.FullName, r.Id)
|
||||
} else {
|
||||
return r, errors.New("makeRevision: b file not present")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user