Passed
Push — master ( 23ac56...137631 )
by Viktor
01:39
created

main.commandHandler   C

Complexity

Conditions 10

Size

Total Lines 68
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 55
nop 2
dl 0
loc 68
rs 5.6727
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like main.commandHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package main
2
3
import (
4
	"bytes"
5
	"fmt"
6
	"gopkg.in/robfig/cron.v2"
7
	"net/http"
8
	"os"
9
	"os/signal"
10
	"strings"
11
	"syscall"
12
	"time"
13
14
	"github.com/FlameInTheDark/dtbot/bot"
15
	"github.com/FlameInTheDark/dtbot/cmd"
16
	"github.com/bwmarrin/discordgo"
17
)
18
19
var (
20
	conf *bot.Config
21
	// CmdHandler bot command handler
22
	CmdHandler *bot.CommandHandler
23
	// Sessions bot session manager
24
	Sessions        *bot.SessionManager
25
	botId           string
0 ignored issues
show
introduced by
var botId should be botID
Loading history...
26
	youtube         *bot.Youtube
27
	botMsg          *bot.BotMessages
28
	dataType        *bot.DataType
29
	dbWorker        *bot.DBWorker
30
	guilds          bot.GuildsMap
31
	botCron         *cron.Cron
32
	messagesCounter int
33
)
34
35
func main() {
36
	botCron = cron.New()
37
	conf = bot.LoadConfig()
38
	CmdHandler = bot.NewCommandHandler()
39
	registerCommands()
40
	Sessions = bot.NewSessionManager()
41
	youtube = &bot.Youtube{Conf: conf}
42
	botMsg = bot.NewMessagesMap()
43
	dataType = bot.NewDataType()
44
	discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
45
	if err != nil {
46
		fmt.Println("Create session error, ", err)
47
		return
48
	}
49
	usr, err := discord.User("@me")
50
	if err != nil {
51
		fmt.Println("Error obtaining account details,", err)
52
		return
53
	}
54
	botId = usr.ID
55
	discord.AddHandler(commandHandler)
56
	discord.AddHandler(func(discord *discordgo.Session, ready *discordgo.Ready) {
57
		discord.UpdateStatus(0, conf.General.Game)
58
		guilds := discord.State.Guilds
59
		fmt.Println("Ready with", len(guilds), "guilds.")
60
	})
61
62
	err = discord.Open()
63
	if err != nil {
64
		fmt.Printf("Connection open error: %v", err)
65
		return
66
	}
67
	defer discord.Close()
68
	fmt.Println("Bot is now running.")
69
70
	sc := make(chan os.Signal, 1)
71
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
72
	dbWorker = bot.NewDBSession(conf.General.DatabaseName)
73
	guilds = dbWorker.InitGuilds(discord, conf)
74
	botCron.Start()
75
	go MetricsSender()
76
	defer botCron.Stop()
77
	defer dbWorker.DBSession.Close()
78
	<-sc
79
}
80
81
// Handle discord messages
82
func commandHandler(discord *discordgo.Session, message *discordgo.MessageCreate) {
83
	messagesCounter++
84
	user := message.Author
85
	if user.ID == botId || user.Bot {
86
		return
87
	}
88
	args := strings.Split(message.Content, " ")
89
	name := strings.ToLower(args[0])
90
	command, found := CmdHandler.Get(name)
91
	if !found {
92
		return
93
	}
94
95
	var permission = true
96
	var msg string
97
	// Checking permissions
98
	perm, err := discord.State.UserChannelPermissions(botId, message.ChannelID)
99
	if err != nil {
100
		//dbWorker.Log("Message", guild.ID, fmt.Sprintf("Error whilst getting bot permissions %v\n", err))
101
		msg = fmt.Sprintf("Error whilst getting bot permissions %v\n", err)
102
		permission = false
103
	} else {
104
		if perm&discordgo.PermissionSendMessages != discordgo.PermissionSendMessages ||
105
			perm&discordgo.PermissionAttachFiles != discordgo.PermissionAttachFiles {
106
			//dbWorker.Log("Message", guild.ID, fmt.Sprintf("Permissions denied"))
107
			msg = "Permissions denied"
108
			permission = false
109
		}
110
	}
111
112
	channel, err := discord.State.Channel(message.ChannelID)
113
	if err != nil {
114
		fmt.Println("Error getting channel,", err)
115
		return
116
	}
117
	guild, err := discord.State.Guild(channel.GuildID)
118
	if err != nil {
119
		fmt.Println("Error getting guild,", err)
120
		return
121
	}
122
123
	if permission {
124
		ctx := bot.NewContext(
125
			botId,
126
			discord,
127
			guild,
128
			channel,
129
			user,
130
			message,
131
			conf,
132
			CmdHandler,
133
			Sessions,
134
			youtube,
135
			botMsg,
136
			dataType,
137
			dbWorker,
138
			guilds,
139
			botCron)
140
		ctx.Args = args[1:]
141
		c := *command
142
		c(*ctx)
143
		//ctx.MetricsMessage()
144
	} else {
145
		dbWorker.Log("Message", guild.ID, msg)
146
		query := []byte(fmt.Sprintf("logs,server=%v module=\"%v\"", guild.ID, "message"))
147
		addr := fmt.Sprintf("%v/write?db=%v", conf.Metrics.Address, conf.Metrics.Database)
148
		r := bytes.NewReader(query)
149
		_, _ = http.Post(addr, "", r)
150
	}
151
}
152
153
// Adds bot commands
154
func registerCommands() {
155
	CmdHandler.Register("!r", cmd.PlayerCommand)
156
	CmdHandler.Register("!w", cmd.WeatherCommand)
157
	CmdHandler.Register("!t", cmd.TranslateCommand)
158
	CmdHandler.Register("!n", cmd.NewsCommand)
159
	CmdHandler.Register("!c", cmd.CurrencyCommand)
160
	CmdHandler.Register("!y", cmd.YoutubeCommand)
161
	CmdHandler.Register("!v", cmd.VoiceCommand)
162
	CmdHandler.Register("!b", cmd.BotCommand)
163
	CmdHandler.Register("!play", cmd.YoutubeShortCommand)
164
	CmdHandler.Register("!d", cmd.DebugCommand)
165
	CmdHandler.Register("!p", cmd.PollCommand)
166
	CmdHandler.Register("!m", cmd.YandexmapCommand)
167
	CmdHandler.Register("!dice", cmd.DiceCommand)
168
	CmdHandler.Register("!help", cmd.HelpCommand)
169
	CmdHandler.Register("!cron", cmd.CronCommand)
170
}
171
172
func MetricsSender() {
0 ignored issues
show
introduced by
exported function MetricsSender should have comment or be unexported
Loading history...
173
	for {
174
		query := []byte(fmt.Sprintf("messages count=%v", messagesCounter))
175
		addr := fmt.Sprintf("%v/write?db=%v", conf.Metrics.Address, conf.Metrics.Database)
176
		r := bytes.NewReader(query)
177
		_, _ = http.Post(addr, "", r)
178
		messagesCounter = 0
179
		time.Sleep(time.Minute)
180
	}
181
}