first commit
Этот коммит содержится в:
470
api/command.go
Обычный файл
470
api/command.go
Обычный файл
@@ -0,0 +1,470 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
l4g "code.google.com/p/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type commandHandler func(c *Context, command *model.Command) bool
|
||||
|
||||
var commands = []commandHandler{
|
||||
logoutCommand,
|
||||
joinCommand,
|
||||
loadTestCommand,
|
||||
echoCommand,
|
||||
}
|
||||
|
||||
func InitCommand(r *mux.Router) {
|
||||
l4g.Debug("Initializing command api routes")
|
||||
r.Handle("/command", ApiUserRequired(command)).Methods("POST")
|
||||
hub.Start()
|
||||
}
|
||||
|
||||
func command(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
props := model.MapFromJson(r.Body)
|
||||
|
||||
command := &model.Command{
|
||||
Command: strings.TrimSpace(props["command"]),
|
||||
ChannelId: strings.TrimSpace(props["channelId"]),
|
||||
Suggest: props["suggest"] == "true",
|
||||
Suggestions: make([]*model.SuggestCommand, 0, 128),
|
||||
}
|
||||
|
||||
checkCommand(c, command)
|
||||
|
||||
if c.Err != nil {
|
||||
return
|
||||
} else {
|
||||
w.Write([]byte(command.ToJson()))
|
||||
}
|
||||
}
|
||||
|
||||
func checkCommand(c *Context, command *model.Command) bool {
|
||||
|
||||
if len(command.Command) == 0 || strings.Index(command.Command, "/") != 0 {
|
||||
c.Err = model.NewAppError("checkCommand", "Command must start with /", "")
|
||||
return false
|
||||
}
|
||||
|
||||
if len(command.ChannelId) > 0 {
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, command.ChannelId, c.Session.UserId)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "checkCommand") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range commands {
|
||||
if v(c, command) {
|
||||
return true
|
||||
} else if c.Err != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func logoutCommand(c *Context, command *model.Command) bool {
|
||||
|
||||
cmd := "/logout"
|
||||
|
||||
if strings.Index(command.Command, cmd) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd, Description: "Logout"})
|
||||
|
||||
if !command.Suggest {
|
||||
command.GotoLocation = "/logout"
|
||||
command.Response = model.RESP_EXECUTED
|
||||
return true
|
||||
}
|
||||
|
||||
} else if strings.Index(cmd, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd, Description: "Logout"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func echoCommand(c *Context, command *model.Command) bool {
|
||||
|
||||
cmd := "/echo"
|
||||
|
||||
if strings.Index(command.Command, cmd) == 0 {
|
||||
parts := strings.SplitN(command.Command, " ", 3)
|
||||
|
||||
channelName := ""
|
||||
if len(parts) >= 2 {
|
||||
channelName = parts[1]
|
||||
}
|
||||
|
||||
message := ""
|
||||
if len(parts) >= 3 {
|
||||
message = parts[2]
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return false
|
||||
} else {
|
||||
channels := result.Data.(*model.ChannelList)
|
||||
|
||||
for _, v := range channels.Channels {
|
||||
if v.Type == model.CHANNEL_DIRECT {
|
||||
continue
|
||||
}
|
||||
|
||||
if v.Name == channelName && !command.Suggest {
|
||||
post := &model.Post{}
|
||||
post.ChannelId = v.Id
|
||||
post.Message = message
|
||||
|
||||
if _, err := CreateValetPost(c, post); err != nil {
|
||||
c.Err = err
|
||||
return false
|
||||
}
|
||||
|
||||
command.Response = model.RESP_EXECUTED
|
||||
return true
|
||||
}
|
||||
|
||||
if len(channelName) == 0 || (strings.Index(v.Name, channelName) == 0 && len(parts) < 3) {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd + " " + v.Name, Description: "Echo a message using Valet in a channel"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if strings.Index(cmd, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd, Description: "Echo a message using Valet in a channel"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func joinCommand(c *Context, command *model.Command) bool {
|
||||
|
||||
// looks for "/join channel-name"
|
||||
cmd := "/join"
|
||||
|
||||
if strings.Index(command.Command, cmd) == 0 {
|
||||
|
||||
parts := strings.Split(command.Command, " ")
|
||||
|
||||
startsWith := ""
|
||||
|
||||
if len(parts) == 2 {
|
||||
startsWith = parts[1]
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Channel().GetMoreChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return false
|
||||
} else {
|
||||
channels := result.Data.(*model.ChannelList)
|
||||
|
||||
for _, v := range channels.Channels {
|
||||
|
||||
if v.Name == startsWith && !command.Suggest {
|
||||
|
||||
if v.Type == model.CHANNEL_DIRECT {
|
||||
return false
|
||||
}
|
||||
|
||||
JoinChannel(c, v.Id, "/command")
|
||||
|
||||
if c.Err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
command.GotoLocation = "/channels/" + v.Name
|
||||
command.Response = model.RESP_EXECUTED
|
||||
return true
|
||||
}
|
||||
|
||||
if len(startsWith) == 0 || strings.Index(v.Name, startsWith) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd + " " + v.Name, Description: "Join the open channel"})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if strings.Index(cmd, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd, Description: "Join an open channel"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func loadTestCommand(c *Context, command *model.Command) bool {
|
||||
cmd := "/loadtest"
|
||||
|
||||
// This command is only available when AllowTesting is true
|
||||
if !utils.Cfg.ServiceSettings.AllowTesting {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.Index(command.Command, cmd) == 0 {
|
||||
if loadTestSetupCommand(c, command) {
|
||||
return true
|
||||
}
|
||||
if loadTestUsersCommand(c, command) {
|
||||
return true
|
||||
}
|
||||
if loadTestChannelsCommand(c, command) {
|
||||
return true
|
||||
}
|
||||
if loadTestPostsCommand(c, command) {
|
||||
return true
|
||||
}
|
||||
} else if strings.Index(cmd, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd, Description: "Debug Load Testing"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func parseRange(command string, cmd string) (utils.Range, bool) {
|
||||
tokens := strings.Fields(strings.TrimPrefix(command, cmd))
|
||||
var begin int
|
||||
var end int
|
||||
var err1 error
|
||||
var err2 error
|
||||
switch {
|
||||
case len(tokens) == 1:
|
||||
begin, err1 = strconv.Atoi(tokens[0])
|
||||
end = begin
|
||||
if err1 != nil {
|
||||
return utils.Range{0, 0}, false
|
||||
}
|
||||
case len(tokens) >= 2:
|
||||
begin, err1 = strconv.Atoi(tokens[0])
|
||||
end, err2 = strconv.Atoi(tokens[1])
|
||||
if err1 != nil || err2 != nil {
|
||||
return utils.Range{0, 0}, false
|
||||
}
|
||||
default:
|
||||
return utils.Range{0, 0}, false
|
||||
}
|
||||
return utils.Range{begin, end}, true
|
||||
}
|
||||
|
||||
func contains(items []string, token string) bool {
|
||||
for _, elem := range items {
|
||||
if elem == token {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func loadTestSetupCommand(c *Context, command *model.Command) bool {
|
||||
cmd := "/loadtest setup"
|
||||
|
||||
if strings.Index(command.Command, cmd) == 0 && !command.Suggest {
|
||||
tokens := strings.Fields(strings.TrimPrefix(command.Command, cmd))
|
||||
doTeams := contains(tokens, "teams")
|
||||
doFuzz := contains(tokens, "fuzz")
|
||||
|
||||
numArgs := 0
|
||||
if doTeams {
|
||||
numArgs++
|
||||
}
|
||||
if doFuzz {
|
||||
numArgs++
|
||||
}
|
||||
|
||||
var numTeams int
|
||||
var numChannels int
|
||||
var numUsers int
|
||||
var numPosts int
|
||||
|
||||
// Defaults
|
||||
numTeams = 10
|
||||
numChannels = 10
|
||||
numUsers = 10
|
||||
numPosts = 10
|
||||
|
||||
if doTeams {
|
||||
if (len(tokens) - numArgs) >= 4 {
|
||||
numTeams, _ = strconv.Atoi(tokens[numArgs+0])
|
||||
numChannels, _ = strconv.Atoi(tokens[numArgs+1])
|
||||
numUsers, _ = strconv.Atoi(tokens[numArgs+2])
|
||||
numPosts, _ = strconv.Atoi(tokens[numArgs+3])
|
||||
}
|
||||
} else {
|
||||
if (len(tokens) - numArgs) >= 3 {
|
||||
numChannels, _ = strconv.Atoi(tokens[numArgs+0])
|
||||
numUsers, _ = strconv.Atoi(tokens[numArgs+1])
|
||||
numPosts, _ = strconv.Atoi(tokens[numArgs+2])
|
||||
}
|
||||
}
|
||||
client := model.NewClient(c.TeamUrl + "/api/v1")
|
||||
|
||||
if doTeams {
|
||||
if err := CreateBasicUser(client); err != nil {
|
||||
l4g.Error("Failed to create testing enviroment")
|
||||
return true
|
||||
}
|
||||
client.LoginByEmail(BTEST_TEAM_DOMAIN_NAME, BTEST_USER_EMAIL, BTEST_USER_PASSWORD)
|
||||
enviroment, err := CreateTestEnviromentWithTeams(
|
||||
client,
|
||||
utils.Range{numTeams, numTeams},
|
||||
utils.Range{numChannels, numChannels},
|
||||
utils.Range{numUsers, numUsers},
|
||||
utils.Range{numPosts, numPosts},
|
||||
doFuzz)
|
||||
if err != true {
|
||||
l4g.Error("Failed to create testing enviroment")
|
||||
return true
|
||||
} else {
|
||||
l4g.Info("Testing enviroment created")
|
||||
for i := 0; i < len(enviroment.Teams); i++ {
|
||||
l4g.Info("Team Created: " + enviroment.Teams[i].Domain)
|
||||
l4g.Info("\t User to login: " + enviroment.Enviroments[i].Users[0].Email + ", " + USER_PASSWORD)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
client.MockSession(c.Session.Id)
|
||||
CreateTestEnviromentInTeam(
|
||||
client,
|
||||
c.Session.TeamId,
|
||||
utils.Range{numChannels, numChannels},
|
||||
utils.Range{numUsers, numUsers},
|
||||
utils.Range{numPosts, numPosts},
|
||||
doFuzz)
|
||||
}
|
||||
return true
|
||||
} else if strings.Index(cmd, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{
|
||||
Suggestion: cmd,
|
||||
Description: "Creates a testing enviroment in current team. [teams] [fuzz] <Num Channels> <Num Users> <NumPosts>"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func loadTestUsersCommand(c *Context, command *model.Command) bool {
|
||||
cmd1 := "/loadtest users"
|
||||
cmd2 := "/loadtest users fuzz"
|
||||
|
||||
if strings.Index(command.Command, cmd1) == 0 && !command.Suggest {
|
||||
cmd := cmd1
|
||||
doFuzz := false
|
||||
if strings.Index(command.Command, cmd2) == 0 {
|
||||
doFuzz = true
|
||||
cmd = cmd2
|
||||
}
|
||||
usersr, err := parseRange(command.Command, cmd)
|
||||
if err == false {
|
||||
usersr = utils.Range{10, 15}
|
||||
}
|
||||
client := model.NewClient(c.TeamUrl + "/api/v1")
|
||||
userCreator := NewAutoUserCreator(client, c.Session.TeamId)
|
||||
userCreator.Fuzzy = doFuzz
|
||||
userCreator.CreateTestUsers(usersr)
|
||||
return true
|
||||
} else if strings.Index(cmd1, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd1, Description: "Add a specified number of random users to current team <Min Users> <Max Users>"})
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add a specified number of random users with fuzz text to current team <Min Users> <Max Users>"})
|
||||
} else if strings.Index(cmd2, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add a specified number of random users with fuzz text to current team <Min Users> <Max Users>"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func loadTestChannelsCommand(c *Context, command *model.Command) bool {
|
||||
cmd1 := "/loadtest channels"
|
||||
cmd2 := "/loadtest channels fuzz"
|
||||
|
||||
if strings.Index(command.Command, cmd1) == 0 && !command.Suggest {
|
||||
cmd := cmd1
|
||||
doFuzz := false
|
||||
if strings.Index(command.Command, cmd2) == 0 {
|
||||
doFuzz = true
|
||||
cmd = cmd2
|
||||
}
|
||||
channelsr, err := parseRange(command.Command, cmd)
|
||||
if err == false {
|
||||
channelsr = utils.Range{20, 30}
|
||||
}
|
||||
client := model.NewClient(c.TeamUrl + "/api/v1")
|
||||
client.MockSession(c.Session.Id)
|
||||
channelCreator := NewAutoChannelCreator(client, c.Session.TeamId)
|
||||
channelCreator.Fuzzy = doFuzz
|
||||
channelCreator.CreateTestChannels(channelsr)
|
||||
return true
|
||||
} else if strings.Index(cmd1, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd1, Description: "Add a specified number of random channels to current team <MinChannels> <MaxChannels>"})
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add a specified number of random channels with fuzz text to current team <Min Channels> <Max Channels>"})
|
||||
} else if strings.Index(cmd2, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add a specified number of random channels with fuzz text to current team <Min Channels> <Max Channels>"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func loadTestPostsCommand(c *Context, command *model.Command) bool {
|
||||
cmd1 := "/loadtest posts"
|
||||
cmd2 := "/loadtest posts fuzz"
|
||||
|
||||
if strings.Index(command.Command, cmd1) == 0 && !command.Suggest {
|
||||
cmd := cmd1
|
||||
doFuzz := false
|
||||
if strings.Index(command.Command, cmd2) == 0 {
|
||||
cmd = cmd2
|
||||
doFuzz = true
|
||||
}
|
||||
|
||||
postsr, err := parseRange(command.Command, cmd)
|
||||
if err == false {
|
||||
postsr = utils.Range{20, 30}
|
||||
}
|
||||
|
||||
tokens := strings.Fields(strings.TrimPrefix(command.Command, cmd))
|
||||
rimages := utils.Range{0, 0}
|
||||
if len(tokens) >= 3 {
|
||||
if numImages, err := strconv.Atoi(tokens[2]); err == nil {
|
||||
rimages = utils.Range{numImages, numImages}
|
||||
}
|
||||
}
|
||||
|
||||
var usernames []string
|
||||
if result := <-Srv.Store.User().GetProfiles(c.Session.TeamId); result.Err == nil {
|
||||
profileUsers := result.Data.(map[string]*model.User)
|
||||
usernames = make([]string, len(profileUsers))
|
||||
i := 0
|
||||
for _, userprof := range profileUsers {
|
||||
usernames[i] = userprof.Username
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
client := model.NewClient(c.TeamUrl + "/api/v1")
|
||||
client.MockSession(c.Session.Id)
|
||||
testPoster := NewAutoPostCreator(client, command.ChannelId)
|
||||
testPoster.Fuzzy = doFuzz
|
||||
testPoster.Users = usernames
|
||||
|
||||
numImages := utils.RandIntFromRange(rimages)
|
||||
numPosts := utils.RandIntFromRange(postsr)
|
||||
for i := 0; i < numPosts; i++ {
|
||||
testPoster.HasImage = (i < numImages)
|
||||
testPoster.CreateRandomPost()
|
||||
}
|
||||
return true
|
||||
} else if strings.Index(cmd1, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd1, Description: "Add some random posts to current channel <Min Posts> <Max Posts> <Min Images> <Max Images>"})
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add some random posts with fuzz text to current channel <Min Posts> <Max Posts> <Min Images> <Max Images>"})
|
||||
} else if strings.Index(cmd2, command.Command) == 0 {
|
||||
command.AddSuggestion(&model.SuggestCommand{Suggestion: cmd2, Description: "Add some random posts with fuzz text to current channel <Min Posts> <Max Posts> <Min Images> <Max Images>"})
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Ссылка в новой задаче
Block a user