Convert the feed to use the new thread and post functions.
This commit is contained in:
parent
9c7acd7dbb
commit
89e58c9a24
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -30,40 +29,19 @@ type FeedData struct {
|
||||||
func Feed(c *RequestContext) ResponseData {
|
func Feed(c *RequestContext) ResponseData {
|
||||||
const postsPerPage = 30
|
const postsPerPage = 30
|
||||||
|
|
||||||
c.Perf.StartBlock("SQL", "Count posts")
|
numPosts, err := CountPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{
|
||||||
numPosts, err := db.QueryInt(c.Context(), c.Conn,
|
ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
|
||||||
`
|
})
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM
|
|
||||||
handmade_post AS post
|
|
||||||
WHERE
|
|
||||||
post.thread_type = ANY ($1)
|
|
||||||
AND deleted = FALSE
|
|
||||||
AND post.thread_id IS NOT NULL
|
|
||||||
`,
|
|
||||||
[]models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
|
|
||||||
)
|
|
||||||
c.Perf.EndBlock()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get count of feed posts"))
|
return c.ErrorResponse(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
numPages := int(math.Ceil(float64(numPosts) / postsPerPage))
|
numPages := int(math.Ceil(float64(numPosts) / postsPerPage))
|
||||||
|
|
||||||
page := 1
|
page, numPages, ok := getPageInfo(c.PathParams["page"], numPosts, postsPerPage)
|
||||||
pageString, hasPage := c.PathParams["page"]
|
if !ok {
|
||||||
if hasPage && pageString != "" {
|
return c.Redirect(hmnurl.BuildFeed(), http.StatusSeeOther)
|
||||||
if pageParsed, err := strconv.Atoi(pageString); err == nil {
|
|
||||||
page = pageParsed
|
|
||||||
} else {
|
|
||||||
return c.Redirect(hmnurl.BuildFeed(), http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if page < 1 || numPages < page {
|
|
||||||
return c.Redirect(hmnurl.BuildFeedWithPage(utils.IntClamp(1, page, numPages)), http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
|
|
||||||
howManyPostsToSkip := (page - 1) * postsPerPage
|
|
||||||
|
|
||||||
pagination := templates.Pagination{
|
pagination := templates.Pagination{
|
||||||
Current: page,
|
Current: page,
|
||||||
|
@ -75,17 +53,7 @@ func Feed(c *RequestContext) ResponseData {
|
||||||
PreviousUrl: hmnurl.BuildFeedWithPage(utils.IntClamp(1, page-1, numPages)),
|
PreviousUrl: hmnurl.BuildFeedWithPage(utils.IntClamp(1, page-1, numPages)),
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentUserId *int
|
posts, err := fetchAllPosts(c, (page-1)*postsPerPage, postsPerPage)
|
||||||
if c.CurrentUser != nil {
|
|
||||||
currentUserId = &c.CurrentUser.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
|
||||||
subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
|
|
||||||
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
|
||||||
c.Perf.EndBlock()
|
|
||||||
|
|
||||||
posts, err := fetchAllPosts(c, lineageBuilder, currentUserId, howManyPostsToSkip, postsPerPage)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
|
||||||
}
|
}
|
||||||
|
@ -158,12 +126,7 @@ func AtomFeed(c *RequestContext) ResponseData {
|
||||||
feedData.AtomFeedUrl = hmnurl.BuildAtomFeed()
|
feedData.AtomFeedUrl = hmnurl.BuildAtomFeed()
|
||||||
feedData.FeedUrl = hmnurl.BuildFeed()
|
feedData.FeedUrl = hmnurl.BuildFeed()
|
||||||
|
|
||||||
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
posts, err := fetchAllPosts(c, 0, itemsPerFeed)
|
||||||
subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
|
|
||||||
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
|
||||||
c.Perf.EndBlock()
|
|
||||||
|
|
||||||
posts, err := fetchAllPosts(c, lineageBuilder, nil, 0, itemsPerFeed)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
|
||||||
}
|
}
|
||||||
|
@ -306,78 +269,37 @@ func AtomFeed(c *RequestContext) ResponseData {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchAllPosts(c *RequestContext, lineageBuilder *models.SubforumLineageBuilder, currentUserID *int, offset int, limit int) ([]templates.PostListItem, error) {
|
func fetchAllPosts(c *RequestContext, offset int, limit int) ([]templates.PostListItem, error) {
|
||||||
c.Perf.StartBlock("SQL", "Fetch posts")
|
postsAndStuff, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{
|
||||||
type feedPostQuery struct {
|
ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
|
||||||
Post models.Post `db:"post"`
|
Limit: limit,
|
||||||
PostVersion models.PostVersion `db:"version"`
|
Offset: offset,
|
||||||
Thread models.Thread `db:"thread"`
|
SortDescending: true,
|
||||||
Proj models.Project `db:"proj"`
|
})
|
||||||
User models.User `db:"auth_user"`
|
|
||||||
ThreadLastReadTime *time.Time `db:"tlri.lastread"`
|
|
||||||
SubforumLastReadTime *time.Time `db:"slri.lastread"`
|
|
||||||
}
|
|
||||||
posts, err := db.Query(c.Context(), c.Conn, feedPostQuery{},
|
|
||||||
`
|
|
||||||
SELECT $columns
|
|
||||||
FROM
|
|
||||||
handmade_post AS post
|
|
||||||
JOIN handmade_postversion AS version ON version.id = post.current_id
|
|
||||||
JOIN handmade_thread AS thread ON thread.id = post.thread_id
|
|
||||||
JOIN handmade_project AS proj ON proj.id = post.project_id
|
|
||||||
LEFT JOIN handmade_threadlastreadinfo AS tlri ON (
|
|
||||||
tlri.thread_id = post.thread_id
|
|
||||||
AND tlri.user_id = $1
|
|
||||||
)
|
|
||||||
LEFT JOIN handmade_subforumlastreadinfo AS slri ON (
|
|
||||||
slri.subforum_id = thread.subforum_id
|
|
||||||
AND slri.user_id = $1
|
|
||||||
)
|
|
||||||
LEFT JOIN auth_user ON post.author_id = auth_user.id
|
|
||||||
WHERE
|
|
||||||
thread.type = ANY ($2)
|
|
||||||
AND post.deleted = FALSE
|
|
||||||
AND post.thread_id IS NOT NULL
|
|
||||||
ORDER BY postdate DESC
|
|
||||||
LIMIT $3 OFFSET $4
|
|
||||||
`,
|
|
||||||
currentUserID,
|
|
||||||
[]models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
)
|
|
||||||
c.Perf.EndBlock()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
||||||
|
subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
|
||||||
|
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
||||||
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
c.Perf.StartBlock("FEED", "Build post items")
|
c.Perf.StartBlock("FEED", "Build post items")
|
||||||
var postItems []templates.PostListItem
|
var postItems []templates.PostListItem
|
||||||
for _, iPostResult := range posts.ToSlice() {
|
for _, postAndStuff := range postsAndStuff {
|
||||||
postResult := iPostResult.(*feedPostQuery)
|
|
||||||
|
|
||||||
hasRead := false
|
|
||||||
if c.CurrentUser != nil && c.CurrentUser.MarkedAllReadAt.After(postResult.Post.PostDate) {
|
|
||||||
hasRead = true
|
|
||||||
} else if postResult.ThreadLastReadTime != nil && postResult.ThreadLastReadTime.After(postResult.Post.PostDate) {
|
|
||||||
hasRead = true
|
|
||||||
} else if postResult.SubforumLastReadTime != nil && postResult.SubforumLastReadTime.After(postResult.Post.PostDate) {
|
|
||||||
hasRead = true
|
|
||||||
}
|
|
||||||
|
|
||||||
postItem := MakePostListItem(
|
postItem := MakePostListItem(
|
||||||
lineageBuilder,
|
lineageBuilder,
|
||||||
&postResult.Proj,
|
&postAndStuff.Project,
|
||||||
&postResult.Thread,
|
&postAndStuff.Thread,
|
||||||
&postResult.Post,
|
&postAndStuff.Post,
|
||||||
&postResult.User,
|
postAndStuff.Author,
|
||||||
!hasRead,
|
postAndStuff.ThreadUnread,
|
||||||
true,
|
true,
|
||||||
c.Theme,
|
c.Theme,
|
||||||
)
|
)
|
||||||
|
|
||||||
postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
|
postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
|
||||||
postItem.LastEditDate = postResult.PostVersion.Date
|
postItem.LastEditDate = postAndStuff.CurrentVersion.Date
|
||||||
|
|
||||||
postItems = append(postItems, postItem)
|
postItems = append(postItems, postItem)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue