Move data-fetching helpers to a separate package
This commit is contained in:
parent
73824a027b
commit
37fcbb205c
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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},
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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!
|
||||
})
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue