this repo has no description
1package main
2
3import (
4 "database/sql"
5 "golang.org/x/text/language"
6 "math"
7 "net/http"
8 "strconv"
9
10 appbsky "github.com/bluesky-social/indigo/api/bsky"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12 "github.com/edavis/bsky-feeds/pkg/feeds"
13 "github.com/edavis/bsky-feeds/pkg/mostliked"
14 "github.com/edavis/bsky-feeds/pkg/popular"
15 "github.com/edavis/bsky-feeds/pkg/videostream"
16 "github.com/labstack/echo/v4"
17 "github.com/labstack/echo/v4/middleware"
18 sqlite "github.com/mattn/go-sqlite3"
19)
20
21type SkeletonRequest struct {
22 Feed string `query:"feed"`
23 Limit string `query:"limit"`
24 Cursor string `query:"cursor"`
25}
26
27type FeedLookup map[string]func(feeds.FeedgenParams) appbsky.FeedGetFeedSkeleton_Output
28
29func parseLangs(userPrefs string) []language.Tag {
30 t, _, _ := language.ParseAcceptLanguage(userPrefs)
31 return t
32}
33
34var generators = FeedLookup{
35 "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.generator/most-liked": mostliked.Feed,
36 "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.generator/most-liked-dev": mostliked.Feed,
37
38 "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.generator/popular": popular.Feed,
39 "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.generator/popular-dev": popular.Feed,
40
41 "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.generator/videostream": videostream.Feed,
42}
43
44func getFeedSkeleton(c echo.Context) error {
45 var req SkeletonRequest
46 if err := c.Bind(&req); err != nil {
47 return c.String(http.StatusBadRequest, "bad request")
48 }
49
50 var limit int = 30
51 if req.Limit != "" {
52 if l, err := strconv.Atoi(req.Limit); err == nil {
53 limit = l
54 }
55 }
56
57 params := feeds.FeedgenParams{
58 Feed: req.Feed,
59 Limit: limit,
60 Cursor: req.Cursor,
61 Langs: parseLangs(c.Request().Header.Get("Accept-Language")),
62 }
63
64 feedFunc, ok := generators[req.Feed]
65 if !ok {
66 return c.String(http.StatusNotFound, "feed not found")
67 }
68 feed := feedFunc(params)
69 return c.JSON(http.StatusOK, feed)
70}
71
72func describeFeedGenerator(c echo.Context) error {
73 type feed struct {
74 URI syntax.ATURI `json:"uri"`
75 }
76
77 type gen struct {
78 DID string `json:"did"`
79 Feeds []feed `json:"feeds"`
80 }
81
82 out := gen{
83 DID: `https://` + NgrokHostname,
84 }
85
86 for feedUri, _ := range generators {
87 aturi, err := syntax.ParseATURI(feedUri)
88 if err != nil {
89 continue
90 }
91 out.Feeds = append(out.Feeds, feed{URI: aturi})
92 }
93
94 return c.JSON(http.StatusOK, out)
95}
96
97func main() {
98 sql.Register("sqlite3_custom", &sqlite.SQLiteDriver{
99 ConnectHook: func(conn *sqlite.SQLiteConn) error {
100 if err := conn.RegisterFunc("exp", math.Exp, true); err != nil {
101 return err
102 }
103 return nil
104 },
105 })
106
107 e := echo.New()
108 e.Use(middleware.Logger())
109 e.Use(middleware.Recover())
110 e.GET("/.well-known/did.json", didDoc)
111 e.GET("/xrpc/app.bsky.feed.getFeedSkeleton", getFeedSkeleton)
112 e.GET("/xrpc/app.bsky.feed.describeFeedGenerator", describeFeedGenerator)
113 e.Logger.Fatal(e.Start(":5000"))
114}