appvieww: make default label defs configurable #703

merged
opened by boltless.me targeting master from sandboxed-atmosphere

hard-coded labels make hard to setup local sandboxed environment as the appview won't run until we fill all 5 definitions under TangledDid.

so make them configurable with TANGLED_LABEL_DEFAULTS which is a list of aturis delimitted by , character

we can have any number/kind of default labels but gfi is required for /good-first-issue page

Signed-off-by: Seongmin Lee git@boltless.me

Changed files
+44 -54
appview
config
models
repo
state
+11
appview/config/config.go
···
TurnstileSecretKey string `env:"TURNSTILE_SECRET_KEY"`
}
+
type LabelConfig struct {
+
DefaultLabelDefs []string `env:"DEFAULTS"` // delimiter=,
+
GoodFirstIssue string `env:"GFI, default=at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.label.definition/good-first-issue"`
+
}
+
func (cfg RedisConfig) ToURL() string {
u := &url.URL{
Scheme: "redis",
···
Redis RedisConfig `env:",prefix=TANGLED_REDIS_"`
Pds PdsConfig `env:",prefix=TANGLED_PDS_"`
Cloudflare Cloudflare `env:",prefix=TANGLED_CLOUDFLARE_"`
+
Label LabelConfig `env:",prefix=TANGLED_LABEL_"`
}
func LoadConfig(ctx context.Context) (*Config, error) {
···
return nil, err
}
+
fmt.Println("default labels:")
+
for _, l := range cfg.Label.DefaultLabelDefs {
+
fmt.Println(l)
+
}
+
return &cfg, nil
}
+25 -43
appview/models/label.go
···
"github.com/bluesky-social/indigo/atproto/syntax"
"github.com/bluesky-social/indigo/xrpc"
"tangled.org/core/api/tangled"
-
"tangled.org/core/consts"
"tangled.org/core/idresolver"
)
···
return result
}
-
var (
-
LabelWontfix = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "wontfix")
-
LabelDuplicate = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "duplicate")
-
LabelAssignee = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "assignee")
-
LabelGoodFirstIssue = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
-
LabelDocumentation = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "documentation")
-
)
-
-
func DefaultLabelDefs() []string {
-
return []string{
-
LabelWontfix,
-
LabelDuplicate,
-
LabelAssignee,
-
LabelGoodFirstIssue,
-
LabelDocumentation,
-
}
-
}
-
-
func FetchDefaultDefs(r *idresolver.Resolver) ([]LabelDefinition, error) {
-
resolved, err := r.ResolveIdent(context.Background(), consts.TangledDid)
-
if err != nil {
-
return nil, fmt.Errorf("failed to resolve tangled.sh DID %s: %v", consts.TangledDid, err)
-
}
-
pdsEndpoint := resolved.PDSEndpoint()
-
if pdsEndpoint == "" {
-
return nil, fmt.Errorf("no PDS endpoint found for tangled.sh DID %s", consts.TangledDid)
-
}
-
client := &xrpc.Client{
-
Host: pdsEndpoint,
-
}
-
+
func FetchLabelDefs(r *idresolver.Resolver, aturis []string) ([]LabelDefinition, error) {
var labelDefs []LabelDefinition
+
ctx := context.Background()
-
for _, dl := range DefaultLabelDefs() {
-
atUri := syntax.ATURI(dl)
-
parsedUri, err := syntax.ParseATURI(string(atUri))
+
for _, dl := range aturis {
+
atUri, err := syntax.ParseATURI(dl)
if err != nil {
-
return nil, fmt.Errorf("failed to parse AT-URI %s: %v", atUri, err)
+
return nil, fmt.Errorf("failed to parse AT-URI %s: %v", dl, err)
+
}
+
if atUri.Collection() != tangled.LabelDefinitionNSID {
+
return nil, fmt.Errorf("expected AT-URI pointing %s collection: %s", tangled.LabelDefinitionNSID, atUri)
}
+
+
owner, err := r.ResolveIdent(ctx, atUri.Authority().String())
+
if err != nil {
+
return nil, fmt.Errorf("failed to resolve default label owner DID %s: %v", atUri.Authority(), err)
+
}
+
+
xrpcc := xrpc.Client{
+
Host: owner.PDSEndpoint(),
+
}
+
record, err := atproto.RepoGetRecord(
-
context.Background(),
-
client,
+
ctx,
+
&xrpcc,
"",
-
parsedUri.Collection().String(),
-
parsedUri.Authority().String(),
-
parsedUri.RecordKey().String(),
+
atUri.Collection().String(),
+
atUri.Authority().String(),
+
atUri.RecordKey().String(),
)
if err != nil {
return nil, fmt.Errorf("failed to get record for %s: %v", atUri, err)
···
}
labelDef, err := LabelDefinitionFromRecord(
-
parsedUri.Authority().String(),
-
parsedUri.RecordKey().String(),
+
atUri.Authority().String(),
+
atUri.RecordKey().String(),
labelRecord,
)
if err != nil {
+2 -2
appview/repo/repo.go
···
return
-
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs()))
+
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", rp.config.Label.DefaultLabelDefs))
if err != nil {
l.Error("failed to fetch labels", "err", err)
rp.pages.Error503(w)
···
Source: sourceAt,
Description: f.Repo.Description,
Created: time.Now(),
-
Labels: models.DefaultLabelDefs(),
+
Labels: rp.config.Label.DefaultLabelDefs,
record := repo.AsRecord()
+1 -3
appview/state/gfi.go
···
package state
import (
-
"fmt"
"log"
"net/http"
"sort"
"github.com/bluesky-social/indigo/atproto/syntax"
-
"tangled.org/core/api/tangled"
"tangled.org/core/appview/db"
"tangled.org/core/appview/models"
"tangled.org/core/appview/pages"
···
page = pagination.FirstPage()
}
-
goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
+
goodFirstIssueLabel := s.config.Label.GoodFirstIssue
gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel))
if err != nil {
+5 -6
appview/state/state.go
···
return nil, fmt.Errorf("failed to create jetstream client: %w", err)
}
-
if err := BackfillDefaultDefs(d, res); err != nil {
+
if err := BackfillDefaultDefs(d, res, config.Label.DefaultLabelDefs); err != nil {
return nil, fmt.Errorf("failed to backfill default label defs: %w", err)
}
···
return
}
-
gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", models.LabelGoodFirstIssue))
+
gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", s.config.Label.GoodFirstIssue))
if err != nil {
// non-fatal
}
···
Rkey: rkey,
Description: description,
Created: time.Now(),
-
Labels: models.DefaultLabelDefs(),
+
Labels: s.config.Label.DefaultLabelDefs,
}
record := repo.AsRecord()
···
return err
}
-
func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver) error {
-
defaults := models.DefaultLabelDefs()
+
func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver, defaults []string) error {
defaultLabels, err := db.GetLabelDefinitions(e, db.FilterIn("at_uri", defaults))
if err != nil {
return err
···
return nil
}
-
labelDefs, err := models.FetchDefaultDefs(r)
+
labelDefs, err := models.FetchLabelDefs(r, defaults)
if err != nil {
return err
}