Monorepo for Tangled

appview: integrate label-value search and DID resolution in handlers

Use shared searchquery helpers (ResolveAuthor, ExtractTextFilters) to
replace duplicated resolution logic in both issue and pull handlers.

Wire up dynamic tag extraction for label-value queries. When label
definitions with DID format are present, resolve handle values to DIDs
at query time via ResolveDIDLabelValues.

Signed-off-by: Thomas Karpiniec <tom.karpiniec@outlook.com>

authored by

Thomas Karpiniec and committed by tangled.org 3496fef9 44086392

+80 -82
+40 -41
appview/issues/issues.go
··· 827 query.Set("state", "open") 828 } 829 830 - var authorDid string 831 - if authorHandle := query.Get("author"); authorHandle != nil { 832 - identity, err := rp.idResolver.ResolveIdent(r.Context(), *authorHandle) 833 if err != nil { 834 - l.Debug("failed to resolve author handle", "handle", *authorHandle, "err", err) 835 - } else { 836 - authorDid = identity.DID.String() 837 } 838 } 839 840 - var negatedAuthorDid string 841 - if negatedAuthors := query.GetAllNegated("author"); len(negatedAuthors) > 0 { 842 - identity, err := rp.idResolver.ResolveIdent(r.Context(), negatedAuthors[0]) 843 - if err != nil { 844 - l.Debug("failed to resolve negated author handle", "handle", negatedAuthors[0], "err", err) 845 - } else { 846 - negatedAuthorDid = identity.DID.String() 847 - } 848 - } 849 850 labels := query.GetAll("label") 851 negatedLabels := query.GetAllNegated("label") 852 853 - var keywords, negatedKeywords []string 854 - var phrases, negatedPhrases []string 855 - for _, item := range query.Items() { 856 - switch item.Kind { 857 - case searchquery.KindKeyword: 858 - if item.Negated { 859 - negatedKeywords = append(negatedKeywords, item.Value) 860 - } else { 861 - keywords = append(keywords, item.Value) 862 - } 863 - case searchquery.KindQuoted: 864 - if item.Negated { 865 - negatedPhrases = append(negatedPhrases, item.Value) 866 - } else { 867 - phrases = append(phrases, item.Value) 868 } 869 } 870 } 871 872 searchOpts := models.IssueSearchOptions{ 873 - Keywords: keywords, 874 - Phrases: phrases, 875 - RepoAt: f.RepoAt().String(), 876 - IsOpen: isOpen, 877 - AuthorDid: authorDid, 878 - Labels: labels, 879 - NegatedKeywords: negatedKeywords, 880 - NegatedPhrases: negatedPhrases, 881 - NegatedLabels: negatedLabels, 882 - NegatedAuthorDid: negatedAuthorDid, 883 - Page: page, 884 } 885 886 totalIssues := 0
··· 827 query.Set("state", "open") 828 } 829 830 + resolve := func(ctx context.Context, ident string) (string, error) { 831 + id, err := rp.idResolver.ResolveIdent(ctx, ident) 832 if err != nil { 833 + return "", err 834 } 835 + return id.DID.String(), nil 836 } 837 838 + authorDid, negatedAuthorDids := searchquery.ResolveAuthor(r.Context(), query, resolve, l) 839 840 labels := query.GetAll("label") 841 negatedLabels := query.GetAllNegated("label") 842 + labelValues := query.GetDynamicTags() 843 + negatedLabelValues := query.GetNegatedDynamicTags() 844 845 + // resolve DID-format label values: if a dynamic tag's label 846 + // definition has format "did", resolve the handle to a DID 847 + if len(labelValues) > 0 || len(negatedLabelValues) > 0 { 848 + labelDefs, err := db.GetLabelDefinitions( 849 + rp.db, 850 + orm.FilterIn("at_uri", f.Labels), 851 + orm.FilterContains("scope", tangled.RepoIssueNSID), 852 + ) 853 + if err == nil { 854 + didLabels := make(map[string]bool) 855 + for _, def := range labelDefs { 856 + if def.ValueType.Format == models.ValueTypeFormatDid { 857 + didLabels[def.Name] = true 858 + } 859 } 860 + labelValues = searchquery.ResolveDIDLabelValues(r.Context(), labelValues, didLabels, resolve, l) 861 + negatedLabelValues = searchquery.ResolveDIDLabelValues(r.Context(), negatedLabelValues, didLabels, resolve, l) 862 + } else { 863 + l.Debug("failed to fetch label definitions for DID resolution", "err", err) 864 } 865 } 866 867 + tf := searchquery.ExtractTextFilters(query) 868 + 869 searchOpts := models.IssueSearchOptions{ 870 + Keywords: tf.Keywords, 871 + Phrases: tf.Phrases, 872 + RepoAt: f.RepoAt().String(), 873 + IsOpen: isOpen, 874 + AuthorDid: authorDid, 875 + Labels: labels, 876 + LabelValues: labelValues, 877 + NegatedKeywords: tf.NegatedKeywords, 878 + NegatedPhrases: tf.NegatedPhrases, 879 + NegatedLabels: negatedLabels, 880 + NegatedLabelValues: negatedLabelValues, 881 + NegatedAuthorDids: negatedAuthorDids, 882 + Page: page, 883 } 884 885 totalIssues := 0
+40 -41
appview/pulls/pulls.go
··· 560 query.Set("state", "open") 561 } 562 563 - var authorDid string 564 - if authorHandle := query.Get("author"); authorHandle != nil { 565 - identity, err := s.idResolver.ResolveIdent(r.Context(), *authorHandle) 566 if err != nil { 567 - l.Debug("failed to resolve author handle", "handle", *authorHandle, "err", err) 568 - } else { 569 - authorDid = identity.DID.String() 570 } 571 } 572 573 - var negatedAuthorDid string 574 - if negatedAuthors := query.GetAllNegated("author"); len(negatedAuthors) > 0 { 575 - identity, err := s.idResolver.ResolveIdent(r.Context(), negatedAuthors[0]) 576 - if err != nil { 577 - l.Debug("failed to resolve negated author handle", "handle", negatedAuthors[0], "err", err) 578 - } else { 579 - negatedAuthorDid = identity.DID.String() 580 - } 581 - } 582 583 labels := query.GetAll("label") 584 negatedLabels := query.GetAllNegated("label") 585 586 - var keywords, negatedKeywords []string 587 - var phrases, negatedPhrases []string 588 - for _, item := range query.Items() { 589 - switch item.Kind { 590 - case searchquery.KindKeyword: 591 - if item.Negated { 592 - negatedKeywords = append(negatedKeywords, item.Value) 593 - } else { 594 - keywords = append(keywords, item.Value) 595 - } 596 - case searchquery.KindQuoted: 597 - if item.Negated { 598 - negatedPhrases = append(negatedPhrases, item.Value) 599 - } else { 600 - phrases = append(phrases, item.Value) 601 } 602 } 603 } 604 605 searchOpts := models.PullSearchOptions{ 606 - Keywords: keywords, 607 - Phrases: phrases, 608 - RepoAt: f.RepoAt().String(), 609 - State: state, 610 - AuthorDid: authorDid, 611 - Labels: labels, 612 - NegatedKeywords: negatedKeywords, 613 - NegatedPhrases: negatedPhrases, 614 - NegatedLabels: negatedLabels, 615 - NegatedAuthorDid: negatedAuthorDid, 616 - Page: page, 617 } 618 619 var totalPulls int
··· 560 query.Set("state", "open") 561 } 562 563 + resolve := func(ctx context.Context, ident string) (string, error) { 564 + id, err := s.idResolver.ResolveIdent(ctx, ident) 565 if err != nil { 566 + return "", err 567 } 568 + return id.DID.String(), nil 569 } 570 571 + authorDid, negatedAuthorDids := searchquery.ResolveAuthor(r.Context(), query, resolve, l) 572 573 labels := query.GetAll("label") 574 negatedLabels := query.GetAllNegated("label") 575 + labelValues := query.GetDynamicTags() 576 + negatedLabelValues := query.GetNegatedDynamicTags() 577 578 + // resolve DID-format label values: if a dynamic tag's label 579 + // definition has format "did", resolve the handle to a DID 580 + if len(labelValues) > 0 || len(negatedLabelValues) > 0 { 581 + labelDefs, err := db.GetLabelDefinitions( 582 + s.db, 583 + orm.FilterIn("at_uri", f.Labels), 584 + orm.FilterContains("scope", tangled.RepoPullNSID), 585 + ) 586 + if err == nil { 587 + didLabels := make(map[string]bool) 588 + for _, def := range labelDefs { 589 + if def.ValueType.Format == models.ValueTypeFormatDid { 590 + didLabels[def.Name] = true 591 + } 592 } 593 + labelValues = searchquery.ResolveDIDLabelValues(r.Context(), labelValues, didLabels, resolve, l) 594 + negatedLabelValues = searchquery.ResolveDIDLabelValues(r.Context(), negatedLabelValues, didLabels, resolve, l) 595 + } else { 596 + l.Debug("failed to fetch label definitions for DID resolution", "err", err) 597 } 598 } 599 600 + tf := searchquery.ExtractTextFilters(query) 601 + 602 searchOpts := models.PullSearchOptions{ 603 + Keywords: tf.Keywords, 604 + Phrases: tf.Phrases, 605 + RepoAt: f.RepoAt().String(), 606 + State: state, 607 + AuthorDid: authorDid, 608 + Labels: labels, 609 + LabelValues: labelValues, 610 + NegatedKeywords: tf.NegatedKeywords, 611 + NegatedPhrases: tf.NegatedPhrases, 612 + NegatedLabels: negatedLabels, 613 + NegatedLabelValues: negatedLabelValues, 614 + NegatedAuthorDids: negatedAuthorDids, 615 + Page: page, 616 } 617 618 var totalPulls int