+95
main.go
+95
main.go
···
1
1
package main
2
2
3
3
import (
4
+
"bytes"
4
5
"context"
5
6
"encoding/json"
6
7
"flag"
···
8
9
"io"
9
10
"log"
10
11
"net/http"
12
+
"os"
13
+
"sync"
11
14
"time"
12
15
13
16
did "github.com/whyrusleeping/go-did"
···
22
25
// "github.com/bluesky-social/indigo/atproto/atclient"
23
26
// comatproto "github.com/bluesky-social/indigo/api/atproto"
24
27
appbsky "github.com/bluesky-social/indigo/api/bsky"
28
+
"github.com/bluesky-social/indigo/atproto/syntax"
29
+
25
30
// "github.com/bluesky-social/indigo/atproto/atclient"
26
31
// "github.com/bluesky-social/indigo/atproto/identity"
27
32
// "github.com/bluesky-social/indigo/atproto/syntax"
···
280
285
Views: labelers,
281
286
})
282
287
})
288
+
289
+
router.GET("/xrpc/app.bsky.feed.getFeedGenerators",
290
+
func(c *gin.Context) {
291
+
feeds := c.QueryArray("feeds")
292
+
ctx := c.Request.Context()
293
+
294
+
type result struct {
295
+
view *appbsky.FeedDefs_GeneratorView
296
+
}
297
+
298
+
results := make([]result, len(feeds))
299
+
300
+
var wg sync.WaitGroup
301
+
wg.Add(len(feeds))
302
+
303
+
for i, raw := range feeds {
304
+
go func(i int, raw string) {
305
+
defer wg.Done()
306
+
307
+
aturi, err := syntax.ParseATURI(raw)
308
+
if err != nil {
309
+
return
310
+
}
311
+
312
+
did := aturi.Authority().String()
313
+
collection := aturi.Collection().String()
314
+
rkey := aturi.RecordKey().String()
315
+
316
+
repoDID, err := utils.NewDID(did)
317
+
if err != nil {
318
+
return
319
+
}
320
+
321
+
// fetch profile and record in parallel too (optional)
322
+
// but to keep it simple, do serial inside this goroutine
323
+
profile, _, _ := appbskyactordefs.ProfileView(ctx, repoDID, sl, BSKYIMAGECDN_URL)
324
+
325
+
rec, err := agnostic.RepoGetRecord(ctx, sl, "", collection, did, rkey)
326
+
if err != nil || rec.Value == nil {
327
+
return
328
+
}
329
+
330
+
var genRec appbsky.FeedGenerator
331
+
if err := json.Unmarshal(*rec.Value, &genRec); err != nil {
332
+
return
333
+
}
334
+
335
+
var avatar *string
336
+
if genRec.Avatar != nil {
337
+
u := utils.MakeImageCDN(repoDID, BSKYIMAGECDN_URL, "avatar", genRec.Avatar.Ref.String())
338
+
avatar = &u
339
+
}
340
+
341
+
results[i].view = &appbsky.FeedDefs_GeneratorView{
342
+
LexiconTypeID: "app.bsky.feed.defs#generatorView",
343
+
AcceptsInteractions: genRec.AcceptsInteractions,
344
+
Avatar: avatar,
345
+
Cid: *rec.Cid,
346
+
ContentMode: genRec.ContentMode,
347
+
Creator: profile,
348
+
Description: genRec.Description,
349
+
DescriptionFacets: genRec.DescriptionFacets,
350
+
Did: did,
351
+
DisplayName: genRec.DisplayName,
352
+
IndexedAt: genRec.CreatedAt,
353
+
Uri: rec.Uri,
354
+
}
355
+
}(i, raw)
356
+
}
357
+
358
+
wg.Wait()
359
+
360
+
// build final slice
361
+
out := make([]*appbsky.FeedDefs_GeneratorView, 0, len(results))
362
+
for _, r := range results {
363
+
if r.view != nil {
364
+
out = append(out, r.view)
365
+
}
366
+
}
367
+
368
+
c.JSON(http.StatusOK, &appbsky.FeedGetFeedGenerators_Output{
369
+
Feeds: out,
370
+
})
371
+
})
372
+
373
+
yourJSONBytes, _ := os.ReadFile("./public/getConfig.json")
374
+
router.GET("/xrpc/app.bsky.unspecced.getConfig", func(c *gin.Context) {
375
+
c.DataFromReader(200, -1, "application/json",
376
+
bytes.NewReader(yourJSONBytes), nil)
377
+
})
283
378
284
379
router.GET("/", func(c *gin.Context) {
285
380
log.Println("hello worldio !")
+40
public/getConfig.json
+40
public/getConfig.json
···
1
+
{
2
+
"checkEmailConfirmed": true,
3
+
"topicsEnabled": true,
4
+
"liveNow": [
5
+
{
6
+
"did": "did:plc:7sfnardo5xxznxc6esxc5ooe",
7
+
"domains": [
8
+
"www.nba.com",
9
+
"nba.com",
10
+
"nba.smart.link",
11
+
"espn.com",
12
+
"www.espn.com"
13
+
]
14
+
},
15
+
{ "did": "did:plc:gx6fyi3jcfxd7ammq2t7mzp2", "domains": ["twitch.tv"] },
16
+
{ "did": "did:plc:mc2hhszsfk6iwapfdwrwoj7i", "domains": ["twitch.tv"] },
17
+
{ "did": "did:plc:sb54dpdfefflykmf5bcfvr7t", "domains": ["youtube.com"] },
18
+
{ "did": "did:plc:dqav4a4ue5cyzgckv3l6fshr", "domains": ["twitch.tv"] },
19
+
{ "did": "did:plc:q6f4hsgifb3qs2e3wwdycjtf", "domains": ["twitch.tv"] },
20
+
{ "did": "did:plc:7tpvfx7mdbceyzj6kgboirle", "domains": ["twitch.tv"] },
21
+
{
22
+
"did": "did:plc:4adlzwqtkv4dirxjwq4c3tlm",
23
+
"domains": ["stream.place", "skylight.social"]
24
+
},
25
+
{
26
+
"did": "did:plc:2zmxikig2sj7gqaezl5gntae",
27
+
"domains": ["stream.place", "skylight.social"]
28
+
},
29
+
{
30
+
"did": "did:plc:jsbkvuuviqj4xooqwcbaftav",
31
+
"domains": ["stream.place", "skylight.social"]
32
+
},
33
+
{
34
+
"did": "did:plc:76iqtegcbbr4pbcxomka5pat",
35
+
"domains": ["stream.place", "skylight.social"]
36
+
},
37
+
{ "did": "did:plc:r2mpjf3gz2ygfaodkzzzfddg", "domains": ["youtube.com"] },
38
+
{ "did": "did:plc:wvwvlbeizca367klhhyudf2n", "domains": ["youtube.com"] }
39
+
]
40
+
}