diff --git a/WikiServer.go b/WikiServer.go index f4a6a37..9379e13 100644 --- a/WikiServer.go +++ b/WikiServer.go @@ -139,6 +139,23 @@ func (this *WikiServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { this.routeRecentChanges(w, r, pageNum) return + } else if r.URL.Path == this.opts.ExpectBaseURL+"diff" { + + fromRev, err := strconv.Atoi(r.URL.Query().Get("f")) + if err != nil { + this.serveErrorMessage(w, err) + return + } + + toRev, err := strconv.Atoi(r.URL.Query().Get("t")) + if err != nil { + this.serveErrorMessage(w, err) + return + } + + this.routeDiff(w, r, fromRev, toRev) + return + } } else if r.Method == "POST" { diff --git a/rDiff.go b/rDiff.go new file mode 100644 index 0000000..fcd3e6f --- /dev/null +++ b/rDiff.go @@ -0,0 +1,64 @@ +package yatwiki3 + +import ( + "bytes" + "database/sql" + "errors" + "fmt" + "html/template" + "net/http" + + "code.ivysaur.me/yatwiki3/diff" +) + +func (this *WikiServer) routeDiff(w http.ResponseWriter, r *http.Request, oldRev, newRev int) { + if oldRev > newRev { + oldRev, newRev = newRev, oldRev + } + + oa, err := this.db.GetRevision(oldRev) + if err != nil { + if err == sql.ErrNoRows { + this.serveErrorMessage(w, errors.New("Invalid revision selected")) + return + } + + this.serveErrorMessage(w, err) + return + } + + na, err := this.db.GetRevision(newRev) + if err != nil { + if err == sql.ErrNoRows { + this.serveErrorMessage(w, errors.New("Invalid revision selected")) + return + } + + this.serveErrorMessage(w, err) + return + } + + if oa.TitleID != na.TitleID { + this.serveErrorMessage(w, fmt.Errorf("Preventing attempt to compare mismatched articles (%s ≠ %s)", oa.Title, na.Title)) + return + } + + b := bytes.Buffer{} + diff.HtmlDiff(string(oa.Body), string(na.Body), &b) + + pto := DefaultPageTemplateOptions(this.opts) + pto.CurrentPageName = oa.Title + pto.CurrentPageIsArticle = true + + pto.Content = template.HTML( + `

` + + `Comparing ` + string(this.viewLink(oa.Title)) + ` versions ` + + `r` + fmt.Sprintf("%d", oa.ID) + `` + + ` - ` + + `r` + fmt.Sprintf("%d", na.ID) + `` + + `

` + + `
` + string(b.Bytes()) + `
`, + ) + this.servePageResponse(w, r, pto) + return +} diff --git a/rErrors.go b/rErrors.go index afa1d89..d547dfd 100644 --- a/rErrors.go +++ b/rErrors.go @@ -44,3 +44,7 @@ func (this *WikiServer) formatTimestamp(m int64) string { // TODO add a more detailed timestamp on hover return template.HTMLEscapeString(time.Unix(m, 0).In(this.loc).Format(this.opts.DateFormat)) } + +func (this *WikiServer) viewLink(articleTitle string) template.HTML { + return template.HTML(`"` + template.HTMLEscapeString(articleTitle) + `"`) +}