aboutsummaryrefslogtreecommitdiff
path: root/backend/fetchers/profiles.go
diff options
context:
space:
mode:
authorGuillermo Serrahima <dev@vylion.com>2026-03-18 17:00:51 +0100
committerGuillermo Serrahima <dev@vylion.com>2026-03-18 17:00:51 +0100
commite7b376211cdf013528c1919a28caa28cc0ec9c93 (patch)
tree2e8e3ae452f09af494a5cd207d7bc0e261eb929a /backend/fetchers/profiles.go
parent64b2d7d08bc5f54d3a00f260b57a3853b74c2456 (diff)
downloadllostre-e7b376211cdf013528c1919a28caa28cc0ec9c93.tar.xz
llostre-e7b376211cdf013528c1919a28caa28cc0ec9c93.zip
file renaming
Diffstat (limited to 'backend/fetchers/profiles.go')
-rw-r--r--backend/fetchers/profiles.go184
1 files changed, 0 insertions, 184 deletions
diff --git a/backend/fetchers/profiles.go b/backend/fetchers/profiles.go
deleted file mode 100644
index 3c0154a..0000000
--- a/backend/fetchers/profiles.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package fetchers
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "llostre/backend/general"
- "net"
- "net/http"
- "strings"
-)
-
-type DIDDocument struct {
- AlsoKnownAs []string `json:"alsoKnownAs"`
- Service []struct {
- ID string `json:"id"`
- Type string `json:"type"`
- ServiceEndpoint string `json:"serviceEndpoint"`
- } `json:"service"`
-}
-
-func FetchDID(handle string) (string, error) {
- // return if it's a DID already
- if strings.HasPrefix(handle, "did:") {
- return handle, nil
- }
-
- // resolve DNS record first
- txtRecords, err := net.LookupTXT("_atproto." + handle)
- if err == nil {
- for _, txt := range txtRecords {
- if after, ok := strings.CutPrefix(txt, "did="); ok {
- return after, nil
- }
- }
- }
-
- // fallback to HTTPS well-known
- resp, err := http.Get(fmt.Sprintf("https://%s/.well-known/atproto-did", handle))
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return "", err
- }
-
- did := strings.TrimSpace(string(body))
- if !strings.HasPrefix(did, "did:") {
- return "", fmt.Errorf("invalid DID returned: %s", did)
- }
-
- return did, nil
-}
-
-func FetchDidDoc(did string) (*DIDDocument, error) {
- didDocURL := fmt.Sprintf("https://plc.directory/%s", did)
-
- resp, err := http.Get(didDocURL)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("DID resolution failed: %d", resp.StatusCode)
- }
-
- var didDoc DIDDocument
- if err := json.NewDecoder(resp.Body).Decode(&didDoc); err != nil {
- return nil, err
- }
-
- return &didDoc, nil
-}
-
-func FetchHandle(did string) (string, error) {
- var didDoc, err = FetchDidDoc(did)
- if err != nil {
- return "", err
- }
-
- if len(didDoc.AlsoKnownAs) == 0 {
- return "", fmt.Errorf("no handle found")
- }
-
- handle := strings.TrimPrefix(didDoc.AlsoKnownAs[0], "at://")
- return handle, nil
-}
-
-func FetchPDS(did string) (string, error) {
- var didDoc, err = FetchDidDoc(did)
- if err != nil {
- return "", err
- }
-
- for _, svc := range didDoc.Service {
- if svc.Type == "AtprotoPersonalDataServer" {
- return svc.ServiceEndpoint, nil
- }
- }
-
- return "", fmt.Errorf("no PDS found for DID %s", did)
-}
-
-func FetchHandleAndPDS(did string) (string, string, error) {
- var didDoc, err = FetchDidDoc(did)
- if err != nil {
- return "", "", err
- }
-
- if len(didDoc.AlsoKnownAs) == 0 {
- return "", "", fmt.Errorf("no handle found")
- }
-
- var pds string
- for _, svc := range didDoc.Service {
- if svc.Type == "AtprotoPersonalDataServer" {
- pds = svc.ServiceEndpoint
- break
- }
- }
-
- handle := strings.TrimPrefix(didDoc.AlsoKnownAs[0], "at://")
-
- return handle, pds, nil
-}
-
-func FetchProfile(did, pdsURL string, cache *Cache) (*general.Profile, error) {
- recordURL := fmt.Sprintf("%s/xrpc/com.atproto.repo.getRecord?repo=%s&collection=app.bsky.actor.profile&rkey=self", pdsURL, did)
-
- resp, err := http.Get(recordURL)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("profile fetch failed: %d", resp.StatusCode)
- }
-
- handle, err := FetchHandle(did)
- if err != nil {
- handle = "handle.invalid"
- }
-
- var response general.ProfileRecordResponse
- if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
- return nil, err
- }
-
- var avatarURL, bannerURL string
- if response.Value.Avatar != nil {
- avatarURL = fmt.Sprintf("https://cdn.bsky.app/img/avatar/plain/%s/%s@jpeg", did, response.Value.Avatar.Ref.Link)
- }
- if response.Value.Banner != nil {
- bannerURL = fmt.Sprintf("https://cdn.bsky.app/img/banner/plain/%s/%s@jpeg", did, response.Value.Banner.Ref.Link)
- }
-
- profile := &general.Profile{
- Handle: handle,
- DisplayName: response.Value.DisplayName,
- AvatarURL: avatarURL,
- BannerURL: bannerURL,
- Pronouns: response.Value.Pronouns,
- }
-
- cache.SetProfile(handle, profile)
- return profile, nil
-}
-
-func FetchProfiles(dids []string, pdsURL string, cache *Cache) map[string]general.Profile {
- profiles := make(map[string]general.Profile)
- for _, did := range dids {
- profile, err := FetchProfile(did, pdsURL, cache)
- if err == nil {
- cache.SetProfile(did, profile)
- profiles[did] = *profile
- }
- }
- return profiles
-}