mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-01-07 18:30:26 +00:00
Drop-in replace main.hyphaData with hyphae.Hypha
This commit is contained in:
parent
dcd12a4a6d
commit
86aa82bc50
@ -30,7 +30,7 @@ func handlerUnattachAsk(w http.ResponseWriter, rq *http.Request) {
|
|||||||
var (
|
var (
|
||||||
hyphaName = HyphaNameFromRq(rq, "unattach-ask")
|
hyphaName = HyphaNameFromRq(rq, "unattach-ask")
|
||||||
hd, isOld = HyphaStorage[hyphaName]
|
hd, isOld = HyphaStorage[hyphaName]
|
||||||
hasAmnt = hd != nil && hd.binaryPath != ""
|
hasAmnt = hd != nil && hd.BinaryPath != ""
|
||||||
)
|
)
|
||||||
if !hasAmnt {
|
if !hasAmnt {
|
||||||
HttpErr(w, http.StatusBadRequest, hyphaName, "Cannot unattach", "No attachment attached yet, therefore you cannot unattach")
|
HttpErr(w, http.StatusBadRequest, hyphaName, "Cannot unattach", "No attachment attached yet, therefore you cannot unattach")
|
||||||
@ -49,7 +49,7 @@ func handlerUnattachConfirm(w http.ResponseWriter, rq *http.Request) {
|
|||||||
var (
|
var (
|
||||||
hyphaName = HyphaNameFromRq(rq, "unattach-confirm")
|
hyphaName = HyphaNameFromRq(rq, "unattach-confirm")
|
||||||
hyphaData, isOld = HyphaStorage[hyphaName]
|
hyphaData, isOld = HyphaStorage[hyphaName]
|
||||||
hasAmnt = hyphaData != nil && hyphaData.binaryPath != ""
|
hasAmnt = hyphaData != nil && hyphaData.BinaryPath != ""
|
||||||
u = user.FromRequest(rq)
|
u = user.FromRequest(rq)
|
||||||
)
|
)
|
||||||
if !u.CanProceed("unattach-confirm") {
|
if !u.CanProceed("unattach-confirm") {
|
||||||
|
@ -35,8 +35,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
|
|||||||
revHash = shorterUrl[:firstSlashIndex]
|
revHash = shorterUrl[:firstSlashIndex]
|
||||||
hyphaName = CanonicalName(shorterUrl[firstSlashIndex+1:])
|
hyphaName = CanonicalName(shorterUrl[firstSlashIndex+1:])
|
||||||
contents = fmt.Sprintf(`<p>This hypha had no text at this revision.</p>`)
|
contents = fmt.Sprintf(`<p>This hypha had no text at this revision.</p>`)
|
||||||
textPath = hyphaName + ".myco"
|
TextPath = hyphaName + ".myco"
|
||||||
textContents, err = history.FileAtRevision(textPath, revHash)
|
textContents, err = history.FileAtRevision(TextPath, revHash)
|
||||||
u = user.FromRequest(rq)
|
u = user.FromRequest(rq)
|
||||||
)
|
)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -61,9 +61,9 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
|
|||||||
log.Println(rq.URL)
|
log.Println(rq.URL)
|
||||||
hyphaName := HyphaNameFromRq(rq, "text")
|
hyphaName := HyphaNameFromRq(rq, "text")
|
||||||
if data, ok := HyphaStorage[hyphaName]; ok {
|
if data, ok := HyphaStorage[hyphaName]; ok {
|
||||||
log.Println("Serving", data.textPath)
|
log.Println("Serving", data.TextPath)
|
||||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
http.ServeFile(w, rq, data.textPath)
|
http.ServeFile(w, rq, data.TextPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +72,9 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
|
|||||||
log.Println(rq.URL)
|
log.Println(rq.URL)
|
||||||
hyphaName := HyphaNameFromRq(rq, "binary")
|
hyphaName := HyphaNameFromRq(rq, "binary")
|
||||||
if data, ok := HyphaStorage[hyphaName]; ok {
|
if data, ok := HyphaStorage[hyphaName]; ok {
|
||||||
log.Println("Serving", data.binaryPath)
|
log.Println("Serving", data.BinaryPath)
|
||||||
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(data.binaryPath)))
|
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(data.BinaryPath)))
|
||||||
http.ServeFile(w, rq, data.binaryPath)
|
http.ServeFile(w, rq, data.BinaryPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
|
|||||||
var (
|
var (
|
||||||
hyphaName = HyphaNameFromRq(rq, "page", "hypha")
|
hyphaName = HyphaNameFromRq(rq, "page", "hypha")
|
||||||
data, hyphaExists = HyphaStorage[hyphaName]
|
data, hyphaExists = HyphaStorage[hyphaName]
|
||||||
hasAmnt = hyphaExists && data.binaryPath != ""
|
hasAmnt = hyphaExists && data.BinaryPath != ""
|
||||||
contents string
|
contents string
|
||||||
openGraph string
|
openGraph string
|
||||||
u = user.FromRequest(rq)
|
u = user.FromRequest(rq)
|
||||||
)
|
)
|
||||||
if hyphaExists {
|
if hyphaExists {
|
||||||
fileContentsT, errT := ioutil.ReadFile(data.textPath)
|
fileContentsT, errT := ioutil.ReadFile(data.TextPath)
|
||||||
_, errB := os.Stat(data.binaryPath)
|
_, errB := os.Stat(data.BinaryPath)
|
||||||
if errT == nil {
|
if errT == nil {
|
||||||
md := markup.Doc(hyphaName, string(fileContentsT))
|
md := markup.Doc(hyphaName, string(fileContentsT))
|
||||||
contents = md.AsHTML()
|
contents = md.AsHTML()
|
||||||
|
53
hypha.go
53
hypha.go
@ -26,7 +26,7 @@ func init() {
|
|||||||
markup.HyphaAccess = func(hyphaName string) (rawText, binaryBlock string, err error) {
|
markup.HyphaAccess = func(hyphaName string) (rawText, binaryBlock string, err error) {
|
||||||
if hyphaData, ok := HyphaStorage[hyphaName]; ok {
|
if hyphaData, ok := HyphaStorage[hyphaName]; ok {
|
||||||
rawText, err = FetchTextPart(hyphaData)
|
rawText, err = FetchTextPart(hyphaData)
|
||||||
if hyphaData.binaryPath != "" {
|
if hyphaData.BinaryPath != "" {
|
||||||
binaryBlock = binaryHtmlBlock(hyphaName, hyphaData)
|
binaryBlock = binaryHtmlBlock(hyphaName, hyphaData)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -36,7 +36,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
markup.HyphaIterate = IterateHyphaNamesWith
|
markup.HyphaIterate = IterateHyphaNamesWith
|
||||||
markup.HyphaImageForOG = func(hyphaName string) string {
|
markup.HyphaImageForOG = func(hyphaName string) string {
|
||||||
if hd, isOld := GetHyphaData(hyphaName); isOld && hd.binaryPath != "" {
|
if hd, isOld := GetHyphaData(hyphaName); isOld && hd.BinaryPath != "" {
|
||||||
return util.URL + "/binary/" + hyphaName
|
return util.URL + "/binary/" + hyphaName
|
||||||
}
|
}
|
||||||
return util.URL + "/favicon.ico"
|
return util.URL + "/favicon.ico"
|
||||||
@ -53,20 +53,17 @@ func GetHyphaData(hyphaName string) (hyphaData *HyphaData, isOld bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HyphaData represents a hypha's meta information: binary and text parts rooted paths and content types.
|
// HyphaData represents a hypha's meta information: binary and text parts rooted paths and content types.
|
||||||
type HyphaData struct {
|
type HyphaData hyphae.Hypha
|
||||||
textPath string
|
|
||||||
binaryPath string
|
|
||||||
}
|
|
||||||
|
|
||||||
// uploadHelp is a helper function for UploadText and UploadBinary
|
// uploadHelp is a helper function for UploadText and UploadBinary
|
||||||
func uploadHelp(hop *history.HistoryOp, hyphaName, ext string, data []byte, u *user.User) *history.HistoryOp {
|
func uploadHelp(hop *history.HistoryOp, hyphaName, ext string, data []byte, u *user.User) *history.HistoryOp {
|
||||||
var (
|
var (
|
||||||
hyphaData, isOld = GetHyphaData(hyphaName)
|
hyphaData, isOld = GetHyphaData(hyphaName)
|
||||||
fullPath = filepath.Join(WikiDir, hyphaName+ext)
|
fullPath = filepath.Join(WikiDir, hyphaName+ext)
|
||||||
originalFullPath = &hyphaData.textPath
|
originalFullPath = &hyphaData.TextPath
|
||||||
)
|
)
|
||||||
if hop.Type == history.TypeEditBinary {
|
if hop.Type == history.TypeEditBinary {
|
||||||
originalFullPath = &hyphaData.binaryPath
|
originalFullPath = &hyphaData.BinaryPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
|
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
|
||||||
@ -121,7 +118,7 @@ func UploadBinary(hyphaName, mime string, file multipart.File, u *user.User) *hi
|
|||||||
// DeleteHypha deletes hypha and makes a history record about that.
|
// DeleteHypha deletes hypha and makes a history record about that.
|
||||||
func (hd *HyphaData) DeleteHypha(hyphaName string, u *user.User) *history.HistoryOp {
|
func (hd *HyphaData) DeleteHypha(hyphaName string, u *user.User) *history.HistoryOp {
|
||||||
hop := history.Operation(history.TypeDeleteHypha).
|
hop := history.Operation(history.TypeDeleteHypha).
|
||||||
WithFilesRemoved(hd.textPath, hd.binaryPath).
|
WithFilesRemoved(hd.TextPath, hd.BinaryPath).
|
||||||
WithMsg(fmt.Sprintf("Delete ‘%s’", hyphaName)).
|
WithMsg(fmt.Sprintf("Delete ‘%s’", hyphaName)).
|
||||||
WithUser(u).
|
WithUser(u).
|
||||||
Apply()
|
Apply()
|
||||||
@ -135,18 +132,18 @@ func (hd *HyphaData) DeleteHypha(hyphaName string, u *user.User) *history.Histor
|
|||||||
// UnattachHypha unattaches hypha and makes a history record about that.
|
// UnattachHypha unattaches hypha and makes a history record about that.
|
||||||
func (hd *HyphaData) UnattachHypha(hyphaName string, u *user.User) *history.HistoryOp {
|
func (hd *HyphaData) UnattachHypha(hyphaName string, u *user.User) *history.HistoryOp {
|
||||||
hop := history.Operation(history.TypeUnattachHypha).
|
hop := history.Operation(history.TypeUnattachHypha).
|
||||||
WithFilesRemoved(hd.binaryPath).
|
WithFilesRemoved(hd.BinaryPath).
|
||||||
WithMsg(fmt.Sprintf("Unattach ‘%s’", hyphaName)).
|
WithMsg(fmt.Sprintf("Unattach ‘%s’", hyphaName)).
|
||||||
WithUser(u).
|
WithUser(u).
|
||||||
Apply()
|
Apply()
|
||||||
if len(hop.Errs) == 0 {
|
if len(hop.Errs) == 0 {
|
||||||
hd, ok := HyphaStorage[hyphaName]
|
hd, ok := HyphaStorage[hyphaName]
|
||||||
if ok {
|
if ok {
|
||||||
if hd.binaryPath != "" {
|
if hd.BinaryPath != "" {
|
||||||
hd.binaryPath = ""
|
hd.BinaryPath = ""
|
||||||
}
|
}
|
||||||
// If nothing is left of the hypha
|
// If nothing is left of the hypha
|
||||||
if hd.textPath == "" {
|
if hd.TextPath == "" {
|
||||||
delete(HyphaStorage, hyphaName)
|
delete(HyphaStorage, hyphaName)
|
||||||
hyphae.DecrementCount()
|
hyphae.DecrementCount()
|
||||||
}
|
}
|
||||||
@ -170,11 +167,11 @@ func renamingPairs(hyphaNames []string, replaceName func(string) string) (map[st
|
|||||||
if _, nameUsed := HyphaStorage[replaceName(hn)]; nameUsed {
|
if _, nameUsed := HyphaStorage[replaceName(hn)]; nameUsed {
|
||||||
return nil, errors.New("Hypha " + replaceName(hn) + " already exists")
|
return nil, errors.New("Hypha " + replaceName(hn) + " already exists")
|
||||||
}
|
}
|
||||||
if hd.textPath != "" {
|
if hd.TextPath != "" {
|
||||||
renameMap[hd.textPath] = replaceName(hd.textPath)
|
renameMap[hd.TextPath] = replaceName(hd.TextPath)
|
||||||
}
|
}
|
||||||
if hd.binaryPath != "" {
|
if hd.BinaryPath != "" {
|
||||||
renameMap[hd.binaryPath] = replaceName(hd.binaryPath)
|
renameMap[hd.BinaryPath] = replaceName(hd.BinaryPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,8 +182,8 @@ func renamingPairs(hyphaNames []string, replaceName func(string) string) (map[st
|
|||||||
func relocateHyphaData(hyphaNames []string, replaceName func(string) string) {
|
func relocateHyphaData(hyphaNames []string, replaceName func(string) string) {
|
||||||
for _, hyphaName := range hyphaNames {
|
for _, hyphaName := range hyphaNames {
|
||||||
if hd, ok := HyphaStorage[hyphaName]; ok {
|
if hd, ok := HyphaStorage[hyphaName]; ok {
|
||||||
hd.textPath = replaceName(hd.textPath)
|
hd.TextPath = replaceName(hd.TextPath)
|
||||||
hd.binaryPath = replaceName(hd.binaryPath)
|
hd.BinaryPath = replaceName(hd.BinaryPath)
|
||||||
HyphaStorage[replaceName(hyphaName)] = hd
|
HyphaStorage[replaceName(hyphaName)] = hd
|
||||||
delete(HyphaStorage, hyphaName)
|
delete(HyphaStorage, hyphaName)
|
||||||
}
|
}
|
||||||
@ -224,7 +221,7 @@ func RenameHypha(hyphaName, newName string, recursive bool, u *user.User) *histo
|
|||||||
|
|
||||||
// binaryHtmlBlock creates an html block for binary part of the hypha.
|
// binaryHtmlBlock creates an html block for binary part of the hypha.
|
||||||
func binaryHtmlBlock(hyphaName string, hd *HyphaData) string {
|
func binaryHtmlBlock(hyphaName string, hd *HyphaData) string {
|
||||||
switch filepath.Ext(hd.binaryPath) {
|
switch filepath.Ext(hd.BinaryPath) {
|
||||||
case ".jpg", ".gif", ".png", ".webp", ".svg", ".ico":
|
case ".jpg", ".gif", ".png", ".webp", ".svg", ".ico":
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
<div class="binary-container binary-container_with-img">
|
<div class="binary-container binary-container_with-img">
|
||||||
@ -257,16 +254,16 @@ func binaryHtmlBlock(hyphaName string, hd *HyphaData) string {
|
|||||||
|
|
||||||
// FetchTextPart tries to read text file in the `d`. If there is no file, empty string is returned.
|
// FetchTextPart tries to read text file in the `d`. If there is no file, empty string is returned.
|
||||||
func FetchTextPart(d *HyphaData) (string, error) {
|
func FetchTextPart(d *HyphaData) (string, error) {
|
||||||
if d.textPath == "" {
|
if d.TextPath == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
_, err := os.Stat(d.textPath)
|
_, err := os.Stat(d.TextPath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return "", nil
|
return "", nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
text, err := ioutil.ReadFile(d.textPath)
|
text, err := ioutil.ReadFile(d.TextPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -277,7 +274,7 @@ func setHeaderLinks() {
|
|||||||
if userLinksHypha, ok := GetHyphaData(util.HeaderLinksHypha); !ok {
|
if userLinksHypha, ok := GetHyphaData(util.HeaderLinksHypha); !ok {
|
||||||
util.SetDefaultHeaderLinks()
|
util.SetDefaultHeaderLinks()
|
||||||
} else {
|
} else {
|
||||||
contents, err := ioutil.ReadFile(userLinksHypha.textPath)
|
contents, err := ioutil.ReadFile(userLinksHypha.TextPath)
|
||||||
if err != nil || len(contents) == 0 {
|
if err != nil || len(contents) == 0 {
|
||||||
util.SetDefaultHeaderLinks()
|
util.SetDefaultHeaderLinks()
|
||||||
} else {
|
} else {
|
||||||
@ -316,13 +313,13 @@ func Index(path string) {
|
|||||||
hyphae.IncrementCount()
|
hyphae.IncrementCount()
|
||||||
}
|
}
|
||||||
if isText {
|
if isText {
|
||||||
hyphaData.textPath = hyphaPartPath
|
hyphaData.TextPath = hyphaPartPath
|
||||||
} else {
|
} else {
|
||||||
// Notify the user about binary part collisions. It's a design decision to just use any of them, it's the user's fault that they have screwed up the folder structure, but the engine should at least let them know, right?
|
// Notify the user about binary part collisions. It's a design decision to just use any of them, it's the user's fault that they have screwed up the folder structure, but the engine should at least let them know, right?
|
||||||
if hyphaData.binaryPath != "" {
|
if hyphaData.BinaryPath != "" {
|
||||||
log.Println("There is a file collision for binary part of a hypha:", hyphaData.binaryPath, "and", hyphaPartPath, "-- going on with the latter")
|
log.Println("There is a file collision for binary part of a hypha:", hyphaData.BinaryPath, "and", hyphaPartPath, "-- going on with the latter")
|
||||||
}
|
}
|
||||||
hyphaData.binaryPath = hyphaPartPath
|
hyphaData.BinaryPath = hyphaPartPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
hyphae/hyphae.go
Normal file
43
hyphae/hyphae.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package hyphae
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Hypha struct {
|
||||||
|
sync.RWMutex
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Exists bool
|
||||||
|
TextPath string
|
||||||
|
BinaryPath string
|
||||||
|
OutLinks []*Hypha
|
||||||
|
BackLinks []*Hypha
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Insert inserts the hypha into the mycelium. It overwrites the previous record, if there was any, and returns false. If the was no previous record, return true.
|
||||||
|
func (h *Hypha) Insert() (justCreated bool) {
|
||||||
|
var hp *Hypha
|
||||||
|
hp, justCreated = ByName(h.Name)
|
||||||
|
|
||||||
|
mycm.Lock()
|
||||||
|
defer mycm.Unlock()
|
||||||
|
if justCreated {
|
||||||
|
mycm.byNames[hp.Name] = h
|
||||||
|
} else {
|
||||||
|
hp = h
|
||||||
|
}
|
||||||
|
|
||||||
|
return justCreated
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// PhaseOut marks the hypha as non-existent. This is an idempotent operation.
|
||||||
|
func (h *Hypha) PhaseOut() {
|
||||||
|
h.Lock()
|
||||||
|
h.Exists = false
|
||||||
|
h.OutLinks = make([]*Hypha, 0)
|
||||||
|
h.TextPath = ""
|
||||||
|
h.BinaryPath = ""
|
||||||
|
h.Unlock()
|
||||||
|
}
|
2
main.go
2
main.go
@ -65,7 +65,7 @@ func handlerList(w http.ResponseWriter, rq *http.Request) {
|
|||||||
u = user.FromRequest(rq)
|
u = user.FromRequest(rq)
|
||||||
)
|
)
|
||||||
for hyphaName, data := range HyphaStorage {
|
for hyphaName, data := range HyphaStorage {
|
||||||
tbody += templates.HyphaListRowHTML(hyphaName, mimetype.FromExtension(filepath.Ext(data.binaryPath)), data.binaryPath != "")
|
tbody += templates.HyphaListRowHTML(hyphaName, mimetype.FromExtension(filepath.Ext(data.BinaryPath)), data.BinaryPath != "")
|
||||||
}
|
}
|
||||||
util.HTTP200Page(w, base("List of pages", templates.HyphaListHTML(tbody, pageCount), u))
|
util.HTTP200Page(w, base("List of pages", templates.HyphaListHTML(tbody, pageCount), u))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user