- commit
- 8186562
- parent
- ca1672d
- author
- Eric Bower
- date
- 2024-03-02 04:02:56 +0000 UTC
fix(pgs): sort rss feed feat(pgs): add new updated_at rss feed
3 files changed,
+69,
-59
M
db/db.go
+1,
-1
1@@ -341,7 +341,7 @@ type DB interface {
2 FindProjectLinks(userID, name string) ([]*Project, error)
3 FindProjectsByUser(userID string) ([]*Project, error)
4 FindProjectsByPrefix(userID, name string) ([]*Project, error)
5- FindAllProjects(page *Pager) (*Paginate[*Project], error)
6+ FindAllProjects(page *Pager, by string) (*Paginate[*Project], error)
7
8 Close() error
9 }
+12,
-12
1@@ -253,17 +253,11 @@ const (
2 sqlRemoveKeys = `DELETE FROM public_keys WHERE id = ANY($1::uuid[])`
3 sqlRemoveUsers = `DELETE FROM app_users WHERE id = ANY($1::uuid[])`
4
5- sqlInsertProject = `INSERT INTO projects (user_id, name, project_dir) VALUES ($1, $2, $3) RETURNING id;`
6- sqlUpdateProject = `UPDATE projects SET updated_at = $3 WHERE user_id = $1 AND name = $2;`
7- sqlUpdateProjectAcl = `UPDATE projects SET acl = $3, updated_at = $4 WHERE user_id = $1 AND name = $2;`
8- sqlFindProjectByName = `SELECT id, user_id, name, project_dir, acl, created_at, updated_at FROM projects WHERE user_id = $1 AND name = $2;`
9- sqlSelectProjectCount = `SELECT count(id) FROM projects`
10- sqlFindAllProjects = `
11- SELECT projects.id, user_id, app_users.name as username, projects.name, project_dir, projects.acl, projects.created_at, projects.updated_at
12- FROM projects
13- LEFT JOIN app_users ON app_users.id = projects.user_id
14- ORDER BY created_at ASC
15- LIMIT $1 OFFSET $2`
16+ sqlInsertProject = `INSERT INTO projects (user_id, name, project_dir) VALUES ($1, $2, $3) RETURNING id;`
17+ sqlUpdateProject = `UPDATE projects SET updated_at = $3 WHERE user_id = $1 AND name = $2;`
18+ sqlUpdateProjectAcl = `UPDATE projects SET acl = $3, updated_at = $4 WHERE user_id = $1 AND name = $2;`
19+ sqlFindProjectByName = `SELECT id, user_id, name, project_dir, acl, created_at, updated_at FROM projects WHERE user_id = $1 AND name = $2;`
20+ sqlSelectProjectCount = `SELECT count(id) FROM projects`
21 sqlFindProjectsByUser = `SELECT id, user_id, name, project_dir, acl, created_at, updated_at FROM projects WHERE user_id = $1 ORDER BY name ASC, updated_at DESC;`
22 sqlFindProjectsByPrefix = `SELECT id, user_id, name, project_dir, acl, created_at, updated_at FROM projects WHERE user_id = $1 AND name = project_dir AND name ILIKE $2 ORDER BY updated_at ASC, name ASC;`
23 sqlFindProjectLinks = `SELECT id, user_id, name, project_dir, acl, created_at, updated_at FROM projects WHERE user_id = $1 AND name != project_dir AND project_dir = $2 ORDER BY name ASC;`
24@@ -1463,8 +1457,14 @@ func (me *PsqlDB) FindProjectsByUser(userID string) ([]*db.Project, error) {
25 return projects, nil
26 }
27
28-func (me *PsqlDB) FindAllProjects(page *db.Pager) (*db.Paginate[*db.Project], error) {
29+func (me *PsqlDB) FindAllProjects(page *db.Pager, by string) (*db.Paginate[*db.Project], error) {
30 var projects []*db.Project
31+ sqlFindAllProjects := fmt.Sprintf(`
32+ SELECT projects.id, user_id, app_users.name as username, projects.name, project_dir, projects.acl, projects.created_at, projects.updated_at
33+ FROM projects
34+ LEFT JOIN app_users ON app_users.id = projects.user_id
35+ ORDER BY %s DESC
36+ LIMIT $1 OFFSET $2`, by)
37 rs, err := me.Db.Query(sqlFindAllProjects, page.Num, page.Num*page.Page)
38 if err != nil {
39 return nil, err
+56,
-46
1@@ -87,58 +87,67 @@ type RssData struct {
2 Contents template.HTML
3 }
4
5-func rssHandler(w http.ResponseWriter, r *http.Request) {
6- dbpool := shared.GetDB(r)
7- logger := shared.GetLogger(r)
8- cfg := shared.GetCfg(r)
9+func createRssHandler(by string) http.HandlerFunc {
10+ return func(w http.ResponseWriter, r *http.Request) {
11+ dbpool := shared.GetDB(r)
12+ logger := shared.GetLogger(r)
13+ cfg := shared.GetCfg(r)
14
15- pager, err := dbpool.FindAllProjects(&db.Pager{Num: 50, Page: 0})
16- if err != nil {
17- logger.Error(err.Error())
18- http.Error(w, err.Error(), http.StatusInternalServerError)
19- return
20- }
21+ pager, err := dbpool.FindAllProjects(&db.Pager{Num: 100, Page: 0}, by)
22+ if err != nil {
23+ logger.Error(err.Error())
24+ http.Error(w, err.Error(), http.StatusInternalServerError)
25+ return
26+ }
27
28- feed := &feeds.Feed{
29- Title: fmt.Sprintf("%s discovery feed", cfg.Domain),
30- Link: &feeds.Link{Href: cfg.ReadURL()},
31- Description: fmt.Sprintf("%s latest projects", cfg.Domain),
32- Author: &feeds.Author{Name: cfg.Domain},
33- Created: time.Now(),
34- }
35+ feed := &feeds.Feed{
36+ Title: fmt.Sprintf("%s discovery feed %s", cfg.Domain, by),
37+ Link: &feeds.Link{Href: cfg.ReadURL()},
38+ Description: fmt.Sprintf("%s projects %s", cfg.Domain, by),
39+ Author: &feeds.Author{Name: cfg.Domain},
40+ Created: time.Now(),
41+ }
42
43- var feedItems []*feeds.Item
44- for _, project := range pager.Data {
45- realUrl := strings.TrimSuffix(
46- cfg.AssetURL(project.Username, project.Name, ""),
47- "/",
48- )
49+ var feedItems []*feeds.Item
50+ for _, project := range pager.Data {
51+ realUrl := strings.TrimSuffix(
52+ cfg.AssetURL(project.Username, project.Name, ""),
53+ "/",
54+ )
55+ uat := project.UpdatedAt.Unix()
56+ id := realUrl
57+ title := fmt.Sprintf("%s-%s", project.Username, project.Name)
58+ if by == "updated_at" {
59+ id = fmt.Sprintf("%s:%d", realUrl, uat)
60+ title = fmt.Sprintf("%s - %d", title, uat)
61+ }
62
63- item := &feeds.Item{
64- Id: realUrl,
65- Title: project.Name,
66- Link: &feeds.Link{Href: realUrl},
67- Content: fmt.Sprintf(`<a href="%s">%s</a>`, realUrl, realUrl),
68- Created: *project.CreatedAt,
69- Updated: *project.CreatedAt,
70- Description: "",
71- Author: &feeds.Author{Name: project.Username},
72- }
73+ item := &feeds.Item{
74+ Id: id,
75+ Title: title,
76+ Link: &feeds.Link{Href: realUrl},
77+ Content: fmt.Sprintf(`<a href="%s">%s</a>`, realUrl, realUrl),
78+ Created: *project.CreatedAt,
79+ Updated: *project.CreatedAt,
80+ Description: "",
81+ Author: &feeds.Author{Name: project.Username},
82+ }
83
84- feedItems = append(feedItems, item)
85- }
86- feed.Items = feedItems
87+ feedItems = append(feedItems, item)
88+ }
89+ feed.Items = feedItems
90
91- rss, err := feed.ToAtom()
92- if err != nil {
93- logger.Error(err.Error())
94- http.Error(w, "Could not generate atom rss feed", http.StatusInternalServerError)
95- }
96+ rss, err := feed.ToAtom()
97+ if err != nil {
98+ logger.Error(err.Error())
99+ http.Error(w, "Could not generate atom rss feed", http.StatusInternalServerError)
100+ }
101
102- w.Header().Add("Content-Type", "application/atom+xml")
103- _, err = w.Write([]byte(rss))
104- if err != nil {
105- logger.Error(err.Error())
106+ w.Header().Add("Content-Type", "application/atom+xml")
107+ _, err = w.Write([]byte(rss))
108+ if err != nil {
109+ logger.Error(err.Error())
110+ }
111 }
112 }
113
114@@ -449,7 +458,8 @@ var mainRoutes = []shared.Route{
115
116 shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
117 shared.NewRoute("GET", "/check", checkHandler),
118- shared.NewRoute("GET", "/rss", rssHandler),
119+ shared.NewRoute("GET", "/rss/updated", createRssHandler("updated_at")),
120+ shared.NewRoute("GET", "/rss", createRssHandler("created_at")),
121 shared.NewRoute("GET", "/(.+)", shared.CreatePageHandler("html/marketing.page.tmpl")),
122 }
123