all repos

mugit @ 2870636536f75a09565216c7c288a22c677f7b67

🐮 git server that your cow will love

mugit/internal/handlers/feed.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
drop gorilla/feeds dependency, 2 months ago
1
package handlers
2
3
import (
4
	"encoding/xml"
5
	"net/http"
6
	"net/url"
7
	"time"
8
)
9
10
type rssFeedXML struct {
11
	XMLName xml.Name      `xml:"rss"`
12
	Version string        `xml:"version,attr"`
13
	Channel rssChannelXML `xml:"channel"`
14
}
15
16
type rssChannelXML struct {
17
	Title       string       `xml:"title"`
18
	Link        string       `xml:"link"`
19
	Description string       `xml:"description"`
20
	Items       []rssItemXML `xml:"item"`
21
}
22
23
type rssItemXML struct {
24
	Title       string `xml:"title"`
25
	Link        string `xml:"link"`
26
	Guid        string `xml:"guid"`
27
	Description string `xml:"description,omitempty"`
28
	PubDate     string `xml:"pubDate,omitempty"`
29
}
30
31
func (h *handlers) repoFeedHandler(w http.ResponseWriter, r *http.Request) {
32
	repo, err := h.openPublicRepo(r.PathValue("name"), "")
33
	if err != nil {
34
		h.write404(w, err)
35
		return
36
	}
37
38
	desc, err := repo.Description()
39
	if err != nil {
40
		h.write500(w, err)
41
		return
42
	}
43
44
	repoName := repo.Name()
45
	feedLink, err := url.JoinPath("http://", h.c.Meta.Host, repoName)
46
	if err != nil {
47
		h.write500(w, err)
48
		return
49
	}
50
51
	feed := rssFeedXML{
52
		Version: "2.0",
53
		Channel: rssChannelXML{
54
			Title:       repoName,
55
			Link:        feedLink,
56
			Description: desc,
57
		},
58
	}
59
60
	// branches
61
	branches, err := repo.Branches()
62
	if err != nil {
63
		h.write500(w, err)
64
		return
65
	}
66
67
	for _, branch := range branches {
68
		href, _ := url.JoinPath("http://", h.c.Meta.Host, repoName, "tree", branch.Name)
69
		it := rssItemXML{
70
			Title: "branch: " + branch.Name,
71
			Link:  href,
72
			Guid:  href,
73
		}
74
		if !branch.LastUpdate.IsZero() {
75
			it.PubDate = branch.LastUpdate.Format(time.RFC1123Z)
76
		}
77
		feed.Channel.Items = append(feed.Channel.Items, it)
78
	}
79
80
	// tags
81
	tags, err := repo.Tags()
82
	if err != nil {
83
		h.write500(w, err)
84
	}
85
86
	for _, tag := range tags {
87
		href, _ := url.JoinPath("http://", h.c.Meta.Host, repoName, "tree", tag.Name())
88
		it := rssItemXML{
89
			Title:       "tag: " + tag.Name(),
90
			Link:        href,
91
			Guid:        href,
92
			Description: tag.Message(),
93
		}
94
		if !tag.When().IsZero() {
95
			it.PubDate = tag.When().Format(time.RFC1123Z)
96
		}
97
		feed.Channel.Items = append(feed.Channel.Items, it)
98
	}
99
100
	w.Header().Set("Content-Type", "application/rss+xml")
101
	w.Write([]byte(xml.Header))
102
	if err := xml.NewEncoder(w).Encode(feed); err != nil {
103
		h.write500(w, err)
104
		return
105
	}
106
}
107
108
func (h *handlers) indexFeedHandler(w http.ResponseWriter, r *http.Request) {
109
	repos, err := h.listPublicRepos()
110
	if err != nil {
111
		h.write500(w, err)
112
		return
113
	}
114
115
	feedLink, err := url.JoinPath("http://", h.c.Meta.Host)
116
	if err != nil {
117
		h.write500(w, err)
118
		return
119
	}
120
121
	feed := rssFeedXML{
122
		Version: "2.0",
123
		Channel: rssChannelXML{
124
			Title:       h.c.Meta.Host,
125
			Link:        feedLink,
126
			Description: h.c.Meta.Description,
127
		},
128
	}
129
130
	for _, repo := range repos {
131
		href, _ := url.JoinPath("http://", h.c.Meta.Host, repo.Name)
132
		it := rssItemXML{
133
			Title:       repo.Name,
134
			Link:        href,
135
			Guid:        href,
136
			Description: repo.Desc,
137
		}
138
		if !repo.LastCommit.IsZero() {
139
			it.PubDate = repo.LastCommit.Format(time.RFC1123Z)
140
		}
141
		feed.Channel.Items = append(feed.Channel.Items, it)
142
	}
143
144
	w.Header().Set("Content-Type", "application/rss+xml")
145
	w.Write([]byte(xml.Header))
146
	if err := xml.NewEncoder(w).Encode(feed); err != nil {
147
		h.write500(w, err)
148
		return
149
	}
150
}