Skip to content

Commit

Permalink
Merge pull request #27 from bouncepaw/0.10
Browse files Browse the repository at this point in the history
0.10
  • Loading branch information
bouncepaw authored Nov 11, 2020
2 parents cbb7a02 + b8ffb7d commit 4f10aa3
Show file tree
Hide file tree
Showing 32 changed files with 1,121 additions and 371 deletions.
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 🍄 MycorrhizaWiki 0.9
# 🍄 MycorrhizaWiki 0.10
A wiki engine.

## Building
Expand All @@ -11,12 +11,25 @@ make
# * create an executable called `mycorrhiza`. Run it with path to your wiki.
```

## Usage
```
mycorrhiza [OPTIONS...] WIKI_PATH
Options:
-home string
The home page (default "home")
-port string
Port to serve the wiki at (default "1737")
-title string
How to call your wiki in the navititle (default "🍄")
```

## Features
* Edit pages through html forms
* Responsive design
* Works in text browsers
* Wiki pages (called hyphae) are in gemtext
* Everything is stored as simple files, no database required
* Wiki pages (called hyphae) are written in mycomarkup
* Everything is stored as simple files, no database required. You can run a wiki on almost any directory and get something to work with.
* Page trees
* Changes are saved to git
* List of hyphae page
Expand All @@ -34,4 +47,3 @@ Help is always needed. We have a [tg chat](https://t.me/mycorrhizadev) where som
* Tagging system
* Authorization
* Better history viewing
* More markups
36 changes: 36 additions & 0 deletions flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"flag"
"log"
"path/filepath"

"github.com/bouncepaw/mycorrhiza/util"
)

func init() {
flag.StringVar(&util.ServerPort, "port", "1737", "Port to serve the wiki at")
flag.StringVar(&util.HomePage, "home", "home", "The home page")
flag.StringVar(&util.SiteTitle, "title", "🍄", "How to call your wiki in the navititle")
}

// Do the things related to cli args and die maybe
func parseCliArgs() {
flag.Parse()

args := flag.Args()
if len(args) == 0 {
log.Fatal("Error: pass a wiki directory")
}

var err error
WikiDir, err = filepath.Abs(args[0])
util.WikiDir = WikiDir
if err != nil {
log.Fatal(err)
}

if !isCanonicalName(util.HomePage) {
log.Fatal("Error: you must use a proper name for the homepage")
}
}
16 changes: 8 additions & 8 deletions history/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ func (rev Revision) HyphaeLinks() (html string) {
}
for _, filename := range strings.Split(out.String(), "\n") {
// If filename has an ampersand:
if strings.IndexRune(filename, '&') >= 0 {
if strings.IndexRune(filename, '.') >= 0 {
// Remove ampersanded suffix from filename:
ampersandPos := strings.LastIndexByte(filename, '&')
ampersandPos := strings.LastIndexByte(filename, '.')
hyphaName := string([]byte(filename)[0:ampersandPos]) // is it safe?
if isNewName(hyphaName) {
// Entries are separated by commas
if len(set) > 1 {
html += `<span aria-hidden="true">, </span>`
}
html += fmt.Sprintf(`<a href="/rev/%[1]s/%[2]s">%[2]s</a>`, rev.Hash, hyphaName)
html += fmt.Sprintf(`<a href="/page/%[1]s">%[1]s</a>`, hyphaName)
}
}
}
Expand All @@ -77,10 +77,10 @@ func (rev Revision) HyphaeLinks() (html string) {

func (rev Revision) RecentChangesEntry() (html string) {
return fmt.Sprintf(`
<li><time>%s</time></li>
<li>%s</li>
<li>%s</li>
<li>%s</li>
<li class="rc-entry__time"><time>%s</time></li>
<li class="rc-entry__hash">%s</li>
<li class="rc-entry__links">%s</li>
<li class="rc-entry__msg">%s</li>
`, rev.TimeString(), rev.Hash, rev.HyphaeLinks(), rev.Message)
}

Expand Down Expand Up @@ -125,6 +125,6 @@ func unixTimestampAsTime(ts string) *time.Time {
// Rename renames from `from` to `to` using `git mv`.
func Rename(from, to string) error {
log.Println(util.ShorterPath(from), util.ShorterPath(to))
_, err := gitsh("mv", from, to)
_, err := gitsh("mv", "--force", from, to)
return err
}
2 changes: 1 addition & 1 deletion history/information.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func Revisions(hyphaName string) ([]Revision, error) {
"log", "--oneline", "--no-merges",
// Hash, Commiter email, Commiter time, Commit msg separated by tab
"--pretty=format:\"%h\t%ce\t%ct\t%s\"",
"--", hyphaName+"&.*",
"--", hyphaName+".*",
)
revs []Revision
)
Expand Down
10 changes: 9 additions & 1 deletion history/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ func (hop *HistoryOp) gitop(args ...string) *HistoryOp {
return hop
}

// WithError appends the `err` to the list of errors.
func (hop *HistoryOp) WithError(err error) *HistoryOp {
hop.Errs = append(hop.Errs, err)
return hop
}

// WithFilesRemoved git-rm-s all passed `paths`. Paths can be rooted or not. Paths that are empty strings are ignored.
func (hop *HistoryOp) WithFilesRemoved(paths ...string) *HistoryOp {
args := []string{"rm", "--quiet", "--"}
Expand All @@ -71,7 +77,9 @@ func (hop *HistoryOp) WithFilesRenamed(pairs map[string]string) *HistoryOp {
for from, to := range pairs {
if from != "" {
os.MkdirAll(filepath.Dir(to), 0777)
hop.gitop(append([]string{"mv"}, from, to)...)
if err := Rename(from, to); err != nil {
hop.Errs = append(hop.Errs, err)
}
}
}
return hop
Expand Down
99 changes: 19 additions & 80 deletions http_mutators.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"

"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/templates"
"github.com/bouncepaw/mycorrhiza/util"
)
Expand Down Expand Up @@ -116,14 +112,13 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
textAreaFill, err = FetchTextPart(hyphaData)
if err != nil {
log.Println(err)
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error",
"Could not fetch text data")
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error", "Could not fetch text data")
return
}
} else {
warning = `<p>You are creating a new hypha.</p>`
}
util.HTTP200Page(w, base("Edit"+hyphaName, templates.EditHTML(hyphaName, textAreaFill, warning)))
util.HTTP200Page(w, base("Edit "+hyphaName, templates.EditHTML(hyphaName, textAreaFill, warning)))
}

// handlerUploadText uploads a new text part for the hypha.
Expand All @@ -133,105 +128,49 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
hyphaName = HyphaNameFromRq(rq, "upload-text")
hyphaData, isOld = HyphaStorage[hyphaName]
textData = rq.PostFormValue("text")
textDataBytes = []byte(textData)
fullPath = filepath.Join(WikiDir, hyphaName+"&.gmi")
)
if textData == "" {
HttpErr(w, http.StatusBadRequest, hyphaName, "Error",
"No text data passed")
return
}
// For some reason, only 0777 works. Why?
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
log.Println(err)
if !isOld {
hyphaData = &HyphaData{}
}
if err := ioutil.WriteFile(fullPath, textDataBytes, 0644); err != nil {
log.Println(err)
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error",
fmt.Sprintf("Failed to write %d bytes to %s",
len(textDataBytes), fullPath))
if textData == "" {
HttpErr(w, http.StatusBadRequest, hyphaName, "Error", "No text data passed")
return
}
if !isOld {
hd := HyphaData{
textType: TextGemini,
textPath: fullPath,
}
HyphaStorage[hyphaName] = &hd
hyphaData = &hd
if hop := hyphaData.UploadText(hyphaName, textData, isOld); len(hop.Errs) != 0 {
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error", hop.Errs[0].Error())
} else {
hyphaData.textType = TextGemini
hyphaData.textPath = fullPath
http.Redirect(w, rq, "/page/"+hyphaName, http.StatusSeeOther)
}
history.Operation(history.TypeEditText).
WithFiles(fullPath).
WithMsg(fmt.Sprintf("Edit ‘%s’", hyphaName)).
WithSignature("anon").
Apply()
http.Redirect(w, rq, "/page/"+hyphaName, http.StatusSeeOther)
}

// handlerUploadBinary uploads a new binary part for the hypha.
func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
log.Println(rq.URL)
hyphaName := HyphaNameFromRq(rq, "upload-binary")
rq.ParseMultipartForm(10 << 20)
// Read file

file, handler, err := rq.FormFile("binary")
if file != nil {
defer file.Close()
}
// If file is not passed:
if err != nil {
HttpErr(w, http.StatusBadRequest, hyphaName, "Error",
"No binary data passed")
HttpErr(w, http.StatusBadRequest, hyphaName, "Error", "No binary data passed")
return
}
// If file is passed:
var (
hyphaData, isOld = HyphaStorage[hyphaName]
mimeType = MimeToBinaryType(handler.Header.Get("Content-Type"))
ext = mimeType.Extension()
fullPath = filepath.Join(WikiDir, hyphaName+"&"+ext)
mime = handler.Header.Get("Content-Type")
)

data, err := ioutil.ReadAll(file)
if err != nil {
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error",
"Could not read passed data")
return
}
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
log.Println(err)
}
if !isOld {
hd := HyphaData{
binaryPath: fullPath,
binaryType: mimeType,
}
HyphaStorage[hyphaName] = &hd
hyphaData = &hd
} else {
if hyphaData.binaryPath != fullPath {
if err := history.Rename(hyphaData.binaryPath, fullPath); err != nil {
log.Println(err)
} else {
log.Println("Moved", hyphaData.binaryPath, "to", fullPath)
}
}
hyphaData.binaryPath = fullPath
hyphaData.binaryType = mimeType
hyphaData = &HyphaData{}
}
if err = ioutil.WriteFile(fullPath, data, 0644); err != nil {
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error",
"Could not save passed data")
return
hop := hyphaData.UploadBinary(hyphaName, mime, file, isOld)

if len(hop.Errs) != 0 {
HttpErr(w, http.StatusInternalServerError, hyphaName, "Error", hop.Errs[0].Error())
} else {
http.Redirect(w, rq, "/page/"+hyphaName, http.StatusSeeOther)
}
log.Println("Written", len(data), "of binary data for", hyphaName, "to path", fullPath)
history.Operation(history.TypeEditText).
WithFiles(fullPath, hyphaData.binaryPath).
WithMsg(fmt.Sprintf("Upload binary part for ‘%s’ with type ‘%s’", hyphaName, mimeType.Mime())).
WithSignature("anon").
Apply()
http.Redirect(w, rq, "/page/"+hyphaName, http.StatusSeeOther)
}
13 changes: 7 additions & 6 deletions http_readers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import (
"log"
"net/http"
"os"
"path/filepath"
"strings"

"github.com/bouncepaw/mycorrhiza/gemtext"
"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/markup"
"github.com/bouncepaw/mycorrhiza/templates"
"github.com/bouncepaw/mycorrhiza/tree"
"github.com/bouncepaw/mycorrhiza/util"
Expand All @@ -32,11 +33,11 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
revHash = shorterUrl[:firstSlashIndex]
hyphaName = CanonicalName(shorterUrl[firstSlashIndex+1:])
contents = fmt.Sprintf(`<p>This hypha had no text at this revision.</p>`)
textPath = hyphaName + "&.gmi"
textPath = hyphaName + ".myco"
textContents, err = history.FileAtRevision(textPath, revHash)
)
if err == nil {
contents = gemtext.ToHtml(hyphaName, textContents)
contents = markup.ToHtml(hyphaName, textContents)
}
page := templates.RevisionHTML(
hyphaName,
Expand Down Expand Up @@ -75,7 +76,7 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
hyphaName := HyphaNameFromRq(rq, "text")
if data, ok := HyphaStorage[hyphaName]; ok {
log.Println("Serving", data.textPath)
w.Header().Set("Content-Type", data.textType.Mime())
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
http.ServeFile(w, rq, data.textPath)
}
}
Expand All @@ -86,7 +87,7 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
hyphaName := HyphaNameFromRq(rq, "binary")
if data, ok := HyphaStorage[hyphaName]; ok {
log.Println("Serving", data.binaryPath)
w.Header().Set("Content-Type", data.binaryType.Mime())
w.Header().Set("Content-Type", ExtensionToMime(filepath.Ext(data.binaryPath)))
http.ServeFile(w, rq, data.binaryPath)
}
}
Expand All @@ -103,7 +104,7 @@ func handlerPage(w http.ResponseWriter, rq *http.Request) {
fileContentsT, errT := ioutil.ReadFile(data.textPath)
_, errB := os.Stat(data.binaryPath)
if errT == nil {
contents = gemtext.ToHtml(hyphaName, string(fileContentsT))
contents = markup.ToHtml(hyphaName, string(fileContentsT))
}
if !os.IsNotExist(errB) {
contents = binaryHtmlBlock(hyphaName, data) + contents
Expand Down
Loading

0 comments on commit 4f10aa3

Please sign in to comment.