forked from gitea/gitea
Add Feed for Releases and Tags (#21696)
Fixes #19091 Add Feed for Releases and Tags, can be accessed through `reponame/releases.rss`, `reponame/releases.atom`, `reponame/tags.rss`, and `reponame/tags.atom` Signed-off-by: Reo <reo_999@proton.me>
This commit is contained in:
parent
9914b21493
commit
48d71b7d6b
|
@ -2279,6 +2279,8 @@ release.downloads = Downloads
|
||||||
release.download_count = Downloads: %s
|
release.download_count = Downloads: %s
|
||||||
release.add_tag_msg = Use the title and content of release as tag message.
|
release.add_tag_msg = Use the title and content of release as tag message.
|
||||||
release.add_tag = Create Tag Only
|
release.add_tag = Create Tag Only
|
||||||
|
release.releases_for = Releases for %s
|
||||||
|
release.tags_for = Tags for %s
|
||||||
|
|
||||||
branch.name = Branch Name
|
branch.name = Branch Name
|
||||||
branch.search = Search branches
|
branch.search = Search branches
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
"code.gitea.io/gitea/modules/markup/markdown"
|
"code.gitea.io/gitea/modules/markup/markdown"
|
||||||
|
@ -268,3 +269,46 @@ func GetFeedType(name string, req *http.Request) (bool, string, string) {
|
||||||
|
|
||||||
return false, name, ""
|
return false, name, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// feedActionsToFeedItems convert gitea's Repo's Releases to feeds Item
|
||||||
|
func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, isReleasesOnly bool) (items []*feeds.Item, err error) {
|
||||||
|
for _, rel := range releases {
|
||||||
|
err := rel.LoadAttributes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var title, content string
|
||||||
|
|
||||||
|
if rel.IsTag {
|
||||||
|
title = rel.TagName
|
||||||
|
} else {
|
||||||
|
title = rel.Title
|
||||||
|
}
|
||||||
|
|
||||||
|
link := &feeds.Link{Href: rel.HTMLURL()}
|
||||||
|
content, err = markdown.RenderString(&markup.RenderContext{
|
||||||
|
Ctx: ctx,
|
||||||
|
URLPrefix: rel.Repo.Link(),
|
||||||
|
Metas: rel.Repo.ComposeMetas(),
|
||||||
|
}, rel.Note)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
items = append(items, &feeds.Item{
|
||||||
|
Title: title,
|
||||||
|
Link: link,
|
||||||
|
Created: rel.CreatedUnix.AsTime(),
|
||||||
|
Author: &feeds.Author{
|
||||||
|
Name: rel.Publisher.DisplayName(),
|
||||||
|
Email: rel.Publisher.GetEmail(),
|
||||||
|
},
|
||||||
|
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href),
|
||||||
|
Content: content,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return items, err
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package feed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
|
||||||
|
"github.com/gorilla/feeds"
|
||||||
|
)
|
||||||
|
|
||||||
|
// shows tags and/or releases on the repo as RSS / Atom feed
|
||||||
|
func ShowReleaseFeed(ctx *context.Context, repo *repo_model.Repository, isReleasesOnly bool, formatType string) {
|
||||||
|
releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
|
||||||
|
IncludeTags: !isReleasesOnly,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetReleasesByRepoID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var title string
|
||||||
|
var link *feeds.Link
|
||||||
|
|
||||||
|
if isReleasesOnly {
|
||||||
|
title = ctx.Tr("repo.release.releases_for", repo.FullName())
|
||||||
|
link = &feeds.Link{Href: repo.HTMLURL() + "/release"}
|
||||||
|
} else {
|
||||||
|
title = ctx.Tr("repo.release.tags_for", repo.FullName())
|
||||||
|
link = &feeds.Link{Href: repo.HTMLURL() + "/tags"}
|
||||||
|
}
|
||||||
|
|
||||||
|
feed := &feeds.Feed{
|
||||||
|
Title: title,
|
||||||
|
Link: link,
|
||||||
|
Description: repo.Description,
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
feed.Items, err = releasesToFeedItems(ctx, releases, isReleasesOnly)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("releasesToFeedItems", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFeed(ctx, feed, formatType)
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/upload"
|
"code.gitea.io/gitea/modules/upload"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
|
"code.gitea.io/gitea/routers/web/feed"
|
||||||
"code.gitea.io/gitea/services/forms"
|
"code.gitea.io/gitea/services/forms"
|
||||||
releaseservice "code.gitea.io/gitea/services/release"
|
releaseservice "code.gitea.io/gitea/services/release"
|
||||||
)
|
)
|
||||||
|
@ -199,6 +200,30 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
|
||||||
ctx.HTML(http.StatusOK, tplReleases)
|
ctx.HTML(http.StatusOK, tplReleases)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReleasesFeedRSS get feeds for releases in RSS format
|
||||||
|
func ReleasesFeedRSS(ctx *context.Context) {
|
||||||
|
releasesOrTagsFeed(ctx, true, "rss")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TagsListFeedRSS get feeds for tags in RSS format
|
||||||
|
func TagsListFeedRSS(ctx *context.Context) {
|
||||||
|
releasesOrTagsFeed(ctx, false, "rss")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleasesFeedAtom get feeds for releases in Atom format
|
||||||
|
func ReleasesFeedAtom(ctx *context.Context) {
|
||||||
|
releasesOrTagsFeed(ctx, true, "atom")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TagsListFeedAtom get feeds for tags in RSS format
|
||||||
|
func TagsListFeedAtom(ctx *context.Context) {
|
||||||
|
releasesOrTagsFeed(ctx, false, "atom")
|
||||||
|
}
|
||||||
|
|
||||||
|
func releasesOrTagsFeed(ctx *context.Context, isReleasesOnly bool, formatType string) {
|
||||||
|
feed.ShowReleaseFeed(ctx, ctx.Repo.Repository, isReleasesOnly, formatType)
|
||||||
|
}
|
||||||
|
|
||||||
// SingleRelease renders a single release's page
|
// SingleRelease renders a single release's page
|
||||||
func SingleRelease(ctx *context.Context) {
|
func SingleRelease(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
|
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
|
||||||
|
|
|
@ -1087,12 +1087,21 @@ func RegisterRoutes(m *web.Route) {
|
||||||
|
|
||||||
// Releases
|
// Releases
|
||||||
m.Group("/{username}/{reponame}", func() {
|
m.Group("/{username}/{reponame}", func() {
|
||||||
m.Get("/tags", repo.TagsList, repo.MustBeNotEmpty,
|
m.Group("/tags", func() {
|
||||||
reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag))
|
m.Get("", repo.TagsList)
|
||||||
|
m.Get(".rss", feedEnabled, repo.TagsListFeedRSS)
|
||||||
|
m.Get(".atom", feedEnabled, repo.TagsListFeedAtom)
|
||||||
|
}, func(ctx *context.Context) {
|
||||||
|
ctx.Data["EnableFeed"] = setting.EnableFeed
|
||||||
|
}, repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag, true))
|
||||||
m.Group("/releases", func() {
|
m.Group("/releases", func() {
|
||||||
m.Get("/", repo.Releases)
|
m.Get("/", repo.Releases)
|
||||||
m.Get("/tag/*", repo.SingleRelease)
|
m.Get("/tag/*", repo.SingleRelease)
|
||||||
m.Get("/latest", repo.LatestRelease)
|
m.Get("/latest", repo.LatestRelease)
|
||||||
|
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
|
||||||
|
m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom)
|
||||||
|
}, func(ctx *context.Context) {
|
||||||
|
ctx.Data["EnableFeed"] = setting.EnableFeed
|
||||||
}, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true))
|
}, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true))
|
||||||
m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader)
|
m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader)
|
||||||
m.Group("/releases", func() {
|
m.Group("/releases", func() {
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
<a class="{{if .PageIsTagList}}active {{end}}item" href="{{.RepoLink}}/tags">{{.locale.Tr "repo.release.tags"}}</a>
|
<a class="{{if .PageIsTagList}}active {{end}}item" href="{{.RepoLink}}/tags">{{.locale.Tr "repo.release.tags"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</h2>
|
</h2>
|
||||||
|
{{if .EnableFeed}}
|
||||||
|
<a href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss"><i class="ui grey icon tooltip ml-3" data-content="{{.locale.Tr "rss_feed"}}" data-position="top center">{{svg "octicon-rss" 18}}</i></a>
|
||||||
|
{{end}}
|
||||||
{{if (and .CanCreateRelease (not .PageIsTagList))}}
|
{{if (and .CanCreateRelease (not .PageIsTagList))}}
|
||||||
<a class="ui right small green button" href="{{$.RepoLink}}/releases/new">
|
<a class="ui right small green button" href="{{$.RepoLink}}/releases/new">
|
||||||
{{.locale.Tr "repo.release.new_release"}}
|
{{.locale.Tr "repo.release.new_release"}}
|
||||||
|
|
Loading…
Reference in New Issue