From 927ac4f1daea34eeee2e1549be1ccdba45c45b2b Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Fri, 4 Feb 2022 02:47:36 +0500 Subject: [PATCH] Use the Hypher interface in a lot of places --- hyphae/backlinks/backlinks.go | 10 ++++---- hyphae/hyphae.go | 4 +++ hyphae/interface.go | 1 + hyphae/iteration.go | 8 +++--- hyphae/iterators.go | 18 +++++++------- shroom/can.go | 14 +++++------ shroom/init.go | 2 +- shroom/log.go | 20 +++++++-------- shroom/rename.go | 46 ++++++++++++++++++----------------- shroom/search.go | 4 +-- tree/tree.go | 22 ++++++++--------- views/stuff.qtpl | 2 +- views/stuff.qtpl.go | 2 +- web/mutators.go | 2 +- web/stuff.go | 2 +- 15 files changed, 82 insertions(+), 75 deletions(-) diff --git a/hyphae/backlinks/backlinks.go b/hyphae/backlinks/backlinks.go index 6597538..9f0ca7a 100644 --- a/hyphae/backlinks/backlinks.go +++ b/hyphae/backlinks/backlinks.go @@ -42,12 +42,12 @@ var backlinkIndex = make(map[string]linkSet) func IndexBacklinks() { // It is safe to ignore the mutex, because there is only one worker. for h := range hyphae.FilterHyphaeWithText(hyphae.YieldExistingHyphae()) { - foundLinks := extractHyphaLinksFromContent(h.Name, fetchText(h)) + foundLinks := extractHyphaLinksFromContent(h.CanonicalName(), fetchText(h)) for _, link := range foundLinks { if _, exists := backlinkIndex[link]; !exists { backlinkIndex[link] = make(linkSet) } - backlinkIndex[link][h.Name] = struct{}{} + backlinkIndex[link][h.CanonicalName()] = struct{}{} } } } @@ -71,11 +71,11 @@ func toLinkSet(xs []string) linkSet { return result } -func fetchText(h *hyphae.Hypha) string { - if h.TextPath == "" { +func fetchText(h hyphae.Hypher) string { + if !h.HasTextPart() { return "" } - text, err := os.ReadFile(h.TextPath) + text, err := os.ReadFile(h.TextPartPath()) if err == nil { return string(text) } diff --git a/hyphae/hyphae.go b/hyphae/hyphae.go index b8d8f14..105b924 100644 --- a/hyphae/hyphae.go +++ b/hyphae/hyphae.go @@ -51,6 +51,10 @@ func (h *Hypha) Kind() HyphaKind { return HyphaText } +func (h *Hypha) DoesExist() bool { // TODO: rename + return h.Exists +} + func (h *Hypha) HasTextPart() bool { return h.TextPath != "" } diff --git a/hyphae/interface.go b/hyphae/interface.go index 2a81673..7391aa6 100644 --- a/hyphae/interface.go +++ b/hyphae/interface.go @@ -16,6 +16,7 @@ type Hypher interface { CanonicalName() string Kind() HyphaKind + DoesExist() bool HasTextPart() bool TextPartPath() string diff --git a/hyphae/iteration.go b/hyphae/iteration.go index 1773977..ae9c2b8 100644 --- a/hyphae/iteration.go +++ b/hyphae/iteration.go @@ -7,20 +7,20 @@ import ( // Iteration represents an iteration over all hyphae in the storage. You may use it instead of directly iterating using hyphae.YieldExistingHyphae when you want to do n checks at once instead of iterating n times. type Iteration struct { sync.Mutex - iterator func() chan *Hypha - checks []func(h *Hypha) CheckResult + iterator func() chan Hypher + checks []func(h Hypher) CheckResult } // NewIteration constructs an iteration without checks. func NewIteration() *Iteration { return &Iteration{ iterator: YieldExistingHyphae, - checks: make([]func(h *Hypha) CheckResult, 0), + checks: make([]func(h Hypher) CheckResult, 0), } } // AddCheck adds the check to the iteration. It is concurrent-safe. -func (i7n *Iteration) AddCheck(check func(h *Hypha) CheckResult) { +func (i7n *Iteration) AddCheck(check func(h Hypher) CheckResult) { i7n.Lock() i7n.checks = append(i7n.checks, check) i7n.Unlock() diff --git a/hyphae/iterators.go b/hyphae/iterators.go index a7b8250..d0d1fe6 100644 --- a/hyphae/iterators.go +++ b/hyphae/iterators.go @@ -8,8 +8,8 @@ import ( ) // YieldExistingHyphae iterates over all hyphae and yields all existing ones. -func YieldExistingHyphae() chan *Hypha { - ch := make(chan *Hypha) +func YieldExistingHyphae() chan Hypher { + ch := make(chan Hypher) go func() { for _, h := range byNames { if h.Exists { @@ -22,12 +22,12 @@ func YieldExistingHyphae() chan *Hypha { } // FilterHyphaeWithText filters the source channel and yields only those hyphae than have text parts. -func FilterHyphaeWithText(src chan *Hypha) chan *Hypha { +func FilterHyphaeWithText(src chan Hypher) chan Hypher { // TODO: reimplement as a function with a callback? - sink := make(chan *Hypha) + sink := make(chan Hypher) go func() { for h := range src { - if h.TextPath != "" { + if h.HasTextPart() { sink <- h } } @@ -79,10 +79,10 @@ func PathographicSort(src chan string) <-chan string { } // Subhyphae returns slice of subhyphae. -func (h *Hypha) Subhyphae() []*Hypha { - var hyphae []*Hypha +func Subhyphae(h Hypher) []Hypher { + var hyphae []Hypher for subh := range YieldExistingHyphae() { - if strings.HasPrefix(subh.Name, h.Name+"/") { + if strings.HasPrefix(subh.CanonicalName(), h.CanonicalName()+"/") { hyphae = append(hyphae, subh) } } @@ -93,7 +93,7 @@ func (h *Hypha) Subhyphae() []*Hypha { func AreFreeNames(hyphaNames ...string) (firstFailure string, ok bool) { for h := range YieldExistingHyphae() { for _, hn := range hyphaNames { - if hn == h.Name { + if hn == h.CanonicalName() { return hn, false } } diff --git a/shroom/can.go b/shroom/can.go index 7db6430..174e76c 100644 --- a/shroom/can.go +++ b/shroom/can.go @@ -9,20 +9,20 @@ import ( ) func canFactory( - rejectLogger func(*hyphae.Hypha, *user.User, string), + rejectLogger func(hyphae.Hypher, *user.User, string), action string, - dispatcher func(*hyphae.Hypha, *user.User, *l18n.Localizer) (string, string), + dispatcher func(hyphae.Hypher, *user.User, *l18n.Localizer) (string, string), noRightsMsg string, notExistsMsg string, mustExist bool, -) func(*user.User, *hyphae.Hypha, *l18n.Localizer) (string, error) { - return func(u *user.User, h *hyphae.Hypha, lc *l18n.Localizer) (string, error) { +) func(*user.User, hyphae.Hypher, *l18n.Localizer) (string, error) { + return func(u *user.User, h hyphae.Hypher, lc *l18n.Localizer) (string, error) { if !u.CanProceed(action) { rejectLogger(h, u, "no rights") return lc.Get("ui.act_no_rights"), errors.New(lc.Get(noRightsMsg)) } - if mustExist && !h.Exists { + if mustExist && !h.DoesExist() { rejectLogger(h, u, "does not exist") return lc.Get("ui.act_notexist"), errors.New(lc.Get(notExistsMsg)) } @@ -61,8 +61,8 @@ var ( CanUnattach = canFactory( rejectUnattachLog, "unattach-confirm", - func(h *hyphae.Hypha, u *user.User, lc *l18n.Localizer) (errmsg, errtitle string) { - if h.BinaryPath == "" { + func(h hyphae.Hypher, u *user.User, lc *l18n.Localizer) (errmsg, errtitle string) { + if h.Kind() != hyphae.HyphaMedia { rejectUnattachLog(h, u, "no amnt") return lc.Get("ui.act_noattachment_tip"), lc.Get("ui.act_noattachment") } diff --git a/shroom/init.go b/shroom/init.go index f286baf..d5bdd82 100644 --- a/shroom/init.go +++ b/shroom/init.go @@ -27,7 +27,7 @@ func init() { } globals.HyphaIterate = func(λ func(string)) { for h := range hyphae.YieldExistingHyphae() { - λ(h.Name) + λ(h.CanonicalName()) } } } diff --git a/shroom/log.go b/shroom/log.go index 0bfee28..d626fa1 100644 --- a/shroom/log.go +++ b/shroom/log.go @@ -7,18 +7,18 @@ import ( "github.com/bouncepaw/mycorrhiza/user" ) -func rejectDeleteLog(h *hyphae.Hypha, u *user.User, errmsg string) { - log.Printf("Reject delete ‘%s’ by @%s: %s\n", h.Name, u.Name, errmsg) +func rejectDeleteLog(h hyphae.Hypher, u *user.User, errmsg string) { + log.Printf("Reject delete ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg) } -func rejectRenameLog(h *hyphae.Hypha, u *user.User, errmsg string) { - log.Printf("Reject rename ‘%s’ by @%s: %s\n", h.Name, u.Name, errmsg) +func rejectRenameLog(h hyphae.Hypher, u *user.User, errmsg string) { + log.Printf("Reject rename ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg) } -func rejectUnattachLog(h *hyphae.Hypha, u *user.User, errmsg string) { - log.Printf("Reject unattach ‘%s’ by @%s: %s\n", h.Name, u.Name, errmsg) +func rejectUnattachLog(h hyphae.Hypher, u *user.User, errmsg string) { + log.Printf("Reject unattach ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg) } -func rejectEditLog(h *hyphae.Hypha, u *user.User, errmsg string) { - log.Printf("Reject edit ‘%s’ by @%s: %s\n", h.Name, u.Name, errmsg) +func rejectEditLog(h hyphae.Hypher, u *user.User, errmsg string) { + log.Printf("Reject edit ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg) } -func rejectAttachLog(h *hyphae.Hypha, u *user.User, errmsg string) { - log.Printf("Reject attach ‘%s’ by @%s: %s\n", h.Name, u.Name, errmsg) +func rejectAttachLog(h hyphae.Hypher, u *user.User, errmsg string) { + log.Printf("Reject attach ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg) } diff --git a/shroom/rename.go b/shroom/rename.go index 3c3d11f..f7645dd 100644 --- a/shroom/rename.go +++ b/shroom/rename.go @@ -13,19 +13,19 @@ import ( "github.com/bouncepaw/mycorrhiza/util" ) -func canRenameThisToThat(oh *hyphae.Hypha, nh *hyphae.Hypha, u *user.User, lc *l18n.Localizer) (errtitle string, err error) { - if nh.Exists { - rejectRenameLog(oh, u, fmt.Sprintf("name ‘%s’ taken already", nh.Name)) - return lc.Get("ui.rename_taken"), fmt.Errorf(lc.Get("ui.rename_taken_tip", &l18n.Replacements{"name": "%[1]s"}), nh.Name) +func canRenameThisToThat(oh hyphae.Hypher, nh hyphae.Hypher, u *user.User, lc *l18n.Localizer) (errtitle string, err error) { + if nh.DoesExist() { + rejectRenameLog(oh, u, fmt.Sprintf("name ‘%s’ taken already", nh.CanonicalName())) + return lc.Get("ui.rename_taken"), fmt.Errorf(lc.Get("ui.rename_taken_tip", &l18n.Replacements{"name": "%[1]s"}), nh.CanonicalName()) } - if nh.Name == "" { + if nh.CanonicalName() == "" { rejectRenameLog(oh, u, "no new name given") return lc.Get("ui.rename_noname"), errors.New(lc.Get("ui.rename_noname_tip")) } - if !hyphae.IsValidName(nh.Name) { - rejectRenameLog(oh, u, fmt.Sprintf("new name ‘%s’ invalid", nh.Name)) + if !hyphae.IsValidName(nh.CanonicalName()) { + rejectRenameLog(oh, u, fmt.Sprintf("new name ‘%s’ invalid", nh.CanonicalName())) return lc.Get("ui.rename_badname"), errors.New(lc.Get("ui.rename_badname_tip", &l18n.Replacements{"chars": "^?!:#@><*|\"\\'&%"})) } @@ -33,7 +33,7 @@ func canRenameThisToThat(oh *hyphae.Hypha, nh *hyphae.Hypha, u *user.User, lc *l } // RenameHypha renames hypha from old name `hyphaName` to `newName` and makes a history record about that. If `recursive` is `true`, its subhyphae will be renamed the same way. -func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) { +func RenameHypha(h hyphae.Hypher, newHypha hyphae.Hypher, recursive bool, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) { newHypha.Lock() defer newHypha.Unlock() hop = history.Operation(history.TypeRenameHypha) @@ -48,9 +48,9 @@ func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *use } var ( - re = regexp.MustCompile(`(?i)` + h.Name) + re = regexp.MustCompile(`(?i)` + h.CanonicalName()) replaceName = func(str string) string { - return re.ReplaceAllString(util.CanonicalName(str), newHypha.Name) + return re.ReplaceAllString(util.CanonicalName(str), newHypha.CanonicalName()) } hyphaeToRename = findHyphaeToRename(h, recursive) renameMap, err = renamingPairs(hyphaeToRename, replaceName) @@ -64,13 +64,14 @@ func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *use renameMsg += " recursively" } hop.WithFilesRenamed(renameMap). - WithMsg(fmt.Sprintf(renameMsg, h.Name, newHypha.Name)). + WithMsg(fmt.Sprintf(renameMsg, h.CanonicalName(), newHypha.CanonicalName())). WithUser(u). Apply() if len(hop.Errs) == 0 { for _, h := range hyphaeToRename { - oldName := h.Name - h.RenameTo(replaceName(h.Name)) + h := h.(*hyphae.Hypha) // ontology think + oldName := h.CanonicalName() + h.RenameTo(replaceName(h.CanonicalName())) h.Lock() h.TextPath = replaceName(h.TextPath) h.BinaryPath = replaceName(h.BinaryPath) @@ -81,24 +82,25 @@ func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *use return hop, "" } -func findHyphaeToRename(superhypha *hyphae.Hypha, recursive bool) []*hyphae.Hypha { - hyphae := []*hyphae.Hypha{superhypha} +func findHyphaeToRename(superhypha hyphae.Hypher, recursive bool) []hyphae.Hypher { + hyphaList := []hyphae.Hypher{superhypha} if recursive { - hyphae = append(hyphae, superhypha.Subhyphae()...) + hyphaList = append(hyphaList, hyphae.Subhyphae(superhypha)...) } - return hyphae + return hyphaList } -func renamingPairs(hyphaeToRename []*hyphae.Hypha, replaceName func(string) string) (map[string]string, error) { +func renamingPairs(hyphaeToRename []hyphae.Hypher, replaceName func(string) string) (map[string]string, error) { renameMap := make(map[string]string) newNames := make([]string, len(hyphaeToRename)) for _, h := range hyphaeToRename { h.Lock() - newNames = append(newNames, replaceName(h.Name)) - if h.TextPath != "" { - renameMap[h.TextPath] = replaceName(h.TextPath) + newNames = append(newNames, replaceName(h.CanonicalName())) + if h.HasTextPart() { + renameMap[h.TextPartPath()] = replaceName(h.TextPartPath()) } - if h.BinaryPath != "" { + if h.Kind() == hyphae.HyphaMedia { // ontology think + h := h.(*hyphae.Hypha) renameMap[h.BinaryPath] = replaceName(h.BinaryPath) } h.Unlock() diff --git a/shroom/search.go b/shroom/search.go index 59d128b..6f6e902 100644 --- a/shroom/search.go +++ b/shroom/search.go @@ -14,8 +14,8 @@ func YieldHyphaNamesContainingString(query string) <-chan string { sorted := hyphae.PathographicSort(out) go func() { for h := range hyphae.YieldExistingHyphae() { - if hyphaNameMatchesString(h.Name, query) { - out <- h.Name + if hyphaNameMatchesString(h.CanonicalName(), query) { + out <- h.CanonicalName() } } close(out) diff --git a/tree/tree.go b/tree/tree.go index 2647bcd..f766cc9 100644 --- a/tree/tree.go +++ b/tree/tree.go @@ -18,25 +18,25 @@ func findSiblings(hyphaName string) []*sibling { } var ( siblingsMap = make(map[string]bool) - siblingCheck = func(h *hyphae.Hypha) hyphae.CheckResult { + siblingCheck = func(h hyphae.Hypher) hyphae.CheckResult { switch { - case h.Name == hyphaName, // Hypha is no sibling of itself - h.Name == parentHyphaName: // Parent hypha is no sibling of its child + case h.CanonicalName() == hyphaName, // Hypha is no sibling of itself + h.CanonicalName() == parentHyphaName: // Parent hypha is no sibling of its child return hyphae.CheckContinue } - if (parentHyphaName != "" && strings.HasPrefix(h.Name, parentHyphaName+"/")) || + if (parentHyphaName != "" && strings.HasPrefix(h.CanonicalName(), parentHyphaName+"/")) || (parentHyphaName == "") { var ( - rawSubPath = strings.TrimPrefix(h.Name, parentHyphaName)[1:] + rawSubPath = strings.TrimPrefix(h.CanonicalName(), parentHyphaName)[1:] slashIdx = strings.IndexRune(rawSubPath, '/') ) if slashIdx > -1 { - var sibPath = h.Name[:slashIdx+len(parentHyphaName)+1] + var sibPath = h.CanonicalName()[:slashIdx+len(parentHyphaName)+1] if _, exists := siblingsMap[sibPath]; !exists { siblingsMap[sibPath] = false } } else { // it is a straight sibling - siblingsMap[h.Name] = true + siblingsMap[h.CanonicalName()] = true } } return hyphae.CheckContinue @@ -63,12 +63,12 @@ func findSiblings(hyphaName string) []*sibling { func countSubhyphae(siblings []*sibling) { var ( - subhyphaCheck = func(h *hyphae.Hypha) hyphae.CheckResult { + subhyphaCheck = func(h hyphae.Hypher) hyphae.CheckResult { for _, s := range siblings { - if path.Dir(h.Name) == s.name { + if path.Dir(h.CanonicalName()) == s.name { s.directSubhyphaeCount++ return hyphae.CheckContinue - } else if strings.HasPrefix(h.Name, s.name+"/") { + } else if strings.HasPrefix(h.CanonicalName(), s.name+"/") { s.indirectSubhyphaeCount++ return hyphae.CheckContinue } @@ -136,7 +136,7 @@ func figureOutChildren(hyphaName string) child { ) for desc := range hyphae.YieldExistingHyphae() { - var descName = desc.Name + var descName = desc.CanonicalName() if strings.HasPrefix(descName, descPrefix) { var subPath = strings.TrimPrefix(descName, descPrefix) addHyphaToChild(descName, subPath, &child) diff --git a/views/stuff.qtpl b/views/stuff.qtpl index 589ff51..efeda7e 100644 --- a/views/stuff.qtpl +++ b/views/stuff.qtpl @@ -257,7 +257,7 @@ sort.Strings(editors) hyphaNames := make(chan string) sortedHypha := hyphae.PathographicSort(hyphaNames) for hypha := range hyphae.YieldExistingHyphae() { - hyphaNames <- hypha.Name + hyphaNames <- hypha.CanonicalName() } close(hyphaNames) %} diff --git a/views/stuff.qtpl.go b/views/stuff.qtpl.go index 990b7a0..9cd2b18 100644 --- a/views/stuff.qtpl.go +++ b/views/stuff.qtpl.go @@ -1007,7 +1007,7 @@ func StreamHyphaListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) { hyphaNames := make(chan string) sortedHypha := hyphae.PathographicSort(hyphaNames) for hypha := range hyphae.YieldExistingHyphae() { - hyphaNames <- hypha.Name + hyphaNames <- hypha.CanonicalName() } close(hyphaNames) diff --git a/web/mutators.go b/web/mutators.go index 39b4275..2386926 100644 --- a/web/mutators.go +++ b/web/mutators.go @@ -35,7 +35,7 @@ func initMutators(r *mux.Router) { func factoryHandlerAsker( actionPath string, - asker func(*user.User, *hyphae.Hypha, *l18n.Localizer) (string, error), + asker func(*user.User, hyphae.Hypher, *l18n.Localizer) (string, error), succTitleKey string, succPageTemplate func(*http.Request, string, bool) string, ) func(http.ResponseWriter, *http.Request) { diff --git a/web/stuff.go b/web/stuff.go index f242cde..7427bb3 100644 --- a/web/stuff.go +++ b/web/stuff.go @@ -145,7 +145,7 @@ func handlerRandom(w http.ResponseWriter, rq *http.Request) { i := rand.Intn(amountOfHyphae) for h := range hyphae.YieldExistingHyphae() { if i == 0 { - randomHyphaName = h.Name + randomHyphaName = h.CanonicalName() } i-- }