summaryrefslogtreecommitdiffstats
path: root/models/wiki.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/wiki.go')
-rw-r--r--models/wiki.go97
1 files changed, 55 insertions, 42 deletions
diff --git a/models/wiki.go b/models/wiki.go
index a4a9cb9dcb..3819eb95f0 100644
--- a/models/wiki.go
+++ b/models/wiki.go
@@ -22,22 +22,37 @@ import (
)
var (
- reservedWikiPaths = []string{"_pages", "_new", "_edit"}
+ reservedWikiNames = []string{"_pages", "_new", "_edit"}
wikiWorkingPool = sync.NewExclusivePool()
)
-// ToWikiPageURL formats a string to corresponding wiki URL name.
-func ToWikiPageURL(name string) string {
+// NormalizeWikiName normalizes a wiki name
+func NormalizeWikiName(name string) string {
+ return strings.Replace(name, "-", " ", -1)
+}
+
+// WikiNameToSubURL converts a wiki name to its corresponding sub-URL.
+func WikiNameToSubURL(name string) string {
return url.QueryEscape(strings.Replace(name, " ", "-", -1))
}
-// ToWikiPageName formats a URL back to corresponding wiki page name,
-// and removes leading characters './' to prevent changing files
-// that are not belong to wiki repository.
-func ToWikiPageName(urlString string) string {
- name, _ := url.QueryUnescape(strings.Replace(urlString, "-", " ", -1))
- name = strings.Replace(name, "\t", " ", -1)
- return strings.Replace(strings.TrimLeft(name, "./"), "/", " ", -1)
+// WikiNameToFilename converts a wiki name to its corresponding filename.
+func WikiNameToFilename(name string) string {
+ name = strings.Replace(name, " ", "-", -1)
+ return url.QueryEscape(name) + ".md"
+}
+
+// WikiFilenameToName converts a wiki filename to its corresponding page name.
+func WikiFilenameToName(filename string) (string, error) {
+ if !strings.HasSuffix(filename, ".md") {
+ return "", fmt.Errorf("Invalid wiki filename: %s", filename)
+ }
+ basename := filename[:len(filename)-3]
+ unescaped, err := url.QueryUnescape(basename)
+ if err != nil {
+ return "", err
+ }
+ return NormalizeWikiName(unescaped), nil
}
// WikiCloneLink returns clone URLs of repository wiki.
@@ -81,7 +96,7 @@ func (repo *Repository) LocalWikiPath() string {
}
// UpdateLocalWiki makes sure the local copy of repository wiki is up-to-date.
-func (repo *Repository) UpdateLocalWiki() error {
+func (repo *Repository) updateLocalWiki() error {
// Don't pass branch name here because it fails to clone and
// checkout to a specific branch when wiki is an empty repository.
var branch = ""
@@ -95,19 +110,19 @@ func discardLocalWikiChanges(localPath string) error {
return discardLocalRepoBranchChanges(localPath, "master")
}
-// pathAllowed checks if a wiki path is allowed
-func pathAllowed(path string) error {
- for i := range reservedWikiPaths {
- if path == reservedWikiPaths[i] {
- return ErrWikiAlreadyExist{path}
+// nameAllowed checks if a wiki name is allowed
+func nameAllowed(name string) error {
+ for _, reservedName := range reservedWikiNames {
+ if name == reservedName {
+ return ErrWikiReservedName{name}
}
}
return nil
}
-// updateWikiPage adds new page to repository wiki.
-func (repo *Repository) updateWikiPage(doer *User, oldWikiPath, wikiPath, content, message string, isNew bool) (err error) {
- if err = pathAllowed(wikiPath); err != nil {
+// updateWikiPage adds a new page to the repository wiki.
+func (repo *Repository) updateWikiPage(doer *User, oldWikiName, newWikiName, content, message string, isNew bool) (err error) {
+ if err = nameAllowed(newWikiName); err != nil {
return err
}
@@ -121,23 +136,21 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiPath, wikiPath, conten
localPath := repo.LocalWikiPath()
if err = discardLocalWikiChanges(localPath); err != nil {
return fmt.Errorf("discardLocalWikiChanges: %v", err)
- } else if err = repo.UpdateLocalWiki(); err != nil {
+ } else if err = repo.updateLocalWiki(); err != nil {
return fmt.Errorf("UpdateLocalWiki: %v", err)
}
- title := ToWikiPageName(wikiPath)
- filename := path.Join(localPath, wikiPath+".md")
+ newWikiPath := path.Join(localPath, WikiNameToFilename(newWikiName))
// If not a new file, show perform update not create.
if isNew {
- if com.IsExist(filename) {
- return ErrWikiAlreadyExist{filename}
+ if com.IsExist(newWikiPath) {
+ return ErrWikiAlreadyExist{newWikiPath}
}
} else {
- file := path.Join(localPath, oldWikiPath+".md")
-
- if err := os.Remove(file); err != nil {
- return fmt.Errorf("Failed to remove %s: %v", file, err)
+ oldWikiPath := path.Join(localPath, WikiNameToFilename(oldWikiName))
+ if err := os.Remove(oldWikiPath); err != nil {
+ return fmt.Errorf("Failed to remove %s: %v", oldWikiPath, err)
}
}
@@ -146,15 +159,16 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiPath, wikiPath, conten
// as a new page operation.
// So we want to make sure the symlink is removed before write anything.
// The new file we created will be in normal text format.
+ if err = os.RemoveAll(newWikiPath); err != nil {
+ return err
+ }
- _ = os.Remove(filename)
-
- if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil {
+ if err = ioutil.WriteFile(newWikiPath, []byte(content), 0666); err != nil {
return fmt.Errorf("WriteFile: %v", err)
}
if len(message) == 0 {
- message = "Update page '" + title + "'"
+ message = "Update page '" + newWikiName + "'"
}
if err = git.AddChanges(localPath, true); err != nil {
return fmt.Errorf("AddChanges: %v", err)
@@ -174,36 +188,35 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiPath, wikiPath, conten
}
// AddWikiPage adds a new wiki page with a given wikiPath.
-func (repo *Repository) AddWikiPage(doer *User, wikiPath, content, message string) error {
- return repo.updateWikiPage(doer, "", wikiPath, content, message, true)
+func (repo *Repository) AddWikiPage(doer *User, wikiName, content, message string) error {
+ return repo.updateWikiPage(doer, "", wikiName, content, message, true)
}
// EditWikiPage updates a wiki page identified by its wikiPath,
// optionally also changing wikiPath.
-func (repo *Repository) EditWikiPage(doer *User, oldWikiPath, wikiPath, content, message string) error {
- return repo.updateWikiPage(doer, oldWikiPath, wikiPath, content, message, false)
+func (repo *Repository) EditWikiPage(doer *User, oldWikiName, newWikiName, content, message string) error {
+ return repo.updateWikiPage(doer, oldWikiName, newWikiName, content, message, false)
}
-// DeleteWikiPage deletes a wiki page identified by its wikiPath.
-func (repo *Repository) DeleteWikiPage(doer *User, wikiPath string) (err error) {
+// DeleteWikiPage deletes a wiki page identified by its path.
+func (repo *Repository) DeleteWikiPage(doer *User, wikiName string) (err error) {
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
localPath := repo.LocalWikiPath()
if err = discardLocalWikiChanges(localPath); err != nil {
return fmt.Errorf("discardLocalWikiChanges: %v", err)
- } else if err = repo.UpdateLocalWiki(); err != nil {
+ } else if err = repo.updateLocalWiki(); err != nil {
return fmt.Errorf("UpdateLocalWiki: %v", err)
}
- filename := path.Join(localPath, wikiPath+".md")
+ filename := path.Join(localPath, WikiNameToFilename(wikiName))
if err := os.Remove(filename); err != nil {
return fmt.Errorf("Failed to remove %s: %v", filename, err)
}
- title := ToWikiPageName(wikiPath)
- message := "Delete page '" + title + "'"
+ message := "Delete page '" + wikiName + "'"
if err = git.AddChanges(localPath, true); err != nil {
return fmt.Errorf("AddChanges: %v", err)