slack-smart-bot 1.12.6 → 1.12.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5596e8869ae4c53cddb593dadcbde5aa6dc5e4a024d7301e7d2d45e1b03882d9
4
- data.tar.gz: 2f4e295bd3881c7f2172b1abd39e40163f3cd244a8ee9f250b8c2e606e8137c5
3
+ metadata.gz: ce7ad9b141fa627afb25ac3a20fcf6e6b9d452105866620681c5430c691023be
4
+ data.tar.gz: 40cb7e645794af392d687afa6a4a839d9e7d9f1113a6fc90862cd6da3a0dedce
5
5
  SHA512:
6
- metadata.gz: 24c6dc230c11db7075dee20b7a9f04202417ae443b3abe6b290668a965ef8778b3d211deb8c660bb869dbf54c7e2912b98a8e6b3b86722e8e88e5a832556596d
7
- data.tar.gz: b075c60bbc5b632374328c8b8c65a1857454cba5b92ef4d8d0e168a4aefdc0b25e6ba5afdc04c6014c53cf5b35d24dceba5015df1c28491f8fd2d4a5604f56ef
6
+ metadata.gz: af7a0da5cf90b055fe4dc48c781823e1941f0ceb8b2747d60dcd43ef44ceb2e380cd8a15ddc016ee7201b9e26e93ab8991db07bb2bea99bdfb69d751ed8fc7cb
7
+ data.tar.gz: 67cf9020b2894fab2fcb8c8082cc94e63d1e5e52eabc91dc8544b1f050fc948127f564687fd339f04f1f98a1fa8a2fdaa246f65e31ac93b06a18a10bef028596
@@ -1,501 +1,551 @@
1
1
  class SlackSmartBot
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 members #CHANNEL`
17
- # help: `bot stats exclude members #CHANNEL`
18
- # help: `bot stats today`
19
- # help: `bot stats yesterday`
20
- # help: `bot stats last month`
21
- # help: `bot stats this month`
22
- # help: `bot stats last week`
23
- # help: `bot stats this week`
24
- # help: `bot stats exclude COMMAND_ID`
25
- # help: `bot stats monthly`
26
- # help: `bot stats alldata`
27
- # help: To see the bot stats
28
- # 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
29
- # helpmaster: You need to set stats to true to generate the stats when running the bot instance.
30
- # help: members #CHANNEL will return stats for only members of the channel supplied
31
- # help: exclude members #CHANNEL will return stats for only members that are not members of the channel supplied
32
- # help: If alldata option supplied then it will be attached files including all data and not only the top 10.
33
- # help: Examples:
34
- # help: _bot stats #sales_
35
- # helpmaster: _bot stats @peter.wind_
36
- # help: _bot stats #sales from 2019/12/15 to 2019/12/31_
37
- # help: _bot stats #sales today_
38
- # help: _bot stats #sales from 2020-01-01 monthly_
39
- # help: _bot stats exclude routines masters from 2021/01/01 monthly_
40
- # help: _bot stats members #development from 2022/01/01 to 2022/01/31_
41
- # help: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
42
- # help: command_id: :bot_stats
43
- # help:
44
- 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)
45
- require 'csv'
46
- if config.stats
47
- message = []
48
- else
49
- message = ["You need to set stats to true to generate the stats when running the bot instance."]
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
- save_stats(__method__)
52
- get_channels_name_and_id() unless @channels_name.keys.include?(dest)
53
- master_admin_users_id = @master_admin_users_id.dup
54
- if dest == @channels_id[config.stats_channel]
55
- #master_admin_users_id << user
56
- user = '' # for the case we are on the stats channel
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
- if (from_user.id != user and
59
- (config.masters.include?(from_user.name) or master_admin_users_id.include?(from_user.id) or dest == @channels_id[config.stats_channel]) and #Jal
60
- (typem==:on_dm or dest[0]=='D' or dest == @channels_id[config.stats_channel] ))
61
- on_dm_master = true #master admin user
62
- else
63
- on_dm_master = false
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
- wrong = false
66
- exclude_channel_members = false
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
- tm = get_channel_members(channel_members)
80
- if tm.nil?
81
- message << ":exclamation: Add the Smart Bot to *<##{channel_members}>* channel first."
82
- wrong = true
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
- tm.each do |m|
85
- user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
86
- members_list << user_info.name unless user_info.is_app_user or user_info.is_bot
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
- end
90
- tzone_users = {}
91
- job_title_users = {}
92
- users_by_job_title = {}
93
-
94
- unless wrong
95
- if on_dm_master or (from_user.id == user) # normal user can only see own stats
96
- if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
97
- message<<'No stats'
98
- else
99
- from = "#{Time.now.strftime("%Y-%m")}-01" if from == ''
100
- to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ''
101
- from_short = from
102
- to_short = to
103
- from_file = from[0..3] + '-' + from[5..6]
104
- to_file = to[0..3] + '-' + to[5..6]
105
- from+= " 00:00:00 +0000"
106
- to+= " 23:59:59 +0000"
107
- rows = []
108
- rows_month = {}
109
- users_month = {}
110
- commands_month = {}
111
- users_id_name = {}
112
- users_name_id = {}
113
- count_users = {}
114
- count_channels_dest = {}
115
-
116
- # to translate global and enterprise users since sometimes was returning different names/ids
117
- #if from[0..3]=='2020' # this was an issue only on that period
118
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
119
- if file >= "#{config.stats_path}.#{from_file}.log" and file <= "#{config.stats_path}.#{to_file}.log"
120
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
121
- unless users_id_name.key?(row[:user_id])
122
- users_id_name[row[:user_id]] = row[:user_name]
123
- users_name_id[row[:user_name]] = row[:user_id]
124
- end
125
- end
126
- end
127
- end
128
- #end
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
- end
158
-
159
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
160
- if file >= "#{config.stats_path}.#{from_file}.log" and file <= "#{config.stats_path}.#{to_file}.log"
161
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
162
- if (include_channel_members and members_list.include?(row[:user_name])) or
163
- (exclude_channel_members and !members_list.include?(row[:user_name])) or
164
- (!include_channel_members and !exclude_channel_members)
165
-
166
- row[:date] = row[:date].to_s
167
- if row[:dest_channel_id].to_s[0]=='D'
168
- row[:dest_channel] = 'DM'
169
- elsif row[:dest_channel].to_s == ''
170
- row[:dest_channel] = row[:dest_channel_id]
171
- end
172
- if users_name_id.size > 0
173
- row[:user_name] = users_id_name[row[:user_id]]
174
- row[:user_id] = users_name_id[row[:user_name]]
175
- else
176
- users_id_name[row[:user_id]] ||= row[:user_name]
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
- total = rows.size
212
- if exclude_masters
213
- message << 'Excluding master admins'
214
- end
215
- if exclude_routines
216
- message << 'Excluding routines'
217
- end
218
- if exclude_command != ''
219
- message << "Excluding command #{exclude_command}"
220
- end
221
- if st_command != ''
222
- message << "Including only command #{st_command}"
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
- if include_channel_members
225
- message << "Including only members of <##{members_channel}>"
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
- if exclude_channel_members
228
- message << "Including only members that are not members of <##{exclude_members_channel}>"
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
- if user!=''
231
- if user==from_user.id
232
- message << "Bot stats for <@#{user}>"
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
- message << "Showing only user <@#{user}>"
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
- end
237
- if channel_id == ''
238
- message << "*Total calls*: #{total} from #{from_short} to #{to_short}"
396
+ job_title_users[job_title] += 1
397
+ users_by_job_title[job_title] << rows.user_name[i]
398
+ end
239
399
  else
