all repos

mugit @ 4af560ca6ad26b59b39cd04800777c7b2895372f

🐮 git server that your cow will love

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
run errcheck, 27 days 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, r.URL.Path, 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
		for _, tag := range tags {
84
			href, _ := url.JoinPath("http://", h.c.Meta.Host, repoName, "tree", tag.Name())
85
			it := rssItemXML{
86
				Title:       "tag: " + tag.Name(),
87
				Link:        href,
88
				GUID:        href,
89
				Description: tag.Message(),
90
			}
91
			if !tag.When().IsZero() {
92
				it.PubDate = tag.When().Format(time.RFC1123Z)
93
			}
94
			feed.Channel.Items = append(feed.Channel.Items, it)
95
		}
96
	}
97
98
	w.Header().Set("Content-Type", "application/rss+xml")
99
	_, _ = w.Write([]byte(xml.Header))
100
	if err := xml.NewEncoder(w).Encode(feed); err != nil {
101
		h.write500(w, err)
102
		return
103
	}
104
}
105
106
func (h *handlers) indexFeedHandler(w http.ResponseWriter, r *http.Request) {
107
	repos, err := h.listPublicRepos()
108
	if err != nil {
109
		h.write500(w, err)
110
		return
111
	}
112
113
	feedLink, err := url.JoinPath("http://", h.c.Meta.Host)
114
	if err != nil {
115
		h.write500(w, err)
116
		return
117
	}
118
119
	feed := rssFeedXML{
120
		Version: "2.0",
121
		Channel: rssChannelXML{
122
			Title:       h.c.Meta.Host,
123
			Link:        feedLink,
124
			Description: h.c.Meta.Description,
125
		},
126
	}
127
128
	for _, repo := range repos {
129
		href, _ := url.JoinPath("http://", h.c.Meta.Host, repo.Name)
130
		it := rssItemXML{
131
			Title:       repo.Name,
132
			Link:        href,
133
			GUID:        href,
134
			Description: repo.Desc,
135
		}
136
		if !repo.LastCommit.IsZero() {
137
			it.PubDate = repo.LastCommit.Format(time.RFC1123Z)
138
		}
139
		feed.Channel.Items = append(feed.Channel.Items, it)
140
	}
141
142
	w.Header().Set("Content-Type", "application/rss+xml")
143
	_, _ = w.Write([]byte(xml.Header))
144
	if err := xml.NewEncoder(w).Encode(feed); err != nil {
145
		h.write500(w, err)
146
		return
147
	}
148
}