summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/mattermost-server/model/search_params.go
diff options
context:
space:
mode:
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.go171
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
+}