Implement paging for person collections

This commit is contained in:
Anthony Wang 2023-02-01 21:24:46 +00:00
parent d8c1f87b32
commit 8f42f98d9f
No known key found for this signature in database
GPG Key ID: 42A5B952E6DD8D38
2 changed files with 45 additions and 63 deletions

View File

@ -12,7 +12,6 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/forgefed"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/activitypub"
@ -188,45 +187,17 @@ func PersonFollowing(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/ActivityPub"
iri := ctx.ContextUser.GetIRI()
// TODO: pagination is really broken
// https://codeberg.org/forgejo/forgejo/commit/90afd4f3294c1f33d9b5afe5c6f082e2831026cb
users, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, utils.GetListOptions(ctx))
listOptions := utils.GetListOptions(ctx)
users, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, listOptions)
if err != nil {
ctx.ServerError("GetUserFollowing", err)
return
}
page := ctx.FormInt("page")
followingCollection := ap.OrderedCollectionNew(ap.IRI(iri + "/following"))
followingCollection.First = ap.IRI(iri + "/following?page=1")
followingCollection.TotalItems = uint(count)
if page == 0 {
response(ctx, followingCollection)
return
}
followingPage := ap.OrderedCollectionPageNew(followingCollection)
followingPage.ID = ap.IRI(fmt.Sprintf("%s/following?page=%d", iri, page))
if page > 1 {
followingPage.Prev = ap.IRI(fmt.Sprintf("%s/following?page=%d", iri, page-1))
}
if len(users)*page < int(count) {
followingPage.Next = ap.IRI(fmt.Sprintf("%s/following?page=%d", iri, page+1))
}
items := make([]string, 0)
for _, user := range users {
err := followingPage.OrderedItems.Append(ap.IRI(user.GetIRI()))
if err != nil {
ctx.ServerError("OrderedItems.Append", err)
return
}
items = append(items, user.GetIRI())
}
response(ctx, followingPage)
responseCollection(ctx, ctx.ContextUser.GetIRI()+"/following", listOptions, items, count)
}
// PersonFollowers function returns the user's Followers Collection
@ -246,27 +217,17 @@ func PersonFollowers(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/ActivityPub"
iri := ctx.ContextUser.GetIRI()
users, _, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, utils.GetListOptions(ctx))
listOptions := utils.GetListOptions(ctx)
users, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, listOptions)
if err != nil {
ctx.ServerError("GetUserFollowers", err)
return
}
followers := ap.OrderedCollectionNew(ap.IRI(iri + "/followers"))
followers.TotalItems = uint(len(users))
items := make([]string, 0)
for _, user := range users {
person := ap.PersonNew(ap.IRI(user.GetIRI()))
err := followers.OrderedItems.Append(person)
if err != nil {
ctx.ServerError("OrderedItems.Append", err)
return
}
items = append(items, user.GetIRI())
}
response(ctx, followers)
responseCollection(ctx, ctx.ContextUser.GetIRI()+"/followers", listOptions, items, count)
}
// PersonLiked function returns the user's Liked Collection
@ -286,9 +247,9 @@ func PersonLiked(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/ActivityPub"
iri := ctx.ContextUser.GetIRI()
listOptions := utils.GetListOptions(ctx)
repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: listOptions,
Actor: ctx.Doer,
Private: ctx.IsSigned,
StarredByID: ctx.ContextUser.ID,
@ -297,18 +258,9 @@ func PersonLiked(ctx *context.APIContext) {
ctx.ServerError("GetUserStarred", err)
return
}
liked := ap.OrderedCollectionNew(ap.IRI(iri + "/liked"))
liked.TotalItems = uint(count)
items := make([]string, 0)
for _, repo := range repos {
repo := forgefed.RepositoryNew(ap.IRI(repo.GetIRI()))
err := liked.OrderedItems.Append(repo)
if err != nil {
ctx.ServerError("OrderedItems.Append", err)
return
}
items = append(items, repo.GetIRI())
}
response(ctx, liked)
responseCollection(ctx, ctx.ContextUser.GetIRI()+"/liked", listOptions, items, count)
}

View File

@ -4,8 +4,10 @@
package activitypub
import (
"fmt"
"net/http"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/forgefed"
"code.gitea.io/gitea/modules/log"
@ -15,6 +17,34 @@ import (
"github.com/go-ap/jsonld"
)
// Respond with a ActivityStreams Collection
func responseCollection(ctx *context.APIContext, iri string, listOptions db.ListOptions, items []string, count int64) {
collection := ap.OrderedCollectionNew(ap.IRI(iri))
collection.First = ap.IRI(iri + "?page=1")
collection.TotalItems = uint(count)
if listOptions.Page == 0 {
response(ctx, collection)
return
}
page := ap.OrderedCollectionPageNew(collection)
page.ID = ap.IRI(fmt.Sprintf("%s?page=%d", iri, listOptions.Page))
if listOptions.Page > 1 {
page.Prev = ap.IRI(fmt.Sprintf("%s?page=%d", iri, listOptions.Page-1))
}
if listOptions.Page*listOptions.PageSize < int(count) {
page.Next = ap.IRI(fmt.Sprintf("%s?page=%d", iri, listOptions.Page+1))
}
for _, item := range items {
err := page.OrderedItems.Append(ap.IRI(item))
if err != nil {
ctx.ServerError("Append", err)
}
}
response(ctx, page)
}
// Respond with an ActivityStreams object
func response(ctx *context.APIContext, v interface{}) {
binary, err := jsonld.WithContext(