1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-13 05:50:27 +00:00
mycorrhiza/shroom/rename.go
2022-04-02 19:58:57 +03:00

108 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package shroom
import (
"errors"
"fmt"
"github.com/bouncepaw/mycorrhiza/backlinks"
"regexp"
"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util"
)
// 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")
}
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.
}
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.
}
var (
re = regexp.MustCompile(`(?i)` + oldHypha.CanonicalName())
replaceName = func(str string) string {
return re.ReplaceAllString(util.CanonicalName(str), newName)
}
hyphaeToRename = findHyphaeToRename(oldHypha, recursive)
renameMap, err = renamingPairs(hyphaeToRename, replaceName)
)
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))
}
hop.WithFilesRenamed(renameMap).Apply()
if len(hop.Errs) != 0 {
return hop.Errs[0]
}
for _, h := range hyphaeToRename {
oldName := h.CanonicalName()
hyphae.RenameHyphaTo(h, replaceName(h.CanonicalName()), replaceName)
backlinks.UpdateBacklinksAfterRename(h, oldName)
}
return nil
}
func findHyphaeToRename(superhypha hyphae.ExistingHypha, recursive bool) []hyphae.ExistingHypha {
hyphaList := []hyphae.ExistingHypha{superhypha}
if recursive {
hyphaList = append(hyphaList, hyphae.Subhyphae(superhypha)...)
}
return hyphaList
}
func renamingPairs(hyphaeToRename []hyphae.ExistingHypha, replaceName func(string) string) (map[string]string, error) {
var (
renameMap = make(map[string]string)
newNames = make([]string, len(hyphaeToRename))
)
for _, h := range hyphaeToRename {
h.Lock()
newNames = append(newNames, replaceName(h.CanonicalName()))
if h.HasTextFile() {
renameMap[h.TextFilePath()] = replaceName(h.TextFilePath())
}
switch h := h.(type) {
case *hyphae.MediaHypha:
renameMap[h.MediaFilePath()] = replaceName(h.MediaFilePath())
}
h.Unlock()
}
if firstFailure, ok := hyphae.AreFreeNames(newNames...); !ok {
return nil, errors.New("Hypha " + firstFailure + " already exists")
}
return renameMap, nil
}