diff --git a/ServerOptions.go b/ServerOptions.go index b82d790..e541dff 100644 --- a/ServerOptions.go +++ b/ServerOptions.go @@ -14,8 +14,12 @@ type ServerOptions struct { FaviconFilePath string AllowDBDownload bool RecentChanges int + RecentChangesRSS int GzipCompressionLevel int BannedUserIPRegexes []string + ExternalBaseURL string + DeclareRSSLanguage string + DeclareRSSEmail string } func DefaultOptions() *ServerOptions { @@ -29,7 +33,11 @@ func DefaultOptions() *ServerOptions { FaviconFilePath: "", // no favicon AllowDBDownload: true, RecentChanges: 20, + RecentChangesRSS: 10, GzipCompressionLevel: 9, BannedUserIPRegexes: make([]string, 0), + ExternalBaseURL: "/", + DeclareRSSLanguage: "en-GB", + DeclareRSSEmail: `nobody@example.com`, } } diff --git a/WikiServer.go b/WikiServer.go index 71ad7c8..2b06431 100644 --- a/WikiServer.go +++ b/WikiServer.go @@ -92,6 +92,10 @@ func (this *WikiServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { this.routeIndex(w, r) return + } else if remainingPath == "rss/changes" { + this.routeRecentChangesRSS(w, r) + return + } else if remainingPath == "" { this.serveRedirect(w, this.opts.ExpectBaseURL+`view/`+url.QueryEscape(this.opts.DefaultPage)) return diff --git a/cmd/yatwiki-server/main.go b/cmd/yatwiki-server/main.go index 5fb35ed..8510759 100644 --- a/cmd/yatwiki-server/main.go +++ b/cmd/yatwiki-server/main.go @@ -21,6 +21,7 @@ func main() { opts.DBFilePath = *dbPath opts.FaviconFilePath = *faviconPath opts.Timezone = time.Local.String() + opts.ExternalBaseURL = "http://" + *bindAddr + "/" ws, err := yatwiki3.NewWikiServer(opts) if err != nil { diff --git a/rRSS.go b/rRSS.go new file mode 100644 index 0000000..52d54cd --- /dev/null +++ b/rRSS.go @@ -0,0 +1,51 @@ +package yatwiki3 + +import ( + "fmt" + "html/template" + "net/http" + "net/url" + "time" +) + +func (this *WikiServer) routeRecentChangesRSS(w http.ResponseWriter, r *http.Request) { + recents, err := this.db.GetRecentChanges(0, this.opts.RecentChangesRSS) + if err != nil { + this.serveInternalError(w, r, err) + return + } + + content := ` + + + ` + template.HTMLEscapeString(this.opts.PageTitle) + ` + ` + template.HTMLEscapeString(this.opts.ExternalBaseURL) + ` + ` + template.HTMLEscapeString(this.opts.PageTitle) + ` + ` + template.HTMLEscapeString(this.opts.DeclareRSSLanguage) + ` + +` + for _, a := range recents { + content += ` + + ` + template.HTMLEscapeString(a.Title+` (r`+fmt.Sprintf("%d", a.ID)+`)`) + ` + ` + template.HTMLEscapeString(this.opts.ExternalBaseURL+`archive/`+fmt.Sprintf("%d", a.ID)) + ` + ` + template.HTMLEscapeString(this.opts.ExternalBaseURL+`archive/`+fmt.Sprintf("%d", a.ID)) + ` + ` + template.HTMLEscapeString(this.opts.DeclareRSSEmail+` (`+this.opts.PageTitle+` `+a.Author+`)`) + ` + ` + template.HTMLEscapeString(time.Unix(a.Modified, 0).In(this.loc).Format(time.RFC1123Z)) + ` + ` + template.HTMLEscapeString(` + latest version + | + revision `+fmt.Sprintf("%d", a.ID)+` + | + diff to previous + `) + ` + + ` + } + content += ` + +` + + w.Header().Set(`Content-Type`, `application/rss+xml`) + w.Write([]byte(content)) +}