From 37fcbb205cf16c1277e9d867c687e083621baea8 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 8 Dec 2021 20:04:15 -0600 Subject: [PATCH] Move data-fetching helpers to a separate package --- src/admintools/adminproject.go | 6 +-- src/{website => hmndata}/project_helper.go | 35 +++---------- src/{website => hmndata}/snippet_helper.go | 8 +-- src/{website => hmndata}/tag_helper.go | 5 +- .../threads_and_posts_helper.go | 11 ++-- src/perf/perf.go | 10 ++++ src/website/admin.go | 5 +- src/website/blogs.go | 37 +++++++------- src/website/feed.go | 16 +++--- src/website/forums.go | 51 ++++++++++--------- src/website/jam.go | 5 +- src/website/landing.go | 13 ++--- src/website/post_helper.go | 3 +- src/website/projects.go | 46 ++++++++++++----- src/website/routes.go | 23 +++------ src/website/showcase.go | 3 +- src/website/snippet.go | 3 +- src/website/user.go | 13 ++--- 18 files changed, 153 insertions(+), 140 deletions(-) rename src/{website => hmndata}/project_helper.go (96%) rename src/{website => hmndata}/snippet_helper.go (97%) rename src/{website => hmndata}/tag_helper.go (93%) rename src/{website => hmndata}/threads_and_posts_helper.go (99%) diff --git a/src/admintools/adminproject.go b/src/admintools/adminproject.go index 68555ea1..d878cb7f 100644 --- a/src/admintools/adminproject.go +++ b/src/admintools/adminproject.go @@ -5,9 +5,9 @@ import ( "fmt" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/parsing" - "git.handmade.network/hmn/hmn/src/website" "github.com/spf13/cobra" ) @@ -46,7 +46,7 @@ func addCreateProjectCommand(projectCommand *cobra.Command) { } defer tx.Rollback(ctx) - p, err := website.FetchProject(ctx, tx, nil, models.HMNProjectID, website.ProjectsQuery{ + p, err := hmndata.FetchProject(ctx, tx, nil, models.HMNProjectID, hmndata.ProjectsQuery{ IncludeHidden: true, Lifecycles: models.AllProjectLifecycles, }) @@ -163,7 +163,7 @@ func addProjectTagCommand(projectCommand *cobra.Command) { conn := db.NewConnPool(1, 1) defer conn.Close() - resultTag, err := website.SetProjectTag(ctx, conn, projectID, tag) + resultTag, err := hmndata.SetProjectTag(ctx, conn, projectID, tag) if err != nil { panic(err) } diff --git a/src/website/project_helper.go b/src/hmndata/project_helper.go similarity index 96% rename from src/website/project_helper.go rename to src/hmndata/project_helper.go index 3ea279bb..1be1cf4b 100644 --- a/src/website/project_helper.go +++ b/src/hmndata/project_helper.go @@ -1,15 +1,15 @@ -package website +package hmndata import ( "context" "fmt" - "git.handmade.network/hmn/hmn/src/hmnurl" - "git.handmade.network/hmn/hmn/src/templates" - "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" + "git.handmade.network/hmn/hmn/src/perf" + "git.handmade.network/hmn/hmn/src/templates" ) type ProjectTypeQuery int @@ -61,7 +61,7 @@ func FetchProjects( currentUser *models.User, q ProjectsQuery, ) ([]ProjectAndStuff, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch projects") defer perf.EndBlock() @@ -312,7 +312,7 @@ func CountProjects( currentUser *models.User, q ProjectsQuery, ) (int, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Count projects") defer perf.EndBlock() @@ -328,25 +328,6 @@ func CountProjects( return len(projects), nil } -func CanEditProject(c *RequestContext, user *models.User, projectId int) (bool, error) { - if user != nil { - if user.IsStaff { - return true, nil - } else { - owners, err := FetchProjectOwners(c.Context(), c.Conn, projectId) - if err != nil { - return false, err - } - for _, owner := range owners { - if owner.ID == user.ID { - return true, nil - } - } - } - } - return false, nil -} - type ProjectOwners struct { ProjectID int Owners []*models.User @@ -366,7 +347,7 @@ func FetchMultipleProjectsOwners( dbConn db.ConnOrTx, projectIds []int, ) ([]ProjectOwners, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch owners for multiple projects") defer perf.EndBlock() @@ -470,7 +451,7 @@ func FetchProjectOwners( dbConn db.ConnOrTx, projectId int, ) ([]*models.User, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch owners for project") defer perf.EndBlock() diff --git a/src/website/snippet_helper.go b/src/hmndata/snippet_helper.go similarity index 97% rename from src/website/snippet_helper.go rename to src/hmndata/snippet_helper.go index c4f16795..84e5c09b 100644 --- a/src/website/snippet_helper.go +++ b/src/hmndata/snippet_helper.go @@ -1,12 +1,12 @@ -package website +package hmndata import ( "context" - "git.handmade.network/hmn/hmn/src/oops" - "git.handmade.network/hmn/hmn/src/db" "git.handmade.network/hmn/hmn/src/models" + "git.handmade.network/hmn/hmn/src/oops" + "git.handmade.network/hmn/hmn/src/perf" ) type SnippetQuery struct { @@ -31,7 +31,7 @@ func FetchSnippets( currentUser *models.User, q SnippetQuery, ) ([]SnippetAndStuff, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch snippets") defer perf.EndBlock() diff --git a/src/website/tag_helper.go b/src/hmndata/tag_helper.go similarity index 93% rename from src/website/tag_helper.go rename to src/hmndata/tag_helper.go index 7552ddfe..1f10ff17 100644 --- a/src/website/tag_helper.go +++ b/src/hmndata/tag_helper.go @@ -1,4 +1,4 @@ -package website +package hmndata import ( "context" @@ -6,6 +6,7 @@ import ( "git.handmade.network/hmn/hmn/src/db" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" + "git.handmade.network/hmn/hmn/src/perf" ) type TagQuery struct { @@ -16,7 +17,7 @@ type TagQuery struct { } func FetchTags(ctx context.Context, dbConn db.ConnOrTx, q TagQuery) ([]*models.Tag, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch snippets") defer perf.EndBlock() diff --git a/src/website/threads_and_posts_helper.go b/src/hmndata/threads_and_posts_helper.go similarity index 99% rename from src/website/threads_and_posts_helper.go rename to src/hmndata/threads_and_posts_helper.go index 9cac64b8..052cc849 100644 --- a/src/website/threads_and_posts_helper.go +++ b/src/hmndata/threads_and_posts_helper.go @@ -1,4 +1,4 @@ -package website +package hmndata import ( "context" @@ -14,6 +14,7 @@ import ( "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" "git.handmade.network/hmn/hmn/src/parsing" + "git.handmade.network/hmn/hmn/src/perf" "github.com/google/uuid" "github.com/jackc/pgx/v4" ) @@ -54,7 +55,7 @@ func FetchThreads( currentUser *models.User, q ThreadsQuery, ) ([]ThreadAndStuff, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch threads") defer perf.EndBlock() @@ -197,7 +198,7 @@ func CountThreads( currentUser *models.User, q ThreadsQuery, ) (int, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Count threads") defer perf.EndBlock() @@ -299,7 +300,7 @@ func FetchPosts( currentUser *models.User, q PostsQuery, ) ([]PostAndStuff, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Fetch posts") defer perf.EndBlock() @@ -520,7 +521,7 @@ func CountPosts( currentUser *models.User, q PostsQuery, ) (int, error) { - perf := ExtractPerf(ctx) + perf := perf.ExtractPerf(ctx) perf.StartBlock("SQL", "Count posts") defer perf.EndBlock() diff --git a/src/perf/perf.go b/src/perf/perf.go index ee0f55c2..d749e116 100644 --- a/src/perf/perf.go +++ b/src/perf/perf.go @@ -167,3 +167,13 @@ func LogPerf(perf *RequestPerf, log *zerolog.Event) { } log.Msg(fmt.Sprintf("Served [%s] %s in %.4fms", perf.Method, perf.Path, float64(perf.End.Sub(perf.Start).Nanoseconds())/1000/1000)) } + +const PerfContextKey = "HMNPerf" + +func ExtractPerf(ctx context.Context) *RequestPerf { + iperf := ctx.Value(PerfContextKey) + if iperf == nil { + return nil + } + return iperf.(*RequestPerf) +} diff --git a/src/website/admin.go b/src/website/admin.go index 2dd6b734..8ac5af60 100644 --- a/src/website/admin.go +++ b/src/website/admin.go @@ -12,6 +12,7 @@ import ( "git.handmade.network/hmn/hmn/src/auth" "git.handmade.network/hmn/hmn/src/config" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" @@ -137,7 +138,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData { for _, p := range posts { post := templates.PostToTemplate(&p.Post, &p.Author, c.Theme) post.AddContentVersion(p.CurrentVersion, &p.Author) // NOTE(asaf): Don't care about editors here - post.Url = UrlForGenericPost(UrlContextForProject(&p.Project), &p.Thread, &p.Post, lineageBuilder) + post.Url = UrlForGenericPost(hmndata.UrlContextForProject(&p.Project), &p.Thread, &p.Post, lineageBuilder) data.Posts = append(data.Posts, postWithTitle{ Post: post, Title: p.Thread.Title, @@ -282,7 +283,7 @@ func deleteAllPostsForUser(ctx context.Context, conn *pgxpool.Pool, userId int) for _, iResult := range it.ToSlice() { row := iResult.(*toDelete) - DeletePost(ctx, tx, row.ThreadID, row.PostID) + hmndata.DeletePost(ctx, tx, row.ThreadID, row.PostID) } err = tx.Commit(ctx) if err != nil { diff --git a/src/website/blogs.go b/src/website/blogs.go index 15e71685..6164f7de 100644 --- a/src/website/blogs.go +++ b/src/website/blogs.go @@ -9,6 +9,7 @@ import ( "time" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" @@ -35,7 +36,7 @@ func BlogIndex(c *RequestContext) ResponseData { const postsPerPage = 5 - numThreads, err := CountThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + numThreads, err := hmndata.CountThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -49,7 +50,7 @@ func BlogIndex(c *RequestContext) ResponseData { c.Redirect(c.UrlContext.BuildBlog(page), http.StatusSeeOther) } - threads, err := FetchThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + threads, err := hmndata.FetchThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, Limit: postsPerPage, @@ -75,7 +76,7 @@ func BlogIndex(c *RequestContext) ResponseData { canCreate := false if c.CurrentProject.HasBlog() && c.CurrentUser != nil { isProjectOwner := false - owners, err := FetchProjectOwners(c.Context(), c.Conn, c.CurrentProject.ID) + owners, err := hmndata.FetchProjectOwners(c.Context(), c.Conn, c.CurrentProject.ID) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project owners")) } @@ -124,7 +125,7 @@ func BlogThread(c *RequestContext) ResponseData { return FourOhFour(c) } - thread, posts, err := FetchThreadPosts(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, PostsQuery{ + thread, posts, err := hmndata.FetchThreadPosts(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -192,7 +193,7 @@ func BlogPostRedirectToThread(c *RequestContext) ResponseData { return FourOhFour(c) } - thread, err := FetchThread(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, ThreadsQuery{ + thread, err := hmndata.FetchThread(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -261,7 +262,7 @@ func BlogNewThreadSubmit(c *RequestContext) ResponseData { } // Create everything else - CreateNewPost(c.Context(), tx, c.CurrentProject.ID, threadId, models.ThreadTypeProjectBlogPost, c.CurrentUser.ID, nil, unparsed, c.Req.Host) + hmndata.CreateNewPost(c.Context(), tx, c.CurrentProject.ID, threadId, models.ThreadTypeProjectBlogPost, c.CurrentUser.ID, nil, unparsed, c.Req.Host) err = tx.Commit(c.Context()) if err != nil { @@ -278,11 +279,11 @@ func BlogPostEdit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -322,7 +323,7 @@ func BlogPostEditSubmit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } @@ -332,7 +333,7 @@ func BlogPostEditSubmit(c *RequestContext) ResponseData { } defer tx.Rollback(c.Context()) - post, err := FetchThreadPost(c.Context(), tx, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), tx, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -353,7 +354,7 @@ func BlogPostEditSubmit(c *RequestContext) ResponseData { return RejectRequest(c, "You must provide a post body.") } - CreatePostVersion(c.Context(), tx, post.Post.ID, unparsed, c.Req.Host, editReason, &c.CurrentUser.ID) + hmndata.CreatePostVersion(c.Context(), tx, post.Post.ID, unparsed, c.Req.Host, editReason, &c.CurrentUser.ID) if title != "" { _, err := tx.Exec(c.Context(), @@ -383,7 +384,7 @@ func BlogPostReply(c *RequestContext) ResponseData { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -432,7 +433,7 @@ func BlogPostReplySubmit(c *RequestContext) ResponseData { return RejectRequest(c, "Your reply cannot be empty.") } - newPostId, _ := CreateNewPost(c.Context(), tx, c.CurrentProject.ID, cd.ThreadID, models.ThreadTypeProjectBlogPost, c.CurrentUser.ID, &cd.PostID, unparsed, c.Req.Host) + newPostId, _ := hmndata.CreateNewPost(c.Context(), tx, c.CurrentProject.ID, cd.ThreadID, models.ThreadTypeProjectBlogPost, c.CurrentUser.ID, &cd.PostID, unparsed, c.Req.Host) err = tx.Commit(c.Context()) if err != nil { @@ -449,11 +450,11 @@ func BlogPostDelete(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) @@ -499,7 +500,7 @@ func BlogPostDeleteSubmit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } @@ -509,7 +510,7 @@ func BlogPostDeleteSubmit(c *RequestContext) ResponseData { } defer tx.Rollback(c.Context()) - threadDeleted := DeletePost(c.Context(), tx, cd.ThreadID, cd.PostID) + threadDeleted := hmndata.DeletePost(c.Context(), tx, cd.ThreadID, cd.PostID) err = tx.Commit(c.Context()) if err != nil { @@ -519,7 +520,7 @@ func BlogPostDeleteSubmit(c *RequestContext) ResponseData { if threadDeleted { return c.Redirect(c.UrlContext.BuildHomepage(), http.StatusSeeOther) } else { - thread, err := FetchThread(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, ThreadsQuery{ + thread, err := hmndata.FetchThread(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, }) diff --git a/src/website/feed.go b/src/website/feed.go index ec5bd1ee..ad5ca297 100644 --- a/src/website/feed.go +++ b/src/website/feed.go @@ -7,13 +7,13 @@ import ( "strings" "time" - "github.com/google/uuid" - + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" "git.handmade.network/hmn/hmn/src/templates" "git.handmade.network/hmn/hmn/src/utils" + "github.com/google/uuid" ) type FeedData struct { @@ -33,7 +33,7 @@ var feedThreadTypes = []models.ThreadType{ } func Feed(c *RequestContext) ResponseData { - numPosts, err := CountPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + numPosts, err := hmndata.CountPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ThreadTypes: feedThreadTypes, }) if err != nil { @@ -156,17 +156,17 @@ func AtomFeed(c *RequestContext) ResponseData { if hasAll { itemsPerFeed = 100000 } - projectsAndStuff, err := FetchProjects(c.Context(), c.Conn, nil, ProjectsQuery{ + projectsAndStuff, err := hmndata.FetchProjects(c.Context(), c.Conn, nil, hmndata.ProjectsQuery{ Lifecycles: models.VisibleProjectLifecycles, Limit: itemsPerFeed, - Types: OfficialProjects, + Types: hmndata.OfficialProjects, OrderBy: "date_approved DESC", }) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed projects")) } for _, p := range projectsAndStuff { - templateProject := templates.ProjectToTemplate(&p.Project, UrlContextForProject(&p.Project).BuildHomepage()) + templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage()) templateProject.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(templateProject.Url)).URN() for _, owner := range p.Owners { templateProject.Owners = append(templateProject.Owners, templates.UserToTemplate(owner, "")) @@ -189,7 +189,7 @@ func AtomFeed(c *RequestContext) ResponseData { feedData.AtomFeedUrl = hmnurl.BuildAtomFeedForShowcase() feedData.FeedUrl = hmnurl.BuildShowcase() - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{ + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{ Limit: itemsPerFeed, }) if err != nil { @@ -216,7 +216,7 @@ func AtomFeed(c *RequestContext) ResponseData { } func fetchAllPosts(c *RequestContext, offset int, limit int) ([]templates.PostListItem, error) { - postsAndStuff, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + postsAndStuff, err := hmndata.FetchPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ThreadTypes: feedThreadTypes, Limit: limit, Offset: offset, diff --git a/src/website/forums.go b/src/website/forums.go index efc68db1..ea6b8bbe 100644 --- a/src/website/forums.go +++ b/src/website/forums.go @@ -10,6 +10,7 @@ import ( "time" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/logging" "git.handmade.network/hmn/hmn/src/models" @@ -68,7 +69,7 @@ func getEditorDataForNew(urlContext *hmnurl.UrlContext, currentUser *models.User return result } -func getEditorDataForEdit(urlContext *hmnurl.UrlContext, currentUser *models.User, baseData templates.BaseData, p PostAndStuff) editorData { +func getEditorDataForEdit(urlContext *hmnurl.UrlContext, currentUser *models.User, baseData templates.BaseData, p hmndata.PostAndStuff) editorData { return editorData{ BaseData: baseData, Title: p.Thread.Title, @@ -90,7 +91,7 @@ func Forum(c *RequestContext) ResponseData { currentSubforumSlugs := cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID) - numThreads, err := CountThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + numThreads, err := hmndata.CountThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, SubforumIDs: []int{cd.SubforumID}, @@ -106,7 +107,7 @@ func Forum(c *RequestContext) ResponseData { } howManyThreadsToSkip := (page - 1) * threadsPerPage - mainThreads, err := FetchThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + mainThreads, err := hmndata.FetchThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, SubforumIDs: []int{cd.SubforumID}, @@ -114,7 +115,7 @@ func Forum(c *RequestContext) ResponseData { Offset: howManyThreadsToSkip, }) - makeThreadListItem := func(row ThreadAndStuff) templates.ThreadListItem { + makeThreadListItem := func(row hmndata.ThreadAndStuff) templates.ThreadListItem { return templates.ThreadListItem{ Title: row.Thread.Title, Url: c.UrlContext.BuildForumThread(cd.LineageBuilder.GetSubforumLineageSlugs(*row.Thread.SubforumID), row.Thread.ID, row.Thread.Title, 1), @@ -140,7 +141,7 @@ func Forum(c *RequestContext) ResponseData { subforumNodes := cd.SubforumTree[cd.SubforumID].Children for _, sfNode := range subforumNodes { - numThreads, err := CountThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + numThreads, err := hmndata.CountThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, SubforumIDs: []int{sfNode.ID}, @@ -149,7 +150,7 @@ func Forum(c *RequestContext) ResponseData { panic(oops.New(err, "failed to get count of threads")) } - subforumThreads, err := FetchThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + subforumThreads, err := hmndata.FetchThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, SubforumIDs: []int{sfNode.ID}, @@ -333,7 +334,7 @@ func ForumThread(c *RequestContext) ResponseData { currentSubforumSlugs := cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID) - threads, err := FetchThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + threads, err := hmndata.FetchThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadIDs: []int{cd.ThreadID}, }) @@ -346,7 +347,7 @@ func ForumThread(c *RequestContext) ResponseData { threadResult := threads[0] thread := threadResult.Thread - numPosts, err := CountPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + numPosts, err := hmndata.CountPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, ThreadIDs: []int{cd.ThreadID}, @@ -369,7 +370,7 @@ func ForumThread(c *RequestContext) ResponseData { PreviousUrl: c.UrlContext.BuildForumThread(currentSubforumSlugs, thread.ID, thread.Title, utils.IntClamp(1, page-1, numPages)), } - postsAndStuff, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + postsAndStuff, err := hmndata.FetchPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadIDs: []int{thread.ID}, Limit: threadPostsPerPage, @@ -440,7 +441,7 @@ func ForumPostRedirect(c *RequestContext) ResponseData { return FourOhFour(c) } - posts, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + posts, err := hmndata.FetchPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, ThreadIDs: []int{cd.ThreadID}, @@ -449,7 +450,7 @@ func ForumPostRedirect(c *RequestContext) ResponseData { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch posts for redirect")) } - var post PostAndStuff + var post hmndata.PostAndStuff postIdx := -1 for i, p := range posts { if p.Post.ID == cd.PostID { @@ -539,7 +540,7 @@ func ForumNewThreadSubmit(c *RequestContext) ResponseData { } // Create everything else - CreateNewPost(c.Context(), tx, c.CurrentProject.ID, threadId, models.ThreadTypeForumPost, c.CurrentUser.ID, nil, unparsed, c.Req.Host) + hmndata.CreateNewPost(c.Context(), tx, c.CurrentProject.ID, threadId, models.ThreadTypeForumPost, c.CurrentUser.ID, nil, unparsed, c.Req.Host) err = tx.Commit(c.Context()) if err != nil { @@ -556,7 +557,7 @@ func ForumPostReply(c *RequestContext) ResponseData { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, }) @@ -605,7 +606,7 @@ func ForumPostReplySubmit(c *RequestContext) ResponseData { return RejectRequest(c, "Your reply cannot be empty.") } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, }) @@ -619,7 +620,7 @@ func ForumPostReplySubmit(c *RequestContext) ResponseData { replyPostId = &cd.PostID } - newPostId, _ := CreateNewPost(c.Context(), tx, c.CurrentProject.ID, cd.ThreadID, models.ThreadTypeForumPost, c.CurrentUser.ID, replyPostId, unparsed, c.Req.Host) + newPostId, _ := hmndata.CreateNewPost(c.Context(), tx, c.CurrentProject.ID, cd.ThreadID, models.ThreadTypeForumPost, c.CurrentUser.ID, replyPostId, unparsed, c.Req.Host) err = tx.Commit(c.Context()) if err != nil { @@ -636,11 +637,11 @@ func ForumPostEdit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, }) @@ -673,7 +674,7 @@ func ForumPostEditSubmit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } @@ -683,7 +684,7 @@ func ForumPostEditSubmit(c *RequestContext) ResponseData { } defer tx.Rollback(c.Context()) - post, err := FetchThreadPost(c.Context(), tx, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), tx, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, }) @@ -704,7 +705,7 @@ func ForumPostEditSubmit(c *RequestContext) ResponseData { return RejectRequest(c, "You must provide a body for your post.") } - CreatePostVersion(c.Context(), tx, cd.PostID, unparsed, c.Req.Host, editReason, &c.CurrentUser.ID) + hmndata.CreatePostVersion(c.Context(), tx, cd.PostID, unparsed, c.Req.Host, editReason, &c.CurrentUser.ID) if title != "" { _, err := tx.Exec(c.Context(), @@ -734,11 +735,11 @@ func ForumPostDelete(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } - post, err := FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, PostsQuery{ + post, err := hmndata.FetchThreadPost(c.Context(), c.Conn, c.CurrentUser, cd.ThreadID, cd.PostID, hmndata.PostsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost}, }) @@ -778,7 +779,7 @@ func ForumPostDeleteSubmit(c *RequestContext) ResponseData { return FourOhFour(c) } - if !UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { + if !hmndata.UserCanEditPost(c.Context(), c.Conn, *c.CurrentUser, cd.PostID) { return FourOhFour(c) } @@ -788,7 +789,7 @@ func ForumPostDeleteSubmit(c *RequestContext) ResponseData { } defer tx.Rollback(c.Context()) - threadDeleted := DeletePost(c.Context(), tx, cd.ThreadID, cd.PostID) + threadDeleted := hmndata.DeletePost(c.Context(), tx, cd.ThreadID, cd.PostID) err = tx.Commit(c.Context()) if err != nil { @@ -811,7 +812,7 @@ func WikiArticleRedirect(c *RequestContext) ResponseData { panic(err) } - thread, err := FetchThread(c.Context(), c.Conn, c.CurrentUser, threadId, ThreadsQuery{ + thread, err := hmndata.FetchThread(c.Context(), c.Conn, c.CurrentUser, threadId, hmndata.ThreadsQuery{ ProjectIDs: []int{c.CurrentProject.ID}, // This is the rare query where we want all thread types! }) diff --git a/src/website/jam.go b/src/website/jam.go index 3d2fdac4..41017164 100644 --- a/src/website/jam.go +++ b/src/website/jam.go @@ -4,6 +4,7 @@ import ( "net/http" "time" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/oops" "git.handmade.network/hmn/hmn/src/templates" @@ -19,7 +20,7 @@ func JamIndex(c *RequestContext) ResponseData { } tagId := -1 - jamTag, err := FetchTag(c.Context(), c.Conn, TagQuery{ + jamTag, err := hmndata.FetchTag(c.Context(), c.Conn, hmndata.TagQuery{ Text: []string{"wheeljam"}, }) if err == nil { @@ -28,7 +29,7 @@ func JamIndex(c *RequestContext) ResponseData { c.Logger.Warn().Err(err).Msg("failed to fetch jam tag; will fetch all snippets as a result") } - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{ + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{ Tags: []int{tagId}, }) if err != nil { diff --git a/src/website/landing.go b/src/website/landing.go index 6803e302..b892b565 100644 --- a/src/website/landing.go +++ b/src/website/landing.go @@ -5,6 +5,7 @@ import ( "math" "net/http" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" @@ -39,7 +40,7 @@ func Index(c *RequestContext) ResponseData { var timelineItems []templates.TimelineItem - numPosts, err := CountPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + numPosts, err := hmndata.CountPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ThreadTypes: feedThreadTypes, }) if err != nil { @@ -64,7 +65,7 @@ func Index(c *RequestContext) ResponseData { } // This is essentially an alternate for feed page 1. - posts, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + posts, err := hmndata.FetchPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ ThreadTypes: feedThreadTypes, Limit: feedPostsPerPage, SortDescending: true, @@ -73,7 +74,7 @@ func Index(c *RequestContext) ResponseData { c.Logger.Warn().Err(err).Msg("failed to fetch latest posts") } for _, p := range posts { - item := PostToTimelineItem(UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, p.Author, c.Theme) + item := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, p.Author, c.Theme) if p.Thread.Type == models.ThreadTypeProjectBlogPost && p.Post.ID == p.Thread.FirstID { // blog post item.Description = template.HTML(p.CurrentVersion.TextParsed) @@ -83,7 +84,7 @@ func Index(c *RequestContext) ResponseData { } c.Perf.StartBlock("SQL", "Get news") - newsThreads, err := FetchThreads(c.Context(), c.Conn, c.CurrentUser, ThreadsQuery{ + newsThreads, err := hmndata.FetchThreads(c.Context(), c.Conn, c.CurrentUser, hmndata.ThreadsQuery{ ProjectIDs: []int{models.HMNProjectID}, ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost}, Limit: 1, @@ -94,7 +95,7 @@ func Index(c *RequestContext) ResponseData { var newsPostItem *templates.TimelineItem if len(newsThreads) > 0 { t := newsThreads[0] - item := PostToTimelineItem(UrlContextForProject(&t.Project), lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor, c.Theme) + item := PostToTimelineItem(hmndata.UrlContextForProject(&t.Project), lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor, c.Theme) item.OwnerAvatarUrl = "" item.Breadcrumbs = nil item.TypeTitle = "" @@ -105,7 +106,7 @@ func Index(c *RequestContext) ResponseData { } c.Perf.EndBlock() - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{ + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{ Limit: 40, }) if err != nil { diff --git a/src/website/post_helper.go b/src/website/post_helper.go index 538b653e..33931ec0 100644 --- a/src/website/post_helper.go +++ b/src/website/post_helper.go @@ -1,6 +1,7 @@ package website import ( + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/templates" @@ -88,7 +89,7 @@ func MakePostListItem( ) templates.PostListItem { var result templates.PostListItem - urlContext := UrlContextForProject(project) + urlContext := hmndata.UrlContextForProject(project) result.Title = thread.Title result.User = templates.UserToTemplate(user, currentTheme) diff --git a/src/website/projects.go b/src/website/projects.go index 3e6be23c..f8395e6a 100644 --- a/src/website/projects.go +++ b/src/website/projects.go @@ -15,6 +15,7 @@ import ( "git.handmade.network/hmn/hmn/src/assets" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" @@ -42,8 +43,8 @@ func ProjectIndex(c *RequestContext) ResponseData { const maxCarouselProjects = 10 const maxPersonalProjects = 10 - officialProjects, err := FetchProjects(c.Context(), c.Conn, c.CurrentUser, ProjectsQuery{ - Types: OfficialProjects, + officialProjects, err := hmndata.FetchProjects(c.Context(), c.Conn, c.CurrentUser, hmndata.ProjectsQuery{ + Types: hmndata.OfficialProjects, }) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch projects")) @@ -72,7 +73,7 @@ func ProjectIndex(c *RequestContext) ResponseData { var restProjects []templates.Project now := time.Now() for _, p := range officialProjects { - templateProject := templates.ProjectToTemplate(&p.Project, UrlContextForProject(&p.Project).BuildHomepage()) + templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage()) templateProject.AddLogo(p.LogoURL(c.Theme)) if p.Project.Slug == "hero" { @@ -118,8 +119,8 @@ func ProjectIndex(c *RequestContext) ResponseData { // Fetch and highlight a random selection of personal projects var personalProjects []templates.Project { - projects, err := FetchProjects(c.Context(), c.Conn, c.CurrentUser, ProjectsQuery{ - Types: PersonalProjects, + projects, err := hmndata.FetchProjects(c.Context(), c.Conn, c.CurrentUser, hmndata.ProjectsQuery{ + Types: hmndata.PersonalProjects, }) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch personal projects")) @@ -135,7 +136,7 @@ func ProjectIndex(c *RequestContext) ResponseData { if i >= maxPersonalProjects { break } - templateProject := templates.ProjectToTemplate(&p.Project, UrlContextForProject(&p.Project).BuildHomepage()) + templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage()) templateProject.AddLogo(p.LogoURL(c.Theme)) personalProjects = append(personalProjects, templateProject) } @@ -177,7 +178,7 @@ func ProjectHomepage(c *RequestContext) ResponseData { // There are no further permission checks to do, because permissions are // checked whatever way we fetch the project. - owners, err := FetchProjectOwners(c.Context(), c.Conn, c.CurrentProject.ID) + owners, err := hmndata.FetchProjectOwners(c.Context(), c.Conn, c.CurrentProject.ID) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, err) } @@ -261,7 +262,7 @@ func ProjectHomepage(c *RequestContext) ResponseData { Value: c.CurrentProject.Blurb, }) - p, err := FetchProject(c.Context(), c.Conn, c.CurrentUser, c.CurrentProject.ID, ProjectsQuery{}) + p, err := hmndata.FetchProject(c.Context(), c.Conn, c.CurrentUser, c.CurrentProject.ID, hmndata.ProjectsQuery{}) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project details")) } @@ -340,7 +341,7 @@ func ProjectHomepage(c *RequestContext) ResponseData { tagId = *c.CurrentProject.TagID } - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{ + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{ Tags: []int{tagId}, }) if err != nil { @@ -459,14 +460,14 @@ func ProjectEdit(c *RequestContext) ResponseData { return FourOhFour(c) } - p, err := FetchProject( + p, err := hmndata.FetchProject( c.Context(), c.Conn, c.CurrentUser, c.CurrentProject.ID, - ProjectsQuery{ + hmndata.ProjectsQuery{ IncludeHidden: true, }, ) - owners, err := FetchProjectOwners(c.Context(), c.Conn, p.Project.ID) + owners, err := hmndata.FetchProjectOwners(c.Context(), c.Conn, p.Project.ID) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch project owners")) } @@ -709,7 +710,7 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P return oops.New(err, "Failed to update project") } - SetProjectTag(ctx, tx, payload.ProjectID, payload.Tag) + hmndata.SetProjectTag(ctx, tx, payload.ProjectID, payload.Tag) if user.IsStaff { _, err = tx.Exec(ctx, @@ -855,3 +856,22 @@ func GetFormImage(c *RequestContext, fieldName string) (FormImage, error) { return res, nil } + +func CanEditProject(c *RequestContext, user *models.User, projectId int) (bool, error) { + if user != nil { + if user.IsStaff { + return true, nil + } else { + owners, err := hmndata.FetchProjectOwners(c.Context(), c.Conn, projectId) + if err != nil { + return false, err + } + for _, owner := range owners { + if owner.ID == user.ID { + return true, nil + } + } + } + } + return false, nil +} diff --git a/src/website/routes.go b/src/website/routes.go index 609c77a2..16da39b5 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -17,6 +17,7 @@ import ( "git.handmade.network/hmn/hmn/src/config" "git.handmade.network/hmn/hmn/src/db" "git.handmade.network/hmn/hmn/src/email" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/logging" "git.handmade.network/hmn/hmn/src/models" @@ -299,7 +300,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool) ht if err != nil { panic(oops.New(err, "project id was not numeric (bad regex in routing)")) } - p, err := FetchProject(c.Context(), c.Conn, c.CurrentUser, id, ProjectsQuery{}) + p, err := hmndata.FetchProject(c.Context(), c.Conn, c.CurrentUser, id, hmndata.ProjectsQuery{}) if err != nil { if errors.Is(err, db.NotFound) { return FourOhFour(c) @@ -309,7 +310,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool) ht } c.CurrentProject = &p.Project - c.UrlContext = UrlContextForProject(c.CurrentProject) + c.UrlContext = hmndata.UrlContextForProject(c.CurrentProject) if !p.Project.Personal { return c.Redirect(c.UrlContext.RewriteProjectUrl(c.URL()), http.StatusSeeOther) @@ -463,7 +464,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) { var owners []*models.User if len(slug) > 0 { - dbProject, err := FetchProjectBySlug(c.Context(), c.Conn, c.CurrentUser, slug, ProjectsQuery{}) + dbProject, err := hmndata.FetchProjectBySlug(c.Context(), c.Conn, c.CurrentUser, slug, hmndata.ProjectsQuery{}) if err == nil { c.CurrentProject = &dbProject.Project owners = dbProject.Owners @@ -477,7 +478,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) { } if c.CurrentProject == nil { - dbProject, err := FetchProject(c.Context(), c.Conn, c.CurrentUser, models.HMNProjectID, ProjectsQuery{ + dbProject, err := hmndata.FetchProject(c.Context(), c.Conn, c.CurrentUser, models.HMNProjectID, hmndata.ProjectsQuery{ IncludeHidden: true, }) if err != nil { @@ -505,7 +506,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) { } c.CurrentUserCanEditCurrentProject = canEditProject - c.UrlContext = UrlContextForProject(c.CurrentProject) + c.UrlContext = hmndata.UrlContextForProject(c.CurrentProject) } c.Theme = "light" @@ -560,11 +561,9 @@ func getCurrentUserAndSession(c *RequestContext, sessionId string) (*models.User return user, session, nil } -const PerfContextKey = "HMNPerf" - func TrackRequestPerf(c *RequestContext) (after func()) { c.Perf = perf.MakeNewRequestPerf(c.Route, c.Req.Method, c.Req.URL.Path) - c.ctx = context.WithValue(c.Context(), PerfContextKey, c.Perf) + c.ctx = context.WithValue(c.Context(), perf.PerfContextKey, c.Perf) return func() { c.Perf.EndRequest() @@ -582,14 +581,6 @@ func TrackRequestPerf(c *RequestContext) (after func()) { } } -func ExtractPerf(ctx context.Context) *perf.RequestPerf { - iperf := ctx.Value(PerfContextKey) - if iperf == nil { - return nil - } - return iperf.(*perf.RequestPerf) -} - func LogContextErrors(c *RequestContext, errs ...error) { for _, err := range errs { c.Logger.Error().Timestamp().Stack().Str("Requested", c.FullUrl()).Err(err).Msg("error occurred during request") diff --git a/src/website/showcase.go b/src/website/showcase.go index 18d5eceb..fe3eff08 100644 --- a/src/website/showcase.go +++ b/src/website/showcase.go @@ -3,6 +3,7 @@ package website import ( "net/http" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/oops" "git.handmade.network/hmn/hmn/src/templates" @@ -15,7 +16,7 @@ type ShowcaseData struct { } func Showcase(c *RequestContext) ResponseData { - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{}) + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{}) if err != nil { return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets")) } diff --git a/src/website/snippet.go b/src/website/snippet.go index bdeca517..d3c4fde7 100644 --- a/src/website/snippet.go +++ b/src/website/snippet.go @@ -7,6 +7,7 @@ import ( "strconv" "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/oops" "git.handmade.network/hmn/hmn/src/templates" ) @@ -29,7 +30,7 @@ func Snippet(c *RequestContext) ResponseData { return FourOhFour(c) } - s, err := FetchSnippet(c.Context(), c.Conn, c.CurrentUser, snippetId, SnippetQuery{}) + s, err := hmndata.FetchSnippet(c.Context(), c.Conn, c.CurrentUser, snippetId, hmndata.SnippetQuery{}) if err != nil { if errors.Is(err, db.NotFound) { return FourOhFour(c) diff --git a/src/website/user.go b/src/website/user.go index 29c435bf..16038c32 100644 --- a/src/website/user.go +++ b/src/website/user.go @@ -13,6 +13,7 @@ import ( "git.handmade.network/hmn/hmn/src/db" "git.handmade.network/hmn/hmn/src/discord" hmnemail "git.handmade.network/hmn/hmn/src/email" + "git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" @@ -99,29 +100,29 @@ func UserProfile(c *RequestContext) ResponseData { } c.Perf.EndBlock() - projectsQuery := ProjectsQuery{ + projectsQuery := hmndata.ProjectsQuery{ OwnerIDs: []int{profileUser.ID}, Lifecycles: models.VisibleProjectLifecycles, OrderBy: "all_last_updated DESC", } - projectsAndStuff, err := FetchProjects(c.Context(), c.Conn, c.CurrentUser, projectsQuery) + projectsAndStuff, err := hmndata.FetchProjects(c.Context(), c.Conn, c.CurrentUser, projectsQuery) templateProjects := make([]templates.Project, 0, len(projectsAndStuff)) for _, p := range projectsAndStuff { - templateProject := templates.ProjectToTemplate(&p.Project, UrlContextForProject(&p.Project).BuildHomepage()) + templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage()) templateProject.AddLogo(p.LogoURL(c.Theme)) templateProjects = append(templateProjects, templateProject) } c.Perf.EndBlock() c.Perf.StartBlock("SQL", "Fetch posts") - posts, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{ + posts, err := hmndata.FetchPosts(c.Context(), c.Conn, c.CurrentUser, hmndata.PostsQuery{ UserIDs: []int{profileUser.ID}, SortDescending: true, }) c.Perf.EndBlock() - snippets, err := FetchSnippets(c.Context(), c.Conn, c.CurrentUser, SnippetQuery{ + snippets, err := hmndata.FetchSnippets(c.Context(), c.Conn, c.CurrentUser, hmndata.SnippetQuery{ OwnerIDs: []int{profileUser.ID}, }) if err != nil { @@ -138,7 +139,7 @@ func UserProfile(c *RequestContext) ResponseData { for _, post := range posts { timelineItems = append(timelineItems, PostToTimelineItem( - UrlContextForProject(&post.Project), + hmndata.UrlContextForProject(&post.Project), lineageBuilder, &post.Post, &post.Thread,