an app.bsky.* indexer

rename command, move models, focus on just ActorProfile for now

cmd/backfiller/backfill.go cmd/monarch/backfill.go
cmd/backfiller/census.go cmd/monarch/census.go
cmd/backfiller/cursors.go cmd/monarch/cursors.go
cmd/backfiller/database.go cmd/monarch/database.go
cmd/backfiller/firehose.go cmd/monarch/firehose.go
-58
cmd/backfiller/handlers.go
···
-
package main
-
-
import (
-
"context"
-
"fmt"
-
-
"github.com/bluesky-social/indigo/atproto/syntax"
-
-
"github.com/ipfs/go-cid"
-
"gorm.io/gorm"
-
)
-
-
type HandlerService struct {
-
store *gorm.DB
-
}
-
-
func NewHandlerService(store *gorm.DB) *HandlerService {
-
store.AutoMigrate(&Account{})
-
store.AutoMigrate(&Profile{})
-
store.AutoMigrate(&List{})
-
store.AutoMigrate(&Labeler{})
-
store.AutoMigrate(&FeedGenerator{})
-
store.AutoMigrate(&Post{})
-
store.AutoMigrate(&Like{})
-
store.AutoMigrate(&StarterPack{})
-
store.AutoMigrate(&Verification{})
-
store.AutoMigrate(&Lexicon{})
-
-
return &HandlerService{
-
store: store,
-
}
-
}
-
-
// handles both creates and updates
-
func (hs *HandlerService) HandleUpsert(ctx context.Context, repo string, rev string, path string, rec *[]byte, cid *cid.Cid) error {
-
uri, err := syntax.ParseATURI(fmt.Sprintf("at://%s/%s", repo, path))
-
if err != nil {
-
return err
-
}
-
-
switch uri.Collection() {
-
case syntax.NSID("app.bsky.actor.profile"):
-
profile := NewProfile(*rec)
-
profile.AtUri = string(uri)
-
hs.store.Create(profile)
-
-
case syntax.NSID("app.bsky.feed.generator"):
-
feedgen := NewFeedGenerator(*rec)
-
feedgen.AtUri = string(uri)
-
hs.store.Create(feedgen)
-
}
-
-
return nil
-
}
-
-
func (hs *HandlerService) HandleDelete(ctx context.Context, repo string, rev string, path string) error {
-
return nil
-
}
cmd/backfiller/main.go cmd/monarch/main.go
-80
cmd/backfiller/models.go
···
-
package main
-
-
import (
-
"bytes"
-
"log/slog"
-
-
appbsky "github.com/bluesky-social/indigo/api/bsky"
-
)
-
-
type Account struct{}
-
-
// func NewAccount
-
-
type Profile struct {
-
ID uint `gorm:"primaryKey"`
-
AtUri string
-
DisplayName *string
-
}
-
-
func NewProfile(rec []byte) *Profile {
-
var out appbsky.ActorProfile
-
if err := out.UnmarshalCBOR(bytes.NewReader(rec)); err != nil {
-
slog.Error("could not unmarshal profile CBOR", "err", err)
-
return nil
-
}
-
return &Profile{
-
DisplayName: out.DisplayName,
-
}
-
}
-
-
type List struct{}
-
-
// func NewList
-
-
type Labeler struct{}
-
-
// func NewFeedGenerator
-
-
type FeedGenerator struct {
-
ID uint `gorm:"primaryKey"`
-
AtUri string
-
DisplayName string
-
}
-
-
func NewFeedGenerator(rec []byte) *FeedGenerator {
-
var out appbsky.FeedGenerator
-
if err := out.UnmarshalCBOR(bytes.NewReader(rec)); err != nil {
-
slog.Error("could not unmarshal feedgen CBOR", "err", err)
-
return nil
-
}
-
return &FeedGenerator{
-
DisplayName: out.DisplayName,
-
}
-
}
-
-
type Post struct {
-
ID uint `gorm:"primaryKey"`
-
AtUri string
-
Text string
-
}
-
-
func NewPost(rec []byte) *Post {
-
return nil
-
}
-
-
type Like struct{}
-
-
// func NewLike
-
-
type StarterPack struct{}
-
-
// func NewStarterPack
-
-
type Verification struct{}
-
-
// func NewVerification
-
-
type Lexicon struct{}
-
-
// func NewLexicon
+45
cmd/monarch/handlers.go
···
+
package main
+
+
import (
+
"context"
+
"fmt"
+
+
"github.com/bluesky-social/indigo/atproto/syntax"
+
"github.com/ipfs/go-cid"
+
"gorm.io/gorm"
+
"tangled.sh/edavis.dev/monarch/models"
+
)
+
+
type HandlerService struct {
+
store *gorm.DB
+
}
+
+
func NewHandlerService(store *gorm.DB) *HandlerService {
+
store.AutoMigrate(&models.ActorProfile{})
+
+
return &HandlerService{
+
store: store,
+
}
+
}
+
+
// handles both creates and updates
+
func (hs *HandlerService) HandleUpsert(ctx context.Context, repo string, rev string, path string, rec *[]byte, cid *cid.Cid) error {
+
uri, err := syntax.ParseATURI(fmt.Sprintf("at://%s/%s", repo, path))
+
if err != nil {
+
return fmt.Errorf("error parsing at-uri: %w", err)
+
}
+
+
switch uri.Collection() {
+
case syntax.NSID("app.bsky.actor.profile"):
+
profile := models.NewActorProfile(uri, *rec)
+
if err := hs.store.Save(profile).Error; err != nil {
+
return fmt.Errorf("error saving profile: %w", err)
+
}
+
}
+
+
return nil
+
}
+
+
func (hs *HandlerService) HandleDelete(ctx context.Context, repo string, rev string, path string) error {
+
return nil
+
}
+1 -1
go.mod
···
-
module github.com/edavis/backfiller
+
module tangled.sh/edavis.dev/monarch
go 1.24
+73
models/models.go
···
+
package models
+
+
import (
+
"bytes"
+
"log/slog"
+
"time"
+
+
appbsky "github.com/bluesky-social/indigo/api/bsky"
+
"github.com/bluesky-social/indigo/atproto/syntax"
+
)
+
+
type StrongRef struct {
+
Uri string
+
Cid string
+
}
+
+
type ActorProfile struct {
+
ID string `gorm:"primaryKey"`
+
+
// Avatar
+
// Banner
+
CreatedAt *string
+
Description *string
+
DisplayName *string
+
JoinedViaStarterPack StrongRef `gorm:"embedded;embeddedPrefix:joinedviastarterpack_"`
+
// Labels
+
// PinnedPost StrongRef
+
+
AutoCreatedAt time.Time `gorm:"autoCreateTime"`
+
AutoUpdatedAt time.Time `gorm:"autoUpdateTime"`
+
}
+
+
func NewActorProfile(uri syntax.ATURI, rec []byte) *ActorProfile {
+
var out appbsky.ActorProfile
+
if err := out.UnmarshalCBOR(bytes.NewReader(rec)); err != nil {
+
slog.Error("could not unmarshal profile CBOR", "err", err)
+
return nil
+
}
+
+
profile := ActorProfile{
+
ID: string(uri),
+
CreatedAt: out.CreatedAt,
+
Description: out.Description,
+
DisplayName: out.DisplayName,
+
}
+
+
if out.JoinedViaStarterPack != nil {
+
profile.JoinedViaStarterPack = StrongRef{
+
Uri: out.JoinedViaStarterPack.Uri,
+
Cid: out.JoinedViaStarterPack.Cid,
+
}
+
}
+
+
return &profile
+
}
+
+
// ActorStatus
+
// FeedGenerator
+
// FeedLike
+
// FeedPost
+
// FeedPostgate
+
// FeedRepost
+
// FeedThreadgate
+
// GraphBlock
+
// GraphFollow
+
// GraphList
+
// GraphListblock
+
// GraphListitem
+
// GraphStarterpack
+
// GraphVerification
+
// LabelerService
+
// ActorDeclaration
+
// LexiconSchema