slack-smart-bot 1.7.0 → 1.8.0

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: cd95efb0ac282a17d1b463fe28293643c0b38b91b3261e0d3899e879950e4655
4
- data.tar.gz: 1d332d2651286f4bef95c1172d95bc6ce422166b50bf788773563747ebbf1c30
3
+ metadata.gz: b15c46b5b101a0a31487508457982e8f5d6b81ad41f54338407ecdb2aa9974f3
4
+ data.tar.gz: d32bfceda9068f5f11d1002f255b77a280f3a7b7068f40a632c03b7cb6378127
5
5
  SHA512:
6
- metadata.gz: f48dc2999a22da392d297cb789dfcc7552ce1ef7aad607283f705d39af5eac58ce2ca002b844178184e6bacdc13fe641ddbe762f8a999b17da7532a5cad234b8
7
- data.tar.gz: f4ac49668234f24295e79afd842218e40a1a918c1107392af84d3b31c6d8908fadb8319f2e4596ef896c44e7c36665714523fc554f4c8b70a3a5a1f02cc2c872
6
+ metadata.gz: 61c6e4060d928a1562176a0596ac968c7d007998c268816af489a0d36624a768ba1eadd3b6d27be7d19d37984b335d70215f718189165c1a9ac0a3a18130c5a0
7
+ data.tar.gz: 48995f9d416dd8906353508ac9bf86219cd92b2ede2f0043c3752dcc4db95564161ad64f41d86fd9f821fa1dc6d9d5bba3ef5519be037214e0003c3423b595c9
data/README.md CHANGED
@@ -124,6 +124,7 @@ def rules(user, command, processed, dest)
124
124
  respond "zZzzzzzZZZZZZzzzzzzz!"
125
125
  react :sleeping
126
126
  sleep 10
127
+ unreact :sleeping
127
128
  react :sunny
128
129
  when /no/i, /nope/i, /cancel/i
129
130
  @questions.delete(from)
@@ -152,6 +153,8 @@ def rules(user, command, processed, dest)
152
153
  else
153
154
  respond "#{user.name}: #{stdout} #{stderr}"
154
155
  end
156
+
157
+ unreact :runner
155
158
 
156
159
  else
157
160
  unless processed
@@ -391,6 +394,7 @@ Examples:
391
394
  >**_`add routine run_tests every 3h !run tests on customers`_**
392
395
  >**_`add routine clean_db at 17:05 !clean customers temp db`_**
393
396
  >**_`add silent routine clean_db at 17:05 !clean customers temp db`_**
397
+ >**_`add routine clean_custdb on Mondays at 05:00 !clean customers db`_**
394
398
 
395
399
  Also instead of adding a Command to be executed, you can attach a file, then the routine will be created and the attached file will be executed on the criteria specified. Only Master Admins are allowed to use it this way.
396
400
 
@@ -8,12 +8,15 @@ def general_rules(user, command, processed, dest, files = [], rules_file = "")
8
8
 
9
9
  # help: ----------------------------------------------
10
10
  # help: `echo SOMETHING`
11
- # help: repeats SOMETHING
11
+ # help: `INTEGER echo SOMETHING`
12
+ # help: repeats SOMETHING. If INTEGER supplied then that number of times.
12
13
  # help: Examples:
13
14
  # help: _echo I am the Smart Bot_
14
- when /^echo\s(.+)/i
15
- save_stats :echo
16
- respond $1
15
+ # help: _100 echo :heart:_
16
+ when /^(\d*)\s*echo\s(.+)/i
17
+ save_stats :echo
18
+ $1.to_s == '' ? times = 1 : times = $1.to_i
19
+ respond ($2*times).to_s
17
20
 
18
21
  else
19
22
  return false
@@ -60,6 +60,7 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
60
60
  respond "zZzzzzzZZZZZZzzzzzzz!"
61
61
  react :sleeping
62
62
  sleep 5
63
+ unreact :sleeping
63
64
  react :sunny
64
65
  when /no/i, /nope/i, /cancel/i
