+6
appview/config/config.go
+6
appview/config/config.go
···
78
TurnstileSecretKey string `env:"TURNSTILE_SECRET_KEY"`
79
}
80
81
func (cfg RedisConfig) ToURL() string {
82
u := &url.URL{
83
Scheme: "redis",
···
105
Redis RedisConfig `env:",prefix=TANGLED_REDIS_"`
106
Pds PdsConfig `env:",prefix=TANGLED_PDS_"`
107
Cloudflare Cloudflare `env:",prefix=TANGLED_CLOUDFLARE_"`
108
}
109
110
func LoadConfig(ctx context.Context) (*Config, error) {
···
78
TurnstileSecretKey string `env:"TURNSTILE_SECRET_KEY"`
79
}
80
81
+
type LabelConfig struct {
82
+
DefaultLabelDefs []string `env:"DEFAULTS"` // delimiter=,
83
+
GoodFirstIssue string `env:"GFI, default=at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.label.definition/good-first-issue"`
84
+
}
85
+
86
func (cfg RedisConfig) ToURL() string {
87
u := &url.URL{
88
Scheme: "redis",
···
110
Redis RedisConfig `env:",prefix=TANGLED_REDIS_"`
111
Pds PdsConfig `env:",prefix=TANGLED_PDS_"`
112
Cloudflare Cloudflare `env:",prefix=TANGLED_CLOUDFLARE_"`
113
+
Label LabelConfig `env:",prefix=TANGLED_LABEL_"`
114
}
115
116
func LoadConfig(ctx context.Context) (*Config, error) {
+25
-43
appview/models/label.go
+25
-43
appview/models/label.go
···
14
"github.com/bluesky-social/indigo/atproto/syntax"
15
"github.com/bluesky-social/indigo/xrpc"
16
"tangled.org/core/api/tangled"
17
-
"tangled.org/core/consts"
18
"tangled.org/core/idresolver"
19
)
20
···
461
return result
462
}
463
464
-
var (
465
-
LabelWontfix = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "wontfix")
466
-
LabelDuplicate = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "duplicate")
467
-
LabelAssignee = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "assignee")
468
-
LabelGoodFirstIssue = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
469
-
LabelDocumentation = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "documentation")
470
-
)
471
472
-
func DefaultLabelDefs() []string {
473
-
return []string{
474
-
LabelWontfix,
475
-
LabelDuplicate,
476
-
LabelAssignee,
477
-
LabelGoodFirstIssue,
478
-
LabelDocumentation,
479
-
}
480
-
}
481
482
-
func FetchDefaultDefs(r *idresolver.Resolver) ([]LabelDefinition, error) {
483
-
resolved, err := r.ResolveIdent(context.Background(), consts.TangledDid)
484
-
if err != nil {
485
-
return nil, fmt.Errorf("failed to resolve tangled.sh DID %s: %v", consts.TangledDid, err)
486
-
}
487
-
pdsEndpoint := resolved.PDSEndpoint()
488
-
if pdsEndpoint == "" {
489
-
return nil, fmt.Errorf("no PDS endpoint found for tangled.sh DID %s", consts.TangledDid)
490
-
}
491
-
client := &xrpc.Client{
492
-
Host: pdsEndpoint,
493
-
}
494
495
-
var labelDefs []LabelDefinition
496
497
-
for _, dl := range DefaultLabelDefs() {
498
-
atUri := syntax.ATURI(dl)
499
-
parsedUri, err := syntax.ParseATURI(string(atUri))
500
-
if err != nil {
501
-
return nil, fmt.Errorf("failed to parse AT-URI %s: %v", atUri, err)
502
-
}
503
record, err := atproto.RepoGetRecord(
504
-
context.Background(),
505
-
client,
506
"",
507
-
parsedUri.Collection().String(),
508
-
parsedUri.Authority().String(),
509
-
parsedUri.RecordKey().String(),
510
)
511
if err != nil {
512
return nil, fmt.Errorf("failed to get record for %s: %v", atUri, err)
···
526
}
527
528
labelDef, err := LabelDefinitionFromRecord(
529
-
parsedUri.Authority().String(),
530
-
parsedUri.RecordKey().String(),
531
labelRecord,
532
)
533
if err != nil {
···
14
"github.com/bluesky-social/indigo/atproto/syntax"
15
"github.com/bluesky-social/indigo/xrpc"
16
"tangled.org/core/api/tangled"
17
"tangled.org/core/idresolver"
18
)
19
···
460
return result
461
}
462
463
+
func FetchLabelDefs(r *idresolver.Resolver, aturis []string) ([]LabelDefinition, error) {
464
+
var labelDefs []LabelDefinition
465
+
ctx := context.Background()
466
467
+
for _, dl := range aturis {
468
+
atUri, err := syntax.ParseATURI(dl)
469
+
if err != nil {
470
+
return nil, fmt.Errorf("failed to parse AT-URI %s: %v", dl, err)
471
+
}
472
+
if atUri.Collection() != tangled.LabelDefinitionNSID {
473
+
return nil, fmt.Errorf("expected AT-URI pointing %s collection: %s", tangled.LabelDefinitionNSID, atUri)
474
+
}
475
476
+
owner, err := r.ResolveIdent(ctx, atUri.Authority().String())
477
+
if err != nil {
478
+
return nil, fmt.Errorf("failed to resolve default label owner DID %s: %v", atUri.Authority(), err)
479
+
}
480
481
+
xrpcc := xrpc.Client{
482
+
Host: owner.PDSEndpoint(),
483
+
}
484
485
record, err := atproto.RepoGetRecord(
486
+
ctx,
487
+
&xrpcc,
488
"",
489
+
atUri.Collection().String(),
490
+
atUri.Authority().String(),
491
+
atUri.RecordKey().String(),
492
)
493
if err != nil {
494
return nil, fmt.Errorf("failed to get record for %s: %v", atUri, err)
···
508
}
509
510
labelDef, err := LabelDefinitionFromRecord(
511
+
atUri.Authority().String(),
512
+
atUri.RecordKey().String(),
513
labelRecord,
514
)
515
if err != nil {
+2
-2
appview/repo/repo.go
+2
-2
appview/repo/repo.go
···
1974
return
1975
}
1976
1977
-
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs()))
1978
if err != nil {
1979
l.Error("failed to fetch labels", "err", err)
1980
rp.pages.Error503(w)
···
2253
Source: sourceAt,
2254
Description: f.Repo.Description,
2255
Created: time.Now(),
2256
-
Labels: models.DefaultLabelDefs(),
2257
}
2258
record := repo.AsRecord()
2259
···
1974
return
1975
}
1976
1977
+
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", rp.config.Label.DefaultLabelDefs))
1978
if err != nil {
1979
l.Error("failed to fetch labels", "err", err)
1980
rp.pages.Error503(w)
···
2253
Source: sourceAt,
2254
Description: f.Repo.Description,
2255
Created: time.Now(),
2256
+
Labels: rp.config.Label.DefaultLabelDefs,
2257
}
2258
record := repo.AsRecord()
2259
+1
-3
appview/state/gfi.go
+1
-3
appview/state/gfi.go
···
1
package state
2
3
import (
4
-
"fmt"
5
"log"
6
"net/http"
7
"sort"
8
9
"github.com/bluesky-social/indigo/atproto/syntax"
10
-
"tangled.org/core/api/tangled"
11
"tangled.org/core/appview/db"
12
"tangled.org/core/appview/models"
13
"tangled.org/core/appview/pages"
···
20
21
page := pagination.FromContext(r.Context())
22
23
-
goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
24
25
gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel))
26
if err != nil {
···
1
package state
2
3
import (
4
"log"
5
"net/http"
6
"sort"
7
8
"github.com/bluesky-social/indigo/atproto/syntax"
9
"tangled.org/core/appview/db"
10
"tangled.org/core/appview/models"
11
"tangled.org/core/appview/pages"
···
18
19
page := pagination.FromContext(r.Context())
20
21
+
goodFirstIssueLabel := s.config.Label.GoodFirstIssue
22
23
gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel))
24
if err != nil {
+5
-6
appview/state/state.go
+5
-6
appview/state/state.go
···
121
return nil, fmt.Errorf("failed to create jetstream client: %w", err)
122
}
123
124
-
if err := BackfillDefaultDefs(d, res); err != nil {
125
return nil, fmt.Errorf("failed to backfill default label defs: %w", err)
126
}
127
···
284
return
285
}
286
287
-
gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", models.LabelGoodFirstIssue))
288
if err != nil {
289
// non-fatal
290
}
···
506
Rkey: rkey,
507
Description: description,
508
Created: time.Now(),
509
-
Labels: models.DefaultLabelDefs(),
510
}
511
record := repo.AsRecord()
512
···
648
return err
649
}
650
651
-
func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver) error {
652
-
defaults := models.DefaultLabelDefs()
653
defaultLabels, err := db.GetLabelDefinitions(e, db.FilterIn("at_uri", defaults))
654
if err != nil {
655
return err
···
659
return nil
660
}
661
662
-
labelDefs, err := models.FetchDefaultDefs(r)
663
if err != nil {
664
return err
665
}
···
121
return nil, fmt.Errorf("failed to create jetstream client: %w", err)
122
}
123
124
+
if err := BackfillDefaultDefs(d, res, config.Label.DefaultLabelDefs); err != nil {
125
return nil, fmt.Errorf("failed to backfill default label defs: %w", err)
126
}
127
···
284
return
285
}
286
287
+
gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", s.config.Label.GoodFirstIssue))
288
if err != nil {
289
// non-fatal
290
}
···
506
Rkey: rkey,
507
Description: description,
508
Created: time.Now(),
509
+
Labels: s.config.Label.DefaultLabelDefs,
510
}
511
record := repo.AsRecord()
512
···
648
return err
649
}
650
651
+
func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver, defaults []string) error {
652
defaultLabels, err := db.GetLabelDefinitions(e, db.FilterIn("at_uri", defaults))
653
if err != nil {
654
return err
···
658
return nil
659
}
660
661
+
labelDefs, err := models.FetchLabelDefs(r, defaults)
662
if err != nil {
663
return err
664
}