Skip to content

Commit

Permalink
Adds healthcheck and inverted topic search
Browse files Browse the repository at this point in the history
  • Loading branch information
richmahn committed Jan 1, 2025
1 parent e5e4f97 commit beedf2d
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 5 deletions.
51 changes: 51 additions & 0 deletions models/door43metadata/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ type SearchCatalogOptions struct {
MetadataTypes []string
MetadataVersions []string
Topics []string
InvertedTopics []string
Healthchecks []string
ShowIngredients util.OptionalBool
Languages []string
LanguageIsGL util.OptionalBool
Expand Down Expand Up @@ -129,6 +131,8 @@ func SearchCatalogCondition(opts *SearchCatalogOptions) builder.Cond {
GetCheckingLevelCond(opts.CheckingLevels),
GetMetadataTypeCond(opts.MetadataTypes, opts.PartialMatch),
GetTopicCond(opts.Topics, opts.PartialMatch),
GetInvertedTopicCond(opts.InvertedTopics, opts.PartialMatch),
GetHealthcheckCond(opts.Healthchecks),
GetTagCond(opts.Tags),
repoCond,
ownerCond,
Expand Down Expand Up @@ -291,6 +295,53 @@ func GetTopicCond(topics []string, partialMatch bool) builder.Cond {
return topicCond
}

// GetInvertedTopicCond gets the inverted topic condition
func GetInvertedTopicCond(topics []string, partialMatch bool) builder.Cond {
topicCond := builder.NewCond()
for _, topic := range topics {
for _, v := range strings.Split(topic, ",") {
if partialMatch {
topicCond = topicCond.Or(builder.NotIn("`repository`.id", builder.Select("repo_id").From("repo_topic").InnerJoin("topic", "`repo_topic`.topic_id = `topic`.id").Where(builder.Like{"`topic`.name", strings.TrimSpace(v)})))
} else {
topicCond = topicCond.Or(builder.NotIn("`repository`.id", builder.Select("repo_id").From("repo_topic").InnerJoin("topic", "`repo_topic`.topic_id = `topic`.id").Where(builder.Eq{"`topic`.name": strings.TrimSpace(v)})))
}
}
}
return topicCond
}

// SeverityLevel represents the level of severity or concern for a health check
type SeverityLevel int

const (
SeverityLevelSuccess SeverityLevel = iota + 1 // 1
SeverityLevelInfo // 2
SeverityLevelWarning // 3
SeverityLevelError // 4
)

// SeverityLevelMap map from string to SeverityLevel (int)
var SeverityLevelMap = map[string]SeverityLevel{
"error": SeverityLevelError,
"warning": SeverityLevelWarning,
"info": SeverityLevelInfo,
"success": SeverityLevelSuccess,
}

// GetHealthcheckCond gets the healthcheck condition
func GetHealthcheckCond(healthchecks []string) builder.Cond {
healthcheckCond := builder.NewCond()
for _, healthcheck := range healthchecks {
for _, v := range strings.Split(healthcheck, ",") {
v = strings.ToLower(strings.TrimSpace(v))
if _, ok := SeverityLevelMap[v]; ok {
healthcheckCond = healthcheckCond.Or(builder.Eq{"`door43_metadata`.healthcheck_severity": SeverityLevelMap[v]})
}
}
}
return healthcheckCond
}

// GetMetadataVersionCond gets the metdata version condition
func GetMetadataVersionCond(versions []string, partialMatch bool) builder.Cond {
versionCond := builder.NewCond()
Expand Down
6 changes: 5 additions & 1 deletion models/repo/repo_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ type SearchRepoOptions struct {
MetadataTypes []string // DCS Customizations
MetadataVersions []string // DCS Customizations
Topics []string // DCS Customizations
InvertedTopics []string // DCS Customizations
Healthchecks []string // DCS Customizations
PartialMatch bool // DCS Customizations
// When specified true, apply some filters over the conditions:
// - Don't show forks, when opts.Fork is OptionalBoolNone.
Expand Down Expand Up @@ -529,7 +531,9 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
door43metadata.GetBookCond(opts.Books),
door43metadata.GetLanguageCond(opts.Languages, opts.PartialMatch),
door43metadata.GetMetadataTypeCond(opts.MetadataTypes, false),
door43metadata.GetTopicCond(opts.Topics, opts.PartialMatch))
door43metadata.GetTopicCond(opts.Topics, opts.PartialMatch),
door43metadata.GetInvertedTopicCond(opts.InvertedTopics, opts.PartialMatch),
door43metadata.GetHealthcheckCond(opts.Healthchecks))

if len(opts.MetadataTypes) > 0 {
cond.And(door43metadata.GetMetadataVersionCond(opts.MetadataVersions, false))
Expand Down
2 changes: 2 additions & 0 deletions routers/api/v1/catalog/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,8 @@ func searchCatalog(ctx *context.APIContext) {
MetadataTypes: metadataTypes,
MetadataVersions: metadataVersions,
Topics: QueryStrings(ctx, "topic"),
InvertedTopics: QueryStrings(ctx, "invertedTopic"),
Healthchecks: QueryStrings(ctx, "healthcheck"),
PartialMatch: ctx.FormBool("partialMatch"),
}

Expand Down
2 changes: 2 additions & 0 deletions routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ func Search(ctx *context.APIContext) {
MetadataTypes: catalog.QueryStrings(ctx, "metadataType"),
MetadataVersions: catalog.QueryStrings(ctx, "metadataVersion"),
Topics: catalog.QueryStrings(ctx, "topic"),
InvertedTopics: catalog.QueryStrings(ctx, "invertedTopic"),
Healthchecks: catalog.QueryStrings(ctx, "healthcheck"),
LanguageIsGL: ctx.FormOptionalBool("is_gl"),
PartialMatch: ctx.FormBool("partialMatch"),
/*** END DCS Customizations ***/
Expand Down
4 changes: 3 additions & 1 deletion routers/web/dcs/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func RenderCatalogSearch(ctx *context.Context, opts *CatalogSearchOptions) {
}

query := ctx.FormTrim("q")
searchFields := []string{"keyword", "book", "lang", "subject", "flavor_type", "flavor", "abbreviation", "content_format", "repo", "owner", "tag", "checking_level", "metadata_type", "metadata_version", "topic", "stage"}
searchFields := []string{"keyword", "book", "lang", "subject", "flavor_type", "flavor", "abbreviation", "content_format", "repo", "owner", "tag", "checking_level", "metadata_type", "metadata_version", "topic", "topic_inverted", "healthcheck", "stage"}
searchMap := map[string][]string{}
for _, field := range searchFields {
searchMap[field] = []string{}
Expand Down Expand Up @@ -146,6 +146,8 @@ func RenderCatalogSearch(ctx *context.Context, opts *CatalogSearchOptions) {
MetadataTypes: searchMap["metadata_type"],
MetadataVersions: searchMap["metadata_version"],
Topics: searchMap["topic"],
InvertedTopics: searchMap["topic_inverted"],
Healthchecks: searchMap["healthcheck"],
Tags: searchMap["tag"],
CheckingLevels: searchMap["checking_level"],
})
Expand Down
4 changes: 3 additions & 1 deletion routers/web/explore/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {

/*** DCS Customizations ***/
origKeyword := keyword
searchFields := []string{"keyword", "book", "lang", "subject", "flavor_type", "flavor", "abbreviation", "content_format", "repo", "owner", "tag", "checking_level", "metadata_type", "metadata_version", "topic", "stage"}
searchFields := []string{"keyword", "book", "lang", "subject", "flavor_type", "flavor", "abbreviation", "content_format", "repo", "owner", "tag", "checking_level", "metadata_type", "metadata_version", "topic", "topic_inverted", "healthcheck", "stage"}
searchMap := map[string][]string{}
for _, field := range searchFields {
searchMap[field] = []string{}
Expand Down Expand Up @@ -157,6 +157,8 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
MetadataTypes: searchMap["metadata_type"], // DCS Customizations
MetadataVersions: searchMap["metadata_version"], // DCS Customizations
Topics: searchMap["topic"], // DCS Customizations
InvertedTopics: searchMap["topic_inverted"], // DCS Customizations
Healthchecks: searchMap["healthcheck"], // DCS Customizations
OnlyShowRelevant: opts.OnlyShowRelevant,
})
if err != nil {
Expand Down
7 changes: 5 additions & 2 deletions templates/shared/searchbuilder.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#search-builder .input-group {
display: flex;
flex-wrap: wrap;
max-width: 50%;
margin-bottom: 10px;
flex: 1 1 45%;
/* Grow to fill space, but not more than 45% */
Expand Down Expand Up @@ -80,8 +81,9 @@
const catalogOnlyFields = ['stage', 'tag'];
const searchFields = [
{ name: 'query', tooltip: 'queries repo name, owner, description & topics. Allows partial match' },
{ name: 'topic', tooltip: 'the topic of a repo, e.g. tc-ready' },
{ name: 'lang', tooltip: 'language code, e.g. en, fr' },
{ name: 'topic', tooltip: 'the topic of a repo, e.g. tc-ready' },
{ name: 'topic_inverted', tooltip: 'show entries that do NOT have this topic' },
{ name: 'subject', tooltip: 'type of resource, e.g. Aligned Bible, Open Bibles Stories', options: ["Aligned Bible", "Aramaic Grammar", "Bible", "Greek Grammar", "Greek Lexicon", "Greek New Testament", "Hebrew Grammar", "Hebrew Old Testament", "Hebrew-Aramaic Lexicon", "OBS Study Notes", "OBS Study Questions", "OBS Translation Notes", "OBS Translation Questions", "Open Bible Stories", "Study Notes", "Study Questions", "Training Library", "Translation Academy", "Translation Notes", "Translation Questions", "Translation Words", "TSV Study Notes", "TSV Study Questions", "TSV Translation Notes", "TSV Translation Questions", "TSV Translation Words Links", "TSV OBS Study Notes", "TSV OBS Study Questions", "TSV OBS Translation Notes", "TSV OBS Translation Questions", "TSV OBS Translation Words Links"] },
{ name: 'owner', tooltip: 'user or organization, e.g. unfoldingWord' },
{ name: 'repo', tooltip: 'repository name, e.g. en_ult' },
Expand All @@ -93,6 +95,7 @@
{ name: 'content_format', tooltip: 'content format, e.g. markdown, tsv7, tsv9, usfm', options: ['markdown', 'tsv7', 'tsv9', 'usfm'] },
{ name: 'tag', tooltip: 'released with the given tag, e.g. v3' },
{ name: 'stage', tooltip: 'stage of the release: prod, preprod, latest or other', options: ['prod', 'preprod', 'latest', 'other'] },
{ name: 'healthcheck', tooltip: 'healthcheck severity level: error, warning, info or success', options: ['error', 'warning', 'info', 'success'] }
];
qInput.addEventListener('input', updateAdvancedFields);
Expand All @@ -105,7 +108,7 @@
const label = document.createElement('label');
label.className = 'input-label';
label.setAttribute('for', fieldObj.name);
label.textContent = fieldObj.name + ':';
label.textContent = fieldObj.name.replace('_', ' ') + ':';
label.setAttribute('title', fieldObj.tooltip);
const input = document.createElement('input');
Expand Down

0 comments on commit beedf2d

Please sign in to comment.