GoAT Site is library that implements Standard.site in Go.
atprotocol standard-site atproto library
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(time): supports RFC3339

+45 -9
+3 -2
document.go
··· 88 88 if err != nil { 89 89 return err 90 90 } 91 - v.t.PublishedAt, err = time.Parse(TimeFormat, v.PublishedAt) 91 + v.t.PublishedAt, err = ParseTime(v.PublishedAt) 92 92 if err != nil { 93 93 return err 94 94 } 95 95 if v.UpdatedAt != nil { 96 - v.t.PublishedAt, err = time.Parse(TimeFormat, *v.UpdatedAt) 96 + v.t.UpdatedAt = new(time.Time) 97 + *v.t.UpdatedAt, err = ParseTime(*v.UpdatedAt) 97 98 if err != nil { 98 99 return err 99 100 }
+11 -3
lexicons.go
··· 4 4 "context" 5 5 "encoding/json" 6 6 "fmt" 7 + "time" 7 8 8 9 "github.com/bluesky-social/indigo/api/agnostic" 9 10 "github.com/bluesky-social/indigo/api/atproto" ··· 21 22 CollectionBase = "site.standard" 22 23 CollectionBlob = "blob" 23 24 24 - TimeFormat = "2006-01-02T15:04:05.000Z" 25 + TimeFormat = "2006-01-02T15:04:05.000Z07:00" 25 26 ) 27 + 28 + func ParseTime(raw string) (t time.Time, err error) { 29 + t, err = time.Parse(TimeFormat, raw) 30 + if err != nil { 31 + t, err = time.Parse(time.RFC3339, raw) 32 + } 33 + return 34 + } 26 35 27 36 // RecordJSON is used to encode and to decode [Record] from JSON. 28 37 type RecordJSON struct { ··· 178 187 } 179 188 docs := make([]T, MaxItemsPerList) 180 189 i := 0 181 - for i < len(rec.Records) { 190 + for i = range len(rec.Records) { 182 191 r := rec.Records[i] 183 192 var v *RecordJSON 184 193 err = json.Unmarshal(*r.Value, &v) ··· 192 201 return nil, nil, ErrInvalidType{collection, v.Record.Type()} 193 202 } 194 203 docs[i] = v.Record.(T) 195 - i++ 196 204 } 197 205 return docs[:i], rec.Cursor, nil 198 206 }
+6 -1
map.go
··· 32 32 } 33 33 return v, true 34 34 }), 35 - newOpt("string", func(v any) (any, bool) { return fmt.Sprintf("%v", v), true }), 35 + newOpt("string", func(v any) (any, bool) { 36 + if cv, ok := v.(fmt.Stringer); ok { 37 + return cv.String(), true 38 + } 39 + return fmt.Sprintf("%v", v), true 40 + }), 36 41 } 37 42 38 43 func getElem(v reflect.Value) (any, error) {
+6 -2
publication_test.go
··· 125 125 t.Log(string(b)) 126 126 } 127 127 128 - const testPub = "at://did:plc:yk4dd2qkboz2yv6tpubpc6co/site.standard.publication/3m6zrpzbs3s2y" 128 + // leaflet publication 129 + // const testPub = "at://did:plc:yk4dd2qkboz2yv6tpubpc6co/site.standard.publication/3m6zrpzbs3s2y" 130 + 131 + // pckt publication (because they do not use the preferred time format!) 132 + const testPub = "at://did:plc:revjuqmkvrw6fnkxppqtszpv/site.standard.publication/3md4kftpfxs2z" 129 133 130 134 var ( 131 135 pubURI syntax.ATURI ··· 177 181 t.Skip() 178 182 } 179 183 uri, client := getClient(t, testPub, &pubURI, &pubClient) 180 - pubs, _, err := site.ListDocuments(context.Background(), client, uri.Authority(), "", false) 184 + pubs, _, err := site.ListPublications(context.Background(), client, uri.Authority(), "", false) 181 185 if err != nil { 182 186 t.Fatal(err) 183 187 }
+19 -1
subscription.go
··· 1 1 package site 2 2 3 + import ( 4 + "encoding/json" 5 + 6 + "github.com/bluesky-social/indigo/atproto/syntax" 7 + ) 8 + 3 9 const CollectionSubscription = CollectionBase + ".graph.subscription" 4 10 5 11 // Subscription enable users to follow publications and receive updates about new content. ··· 7 13 type Subscription struct { 8 14 // Publication is an AT-URI reference to the publication record being subscribed to. 9 15 // E.g., `at://did:plc:abc123/site.standard.publication/xyz789`. 10 - Publication string `json:"publication"` 16 + Publication syntax.ATURI `json:"publication,string"` 17 + } 18 + 19 + func (s *Subscription) UnmarshalJSON(b []byte) error { 20 + var v struct { 21 + Publication string `json:"publication"` 22 + } 23 + err := json.Unmarshal(b, &v) 24 + if err != nil { 25 + return err 26 + } 27 + s.Publication, err = syntax.ParseATURI(v.Publication) 28 + return err 11 29 } 12 30 13 31 func (s *Subscription) Type() string {