diff options
Diffstat (limited to 'vendor/github.com/mattermost/mattermost-server/model/search_params.go')
-rw-r--r-- | vendor/github.com/mattermost/mattermost-server/model/search_params.go | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/vendor/github.com/mattermost/mattermost-server/model/search_params.go b/vendor/github.com/mattermost/mattermost-server/model/search_params.go new file mode 100644 index 00000000..1692b3aa --- /dev/null +++ b/vendor/github.com/mattermost/mattermost-server/model/search_params.go @@ -0,0 +1,171 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "encoding/json" + "regexp" + "strings" +) + +var searchTermPuncStart = regexp.MustCompile(`^[^\pL\d\s#"]+`) +var searchTermPuncEnd = regexp.MustCompile(`[^\pL\d\s*"]+$`) + +type SearchParams struct { + Terms string + IsHashtag bool + InChannels []string + FromUsers []string + OrTerms bool +} + +func (o *SearchParams) ToJson() string { + b, _ := json.Marshal(o) + return string(b) +} + +var searchFlags = [...]string{"from", "channel", "in"} + +func splitWords(text string) []string { + words := []string{} + + foundQuote := false + location := 0 + for i, char := range text { + if char == '"' { + if foundQuote { + // Grab the quoted section + word := text[location : i+1] + words = append(words, word) + foundQuote = false + location = i + 1 + } else { + words = append(words, strings.Fields(text[location:i])...) + foundQuote = true + location = i + } + } + } + + words = append(words, strings.Fields(text[location:])...) + + return words +} + +func parseSearchFlags(input []string) ([]string, [][2]string) { + words := []string{} + flags := [][2]string{} + + skipNextWord := false + for i, word := range input { + if skipNextWord { + skipNextWord = false + continue + } + + isFlag := false + + if colon := strings.Index(word, ":"); colon != -1 { + flag := word[:colon] + value := word[colon+1:] + + for _, searchFlag := range searchFlags { + // check for case insensitive equality + if strings.EqualFold(flag, searchFlag) { + if value != "" { + flags = append(flags, [2]string{searchFlag, value}) + isFlag = true + } else if i < len(input)-1 { + flags = append(flags, [2]string{searchFlag, input[i+1]}) + skipNextWord = true + isFlag = true + } + + if isFlag { + break + } + } + } + } + + if !isFlag { + // trim off surrounding punctuation (note that we leave trailing asterisks to allow wildcards) + word = searchTermPuncStart.ReplaceAllString(word, "") + word = searchTermPuncEnd.ReplaceAllString(word, "") + + // and remove extra pound #s + word = hashtagStart.ReplaceAllString(word, "#") + + if len(word) != 0 { + words = append(words, word) + } + } + } + + return words, flags +} + +func ParseSearchParams(text string) []*SearchParams { + words, flags := parseSearchFlags(splitWords(text)) + + hashtagTermList := []string{} + plainTermList := []string{} + + for _, word := range words { + if validHashtag.MatchString(word) { + hashtagTermList = append(hashtagTermList, word) + } else { + plainTermList = append(plainTermList, word) + } + } + + hashtagTerms := strings.Join(hashtagTermList, " ") + plainTerms := strings.Join(plainTermList, " ") + + inChannels := []string{} + fromUsers := []string{} + + for _, flagPair := range flags { + flag := flagPair[0] + value := flagPair[1] + + if flag == "in" || flag == "channel" { + inChannels = append(inChannels, value) + } else if flag == "from" { + fromUsers = append(fromUsers, value) + } + } + + paramsList := []*SearchParams{} + + if len(plainTerms) > 0 { + paramsList = append(paramsList, &SearchParams{ + Terms: plainTerms, + IsHashtag: false, + InChannels: inChannels, + FromUsers: fromUsers, + }) + } + + if len(hashtagTerms) > 0 { + paramsList = append(paramsList, &SearchParams{ + Terms: hashtagTerms, + IsHashtag: true, + InChannels: inChannels, + FromUsers: fromUsers, + }) + } + + // special case for when no terms are specified but we still have a filter + if len(plainTerms) == 0 && len(hashtagTerms) == 0 && (len(inChannels) != 0 || len(fromUsers) != 0) { + paramsList = append(paramsList, &SearchParams{ + Terms: "", + IsHashtag: false, + InChannels: inChannels, + FromUsers: fromUsers, + }) + } + + return paramsList +} |