Move data-fetching helpers to a separate package

This commit is contained in:
Ben Visness 2021-12-08 20:04:15 -06:00
parent 73824a027b
commit 37fcbb205c
18 changed files with 153 additions and 140 deletions

View File

@ -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)
}

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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)
}

View File

@ -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 {

View File

@ -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},
})

View File

@ -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,

View File

@ -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!
})

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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
}

View File

@ -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")

View File

@ -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"))
}

View File

@ -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)

View File

@ -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,