grafana/pkg/services/search/handlers.go
2017-06-12 16:48:51 +02:00

168 lines
3.3 KiB
Go

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/services/guardian"
"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,
DashboardIds: query.DashboardIds,
Type: query.Type,
ParentId: query.FolderId,
Mode: query.Mode,
}
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
}
hits, err := removeRestrictedDashboardsFromList(hits, query)
if err != nil {
return err
}
// 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 removeRestrictedDashboardsFromList(hits HitList, query *Query) (HitList, error) {
var dashboardIds = []int64{}
for _, hit := range hits {
dashboardIds = append(dashboardIds, hit.Id)
}
filteredHits, err := guardian.FilterRestrictedDashboards(dashboardIds, query.OrgId, query.UserId)
if err != nil {
return nil, err
}
filtered := HitList{}
for _, hit := range hits {
for _, dashId := range filteredHits {
if hit.Id == dashId {
filtered = append(filtered, hit)
}
}
}
return filtered, 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)
}