this repo has no description
1package mostliked
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
7 "log"
8 "strconv"
9 "strings"
10
11 appbsky "github.com/bluesky-social/indigo/api/bsky"
12 "github.com/edavis/bsky-feeds/pkg/feeds"
13 _ "github.com/mattn/go-sqlite3"
14)
15
16type PostRow struct {
17 Uri string
18}
19
20func getPosts(ctx context.Context, dbCnx *sql.DB, langs []string, limit, offset int) ([]PostRow, error) {
21 var queryParams []any
22 var query strings.Builder
23 fmt.Fprint(&query, "SELECT posts.uri FROM posts LEFT JOIN langs ON posts.uri = langs.uri")
24 if len(langs) > 0 {
25 fmt.Fprint(&query, " WHERE lang IN (")
26 for idx, lang := range langs {
27 if idx > 0 {
28 fmt.Fprint(&query, ",")
29 }
30 fmt.Fprint(&query, "?")
31 queryParams = append(queryParams, lang)
32 }
33 fmt.Fprint(&query, ")")
34 }
35 fmt.Fprint(&query, " ORDER BY likes DESC, create_ts DESC LIMIT ? OFFSET ?")
36 queryParams = append(queryParams, limit, offset)
37
38 fmt.Printf("query: %v %+v\n", query.String(), queryParams)
39
40 rows, err := dbCnx.QueryContext(ctx, query.String(), queryParams...)
41 if err != nil {
42 return nil, err
43 }
44 defer rows.Close()
45
46 var posts []PostRow
47 for rows.Next() {
48 var post PostRow
49 if err := rows.Scan(&post.Uri); err != nil {
50 return nil, err
51 }
52 posts = append(posts, post)
53 }
54
55 return posts, nil
56}
57
58func Feed(params feeds.FeedgenParams) appbsky.FeedGetFeedSkeleton_Output {
59 ctx := context.Background()
60 dbCnx, err := sql.Open("sqlite3", "data/mostliked.db?_journal=WAL&_fk=on")
61 if err != nil {
62 log.Printf("error opening db: %v\n", err)
63 }
64 defer dbCnx.Close()
65
66 var langs []string
67 for _, lang := range params.Langs {
68 langs = append(langs, lang.String())
69 }
70
71 offset := 0
72 if params.Cursor != "" {
73 if parsed, err := strconv.Atoi(params.Cursor); err == nil {
74 offset = parsed
75 } else {
76 log.Printf("error converting cursor: %v\n", err)
77 }
78 }
79
80 rows, err := getPosts(ctx, dbCnx, langs, params.Limit-1, offset)
81 if err != nil {
82 log.Printf("error fetching rows: %v\n", err)
83 }
84
85 var cursor string
86 posts := make([]*appbsky.FeedDefs_SkeletonFeedPost, 0, params.Limit)
87
88 posts = append(posts, &appbsky.FeedDefs_SkeletonFeedPost{
89 Post: "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.post/3ltbfk5yfbs2n",
90 Reason: &appbsky.FeedDefs_SkeletonFeedPost_Reason{
91 FeedDefs_SkeletonReasonPin: &appbsky.FeedDefs_SkeletonReasonPin{},
92 },
93 })
94
95 for _, row := range rows {
96 posts = append(posts, &appbsky.FeedDefs_SkeletonFeedPost{Post: row.Uri})
97 }
98
99 skeleton := appbsky.FeedGetFeedSkeleton_Output{
100 Feed: posts,
101 }
102
103 offset += len(posts)
104 cursor = strconv.Itoa(offset)
105
106 if len(posts) == params.Limit {
107 skeleton.Cursor = &cursor
108 }
109
110 return skeleton
111}