slack-smart-bot 1.12.7 → 1.12.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +521 -471
- data/lib/slack/smart-bot/process.rb +8 -1
- data/whats_new.txt +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce7ad9b141fa627afb25ac3a20fcf6e6b9d452105866620681c5430c691023be
|
|
4
|
+
data.tar.gz: 40cb7e645794af392d687afa6a4a839d9e7d9f1113a6fc90862cd6da3a0dedce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af7a0da5cf90b055fe4dc48c781823e1941f0ceb8b2747d60dcd43ef44ceb2e380cd8a15ddc016ee7201b9e26e93ab8991db07bb2bea99bdfb69d751ed8fc7cb
|
|
7
|
+
data.tar.gz: 67cf9020b2894fab2fcb8c8082cc94e63d1e5e52eabc91dc8544b1f050fc948127f564687fd339f04f1f98a1fa8a2fdaa246f65e31ac93b06a18a10bef028596
|
|
@@ -1,501 +1,551 @@
|
|
|
1
1
|
class SlackSmartBot
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
2
|
+
# help: ----------------------------------------------
|
|
3
|
+
# help: `bot stats`
|
|
4
|
+
# helpmaster: `bot stats USER_NAME`
|
|
5
|
+
# help: `bot stats exclude masters`
|
|
6
|
+
# help: `bot stats exclude routines`
|
|
7
|
+
# help: `bot stats from YYYY/MM/DD`
|
|
8
|
+
# help: `bot stats from YYYY/MM/DD to YYYY/MM/DD`
|
|
9
|
+
# help: `bot stats CHANNEL`
|
|
10
|
+
# help: `bot stats CHANNEL from YYYY/MM/DD`
|
|
11
|
+
# help: `bot stats CHANNEL from YYYY/MM/DD to YYYY/MM/DD`
|
|
12
|
+
# help: `bot stats command COMMAND`
|
|
13
|
+
# helpmaster: `bot stats USER_NAME from YYYY/MM/DD to YYYY/MM/DD`
|
|
14
|
+
# helpmaster: `bot stats CHANNEL USER_NAME from YYYY/MM/DD to YYYY/MM/DD`
|
|
15
|
+
# help: `bot stats CHANNEL exclude masters from YYYY/MM/DD to YYYY/MM/DD`
|
|
16
|
+
# help: `bot stats HEADER /REGEXP/`
|
|
17
|
+
# help: `bot stats members #CHANNEL`
|
|
18
|
+
# help: `bot stats exclude members #CHANNEL`
|
|
19
|
+
# help: `bot stats today`
|
|
20
|
+
# help: `bot stats yesterday`
|
|
21
|
+
# help: `bot stats last month`
|
|
22
|
+
# help: `bot stats this month`
|
|
23
|
+
# help: `bot stats last week`
|
|
24
|
+
# help: `bot stats this week`
|
|
25
|
+
# help: `bot stats exclude COMMAND_ID`
|
|
26
|
+
# help: `bot stats monthly`
|
|
27
|
+
# help: `bot stats alldata`
|
|
28
|
+
# help: To see the bot stats
|
|
29
|
+
# helpmaster: You can use this command only if you are a Master admin user and if you are in a private conversation with the bot, or you are on the Smartbot-stats channel
|
|
30
|
+
# helpmaster: You need to set stats to true to generate the stats when running the bot instance.
|
|
31
|
+
# help: members #CHANNEL will return stats for only members of the channel supplied
|
|
32
|
+
# help: exclude members #CHANNEL will return stats for only members that are not members of the channel supplied
|
|
33
|
+
# help: HEADER /REGEXP/ will return stats for only the rows that match the regexp on the stats header supplied
|
|
34
|
+
# help: If alldata option supplied then it will be attached files including all data and not only the top 10.
|
|
35
|
+
# help: Examples:
|
|
36
|
+
# help: _bot stats #sales_
|
|
37
|
+
# helpmaster: _bot stats @peter.wind_
|
|
38
|
+
# help: _bot stats #sales from 2019/12/15 to 2019/12/31_
|
|
39
|
+
# help: _bot stats #sales today_
|
|
40
|
+
# help: _bot stats #sales from 2020-01-01 monthly_
|
|
41
|
+
# help: _bot stats exclude routines masters from 2021/01/01 monthly_
|
|
42
|
+
# help: _bot stats members #development from 2022/01/01 to 2022/01/31_\
|
|
43
|
+
# help: _bot stats type_message /(on_pub|on_pg)/_
|
|
44
|
+
# help: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
|
|
45
|
+
# help: command_id: :bot_stats
|
|
46
|
+
# help:
|
|
47
|
+
def bot_stats(dest, from_user, typem, channel_id, from, to, user, st_command, exclude_masters, exclude_routines, exclude_command, monthly, all_data, members_channel, exclude_members_channel, header, regexp)
|
|
48
|
+
require "csv"
|
|
49
|
+
if config.stats
|
|
50
|
+
message = []
|
|
51
|
+
else
|
|
52
|
+
message = ["You need to set stats to true to generate the stats when running the bot instance."]
|
|
53
|
+
end
|
|
54
|
+
save_stats(__method__)
|
|
55
|
+
react :runner
|
|
56
|
+
get_channels_name_and_id() unless @channels_name.keys.include?(dest) or dest[0] == "D"
|
|
57
|
+
master_admin_users_id = @master_admin_users_id.dup
|
|
58
|
+
if dest == @channels_id[config.stats_channel]
|
|
59
|
+
#master_admin_users_id << user
|
|
60
|
+
user = "" # for the case we are on the stats channel
|
|
61
|
+
end
|
|
62
|
+
if (from_user.id != user and
|
|
63
|
+
(config.masters.include?(from_user.name) or master_admin_users_id.include?(from_user.id) or dest == @channels_id[config.stats_channel]) and #Jal
|
|
64
|
+
(typem == :on_dm or dest[0] == "D" or dest == @channels_id[config.stats_channel]))
|
|
65
|
+
on_dm_master = true #master admin user
|
|
66
|
+
else
|
|
67
|
+
on_dm_master = false
|
|
68
|
+
end
|
|
69
|
+
wrong = false
|
|
70
|
+
exclude_channel_members = false
|
|
71
|
+
include_channel_members = false
|
|
72
|
+
members_list = []
|
|
73
|
+
if exclude_members_channel != "" or members_channel != ""
|
|
74
|
+
if members_channel != ""
|
|
75
|
+
channel_members = members_channel
|
|
76
|
+
include_channel_members = true
|
|
77
|
+
else
|
|
78
|
+
channel_members = exclude_members_channel
|
|
79
|
+
exclude_channel_members = true
|
|
80
|
+
end
|
|
81
|
+
get_channels_name_and_id() unless @channels_id.keys.include?(channel_members)
|
|
82
|
+
|
|
83
|
+
tm = get_channel_members(channel_members)
|
|
84
|
+
if tm.nil?
|
|
85
|
+
message << ":exclamation: Add the Smart Bot to *<##{channel_members}>* channel first."
|
|
86
|
+
wrong = true
|
|
87
|
+
else
|
|
88
|
+
tm.each do |m|
|
|
89
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
|
90
|
+
members_list << user_info.name unless user_info.is_app_user or user_info.is_bot
|
|
50
91
|
end
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if header.size > 0
|
|
96
|
+
headers = ["date", "bot_channel", "bot_channel_id", "dest_channel", "dest_channel_id", "type_message", "user_name", "user_id", "text", "command", "files", "time_zone", "job_title"]
|
|
97
|
+
header.each do |h|
|
|
98
|
+
if !headers.include?(h.downcase)
|
|
99
|
+
message << ":exclamation: Wrong header #{h}. It should be one of the following: #{headers.join(", ")}"
|
|
100
|
+
wrong = true
|
|
57
101
|
end
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
102
|
+
end
|
|
103
|
+
if regexp.size > 0
|
|
104
|
+
regexp.each do |r|
|
|
105
|
+
begin
|
|
106
|
+
Regexp.new(r)
|
|
107
|
+
rescue
|
|
108
|
+
message << ":exclamation: Wrong regexp #{r}."
|
|
109
|
+
wrong = true
|
|
110
|
+
end
|
|
64
111
|
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
include_channel_members = false
|
|
68
|
-
members_list = []
|
|
69
|
-
if exclude_members_channel!='' or members_channel!=''
|
|
70
|
-
if members_channel!=''
|
|
71
|
-
channel_members = members_channel
|
|
72
|
-
include_channel_members = true
|
|
73
|
-
else
|
|
74
|
-
channel_members = exclude_members_channel
|
|
75
|
-
exclude_channel_members = true
|
|
76
|
-
end
|
|
77
|
-
get_channels_name_and_id() unless @channels_id.keys.include?(channel_members)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
78
114
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
115
|
+
tzone_users = {}
|
|
116
|
+
job_title_users = {}
|
|
117
|
+
users_by_job_title = {}
|
|
118
|
+
unless wrong
|
|
119
|
+
if on_dm_master or (from_user.id == user) # normal user can only see own stats
|
|
120
|
+
if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
|
|
121
|
+
message << "No stats"
|
|
122
|
+
else
|
|
123
|
+
from = "#{Time.now.strftime("%Y-%m")}-01" if from == ""
|
|
124
|
+
to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ""
|
|
125
|
+
from_short = from
|
|
126
|
+
to_short = to
|
|
127
|
+
from_file = from[0..3] + "-" + from[5..6]
|
|
128
|
+
to_file = to[0..3] + "-" + to[5..6]
|
|
129
|
+
from += " 00:00:00 +0000"
|
|
130
|
+
to += " 23:59:59 +0000"
|
|
131
|
+
rows = []
|
|
132
|
+
rows_month = {}
|
|
133
|
+
users_month = {}
|
|
134
|
+
commands_month = {}
|
|
135
|
+
users_id_name = {}
|
|
136
|
+
users_name_id = {}
|
|
137
|
+
count_users = {}
|
|
138
|
+
count_channels_dest = {}
|
|
139
|
+
# to translate global and enterprise users since sometimes was returning different names/ids
|
|
140
|
+
#if from[0..3]=='2020' # this was an issue only on that period
|
|
141
|
+
Dir["#{config.stats_path}.*.log"].sort.each do |file|
|
|
142
|
+
if file >= "#{config.stats_path}.#{from_file}.log" and file <= "#{config.stats_path}.#{to_file}.log"
|
|
143
|
+
CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
|
|
144
|
+
unless users_id_name.key?(row[:user_id])
|
|
145
|
+
users_id_name[row[:user_id]] = row[:user_name]
|
|
146
|
+
users_name_id[row[:user_name]] = row[:user_id]
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
#end
|
|
152
|
+
if user != ""
|
|
153
|
+
user_info = @users.select { |u| u.id == user or (u.key?(:enterprise_user) and u.enterprise_user.id == user) }[-1]
|
|
154
|
+
if user_info.nil? # for the case the user is populated from outside of slack
|
|
155
|
+
user_name = user
|
|
156
|
+
user_id = user
|
|
83
157
|
else
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
158
|
+
if users_id_name.key?(user_info.id)
|
|
159
|
+
user_name = users_id_name[user_info.id]
|
|
160
|
+
else
|
|
161
|
+
user_name = user_info.name
|
|
162
|
+
end
|
|
163
|
+
if users_name_id.key?(user_info.name)
|
|
164
|
+
user_id = users_name_id[user_info.name]
|
|
165
|
+
else
|
|
166
|
+
user_id = user_info.id
|
|
87
167
|
end
|
|
88
168
|
end
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if user!=''
|
|
131
|
-
user_info = @users.select{|u| u.id == user or (u.key?(:enterprise_user) and u.enterprise_user.id == user)}[-1]
|
|
132
|
-
if user_info.nil? # for the case the user is populated from outside of slack
|
|
133
|
-
user_name = user
|
|
134
|
-
user_id = user
|
|
135
|
-
else
|
|
136
|
-
if users_id_name.key?(user_info.id)
|
|
137
|
-
user_name = users_id_name[user_info.id]
|
|
138
|
-
else
|
|
139
|
-
user_name = user_info.name
|
|
140
|
-
end
|
|
141
|
-
if users_name_id.key?(user_info.name)
|
|
142
|
-
user_id = users_name_id[user_info.name]
|
|
143
|
-
else
|
|
144
|
-
user_id = user_info.id
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
master_admins = config.masters.dup
|
|
149
|
-
if users_id_name.size > 0
|
|
150
|
-
config.masters.each do |u|
|
|
151
|
-
if users_id_name.key?(u)
|
|
152
|
-
master_admins << users_id_name[u]
|
|
153
|
-
elsif users_name_id.key?(u)
|
|
154
|
-
master_admins << users_name_id[u]
|
|
155
|
-
end
|
|
169
|
+
end
|
|
170
|
+
master_admins = config.masters.dup
|
|
171
|
+
if users_id_name.size > 0
|
|
172
|
+
config.masters.each do |u|
|
|
173
|
+
if users_id_name.key?(u)
|
|
174
|
+
master_admins << users_id_name[u]
|
|
175
|
+
elsif users_name_id.key?(u)
|
|
176
|
+
master_admins << users_name_id[u]
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
Dir["#{config.stats_path}.*.log"].sort.each do |file|
|
|
181
|
+
if file >= "#{config.stats_path}.#{from_file}.log" and file <= "#{config.stats_path}.#{to_file}.log"
|
|
182
|
+
CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
|
|
183
|
+
if (include_channel_members and members_list.include?(row[:user_name])) or
|
|
184
|
+
(exclude_channel_members and !members_list.include?(row[:user_name])) or
|
|
185
|
+
(!include_channel_members and !exclude_channel_members)
|
|
186
|
+
row[:date] = row[:date].to_s
|
|
187
|
+
if row[:dest_channel_id].to_s[0] == "D"
|
|
188
|
+
row[:dest_channel] = "DM"
|
|
189
|
+
elsif row[:dest_channel].to_s == ""
|
|
190
|
+
row[:dest_channel] = row[:dest_channel_id]
|
|
191
|
+
end
|
|
192
|
+
if users_name_id.size > 0
|
|
193
|
+
row[:user_name] = users_id_name[row[:user_id]]
|
|
194
|
+
row[:user_id] = users_name_id[row[:user_name]]
|
|
195
|
+
else
|
|
196
|
+
users_id_name[row[:user_id]] ||= row[:user_name]
|
|
197
|
+
end
|
|
198
|
+
if !exclude_masters or (exclude_masters and !master_admins.include?(row[:user_name]) and
|
|
199
|
+
!master_admins.include?(row[:user_id]) and
|
|
200
|
+
!master_admin_users_id.include?(row[:user_id]))
|
|
201
|
+
if !exclude_routines or (exclude_routines and !row[:user_name].match?(/^routine\//))
|
|
202
|
+
unless header.empty?
|
|
203
|
+
add = true
|
|
204
|
+
header.each_with_index do |h, i|
|
|
205
|
+
if row[h.downcase.to_sym].to_s.match?(Regexp.new(regexp[i])) == false
|
|
206
|
+
add = false
|
|
207
|
+
break
|
|
208
|
+
end
|
|
156
209
|
end
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
end
|
|
178
|
-
if !exclude_masters or (exclude_masters and !master_admins.include?(row[:user_name]) and
|
|
179
|
-
!master_admins.include?(row[:user_id]) and
|
|
180
|
-
!master_admin_users_id.include?(row[:user_id]))
|
|
181
|
-
if !exclude_routines or (exclude_routines and !row[:user_name].match?(/^routine\//) )
|
|
182
|
-
if exclude_command == '' or (exclude_command!='' and row[:command]!=exclude_command)
|
|
183
|
-
if st_command == '' or (st_command != '' and row[:command] == st_command)
|
|
184
|
-
if row[:bot_channel_id] == channel_id or channel_id == '' or row[:dest_channel_id] == channel_id
|
|
185
|
-
if row[:date] >= from and row[:date] <= to
|
|
186
|
-
count_users[row[:user_id]] ||= 0
|
|
187
|
-
count_users[row[:user_id]] += 1
|
|
188
|
-
if user=='' or (user!='' and row[:user_name] == user_name) or (user!='' and row[:user_id] == user_id)
|
|
189
|
-
rows << row.to_h
|
|
190
|
-
count_channels_dest[row[:dest_channel]] ||= 0
|
|
191
|
-
count_channels_dest[row[:dest_channel]] += 1
|
|
192
|
-
if monthly
|
|
193
|
-
rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
|
|
194
|
-
users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
|
|
195
|
-
commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
|
|
196
|
-
rows_month[row[:date][0..6]] += 1
|
|
197
|
-
users_month[row[:date][0..6]] << row[:user_id]
|
|
198
|
-
commands_month[row[:date][0..6]] << row[:command]
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
end
|
|
210
|
+
end
|
|
211
|
+
if header.empty? or (header.size > 0 and add)
|
|
212
|
+
if exclude_command == "" or (exclude_command != "" and row[:command] != exclude_command)
|
|
213
|
+
if st_command == "" or (st_command != "" and row[:command] == st_command)
|
|
214
|
+
if row[:bot_channel_id] == channel_id or channel_id == "" or row[:dest_channel_id] == channel_id
|
|
215
|
+
if row[:date] >= from and row[:date] <= to
|
|
216
|
+
count_users[row[:user_id]] ||= 0
|
|
217
|
+
count_users[row[:user_id]] += 1
|
|
218
|
+
if user == "" or (user != "" and row[:user_name] == user_name) or (user != "" and row[:user_id] == user_id)
|
|
219
|
+
rows << row.to_h
|
|
220
|
+
count_channels_dest[row[:dest_channel]] ||= 0
|
|
221
|
+
count_channels_dest[row[:dest_channel]] += 1
|
|
222
|
+
if monthly
|
|
223
|
+
rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
|
|
224
|
+
users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
|
|
225
|
+
commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
|
|
226
|
+
rows_month[row[:date][0..6]] += 1
|
|
227
|
+
users_month[row[:date][0..6]] << row[:user_id]
|
|
228
|
+
commands_month[row[:date][0..6]] << row[:command]
|
|
229
|
+
end
|
|
207
230
|
end
|
|
231
|
+
end
|
|
208
232
|
end
|
|
233
|
+
end
|
|
209
234
|
end
|
|
235
|
+
end
|
|
210
236
|
end
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
total = rows.size
|
|
243
|
+
if exclude_masters
|
|
244
|
+
message << "Excluding master admins"
|
|
245
|
+
end
|
|
246
|
+
if exclude_routines
|
|
247
|
+
message << "Excluding routines"
|
|
248
|
+
end
|
|
249
|
+
if exclude_command != ""
|
|
250
|
+
message << "Excluding command #{exclude_command}"
|
|
251
|
+
end
|
|
252
|
+
if st_command != ""
|
|
253
|
+
message << "Including only command #{st_command}"
|
|
254
|
+
end
|
|
255
|
+
if include_channel_members
|
|
256
|
+
message << "Including only members of <##{members_channel}>"
|
|
257
|
+
end
|
|
258
|
+
if exclude_channel_members
|
|
259
|
+
message << "Including only members that are not members of <##{exclude_members_channel}>"
|
|
260
|
+
end
|
|
261
|
+
if header.size > 0
|
|
262
|
+
header.each_with_index do |h, i|
|
|
263
|
+
message << "Including only #{h} that match /#{regexp[i]}/i"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
if user != ""
|
|
267
|
+
if user == from_user.id
|
|
268
|
+
message << "Bot stats for <@#{user}>"
|
|
269
|
+
else
|
|
270
|
+
message << "Showing only user <@#{user}>"
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
if channel_id == ""
|
|
274
|
+
message << "*Total calls*: #{total} from #{from_short} to #{to_short}"
|
|
275
|
+
else
|
|
276
|
+
message << "*Total calls <##{channel_id}>*: #{total} from #{from_short} to #{to_short}"
|
|
277
|
+
end
|
|
278
|
+
unless count_users.size == 0 or total == 0 or user == ""
|
|
279
|
+
my_place = (count_users.sort_by(&:last).reverse.to_h.keys.index(user_id) + 1)
|
|
280
|
+
message << "\tYou are the *\# #{my_place}* of *#{count_users.size}* users"
|
|
281
|
+
end
|
|
282
|
+
if total > 0
|
|
283
|
+
if monthly
|
|
284
|
+
if on_dm_master
|
|
285
|
+
message << "*Totals by month / commands / users (%new)*"
|
|
286
|
+
else
|
|
287
|
+
message << "*Totals by month / commands*"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
all_users = []
|
|
291
|
+
new_users = []
|
|
292
|
+
rows_month.each do |k, v|
|
|
293
|
+
if all_users.empty?
|
|
294
|
+
message_new_users = ""
|
|
295
|
+
else
|
|
296
|
+
new_users = (users_month[k] - all_users).uniq
|
|
297
|
+
message_new_users = "(#{new_users.size * 100 / users_month[k].uniq.size}%)"
|
|
298
|
+
end
|
|
299
|
+
all_users += users_month[k]
|
|
300
|
+
if on_dm_master
|
|
301
|
+
message << "\t#{k}: #{v} (#{(v.to_f * 100 / total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
|
|
302
|
+
else
|
|
303
|
+
message << "\t#{k}: #{v} (#{(v.to_f * 100 / total).round(2)}%) / #{commands_month[k].uniq.size}"
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
if channel_id == ""
|
|
309
|
+
message << "*SmartBots*"
|
|
310
|
+
channels = rows.bot_channel.uniq.sort
|
|
311
|
+
channels.each do |channel|
|
|
312
|
+
count = rows.count { |h| h.bot_channel == channel }
|
|
313
|
+
channel_info = @channels_list.select { |c| c.name.to_s.downcase == channel.to_s.downcase }[-1]
|
|
314
|
+
if @channels_id.key?(channel) and !channel_info.is_private
|
|
315
|
+
c = "<##{@channels_id[channel]}>"
|
|
316
|
+
else
|
|
317
|
+
c = channel
|
|
318
|
+
end
|
|
319
|
+
message << "\t#{c}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
channels_dest_attachment = []
|
|
323
|
+
count_channels_dest = count_channels_dest.sort_by(&:last).reverse.to_h
|
|
324
|
+
if count_channels_dest.size > 10
|
|
325
|
+
message << "*From Channel* - #{count_channels_dest.size} (Top 10)"
|
|
326
|
+
else
|
|
327
|
+
message << "*From Channel* - #{count_channels_dest.size}"
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
count_channels_dest.keys[0..9].each do |ch|
|
|
331
|
+
channel_info = @channels_list.select { |c| c.name.to_s.downcase == ch.to_s.downcase }[-1]
|
|
332
|
+
if @channels_id.key?(ch) and !channel_info.is_private
|
|
333
|
+
c = "<##{@channels_id[ch]}>"
|
|
334
|
+
else
|
|
335
|
+
c = ch
|
|
336
|
+
end
|
|
337
|
+
message << "\t#{c}: #{count_channels_dest[ch]} (#{(count_channels_dest[ch].to_f * 100 / total).round(2)}%)"
|
|
338
|
+
end
|
|
339
|
+
if count_channels_dest.size > 10 and all_data
|
|
340
|
+
count_channels_dest.each do |ch, value|
|
|
341
|
+
channel_info = @channels_list.select { |c| c.name.to_s.downcase == ch.to_s.downcase }[-1]
|
|
342
|
+
channels_dest_attachment << "\t##{ch}: #{value} (#{(value.to_f * 100 / total).round(2)}%)"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
users_attachment = []
|
|
347
|
+
if user == ""
|
|
348
|
+
users = rows.user_id.uniq.sort
|
|
349
|
+
if rows[0].key?(:time_zone) #then save_stats is saving the time zone already
|
|
350
|
+
rows.time_zone.each do |time_zone|
|
|
351
|
+
unless time_zone == ""
|
|
352
|
+
tzone_users[time_zone] ||= 0
|
|
353
|
+
tzone_users[time_zone] += 1
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
else
|
|
357
|
+
rows.user_id.each_with_index do |usr, i|
|
|
358
|
+
if rows[i].values.size >= 12 #then save_stats is saving the time zone already but not all the data
|
|
359
|
+
unless rows[i].values[11] == ""
|
|
360
|
+
tzone_users[rows[i].values[11]] ||= 0
|
|
361
|
+
tzone_users[rows[i].values[11]] += 1
|
|
223
362
|
end
|
|
224
|
-
|
|
225
|
-
|
|
363
|
+
else
|
|
364
|
+
user_info = @users.select { |u| u.id == usr or (u.key?(:enterprise_user) and u.enterprise_user.id == usr) }[-1]
|
|
365
|
+
unless user_info.nil? or user_info.is_app_user or user_info.is_bot
|
|
366
|
+
tzone_users[user_info.tz_label] ||= 0
|
|
367
|
+
tzone_users[user_info.tz_label] += 1
|
|
226
368
|
end
|
|
227
|
-
|
|
228
|
-
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
if rows[0].key?(:job_title) #then save_stats is saving the job title already
|
|
373
|
+
rows.job_title.each_with_index do |job_title, idx|
|
|
374
|
+
unless job_title.to_s == ""
|
|
375
|
+
unless job_title_users.key?(job_title)
|
|
376
|
+
job_title = job_title.to_s.split.map { |x| x[0].upcase + x[1..-1] }.join(" ")
|
|
377
|
+
job_title_users[job_title] ||= 0
|
|
378
|
+
users_by_job_title[job_title] ||= []
|
|
229
379
|
end
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
380
|
+
job_title_users[job_title] += 1
|
|
381
|
+
users_by_job_title[job_title] << rows.user_name[idx]
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
else
|
|
385
|
+
rows.user_id.each_with_index do |usr, i|
|
|
386
|
+
unless usr.include?("routine/")
|
|
387
|
+
if rows[i].values.size >= 13 #then save_stats is saving the job_title already but not all the data
|
|
388
|
+
unless rows[i].values[12].to_s == ""
|
|
389
|
+
if job_title_users.key?(rows[i].values[12].to_s)
|
|
390
|
+
job_title = rows[i].values[12]
|
|
233
391
|
else
|
|
234
|
-
|
|
392
|
+
job_title = rows[i].values[12].to_s.split.map { |x| x[0].upcase + x[1..-1] }.join(" ")
|
|
393
|
+
job_title_users[job_title] ||= 0
|
|
394
|
+
users_by_job_title[job_title] ||= []
|
|
235
395
|
end
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
396
|
+
job_title_users[job_title] += 1
|
|
397
|
+
users_by_job_title[job_title] << rows.user_name[i]
|
|
398
|
+
end
|
|
239
399
|
else
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
message <<"\tYou are the *\# #{my_place}* of *#{count_users.size}* users"
|
|
245
|
-
end
|
|
246
|
-
if total > 0
|
|
247
|
-
if monthly
|
|
248
|
-
if on_dm_master
|
|
249
|
-
message << '*Totals by month / commands / users (%new)*'
|
|
250
|
-
else
|
|
251
|
-
message << '*Totals by month / commands*'
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
all_users = []
|
|
255
|
-
new_users = []
|
|
256
|
-
rows_month.each do |k,v|
|
|
257
|
-
if all_users.empty?
|
|
258
|
-
message_new_users = ''
|
|
259
|
-
else
|
|
260
|
-
new_users = (users_month[k]-all_users).uniq
|
|
261
|
-
message_new_users = "(#{new_users.size*100/users_month[k].uniq.size}%)"
|
|
262
|
-
end
|
|
263
|
-
all_users += users_month[k]
|
|
264
|
-
if on_dm_master
|
|
265
|
-
message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
|
|
266
|
-
else
|
|
267
|
-
message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size}"
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
if channel_id == ''
|
|
273
|
-
message << "*SmartBots*"
|
|
274
|
-
channels = rows.bot_channel.uniq.sort
|
|
275
|
-
channels.each do |channel|
|
|
276
|
-
count = rows.count {|h| h.bot_channel==channel}
|
|
277
|
-
channel_info = @channels_list.select { |c| c.name.to_s.downcase == channel.to_s.downcase}[-1]
|
|
278
|
-
if @channels_id.key?(channel) and !channel_info.is_private
|
|
279
|
-
c = "<##{@channels_id[channel]}>"
|
|
280
|
-
else
|
|
281
|
-
c = channel
|
|
282
|
-
end
|
|
283
|
-
message << "\t#{c}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
channels_dest_attachment = []
|
|
287
|
-
count_channels_dest = count_channels_dest.sort_by(&:last).reverse.to_h
|
|
288
|
-
if count_channels_dest.size > 10
|
|
289
|
-
message << "*From Channel* - #{count_channels_dest.size} (Top 10)"
|
|
400
|
+
user_info = @users.select { |u| u.id == usr or (u.key?(:enterprise_user) and u.enterprise_user.id == usr) }[-1]
|
|
401
|
+
unless user_info.nil? or user_info.is_app_user or user_info.is_bot
|
|
402
|
+
if job_title_users.key?(user_info.profile.title)
|
|
403
|
+
job_title = user_info.profile.title
|
|
290
404
|
else
|
|
291
|
-
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
count_channels_dest.keys[0..9].each do |ch|
|
|
295
|
-
channel_info = @channels_list.select { |c| c.name.to_s.downcase == ch.to_s.downcase}[-1]
|
|
296
|
-
if @channels_id.key?(ch) and !channel_info.is_private
|
|
297
|
-
c = "<##{@channels_id[ch]}>"
|
|
298
|
-
else
|
|
299
|
-
c = ch
|
|
300
|
-
end
|
|
301
|
-
message << "\t#{c}: #{count_channels_dest[ch]} (#{(count_channels_dest[ch].to_f*100/total).round(2)}%)"
|
|
405
|
+
job_title = user_info.profile.title.split.map { |x| x[0].upcase + x[1..-1] }.join(" ")
|
|
302
406
|
end
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
407
|
+
unless job_title.to_s == ""
|
|
408
|
+
job_title_users[job_title] ||= 0
|
|
409
|
+
job_title_users[job_title] += 1
|
|
410
|
+
users_by_job_title[job_title] ||= []
|
|
411
|
+
users_by_job_title[job_title] << rows.user_name[i]
|
|
308
412
|
end
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if users.size > 10 and all_data
|
|
393
|
-
users_attachment << "\t#{users_id_name[user]}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
|
394
|
-
end
|
|
395
|
-
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
users_by_job_title.each do |job_title, users|
|
|
419
|
+
users.uniq!
|
|
420
|
+
end
|
|
421
|
+
if users.size > 10
|
|
422
|
+
message << "*Users* - #{users.size} (Top 10)"
|
|
423
|
+
else
|
|
424
|
+
message << "*Users* - #{users.size}"
|
|
425
|
+
end
|
|
426
|
+
count_user = {}
|
|
427
|
+
users.each do |user|
|
|
428
|
+
count = rows.count { |h| h.user_id == user }
|
|
429
|
+
count_user[user] = count
|
|
430
|
+
end
|
|
431
|
+
i = 0
|
|
432
|
+
total_without_routines = total
|
|
433
|
+
count_user.sort_by { |k, v| -v }.each do |user, count|
|
|
434
|
+
i += 1
|
|
435
|
+
if user.include?("routine/")
|
|
436
|
+
user_link = users_id_name[user]
|
|
437
|
+
total_without_routines -= count
|
|
438
|
+
else
|
|
439
|
+
user_link = "<@#{user}>"
|
|
440
|
+
end
|
|
441
|
+
if i <= 10
|
|
442
|
+
message << "\t#{user_link}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
443
|
+
end
|
|
444
|
+
if users.size > 10 and all_data
|
|
445
|
+
users_attachment << "\t#{users_id_name[user]}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
if tzone_users.size > 0
|
|
449
|
+
message << "*Time Zones*"
|
|
450
|
+
total_known = 0
|
|
451
|
+
tzone_users.each do |tzone, num|
|
|
452
|
+
unless tzone.to_s == ""
|
|
453
|
+
message << "\t#{tzone}: #{num} (#{(num.to_f * 100 / total_without_routines).round(2)}%)"
|
|
454
|
+
total_known += num
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
total_unknown = total_without_routines - total_known
|
|
458
|
+
message << "\tUnknown: #{total_unknown} (#{(total_unknown.to_f * 100 / total_without_routines).round(2)}%)" if total_unknown > 0
|
|
459
|
+
end
|
|
460
|
+
if users.size > 0
|
|
461
|
+
if job_title_users.size > 10
|
|
462
|
+
message << "*Job Titles* - #{job_title_users.size} (Top 10)"
|
|
463
|
+
else
|
|
464
|
+
message << "*Job Titles* - #{job_title_users.size}"
|
|
465
|
+
end
|
|
466
|
+
total_known = 0
|
|
467
|
+
i = 0
|
|
468
|
+
job_title_users.sort_by { |k, v| -v }.each do |jtitle, num|
|
|
469
|
+
unless jtitle.to_s == ""
|
|
470
|
+
i += 1
|
|
471
|
+
if i <= 10
|
|
472
|
+
message << "\t#{jtitle}: #{num} (#{(num.to_f * 100 / total_without_routines).round(2)}%)"
|
|
473
|
+
end
|
|
474
|
+
total_known += num
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
total_unknown = total_without_routines - total_known
|
|
478
|
+
message << "\tUnknown: #{total_unknown} (#{(total_unknown.to_f * 100 / total_without_routines).round(2)}%)" if total_unknown > 0
|
|
479
|
+
end
|
|
480
|
+
if users.size > 0
|
|
481
|
+
if users_by_job_title.size > 10
|
|
482
|
+
message << "*Num Users by Job Title* (Top 10)"
|
|
483
|
+
else
|
|
484
|
+
message << "*Num Users by Job Title*"
|
|
485
|
+
end
|
|
486
|
+
i = 0
|
|
487
|
+
users_by_job_title.sort_by { |k, v| -v.size }.each do |jtitle, usersj|
|
|
488
|
+
i += 1
|
|
489
|
+
if i <= 10
|
|
490
|
+
message << "\t#{jtitle}: #{usersj.size} (#{(usersj.size.to_f * 100 / users.size).round(2)}%)"
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
commands_attachment = []
|
|
396
496
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
end
|
|
405
|
-
end
|
|
406
|
-
total_unknown = total_without_routines - total_known
|
|
407
|
-
message << "\tUnknown: #{total_unknown} (#{(total_unknown.to_f*100/total_without_routines).round(2)}%)" if total_unknown > 0
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
if job_title_users.size > 0
|
|
411
|
-
if job_title_users.size > 10
|
|
412
|
-
message << "*Job Titles* - #{job_title_users.size} (Top 10)"
|
|
413
|
-
else
|
|
414
|
-
message << "*Job Titles* - #{job_title_users.size}"
|
|
415
|
-
end
|
|
416
|
-
total_known = 0
|
|
417
|
-
i = 0
|
|
418
|
-
job_title_users.sort_by {|k,v| -v}.each do |jtitle, num|
|
|
419
|
-
unless jtitle.to_s == ''
|
|
420
|
-
i += 1
|
|
421
|
-
if i <= 10
|
|
422
|
-
message << "\t#{jtitle}: #{num} (#{(num.to_f*100/total_without_routines).round(2)}%)"
|
|
423
|
-
end
|
|
424
|
-
total_known+=num
|
|
425
|
-
end
|
|
426
|
-
end
|
|
427
|
-
total_unknown = total_without_routines - total_known
|
|
428
|
-
message << "\tUnknown: #{total_unknown} (#{(total_unknown.to_f*100/total_without_routines).round(2)}%)" if total_unknown > 0
|
|
429
|
-
end
|
|
430
|
-
if users_by_job_title.size > 0
|
|
431
|
-
if users_by_job_title.size > 10
|
|
432
|
-
message << "*Num Users by Job Title* (Top 10)"
|
|
433
|
-
else
|
|
434
|
-
message << "*Num Users by Job Title*"
|
|
435
|
-
end
|
|
436
|
-
i = 0
|
|
437
|
-
users_by_job_title.sort_by {|k,v| -v.size}.each do |jtitle, users|
|
|
438
|
-
i += 1
|
|
439
|
-
if i <= 10
|
|
440
|
-
jtitle = 'Unknown' if jtitle.to_s == ''
|
|
441
|
-
message << "\t#{jtitle}: #{users.size} (#{(users.size.to_f*100/total_users_by_job_title).round(2)}%)"
|
|
442
|
-
end
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
|
-
end
|
|
446
|
-
commands_attachment = []
|
|
497
|
+
if st_command == ""
|
|
498
|
+
commands = rows.command.uniq.sort
|
|
499
|
+
count_command = {}
|
|
500
|
+
commands.each do |command|
|
|
501
|
+
count = rows.count { |h| h.command == command }
|
|
502
|
+
count_command[command] = count
|
|
503
|
+
end
|
|
447
504
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
count_command[command] = count
|
|
454
|
-
end
|
|
505
|
+
if commands.size > 10
|
|
506
|
+
message << "*Commands* - #{commands.size} (Top 10)"
|
|
507
|
+
else
|
|
508
|
+
message << "*Commands* - #{commands.size}"
|
|
509
|
+
end
|
|
455
510
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
511
|
+
i = 0
|
|
512
|
+
count_command.sort_by { |k, v| -v }.each do |command, count|
|
|
513
|
+
i += 1
|
|
514
|
+
if i <= 10
|
|
515
|
+
message << "\t#{command}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
516
|
+
end
|
|
517
|
+
if commands.size > 10 and all_data
|
|
518
|
+
commands_attachment << "\t#{command}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
end
|
|
461
522
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if commands.size > 10 and all_data
|
|
469
|
-
commands_attachment << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
|
470
|
-
end
|
|
471
|
-
end
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
message << "*Message type*"
|
|
475
|
-
types = rows.type_message.uniq.sort
|
|
476
|
-
types.each do |type|
|
|
477
|
-
count = rows.count {|h| h.type_message==type}
|
|
478
|
-
message << "\t#{type}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
|
479
|
-
end
|
|
523
|
+
message << "*Message type*"
|
|
524
|
+
types = rows.type_message.uniq.sort
|
|
525
|
+
types.each do |type|
|
|
526
|
+
count = rows.count { |h| h.type_message == type }
|
|
527
|
+
message << "\t#{type}: #{count} (#{(count.to_f * 100 / total).round(2)}%)"
|
|
528
|
+
end
|
|
480
529
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
end
|
|
493
|
-
end
|
|
494
|
-
end
|
|
495
|
-
else
|
|
496
|
-
message<<"Only Master admin users on a private conversation with the bot can see this kind of bot stats."
|
|
530
|
+
if on_dm_master
|
|
531
|
+
message << "*Last activity*: #{rows[-1].date} #{rows[-1].bot_channel} #{rows[-1].type_message} #{rows[-1].user_name} #{rows[-1].command}"
|
|
532
|
+
end
|
|
533
|
+
if users_attachment.size > 0
|
|
534
|
+
send_file(dest, "", "users.txt", "", "text/plain", "text", content: users_attachment.join("\n"))
|
|
535
|
+
end
|
|
536
|
+
if commands_attachment.size > 0
|
|
537
|
+
send_file(dest, "", "commands.txt", "", "text/plain", "text", content: commands_attachment.join("\n"))
|
|
538
|
+
end
|
|
539
|
+
if channels_dest_attachment.size > 0
|
|
540
|
+
send_file(dest, "", "channels_dest.txt", "", "text/plain", "text", content: channels_dest_attachment.join("\n"))
|
|
497
541
|
end
|
|
542
|
+
end
|
|
498
543
|
end
|
|
499
|
-
|
|
544
|
+
else
|
|
545
|
+
message << "Only Master admin users on a private conversation with the bot can see this kind of bot stats."
|
|
546
|
+
end
|
|
500
547
|
end
|
|
501
|
-
|
|
548
|
+
unreact :runner
|
|
549
|
+
respond "#{message.join("\n")}", dest
|
|
550
|
+
end
|
|
551
|
+
end
|
|
@@ -342,7 +342,14 @@ class SlackSmartBot
|
|
|
342
342
|
if (typem == :on_master or typem == :on_bot) and dest[0]!='D' and dest!=@channels_id[config.stats_channel] #routine bot stats to be published on DM
|
|
343
343
|
st_channel = dchannel
|
|
344
344
|
end
|
|
345
|
-
|
|
345
|
+
res = opts.scan(/(\w+)\s+\/([^\/]+)\//i)
|
|
346
|
+
header = []
|
|
347
|
+
regexp = []
|
|
348
|
+
res.each do |r|
|
|
349
|
+
header << r[0]
|
|
350
|
+
regexp << r[1]
|
|
351
|
+
end
|
|
352
|
+
bot_stats(dest, user, typem, st_channel, st_from, st_to, st_user, st_command, exclude_masters, exclude_routines, exclude_command, monthly, all_data, members_channel, exclude_members_channel, header, regexp)
|
|
346
353
|
when /\A(set|turn)\s+maintenance\s+(on|off)\s*()\z/im, /\A(set|turn)\s+maintenance\s+(on)\s*(.+)\s*\z/im
|
|
347
354
|
status = $2.downcase
|
|
348
355
|
message = $3.to_s
|
data/whats_new.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
*Version 1.12.
|
|
1
|
+
*Version 1.12.8* Released 2022-Nov-17
|
|
2
2
|
|
|
3
3
|
*For General users*
|
|
4
4
|
- `run repl` accepts local parameters and precode to be supplied (<https://github.com/MarioRuiz/slack-smart-bot/issues/60|#60>).
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
- Bot Stats is now saving the job title of the user (<https://github.com/MarioRuiz/slack-smart-bot/issues/77|#77>)
|
|
18
18
|
- Any member of smartbot-stats channel can use the `bot stats` command on the channel (<https://github.com/MarioRuiz/slack-smart-bot/issues/78|#78>)
|
|
19
19
|
- Added options for `bot stats` command: today, yesterday, this week, last week, this year, last year (<https://github.com/MarioRuiz/slack-smart-bot/issues/79|#79>)
|
|
20
|
+
- `bot stats HEADER /regexp/` filter results by stats header following the regexp supplied (<https://github.com/MarioRuiz/slack-smart-bot/issues/81|#81>)
|
|
20
21
|
------------------------------
|
|
21
22
|
|
|
22
23
|
*Previous*: <https://github.com/MarioRuiz/slack-smart-bot/blob/b1a368c3342094e886f53d96dc4d12ecd81ab04b/whats_new.txt|1.11.0>
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: slack-smart-bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.12.
|
|
4
|
+
version: 1.12.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mario Ruiz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-11-
|
|
11
|
+
date: 2022-11-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: slack-ruby-client
|