package search import ( "log" "path/filepath" "sort" "github.com/grafana/grafana/pkg/bus" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" ) var jsonDashIndex *JsonDashIndex func Init() { bus.AddHandler("search", searchHandler) jsonIndexCfg, _ := setting.Cfg.GetSection("dashboards.json") if jsonIndexCfg == nil { log.Fatal("Config section missing: dashboards.json") return } jsonIndexEnabled := jsonIndexCfg.Key("enabled").MustBool(false) if jsonIndexEnabled { jsonFilesPath := jsonIndexCfg.Key("path").String() if !filepath.IsAbs(jsonFilesPath) { jsonFilesPath = filepath.Join(setting.HomePath, jsonFilesPath) } jsonDashIndex = NewJsonDashIndex(jsonFilesPath) go jsonDashIndex.updateLoop() } } func searchHandler(query *Query) error { hits := make(HitList, 0) dashQuery := FindPersistedDashboardsQuery{ Title: query.Title, UserId: query.UserId, IsStarred: query.IsStarred, OrgId: query.OrgId, } if err := bus.Dispatch(&dashQuery); err != nil { return err } hits = append(hits, dashQuery.Result...) if jsonDashIndex != nil { jsonHits, err := jsonDashIndex.Search(query) if err != nil { return err } hits = append(hits, jsonHits...) } // filter out results with tag filter if len(query.Tags) > 0 { filtered := HitList{} for _, hit := range hits { if hasRequiredTags(query.Tags, hit.Tags) { filtered = append(filtered, hit) } } hits = filtered } // sort main result array sort.Sort(hits) if len(hits) > query.Limit { hits = hits[0:query.Limit] } // sort tags for _, hit := range hits { sort.Strings(hit.Tags) } // add isStarred info if err := setIsStarredFlagOnSearchResults(query.UserId, hits); err != nil { return err } query.Result = hits return nil } func stringInSlice(a string, list []string) bool { for _, b := range list { if b == a { return true } } return false } func hasRequiredTags(queryTags, hitTags []string) bool { for _, queryTag := range queryTags { if !stringInSlice(queryTag, hitTags) { return false } } return true } func setIsStarredFlagOnSearchResults(userId int64, hits []*Hit) error { query := m.GetUserStarsQuery{UserId: userId} if err := bus.Dispatch(&query); err != nil { return err } for _, dash := range hits { if _, exists := query.Result[dash.Id]; exists { dash.IsStarred = true } } return nil } func GetDashboardFromJsonIndex(filename string) *m.Dashboard { if jsonDashIndex == nil { return nil } return jsonDashIndex.GetDashboard(filename) }