package fetchers import ( "encoding/json" "fmt" "llostre/backend/general" "llostre/backend/notes" "log/slog" ) func FetchAppBskyFeedPosts(logger *slog.Logger, did, pdsURL, slingshotURL string, cache *Cache) ([]notes.Note, error) { // get author of the note author, found := cache.GetProfile(did) var err error if !found { author, err = FetchAppBskyActorProfile(logger, did, pdsURL, slingshotURL, cache) } if err != nil { return nil, err } // try slingshot first if given if slingshotURL != "" { records, err := general.FetchRawRecordCollection(logger, did, "app.bsky.feed.post", slingshotURL) if err != nil { logger.Error("Fetching from slingshot failed") } else { return parseAppBskyFeedPostCollection(logger, records, author, cache) } } records, err := general.FetchRawRecordCollection(logger, did, "app.bsky.feed.post", pdsURL) if err != nil { return nil, err } return parseAppBskyFeedPostCollection(logger, records, author, cache) } func FetchAppBskyFeedPostByURI(logger *slog.Logger, uri, slingshotURL string, cache *Cache) (*notes.Note, error) { // check cache if cached, found := cache.Get(uri); found { return cached, nil } repo, _, _, err := general.ParseURI(uri) // need to resolve DID to PDS pdsURL, err := FetchPDS(repo) if err != nil { return nil, err } // get author of the note author, found := cache.GetProfile(repo) if !found { author, err = FetchAppBskyActorProfile(logger, repo, pdsURL, slingshotURL, cache) } if err != nil { return nil, err } // try slingshot first if given if slingshotURL != "" { rawRecord, err := general.FetchRawRecordByURI(logger, uri, slingshotURL) if err != nil { logger.Error("fetching from slingshot failed", "error", err) } else { return parseAppBskyFeedPostRecord(rawRecord, author, cache) } } rawRecord, err := general.FetchRawRecordByURI(logger, uri, pdsURL) if err != nil { logger.Error("Fetching from PDS failed") return nil, err } return parseAppBskyFeedPostRecord(rawRecord, author, cache) } func parseAppBskyFeedPostRecord(rawRecord *general.RawRecord, author *notes.Author, cache *Cache) (*notes.Note, error) { if rawRecord == nil { return nil, fmt.Errorf("unable to parse nil record") } record := notes.AppBskyFeedPostRecord{ URI: rawRecord.URI, } err := json.Unmarshal(rawRecord.Value, &record.Value) if err != nil { return nil, err } note, err := notes.NoteFromAppBskyFeedPostRecord(record, author) if err != nil { return nil, err } // cache it cache.Set(note.URI, note) return note, nil } func parseAppBskyFeedPostCollection(logger *slog.Logger, records []general.RawRecord, author *notes.Author, cache *Cache) ([]notes.Note, error) { posts := make([]notes.Note, 0, len(records)) for _, record := range records { note, err := parseAppBskyFeedPostRecord(&record, author, cache) if err != nil { logger.Error("failed to parse post record", "error", err) continue } cache.Set(note.URI, note) posts = append(posts, *note) } return posts, nil }