package videostream import ( "context" "database/sql" "log" "strconv" appbsky "github.com/bluesky-social/indigo/api/bsky" "github.com/edavis/bsky-feeds/pkg/feeds" _ "github.com/mattn/go-sqlite3" ) type PostRow struct { Uri string } func getPosts(ctx context.Context, dbCnx *sql.DB, limit, offset int) ([]PostRow, error) { rows, err := dbCnx.QueryContext(ctx, `select uri from posts where create_ts < unixepoch('now', '-2 minutes') order by create_ts desc limit ? offset ?`, limit, offset) if err != nil { return nil, err } defer rows.Close() var posts []PostRow for rows.Next() { var post PostRow if err := rows.Scan(&post.Uri); err != nil { return nil, err } posts = append(posts, post) } return posts, nil } func Feed(params feeds.FeedgenParams) appbsky.FeedGetFeedSkeleton_Output { ctx := context.Background() dbCnx, err := sql.Open("sqlite3", "data/videostream.db?_journal=WAL&_fk=on") if err != nil { log.Printf("error opening db: %v\n", err) } defer dbCnx.Close() offset := 0 if params.Cursor != "" { if parsed, err := strconv.Atoi(params.Cursor); err == nil { offset = parsed } else { log.Printf("error converting cursor: %v\n", err) } } rows, err := getPosts(ctx, dbCnx, params.Limit, offset) if err != nil { log.Printf("error fetching rows: %v\n", err) } var cursor string posts := make([]*appbsky.FeedDefs_SkeletonFeedPost, 0, params.Limit) for _, row := range rows { posts = append(posts, &appbsky.FeedDefs_SkeletonFeedPost{Post: row.Uri}) } skeleton := appbsky.FeedGetFeedSkeleton_Output{ Feed: posts, } offset += len(posts) cursor = strconv.Itoa(offset) if len(posts) == params.Limit { skeleton.Cursor = &cursor } return skeleton }