1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-14 06:10:26 +00:00
mycorrhiza/shroom/rename.go

108 lines
3.1 KiB
Go
Raw Normal View History

2021-02-20 14:03:54 +00:00
package shroom
2021-02-17 18:41:35 +00:00
import (
"errors"
"fmt"
"github.com/bouncepaw/mycorrhiza/hyphae/backlinks"
2021-02-17 18:41:35 +00:00
"regexp"
"github.com/bouncepaw/mycorrhiza/history"
2021-02-20 14:03:54 +00:00
"github.com/bouncepaw/mycorrhiza/hyphae"
2021-02-17 18:41:35 +00:00
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util"
)
2022-02-20 09:27:30 +00:00
// Rename renames the old hypha to the new name and makes a history record about that. Call if and only if the user has the permission to rename.
func Rename(oldHypha hyphae.ExistingHypha, newName string, recursive bool, u *user.User) error {
if newName == "" {
rejectRenameLog(oldHypha, u, "no new name given")
return errors.New("ui.rename_noname_tip")
2021-02-17 18:41:35 +00:00
}
if !hyphae.IsValidName(newName) {
rejectRenameLog(oldHypha, u, fmt.Sprintf("new name %s invalid", newName))
return errors.New("ui.rename_badname_tip") // FIXME: There is a bug related to this.
2021-02-17 18:41:35 +00:00
}
switch targetHypha := hyphae.ByName(newName); targetHypha.(type) {
case hyphae.ExistingHypha:
if targetHypha.CanonicalName() == oldHypha.CanonicalName() {
return nil
}
rejectRenameLog(oldHypha, u, fmt.Sprintf("name %s taken already", newName))
return errors.New("ui.rename_taken_tip") // FIXME: There is a bug related to this.
2021-02-17 18:41:35 +00:00
}
var (
re = regexp.MustCompile(`(?i)` + oldHypha.CanonicalName())
2021-02-17 18:41:35 +00:00
replaceName = func(str string) string {
return re.ReplaceAllString(util.CanonicalName(str), newName)
2021-02-17 18:41:35 +00:00
}
hyphaeToRename = findHyphaeToRename(oldHypha, recursive)
2021-02-17 18:41:35 +00:00
renameMap, err = renamingPairs(hyphaeToRename, replaceName)
)
2021-02-17 18:41:35 +00:00
if err != nil {
return err
}
hop := history.Operation(history.TypeRenameHypha).WithUser(u)
if len(hyphaeToRename) > 0 {
hop.WithMsg(fmt.Sprintf(
"Rename %s to %s recursively",
oldHypha.CanonicalName(),
newName))
} else {
hop.WithMsg(fmt.Sprintf(
"Rename %s to %s",
oldHypha.CanonicalName(),
newName))
2021-02-17 18:41:35 +00:00
}
hop.WithFilesRenamed(renameMap).Apply()
if len(hop.Errs) != 0 {
return hop.Errs[0]
2021-02-17 18:41:35 +00:00
}
for _, h := range hyphaeToRename {
oldName := h.CanonicalName()
hyphae.RenameHyphaTo(h, replaceName(h.CanonicalName()), replaceName)
backlinks.UpdateBacklinksAfterRename(h, oldName)
2021-02-17 18:41:35 +00:00
}
return nil
2021-02-17 18:41:35 +00:00
}
2022-02-19 08:26:38 +00:00
func findHyphaeToRename(superhypha hyphae.ExistingHypha, recursive bool) []hyphae.ExistingHypha {
hyphaList := []hyphae.ExistingHypha{superhypha}
2021-02-17 18:41:35 +00:00
if recursive {
hyphaList = append(hyphaList, hyphae.Subhyphae(superhypha)...)
2021-02-17 18:41:35 +00:00
}
return hyphaList
2021-02-17 18:41:35 +00:00
}
2022-02-19 08:26:38 +00:00
func renamingPairs(hyphaeToRename []hyphae.ExistingHypha, replaceName func(string) string) (map[string]string, error) {
var (
renameMap = make(map[string]string)
newNames = make([]string, len(hyphaeToRename))
)
2021-02-17 18:41:35 +00:00
for _, h := range hyphaeToRename {
2021-03-02 16:36:57 +00:00
h.Lock()
newNames = append(newNames, replaceName(h.CanonicalName()))
2022-02-19 08:26:38 +00:00
if h.HasTextFile() {
renameMap[h.TextFilePath()] = replaceName(h.TextFilePath())
2021-02-17 18:41:35 +00:00
}
switch h := h.(type) {
2022-02-19 08:26:38 +00:00
case *hyphae.MediaHypha:
renameMap[h.MediaFilePath()] = replaceName(h.MediaFilePath())
2021-02-17 18:41:35 +00:00
}
2021-03-02 16:36:57 +00:00
h.Unlock()
2021-02-17 18:41:35 +00:00
}
2021-02-20 14:03:54 +00:00
if firstFailure, ok := hyphae.AreFreeNames(newNames...); !ok {
2022-02-19 08:26:38 +00:00
return nil, errors.New("Hypha " + firstFailure + " already exists")
2021-02-17 18:41:35 +00:00
}
return renameMap, nil
}