65
66
  @questions.delete(from)
@@ -81,6 +82,7 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
81
82
  process_to_run = "ruby -v"
82
83
  process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
83
84
  stdout, stderr, status = Open3.capture3(process_to_run)
85
+ unreact :runner
84
86
  if stderr == ""
85
87
  if stdout == ""
86
88
  respond "#{display_name}: Nothing returned."
@@ -5,4 +5,5 @@ require_relative 'comm/respond'
5
5
  require_relative 'comm/send_file'
6
6
  require_relative 'comm/send_msg_channel'
7
7
  require_relative 'comm/send_msg_user'
8
- require_relative 'comm/react'
8
+ require_relative 'comm/react'
9
+ require_relative 'comm/unreact'
@@ -38,7 +38,7 @@ class SlackSmartBot
38
38
  f.puts "|#{dest}|#{config[:nick_id]}|#{msg}"
39
39
  }
40
40
  end
41
- elsif dest[0] == "D" or dest[0] == "U" # Direct message
41
+ elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
42
42
  send_msg_user(dest, msg)
43
43
  elsif dest[0] == "@"
44
44
  begin
@@ -8,7 +8,7 @@ class SlackSmartBot
8
8
  def send_file(to, msg, file, title, format, type = "text", content: '')
9
9
  unless config[:simulate]
10
10
  file = 'myfile' if file.to_s == '' and content!=''
11
- if to[0] == "U" #user
11
+ if to[0] == "U" or to[0] == "W" #user
12
12
  im = client.web_client.im_open(user: to)
13
13
  channel = im["channel"]["id"]
14
14
  else
@@ -0,0 +1,16 @@
1
+ class SlackSmartBot
2
+ # list of available emojis: https://www.webfx.com/tools/emoji-cheat-sheet/
3
+ # unreact(:thumbsup)
4
+ def unreact(emoji, parent=false)
5
+ if parent
6
+ ts = Thread.current[:thread_ts]
7
+ else
8
+ ts = Thread.current[:ts]
9
+ end
10
+ begin
11
+ client.web_client.reactions_remove(channel: Thread.current[:dest], name: emoji, timestamp: ts)
12
+ rescue Exception => stack
13
+ @logger.warn stack
14
+ end
15
+ end
16
+ end
@@ -5,6 +5,7 @@ class SlackSmartBot
5
5
  # helpadmin: `add silent routine NAME every NUMBER PERIOD`
6
6
  # helpadmin: `create routine NAME every NUMBER PERIOD`
7
7
  # helpadmin: `add routine NAME at TIME COMMAND`
8
+ # helpadmin: `add routine NAME on DAYWEEK at TIME COMMAND`
8
9
  # helpadmin: `add routine NAME at TIME`
9
10
  # helpadmin: `add silent routine NAME at TIME`
10
11
  # helpadmin: `create routine NAME at TIME`
@@ -15,12 +16,14 @@ class SlackSmartBot
15
16
  # helpadmin: NUMBER: Integer
16
17
  # helpadmin: PERIOD: days, d, hours, h, minutes, mins, min, m, seconds, secs, sec, s
17
18
  # helpadmin: TIME: time at format HH:MM:SS
19
+ # helpadmin: DAYWEEK: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. And their plurals.
18
20
  # helpadmin: COMMAND: any valid smart bot command or rule
19
21
  # helpadmin: Examples:
20
22
  # helpadmin: _add routine example every 30s ruby puts 'a'_
21
23
  # helpadmin: _add routine example every 3 days ruby puts 'a'_
22
24
  # helpadmin: _add routine example at 17:05 ruby puts 'a'_
23
25
  # helpadmin: _create silent routine every 12 hours !Run customer tests_
26
+ # helpadmin: _add routine example on Mondays at 05:00 !run customer tests_
24
27
  # helpadmin:
25
28
  def add_routine(dest, from, user, name, type, number_time, period, command_to_run, files, silent)
26
29
  save_stats(__method__)
