mirror of
https://github.com/aykhans/bsky-feedgen.git
synced 2025-05-31 02:50:03 +00:00
102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/aykhans/bsky-feedgen/pkg/api/middleware"
|
|
"github.com/aykhans/bsky-feedgen/pkg/api/response"
|
|
"github.com/aykhans/bsky-feedgen/pkg/feed"
|
|
"github.com/aykhans/bsky-feedgen/pkg/types"
|
|
"github.com/aykhans/bsky-feedgen/pkg/utils"
|
|
"github.com/bluesky-social/indigo/api/bsky"
|
|
"github.com/whyrusleeping/go-did"
|
|
)
|
|
|
|
type FeedHandler struct {
|
|
feedsOutput []*bsky.FeedDescribeFeedGenerator_Feed
|
|
feedsMap map[string]feed.Feed
|
|
publisherDID *did.DID
|
|
}
|
|
|
|
func NewFeedHandler(feeds []feed.Feed, publisherDID *did.DID) *FeedHandler {
|
|
ctx := context.Background()
|
|
|
|
feedsMap := make(map[string]feed.Feed)
|
|
for _, feed := range feeds {
|
|
feedsMap[feed.GetName(ctx)] = feed
|
|
}
|
|
|
|
feedsOutput := make([]*bsky.FeedDescribeFeedGenerator_Feed, len(feeds))
|
|
for i, f := range feeds {
|
|
feedsOutput[i] = utils.ToPtr(f.Describe(ctx))
|
|
}
|
|
|
|
return &FeedHandler{
|
|
feedsOutput: feedsOutput,
|
|
feedsMap: feedsMap,
|
|
publisherDID: publisherDID,
|
|
}
|
|
}
|
|
|
|
func (handler *FeedHandler) DescribeFeeds(w http.ResponseWriter, r *http.Request) {
|
|
response.JSON(w, 200, bsky.FeedDescribeFeedGenerator_Output{
|
|
Did: handler.publisherDID.String(),
|
|
Feeds: handler.feedsOutput,
|
|
})
|
|
}
|
|
|
|
func (handler *FeedHandler) GetFeedSkeleton(w http.ResponseWriter, r *http.Request) {
|
|
userDID, _ := r.Context().Value(middleware.UserDIDKey).(string)
|
|
|
|
feedQuery := r.URL.Query().Get("feed")
|
|
if feedQuery == "" {
|
|
response.JSON(w, 400, response.M{"error": "feed query parameter is required"})
|
|
return
|
|
}
|
|
|
|
feedNameStartingIndex := strings.LastIndex(feedQuery, "/")
|
|
if feedNameStartingIndex == -1 {
|
|
response.JSON(w, 400, response.M{"error": "feed query parameter is invalid"})
|
|
}
|
|
|
|
feedName := feedQuery[feedNameStartingIndex+1:]
|
|
feed := handler.feedsMap[feedName]
|
|
if feed == nil {
|
|
response.JSON(w, 400, response.M{"error": "feed not found"})
|
|
return
|
|
}
|
|
|
|
limitQuery := r.URL.Query().Get("limit")
|
|
var limit int64 = 50
|
|
if limitQuery != "" {
|
|
parsedLimit, err := strconv.ParseInt(limitQuery, 10, 64)
|
|
if err == nil && parsedLimit >= 1 && parsedLimit <= 100 {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
cursor := r.URL.Query().Get("cursor")
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
defer cancel()
|
|
|
|
feedItems, newCursor, err := feed.GetPage(ctx, userDID, limit, cursor)
|
|
if err != nil {
|
|
if err == types.ErrInternal {
|
|
response.JSON500(w)
|
|
return
|
|
}
|
|
response.JSON(w, 400, response.M{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
response.JSON(w, 200, bsky.FeedGetFeedSkeleton_Output{
|
|
Feed: feedItems,
|
|
Cursor: newCursor,
|
|
})
|
|
}
|