this repo has no description
at master 2.9 kB view raw
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}