@@ -30,13 +33,14 @@ class SlackSmartBot
30
33
  respond "I'm sorry but there is already a routine with that name.\nCall `see routines` to see added routines", dest
31
34
  else
32
35
  number_time += ":00" if number_time.split(":").size == 2
33
- if (type == "at") && !number_time.match?(/^[01][0-9]:[0-5][0-9]:[0-5][0-9]$/) &&
36
+ if (type != "every") && !number_time.match?(/^[01][0-9]:[0-5][0-9]:[0-5][0-9]$/) &&
34
37
  !number_time.match?(/^2[0-3]:[0-5][0-9]:[0-5][0-9]$/)
35
38
  respond "Wrong time specified: *#{number_time}*"
36
39
  else
37
40
  file_path = ""
38
41
  every = ""
39
42
  at = ""
43
+ dayweek = ''
40
44
  next_run = Time.now
41
45
  case period.downcase
42
46
  when "days", "d"
@@ -52,16 +56,31 @@ class SlackSmartBot
52
56
  every = "#{number_time} seconds"
53
57
  every_in_seconds = number_time.to_i
54
58
  else # time
59
+ if type != 'at'
60
+ dayweek = type.downcase
61
+ days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
62
+ incr = days.index(dayweek) - Time.now.wday
63
+ if incr < 0
64
+ incr = (7+incr)*24*60*60
65
+ else
66
+ incr = incr * 24 * 60 * 60
67
+ end
68
+ days = incr/(24*60*60)
69
+ every_in_seconds = 7 * 24 * 60 * 60 # one week
70
+ else
71
+ days = 0
72
+ every_in_seconds = 24 * 60 * 60 # one day
73
+ end
74
+
55
75
  at = number_time
56
- if next_run.strftime("%H:%M:%S") < number_time
76
+ if next_run.strftime("%H:%M:%S") < number_time and days == 0
57
77
  nt = number_time.split(":")
58
78
  next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
59
79
  else
60
- next_run += (24 * 60 * 60) # one more day
80
+ next_run += ((24 * 60 * 60) * days) # one or more days
61
81
  nt = number_time.split(":")
62
82
  next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
63
83
  end
64
- every_in_seconds = 24 * 60 * 60
65
84
  end
66
85
  Dir.mkdir("#{config.path}/routines/#{@channel_id}") unless Dir.exist?("#{config.path}/routines/#{@channel_id}")
67
86
 
@@ -78,7 +97,7 @@ class SlackSmartBot
78
97
 
79
98
  @routines[@channel_id] = {} unless @routines.key?(@channel_id)
80
99
  @routines[@channel_id][name] = { channel_name: config.channel, creator: from, creator_id: user.id, status: :on,
81
- every: every, every_in_seconds: every_in_seconds, at: at, file_path: file_path,
100
+ every: every, every_in_seconds: every_in_seconds, at: at, dayweek: dayweek, file_path: file_path,
82
101
  command: command_to_run.to_s.strip, silent: silent,
83
102
  next_run: next_run.to_s, dest: dest, last_run: "", last_elapsed: "",
84
103
  running: false }
@@ -44,6 +44,7 @@ class SlackSmartBot
44
44
  msg << "\tStatus: #{v[:status]}"
45
45
  msg << "\tEvery: #{v[:every]}" unless v[:every] == ""
46
46
  msg << "\tAt: #{v[:at]}" unless v[:at] == ""
47
+ msg << "\tOn: #{v[:dayweek]}" unless !v.key?(:dayweek) or v[:dayweek].to_s == ""
47
48
  msg << "\tNext Run: #{v[:next_run]}"
48
49
  msg << "\tLast Run: #{v[:last_run]}"
49
50
  msg << "\tTime consumed on last run: #{v[:last_elapsed]}" unless v[:command] !=''
@@ -22,7 +22,7 @@ class SlackSmartBot
22
22
  # helpadmin: _bot stats @peter.wind_
23
23
  # helpadmin: _bot stats #sales from 2019/12/15 to 2019/12/31_
24
24
  # helpadmin: _bot stats #sales today_
