From 56d4893b2a996da6388801c9c8ff16b9b588ad55 Mon Sep 17 00:00:00 2001 From: jladbrook Date: Tue, 25 Apr 2023 15:08:29 +0100 Subject: [PATCH] Add RSS Feeds for branches and files (#22719) Fix #22228 adding RSS feeds for branches and files. RSS feeds are accessed through: * [gitea]/src/branch/{branch}.rss * [gitea]/src/branch/{branch}/{file_name}.rss No changes have been made to the UI to expose the feed urls for branches and files. --- routers/web/feed/branch.go | 50 +++++++++++++++++ routers/web/feed/file.go | 56 +++++++++++++++++++ routers/web/feed/render.go | 22 ++++++++ routers/web/repo/branch.go | 6 ++ routers/web/repo/view.go | 9 ++- routers/web/web.go | 3 + templates/repo/branch/list.tmpl | 10 ++++ templates/repo/home.tmpl | 10 ++-- templates/repo/view_file.tmpl | 5 ++ .../js/components/RepoBranchTagSelector.vue | 3 + web_src/js/svg.js | 2 + 11 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 routers/web/feed/branch.go create mode 100644 routers/web/feed/file.go create mode 100644 routers/web/feed/render.go diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go new file mode 100644 index 0000000000..fb9d2a7351 --- /dev/null +++ b/routers/web/feed/branch.go @@ -0,0 +1,50 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + "fmt" + "strings" + "time" + + "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" + + "github.com/gorilla/feeds" +) + +// ShowBranchFeed shows tags and/or releases on the repo as RSS / Atom feed +func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType string) { + commits, err := ctx.Repo.Commit.CommitsByRange(0, 10) + if err != nil { + ctx.ServerError("ShowBranchFeed %s", err) + return + } + + title := fmt.Sprintf("Latest commits for branch %s", ctx.Repo.BranchName) + link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL()} + + feed := &feeds.Feed{ + Title: title, + Link: link, + Description: repo.Description, + Created: time.Now(), + } + + for _, commit := range commits { + feed.Items = append(feed.Items, &feeds.Item{ + Id: commit.ID.String(), + Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, + Author: &feeds.Author{ + Name: commit.Author.Name, + Email: commit.Author.Email, + }, + Description: commit.Message(), + Content: commit.Message(), + }) + } + + writeFeed(ctx, feed, formatType) +} diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go new file mode 100644 index 0000000000..3dc9a4e27f --- /dev/null +++ b/routers/web/feed/file.go @@ -0,0 +1,56 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + "fmt" + "strings" + "time" + + "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/util" + + "github.com/gorilla/feeds" +) + +// ShowFileFeed shows tags and/or releases on the repo as RSS / Atom feed +func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string) { + fileName := ctx.Repo.TreePath + if len(fileName) == 0 { + return + } + commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ctx.Repo.RefName, fileName, 1) + if err != nil { + ctx.ServerError("ShowBranchFeed %s", err) + return + } + + title := fmt.Sprintf("Latest commits for file %s", ctx.Repo.TreePath) + + link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)} + + feed := &feeds.Feed{ + Title: title, + Link: link, + Description: repo.Description, + Created: time.Now(), + } + + for _, commit := range commits { + feed.Items = append(feed.Items, &feeds.Item{ + Id: commit.ID.String(), + Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, + Author: &feeds.Author{ + Name: commit.Author.Name, + Email: commit.Author.Email, + }, + Description: commit.Message(), + Content: commit.Message(), + }) + } + + writeFeed(ctx, feed, formatType) +} diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go new file mode 100644 index 0000000000..0f327f87f2 --- /dev/null +++ b/routers/web/feed/render.go @@ -0,0 +1,22 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package feed + +import ( + model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" +) + +// RenderBranchFeed render format for branch or file +func RenderBranchFeed(ctx *context.Context) { + _, _, showFeedType := GetFeedType(ctx.Params(":reponame"), ctx.Req) + var renderer func(ctx *context.Context, repo *model.Repository, formatType string) + switch { + case ctx.Repo.TreePath == "": + renderer = ShowBranchFeed + case ctx.Repo.TreePath != "": + renderer = ShowFileFeed + } + renderer(ctx, ctx.Repo.Repository, showFeedType) +} diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 9f26634311..1014449f78 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/routers/web/feed" "code.gitea.io/gitea/services/forms" release_service "code.gitea.io/gitea/services/release" repo_service "code.gitea.io/gitea/services/repository" @@ -340,6 +341,11 @@ func getDeletedBranches(ctx *context.Context) ([]*Branch, error) { return branches, nil } +// BranchFeedRSS get feeds for tags in RSS format +func BranchFeedRSS(ctx *context.Context) { + feed.ShowBranchFeed(ctx, ctx.Repo.Repository, "rss") +} + // CreateBranch creates new branch in repository func CreateBranch(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewBranchForm) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index f9dca91844..9f2770a3ac 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -710,7 +710,14 @@ func Home(ctx *context.Context) { if setting.Other.EnableFeed { isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req) if isFeed { - feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) + switch { + case ctx.Link == fmt.Sprintf("%s.%s", ctx.Repo.RepoLink, showFeedType): + feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) + case ctx.Repo.TreePath == "": + feed.ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) + case ctx.Repo.TreePath != "": + feed.ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) + } return } } diff --git a/routers/web/web.go b/routers/web/web.go index 88b6777d73..f7f32734d8 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1450,6 +1450,9 @@ func RegisterRoutes(m *web.Route) { m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) + m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feed.RenderBranchFeed) + m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feed.RenderBranchFeed) + m.Group("/src", func() { m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home) m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.Home) diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index b027c175a4..596d9ae78b 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -26,6 +26,11 @@ {{svg "octicon-git-branch"}} {{end}} + {{if .EnableFeed}} + + {{svg "octicon-rss"}} + + {{end}} {{if not $.DisableDownloadSourceArchives}} {{end}} + {{if $.EnableFeed}} + + {{svg "octicon-rss"}} + + {{end}} {{if and (not .IsDeleted) (not $.DisableDownloadSourceArchives)}} + + {{end}} {{if eq $n 0}} - {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} - - - - {{end}} {{.locale.Tr "repo.find_file.go_to_file"}} {{end}} diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 7ee08c9efc..fe67de5392 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -42,6 +42,11 @@ {{svg "octicon-download"}} {{svg "octicon-copy" 14}} + {{if .EnableFeed}} + + {{svg "octicon-rss" 14}} + + {{end}} {{if .Repository.CanEnableEditor}} {{if .CanEditFile}} {{svg "octicon-pencil"}} diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index 6a65eeec6f..863da6206f 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -39,6 +39,9 @@