240
- message << "*Total calls <##{channel_id}>*: #{total} from #{from_short} to #{to_short}"
241
- end
242
- unless count_users.size == 0 or total == 0 or user == ''
243
- my_place = (count_users.sort_by(&:last).reverse.to_h.keys.index(user_id)+1)
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
- message << "*From Channel* - #{count_channels_dest.size}"
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
- if count_channels_dest.size > 10 and all_data
304
- count_channels_dest.each do |ch, value|
305
- channel_info = @channels_list.select { |c| c.name.to_s.downcase == ch.to_s.downcase}[-1]
306
- channels_dest_attachment << "\t##{ch}: #{value} (#{(value.to_f*100/total).round(2)}%)"
307
- end
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
- users_attachment = []
311
- if user==''
312
- users = rows.user_id.uniq.sort
313
- if rows[0].key?(:time_zone) #then save_stats is saving the time zone already
314
- rows.time_zone.each do |time_zone|
315
- unless time_zone == ''
316
- tzone_users[time_zone] ||= 0
317
- tzone_users[time_zone] += 1
318
- end
319
- end
320
- else
321
- rows.user_id.each_with_index do |usr, i|
322
- if rows[i].values.size >= 12 #then save_stats is saving the time zone already but not all the data
323
- unless rows[i].values[11] == ''
324
- tzone_users[rows[i].values[11]] ||= 0
325
- tzone_users[rows[i].values[11]] += 1
326
- end
327
- else
328
- user_info = @users.select { |u| u.id == usr or (u.key?(:enterprise_user) and u.enterprise_user.id == usr) }[-1]
329
- unless user_info.nil? or user_info.is_app_user or user_info.is_bot
330
- tzone_users[user_info.tz_label] ||= 0
331
- tzone_users[user_info.tz_label] += 1
332
- end
333
- end
334
- end
335
- end
336
- if rows[0].key?(:job_title) #then save_stats is saving the job title already
337
- rows.job_title.each_with_index do |job_title, idx|
338
- job_title = job_title.to_s.split.map(&:capitalize).join(' ')
339
- job_title_users[job_title] ||= 0
340
- job_title_users[job_title] += 1
341
- users_by_job_title[job_title] ||= []
342
- users_by_job_title[job_title] << rows.user_name[idx]
343
- end
344
- else
345
- rows.user_id.each_with_index do |usr, i|
346
- if rows[i].values.size >= 13 #then save_stats is saving the job_title already but not all the data
347
- job_title = rows[i].values[12].to_s.split.map(&:capitalize).join(' ')
348
- job_title_users[job_title] ||= 0
349
- job_title_users[job_title] += 1
350
- users_by_job_title[job_title] ||= []
351
- users_by_job_title[job_title] << rows.user_name[i]
352
- else
353
- user_info = @users.select { |u| u.id == usr or (u.key?(:enterprise_user) and u.enterprise_user.id == usr) }[-1]
354
- unless user_info.nil? or user_info.is_app_user or user_info.is_bot
355
- job_title = user_info.profile.title.split.map(&:capitalize).join(' ')
356
- job_title_users[job_title] ||= 0
357
- job_title_users[job_title] += 1
358
- users_by_job_title[job_title] ||= []
359
- users_by_job_title[job_title] << rows.user_name[i]
360
- end
361
- end
362
- end
363
- end
364
- total_users_by_job_title = 0
365
- users_by_job_title.each do |job_title, users|
366
- users.uniq!
367
- total_users_by_job_title += users.size
368
- end
369
- if users.size > 10
370
- message << "*Users* - #{users.size} (Top 10)"
371
- else
372
- message << "*Users* - #{users.size}"
373
- end
374
- count_user = {}
375
- users.each do |user|
376
- count = rows.count {|h| h.user_id==user}
377
- count_user[user] = count
378
- end
379
- i = 0
380
- total_without_routines = total
381
- count_user.sort_by {|k,v| -v}.each do |user, count|
382
- i+=1
383
- if user.include?('routine/')
384
- user_link = users_id_name[user]
385
- total_without_routines -= count
386
- else
387
- user_link = "<@#{user}>"
388
- end
389
- if i <= 10
390
- message << "\t#{user_link}: #{count} (#{(count.to_f*100/total).round(2)}%)"
391
- end
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
- if tzone_users.size > 0
398
- message << "*Time Zones*"
399
- total_known = 0
400
- tzone_users.each do |tzone, num|
401
- unless tzone.to_s == ''
402
- message << "\t#{tzone}: #{num} (#{(num.to_f*100/total_without_routines).round(2)}%)"
403
- total_known+=num
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
- if st_command == ''
449
- commands = rows.command.uniq.sort
450
- count_command = {}
451
- commands.each do |command|
452
- count = rows.count {|h| h.command==command}
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
- if commands.size > 10
457
- message << "*Commands* - #{commands.size} (Top 10)"
458
- else
459
- message << "*Commands* - #{commands.size}"
460
- end
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
- i = 0
463
- count_command.sort_by {|k,v| -v}.each do |command, count|
464
- i+=1
465
- if i <= 10
466
- message << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
467
- end
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
- if on_dm_master
482
- message << "*Last activity*: #{rows[-1].date} #{rows[-1].bot_channel} #{rows[-1].type_message} #{rows[-1].user_name} #{rows[-1].command}"
483
- end
484
- if users_attachment.size>0
485
- send_file(dest, "", 'users.txt', "", 'text/plain', "text", content: users_attachment.join("\n"))
486
- end
487
- if commands_attachment.size>0
488
- send_file(dest, "", 'commands.txt', "", 'text/plain', "text", content: commands_attachment.join("\n"))
489
- end
490
- if channels_dest_attachment.size>0
491
- send_file(dest, "", 'channels_dest.txt', "", 'text/plain', "text", content: channels_dest_attachment.join("\n"))
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
- respond "#{message.join("\n")}", dest
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
- end
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
- 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)
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
@@ -212,7 +212,7 @@ class SlackSmartBot
212
212
  else
213
213
  Thread.current[:using_channel] = ''
214
214
  end
215
- if (typem == :on_pub or typem == :on_pg) and (!command.match?(/\A\s*bot\s+stats\s*(.*)\s*$/i) or dest!=@channels_id[config.stats_channel])
215
+ if (typem == :on_pub or typem == :on_pg) and (!command.match?(/\s*bot\s+stats\s*(.*)\s*$/i) or dest!=@channels_id[config.stats_channel])
216
216
  processed = false
217
217
  else
218
218
  processed = process(user, command, dest, dchannel, rules_file, typem, files, Thread.current[:thread_ts])
data/whats_new.txt CHANGED
@@ -1,4 +1,4 @@
1
- *Version 1.12.6* Released 2022-Nov-08
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.6
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-08 00:00:00.000000000 Z
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