this repo has no description

feat: start work on feedweb

Changed files
+208 -8
cmd
feedweb
mostliked
mostliked
pkg
mostliked
+2
.gitignore
···
···
+
bin/
+
db/
+7
Makefile
···
···
+
all: bin/mostliked bin/feedweb
+
+
bin/mostliked: cmd/mostliked/*.go pkg/mostliked/*.go
+
go build -o $@ ./cmd/mostliked
+
+
bin/feedweb: cmd/feedweb/*.go pkg/*/*.go mostliked/*.go
+
go build -o $@ ./cmd/feedweb
+61
cmd/feedweb/feedweb.go
···
···
+
package main
+
+
import (
+
"net/http"
+
+
"github.com/labstack/echo/v4"
+
"github.com/labstack/echo/v4/middleware"
+
"github.com/edavis/bsky-feeds/mostliked"
+
)
+
+
type SkeletonRequest struct {
+
Feed string `query:"feed"`
+
Limit int64 `query:"limit"`
+
Offset string `query:"offset"`
+
}
+
+
type SkeletonResponse struct {
+
Cursor string `json:"cursor,omitempty"`
+
Feed []Post `json:"feed"`
+
}
+
+
type Post struct {
+
Uri string `json:"post"`
+
}
+
+
type SkeletonHeader struct {
+
Langs []string `header:"Accept-Language"`
+
}
+
+
func getFeedSkeleton(c echo.Context) error {
+
var req SkeletonRequest
+
if err := c.Bind(&req); err != nil {
+
return c.String(http.StatusBadRequest, "bad request")
+
}
+
var hdr SkeletonHeader
+
if err := (&echo.DefaultBinder{}).BindHeaders(c, &hdr); err != nil {
+
return c.String(http.StatusBadRequest, "bad request")
+
}
+
+
var posts []Post
+
uris := mostliked.Feed(mostliked.FeedViewParams{
+
Limit: req.Limit,
+
Offset: req.Offset,
+
Langs: hdr.Langs,
+
})
+
for _, uri := range uris {
+
posts = append(posts, Post{uri})
+
}
+
response := SkeletonResponse{
+
Feed: posts,
+
}
+
return c.JSON(http.StatusOK, response)
+
}
+
+
func main() {
+
e := echo.New()
+
e.Use(middleware.Logger())
+
e.Use(middleware.Recover())
+
e.GET("/xrpc/app.bsky.feed.getFeedSkeleton", getFeedSkeleton)
+
e.Logger.Fatal(e.Start(":5000"))
+
}
+8 -8
cmd/mostliked/mostliked.go
···
appbsky "github.com/bluesky-social/indigo/api/bsky"
jetstream "github.com/bluesky-social/jetstream/pkg/models"
-
"github.com/edavis/bsky-feeds/pkg/mostliked"
"github.com/gorilla/websocket"
"github.com/karlseguin/ccache/v3"
_ "github.com/mattn/go-sqlite3"
···
}
}
-
func trimPostsTable(ctx context.Context, queries *mostliked.Queries) {
ticker := time.NewTicker(1 * time.Minute)
defer ticker.Stop()
···
func processEvents(events <-chan []byte) {
ctx := context.Background()
-
db, err := sql.Open("sqlite3", "db/mostliked.db?_journal=WAL&_fk=on")
if err != nil {
log.Fatal("error opening db")
}
-
if _, err := db.ExecContext(ctx, ddl); err != nil {
log.Fatal("couldn't create tables")
}
-
defer db.Close()
-
queries := mostliked.New(db)
drafts := ccache.New(ccache.Configure[DraftPost]().MaxSize(50_000).GetsPerPromote(1))
···
}
drafts.Delete(like.Subject.Uri)
log.Println("storing", like.Subject.Uri, "in database")
-
err := queries.InsertPost(ctx, mostliked.InsertPostParams{
Uri: like.Subject.Uri,
CreateTs: draftPost.Created,
Likes: draftPost.Likes,
···
if err != nil {
log.Println("error inserting post")
}
-
err = queries.InsertLang(ctx, mostliked.InsertLangParams{
Uri: like.Subject.Uri,
Lang: strings.ToLower(draftPost.Language.IsoCode639_1().String()),
})
···
appbsky "github.com/bluesky-social/indigo/api/bsky"
jetstream "github.com/bluesky-social/jetstream/pkg/models"
+
db "github.com/edavis/bsky-feeds/pkg/mostliked"
"github.com/gorilla/websocket"
"github.com/karlseguin/ccache/v3"
_ "github.com/mattn/go-sqlite3"
···
}
}
+
func trimPostsTable(ctx context.Context, queries *db.Queries) {
ticker := time.NewTicker(1 * time.Minute)
defer ticker.Stop()
···
func processEvents(events <-chan []byte) {
ctx := context.Background()
+
dbCnx, err := sql.Open("sqlite3", "db/mostliked.db?_journal=WAL&_fk=on")
if err != nil {
log.Fatal("error opening db")
}
+
if _, err := dbCnx.ExecContext(ctx, ddl); err != nil {
log.Fatal("couldn't create tables")
}
+
defer dbCnx.Close()
+
queries := db.New(dbCnx)
drafts := ccache.New(ccache.Configure[DraftPost]().MaxSize(50_000).GetsPerPromote(1))
···
}
drafts.Delete(like.Subject.Uri)
log.Println("storing", like.Subject.Uri, "in database")
+
err := queries.InsertPost(ctx, db.InsertPostParams{
Uri: like.Subject.Uri,
CreateTs: draftPost.Created,
Likes: draftPost.Likes,
···
if err != nil {
log.Println("error inserting post")
}
+
err = queries.InsertLang(ctx, db.InsertLangParams{
Uri: like.Subject.Uri,
Lang: strings.ToLower(draftPost.Language.IsoCode639_1().String()),
})
+7
cmd/mostliked/query.sql
···
-- name: TrimPosts :exec
delete from posts where create_ts < unixepoch('now', '-24 hours');
···
-- name: TrimPosts :exec
delete from posts where create_ts < unixepoch('now', '-24 hours');
+
+
-- name: ViewFeed :many
+
select posts.uri, create_ts, likes, lang
+
from posts
+
left join langs on posts.uri = langs.uri
+
order by likes desc
+
limit ? offset ?;
+9
go.mod
···
github.com/bluesky-social/jetstream v0.0.0-20240925210745-2cd1b6147279
github.com/gorilla/websocket v1.5.3
github.com/karlseguin/ccache/v3 v3.0.5
github.com/mattn/go-sqlite3 v1.14.22
github.com/pemistahl/lingua-go v1.4.0
)
···
github.com/go-logr/stdr v1.2.2 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
···
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
···
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/whyrusleeping/cbor-gen v0.1.3-0.20240904181319-8dc02b38228c // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
···
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/protobuf v1.34.2 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
···
github.com/bluesky-social/jetstream v0.0.0-20240925210745-2cd1b6147279
github.com/gorilla/websocket v1.5.3
github.com/karlseguin/ccache/v3 v3.0.5
+
github.com/labstack/echo/v4 v4.11.3
github.com/mattn/go-sqlite3 v1.14.22
github.com/pemistahl/lingua-go v1.4.0
)
···
github.com/go-logr/stdr v1.2.2 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
+
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
···
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+
github.com/labstack/gommon v0.4.1 // indirect
+
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
···
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
+
github.com/valyala/bytebufferpool v1.0.0 // indirect
+
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/whyrusleeping/cbor-gen v0.1.3-0.20240904181319-8dc02b38228c // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
···
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
+
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.22.0 // indirect
+
golang.org/x/text v0.16.0 // indirect
+
golang.org/x/time v0.5.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/protobuf v1.34.2 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
+20
go.sum
···
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
···
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
···
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/whyrusleeping/cbor-gen v0.1.3-0.20240904181319-8dc02b38228c h1:UsxJNcLPfyLyVaA4iusIrsLAqJn/xh36Qgb8emqtXzk=
···
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
···
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
···
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
···
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
···
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+
github.com/labstack/echo/v4 v4.11.3 h1:Upyu3olaqSHkCjs1EJJwQ3WId8b8b1hxbogyommKktM=
+
github.com/labstack/echo/v4 v4.11.3/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws=
+
github.com/labstack/gommon v0.4.1 h1:gqEff0p/hTENGMABzezPoPSRtIh1Cvw0ueMOe0/dfOk=
+
github.com/labstack/gommon v0.4.1/go.mod h1:TyTrpPqxR5KMk8LKVtLmfMjeQ5FEkBYdxLYPw/WfrOM=
+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
···
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
+
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/whyrusleeping/cbor-gen v0.1.3-0.20240904181319-8dc02b38228c h1:UsxJNcLPfyLyVaA4iusIrsLAqJn/xh36Qgb8emqtXzk=
···
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
+
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
···
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
···
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+45
mostliked/feed.go
···
···
+
package mostliked
+
+
import (
+
"context"
+
"database/sql"
+
"log"
+
"strconv"
+
+
db "github.com/edavis/bsky-feeds/pkg/mostliked"
+
_ "github.com/mattn/go-sqlite3"
+
)
+
+
type FeedViewParams struct {
+
Limit int64
+
Offset string
+
Langs []string
+
}
+
+
func Feed(args FeedViewParams) []string {
+
ctx := context.Background()
+
dbCnx, err := sql.Open("sqlite3", "db/mostliked.db?_journal=WAL&_fk=on")
+
if err != nil {
+
log.Fatal("error opening db")
+
}
+
defer dbCnx.Close()
+
+
offset, err := strconv.Atoi(args.Offset)
+
if err != nil {
+
log.Println("error converting offset to integer")
+
}
+
+
queries := db.New(dbCnx)
+
rows, err := queries.ViewFeed(ctx, db.ViewFeedParams{
+
Limit: args.Limit,
+
Offset: int64(offset),
+
})
+
if err != nil {
+
log.Println("error fetching rows")
+
}
+
var uris []string
+
for _, row := range rows {
+
uris = append(uris, row.Uri)
+
}
+
return uris
+
}
+49
pkg/mostliked/query.sql.go
···
import (
"context"
)
const insertLang = `-- name: InsertLang :exec
···
_, err := q.db.ExecContext(ctx, updateLikes, uri)
return err
}
···
import (
"context"
+
"database/sql"
)
const insertLang = `-- name: InsertLang :exec
···
_, err := q.db.ExecContext(ctx, updateLikes, uri)
return err
}
+
+
const viewFeed = `-- name: ViewFeed :many
+
select posts.uri, create_ts, likes, lang
+
from posts
+
left join langs on posts.uri = langs.uri
+
order by likes desc
+
limit ? offset ?
+
`
+
+
type ViewFeedParams struct {
+
Limit int64
+
Offset int64
+
}
+
+
type ViewFeedRow struct {
+
Uri string
+
CreateTs int64
+
Likes int64
+
Lang sql.NullString
+
}
+
+
func (q *Queries) ViewFeed(ctx context.Context, arg ViewFeedParams) ([]ViewFeedRow, error) {
+
rows, err := q.db.QueryContext(ctx, viewFeed, arg.Limit, arg.Offset)
+
if err != nil {
+
return nil, err
+
}
+
defer rows.Close()
+
var items []ViewFeedRow
+
for rows.Next() {
+
var i ViewFeedRow
+
if err := rows.Scan(
+
&i.Uri,
+
&i.CreateTs,
+
&i.Likes,
+
&i.Lang,
+
); err != nil {
+
return nil, err
+
}
+
items = append(items, i)
+
}
+
if err := rows.Close(); err != nil {
+
return nil, err
+
}
+
if err := rows.Err(); err != nil {
+
return nil, err
+
}
+
return items, nil
+
}