25
- # helpadmin: _bot stats #sales monthly_
25
+ # helpadmin: _bot stats #sales from 2020-01-01 monthly_
26
26
  # helpadmin:
27
27
  def bot_stats(dest, from_user, typem, channel_id, from, to, user, exclude_masters, exclude_command, monthly)
28
28
  require 'csv'
@@ -36,6 +36,10 @@ class SlackSmartBot
36
36
  if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
37
37
  message<<'No stats'
38
38
  else
39
+ if user!=''
40
+ user_info = client.web_client.users_info(user: user)
41
+ user_name = user_info.user.name
42
+ end
39
43
  from = "#{Time.now.strftime("%Y-%m")}-01" if from == ''
40
44
  to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ''
41
45
  from_short = from
@@ -46,20 +50,26 @@ class SlackSmartBot
46
50
  to+= " 23:59:59 +0000"
47
51
  rows = []
48
52
  rows_month = {}
53
+ users_month = {}
54
+ commands_month = {}
49
55
 
50
56
  Dir["#{config.stats_path}.*.log"].sort.each do |file|
51
57
  if file >= "#{config.stats_path}.#{from_file}.log" or file <= "#{config.stats_path}.#{to_file}.log"
52
58
  CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
53
59
  row[:date] = row[:date].to_s
54
60
  if !exclude_masters or (exclude_masters and !config.masters.include?(row[:user_name]))
55
- if user=='' or (user!='' and row[:user_id] == user)
61
+ if user=='' or (user!='' and row[:user_name] == user_name)
56
62
  if exclude_command == '' or (exclude_command!='' and row[:command]!=exclude_command)
57
63
  if row[:bot_channel_id] == channel_id or channel_id == ''
58
64
  if row[:date] >= from and row[:date] <= to
59
65
  rows << row.to_h
60
66
  if monthly
61
67
  rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
68
+ users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
69
+ commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
62
70
  rows_month[row[:date][0..6]] += 1
71
+ users_month[row[:date][0..6]] << row[:user_name]
72
+ commands_month[row[:date][0..6]] << row[:command]
63
73
  end
64
74
  end
65
75
  end
@@ -87,9 +97,18 @@ class SlackSmartBot
87
97
  end
88
98
  if total > 0
89
99
  if monthly
90
- message << '*Totals by month*'
100
+ message << '*Totals by month / commands / users (%new)*'
101
+ all_users = []
102
+ new_users = []
91
103
  rows_month.each do |k,v|
92
- message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%)"
104
+ if all_users.empty?
105
+ message_new_users = ''
106
+ else
107
+ new_users = (users_month[k]-all_users).uniq
108
+ message_new_users = "(#{new_users.size*100/users_month[k].uniq.size}%)"
109
+ end
110
+ all_users += users_month[k]
111
+ message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
93
112
  end
94
113
  end
95
114
 
@@ -102,16 +121,16 @@ class SlackSmartBot
102
121
  end
103
122
  end
104
123
  if user==''
105
- message << "*Users*"
106
124
  users = rows.user_name.uniq.sort
125
+ message << "*Users* - #{users.size}"
107
126
  users.each do |user|
108
127
  count = rows.count {|h| h.user_name==user}
109
128
  message << "\t#{user}: #{count} (#{(count.to_f*100/total).round(2)}%)"
110
129
  end
111
130
  end
112
131
 
113
- message << "*Commands*"
114
132
  commands = rows.command.uniq.sort
133
+ message << "*Commands* - #{commands.size}"
115
134
  commands.each do |command|
116
135
  count = rows.count {|h| h.command==command}
117
136
  message << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
@@ -70,7 +70,8 @@ class SlackSmartBot
70
70
  channel = $1
71
71
  kill_bot_on_channel(dest, from, channel)
72
72
  when /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s.+)?\s*$/i,
73
- /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i
73
+ /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+on\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)s?\s+at\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i,
74
+ /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i
74
75
  silent = $2.to_s!=''
75
76
  name = $3.downcase
76
77
  type = $4
@@ -117,6 +117,7 @@ class SlackSmartBot
117
117
  begin
118
118
  #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
119
119
  user_info = client.web_client.users_info(user: data.user)
120
+ user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
120
121
  if @questions.key?(user_info.user.name)
121
122
  if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
122
123
  @questions.delete(user_info.user.name)
@@ -13,7 +13,6 @@ class SlackSmartBot
13
13
  ruby = ""
14
14
  end
15
15
  @routines[@channel_id][name][:silent] = false if !@routines[@channel_id][name].key?(:silent)
16
-
17
16
  if @routines[@channel_id][name][:at] == "" or
18
17
  (@routines[@channel_id][name][:at] != "" and @routines[@channel_id][name][:running] and
19
18
  @routines[@channel_id][name][:next_run] != "" and Time.now.to_s >= @routines[@channel_id][name][:next_run])
@@ -55,11 +54,34 @@ class SlackSmartBot
55
54
  require "time"
56
55
  every_in_seconds = Time.parse(@routines[@channel_id][name][:next_run]) - Time.now
57
56
  elsif @routines[@channel_id][name][:at] != "" #coming from start after pause for 'at'
58
- if started.strftime("%H:%M:%S") < @routines[@channel_id][name][:at]
57
+ if @routines[@channel_id][name].key?(:dayweek) and @routines[@channel_id][name][:dayweek].to_s!=''
58
+ day = @routines[@channel_id][name][:dayweek]
59
+ days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
60
+ incr = days.index(day) - Time.now.wday
61
+ if incr < 0
62
+ incr = (7+incr)*24*60*60
63
+ else
64
+ incr = incr * 24 * 60 * 60
65
+ end
66
+ days = incr/(24*60*60)
67
+ weekly = true
68
+ else
69
+ days = 0
70
+ weekly = false
71
+ end
72
+
73
+ if started.strftime("%H:%M:%S") < @routines[@channel_id][name][:at] and days == 0
59
74
  nt = @routines[@channel_id][name][:at].split(":")
60
75
  next_run = Time.new(started.year, started.month, started.day, nt[0], nt[1], nt[2])
61
76
  else
62
- next_run = started + (24 * 60 * 60) # one more day
77
+ if days == 0 and started.strftime("%H:%M:%S") >= @routines[@channel_id][name][:at]
78
+ if weekly
79
+ days = 7
80
+ else
81
+ days = 1
82
+ end
83
+ end
84
+ next_run = started + (days * 24 * 60 * 60) # one more day/week
63
85
  nt = @routines[@channel_id][name][:at].split(":")
64
86
  next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
65
87
  end
metadata CHANGED
@@ -1,35 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-smart-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-27 00:00:00.000000000 Z
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slack-ruby-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.14'
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
- version: 0.14.6
19
+ version: 0.15.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '0.15'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '0.14'
30
27
  - - ">="
31
28
  - !ruby/object:Gem::Version
32
- version: 0.14.6
29
+ version: 0.15.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.15'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: nice_http
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +81,7 @@ dependencies:
81
81
  version: '1'
82
82
  - - ">="
83
83
  - !ruby/object:Gem::Version
84
- version: 1.1.0
84
+ version: 1.2.1
85
85
  type: :runtime
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
@@ -91,7 +91,7 @@ dependencies:
91
91
  version: '1'
92
92
  - - ">="
93
93
  - !ruby/object:Gem::Version
94
- version: 1.1.0
94
+ version: 1.2.1
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: rspec
97
97
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,7 @@ files:
136
136
  - lib/slack/smart-bot/comm/send_file.rb
137
137
  - lib/slack/smart-bot/comm/send_msg_channel.rb
138
138
  - lib/slack/smart-bot/comm/send_msg_user.rb
139
+ - lib/slack/smart-bot/comm/unreact.rb
139
140
  - lib/slack/smart-bot/commands.rb
140
141
  - lib/slack/smart-bot/commands/general/bot_help.rb
141
142
  - lib/slack/smart-bot/commands/general/bot_status.rb