slack-smart-bot 1.8.2 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -11
  3. data/lib/slack-smart-bot.rb +43 -44
  4. data/lib/slack-smart-bot_rules.rb +6 -6
  5. data/lib/slack/smart-bot/comm.rb +5 -1
  6. data/lib/slack/smart-bot/comm/ask.rb +12 -5
  7. data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
  8. data/lib/slack/smart-bot/comm/event_hello.rb +30 -0
  9. data/lib/slack/smart-bot/comm/get_channel_members.rb +8 -0
  10. data/lib/slack/smart-bot/comm/get_channels.rb +20 -0
  11. data/lib/slack/smart-bot/comm/get_user_info.rb +16 -0
  12. data/lib/slack/smart-bot/comm/react.rb +21 -8
  13. data/lib/slack/smart-bot/comm/respond.rb +10 -5
  14. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  15. data/lib/slack/smart-bot/comm/send_msg_user.rb +4 -4
  16. data/lib/slack/smart-bot/comm/unreact.rb +21 -8
  17. data/lib/slack/smart-bot/commands.rb +3 -1
  18. data/lib/slack/smart-bot/commands/general/bot_help.rb +16 -3
  19. data/lib/slack/smart-bot/commands/general/bot_stats.rb +313 -0
  20. data/lib/slack/smart-bot/commands/general/bot_status.rb +1 -1
  21. data/lib/slack/smart-bot/commands/general/bye_bot.rb +1 -1
  22. data/lib/slack/smart-bot/commands/general/hi_bot.rb +1 -1
  23. data/lib/slack/smart-bot/commands/general/use_rules.rb +2 -6
  24. data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
  25. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +65 -33
  26. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +3 -7
  27. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +1 -0
  28. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +8 -2
  29. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +1 -0
  30. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  31. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +52 -21
  32. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +5 -5
  33. data/lib/slack/smart-bot/commands/on_bot/repl.rb +50 -18
  34. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +34 -9
  35. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +2 -3
  36. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
  37. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +27 -9
  38. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +14 -1
  39. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -3
  40. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -1
  41. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +41 -0
  42. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +4 -8
  43. data/lib/slack/smart-bot/listen.rb +6 -5
  44. data/lib/slack/smart-bot/process.rb +227 -188
  45. data/lib/slack/smart-bot/process_first.rb +104 -87
  46. data/lib/slack/smart-bot/treat_message.rb +98 -38
  47. data/lib/slack/smart-bot/utils.rb +2 -0
  48. data/lib/slack/smart-bot/utils/answer.rb +18 -0
  49. data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
  50. data/lib/slack/smart-bot/utils/build_help.rb +57 -5
  51. data/lib/slack/smart-bot/utils/create_routine_thread.rb +11 -2
  52. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
  53. data/lib/slack/smart-bot/utils/get_help.rb +79 -17
  54. data/lib/slack/smart-bot/utils/save_stats.rb +21 -8
  55. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
  56. data/whats_new.txt +18 -0
  57. metadata +21 -12
  58. data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -195
@@ -13,39 +13,64 @@ class SlackSmartBot
13
13
  (!user.key?(:enterprise_user) or ( user.key?(:enterprise_user) and !config[:allow_access][__method__].include?(user[:enterprise_user].id)))
14
14
  respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
15
15
  else
16
- unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
16
+ unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File.") or
17
17
  code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
18
18
  code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
19
- code.include?("ENV") or code.match?(/=\s*IO/)
19
+ code.include?("ENV") or code.match?(/=\s*IO/) or code.include?("Dir.") or code.match?(/=\s*IO/) or
20
+ code.match?(/=\s*File/) or code.match?(/=\s*Dir/) or code.match?(/<\s*File/) or code.match?(/<\s*Dir/) or
21
+ code.match?(/\w+:\s*File/) or code.match?(/\w+:\s*Dir/)
22
+ react :running
20
23
  unless rules_file.empty?
21
24
  begin
22
25
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
23
26
  end
24
27
  end
25
28
 
26
- respond "Running", dest if code.size > 100
29
+ respond "Running", dest if code.size > 200
27
30
 
28
31
  begin
29
32
  code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting
33
+ code.gsub!('$','\$') #to take $ as literal, fex: puts '$lolo' => puts '\$lolo'
30
34
  ruby = "ruby -e \"#{code.gsub('"', '\"')}\""
31
35
  if defined?(project_folder) and project_folder.to_s != "" and Dir.exist?(project_folder)
32
36
  ruby = ("cd #{project_folder} &&" + ruby)
33
37
  else
34
38
  def project_folder() "" end
35
39
  end
36
- stdout, stderr, status = Open3.capture3(ruby)
37
- if stderr == ""
38
- if stdout == ""
39
- respond "Nothing returned. Remember you need to use p or puts to print", dest
40
+
41
+ stdin, stdout, stderr, wait_thr = Open3.popen3(ruby)
42
+ timeout = timeoutt = 20
43
+ procstart = Time.now
44
+ while (wait_thr.status == 'run' or wait_thr.status == 'sleep') and timeout > 0
45
+ timeout -= 0.1
46
+ sleep 0.1
47
+ end
48
+ if timeout > 0
49
+ stdout = stdout.read
50
+ stderr = stderr.read
51
+ if stderr == ""
52
+ if stdout == ""
53
+ respond "Nothing returned. Remember you need to use p or puts to print", dest
54
+ else
55
+ respond stdout, dest
56
+ end
40
57
  else
41
- respond stdout, dest
58
+ respond "#{stderr}\n#{stdout}", dest
42
59
  end
43
60
  else
44
- respond "#{stderr}\n#{stdout}", dest
61
+ respond "The process didn't finish in #{timeoutt} secs so it was aborted. Timeout!"
62
+ pids = `pgrep -P #{wait_thr.pid}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
63
+ pids.each do |pid|
64
+ begin
65
+ Process.kill("KILL", pid)
66
+ rescue
67
+ end
68
+ end
45
69
  end
46
70
  rescue Exception => exc
47
71
  respond exc, dest
48
72
  end
73
+ unreact :running
49
74
  else
50
75
  respond "Sorry I cannot run this due security reasons", dest
51
76
  end
@@ -4,7 +4,6 @@ class SlackSmartBot
4
4
  # help: `run repl SESSION_NAME ENV_VAR=VALUE ENV_VAR=VALUE`
5
5
  # help: `run live SESSION_NAME`
6
6
  # help: `run irb SESSION_NAME`
7
- # help:
8
7
  # help: Will run the repl session specified and return the output.
9
8
  # help: You can supply the Environmental Variables you need for the Session
10
9
  # help: It will return only the values that were print out on the repl with puts, print, p or pp
@@ -22,7 +21,7 @@ class SlackSmartBot
22
21
  Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
23
22
  Dir.mkdir("#{config.path}/repl/#{@channel_id}") unless Dir.exist?("#{config.path}/repl/#{@channel_id}")
24
23
  if File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.run")
25
- if @repls.key?(session_name) and @repls[session_name][:type] == :private and
24
+ if @repls.key?(session_name) and (@repls[session_name][:type] == :private or @repls[session_name][:type] == :private_clean) and
26
25
  @repls[session_name][:creator_name]!=user.name and
27
26
  !config.admins.include?(user.name)
28
27
  respond "The REPL with session name: #{session_name} is private", dest
@@ -44,7 +43,7 @@ class SlackSmartBot
44
43
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
45
44
  end
46
45
  end
47
- if File.exist?("#{project_folder}/.smart-bot-repl")
46
+ if File.exist?("#{project_folder}/.smart-bot-repl") and @repls[session_name][:type] != :private_clean and @repls[session_name][:type] != :public_clean
48
47
  content += File.read("#{project_folder}/.smart-bot-repl")
49
48
  content += "\n"
50
49
  end
@@ -14,7 +14,7 @@ class SlackSmartBot
14
14
  else
15
15
  message = ""
16
16
  @repls.sort.to_h.each do |session_name, repl|
17
- if (repl.creator_name == user.name or repl.type == :public) or (config.admins.include?(user.name) and typem == :on_dm)
17
+ if (repl.creator_name == user.name or repl.type == :public or repl.type == :public_clean) or (config.admins.include?(user.name) and typem == :on_dm)
18
18
  message += "(#{repl.type}) *#{session_name}*: #{repl.description} / created: #{repl.created} / accessed: #{repl.accessed} / creator: #{repl.creator_name} / runs: #{repl.runs_by_creator+repl.runs_by_others} / gets: #{repl.gets} \n"
19
19
  end
20
20
  end
@@ -13,26 +13,44 @@ class SlackSmartBot
13
13
  else
14
14
  unless typem == :on_extended
15
15
  msg = ""
16
- if @shortcuts[:all].keys.size > 0
16
+ if @shortcuts[:all].keys.size > 0 or @shortcuts_global[:all].keys.size > 0
17
17
  msg = "*Available shortcuts for all:*\n"
18
- @shortcuts[:all].each { |name, value|
19
- msg += " _#{name}: #{value}_\n"
20
- }
18
+
19
+ if @shortcuts[:all].keys.size > 0
20
+ @shortcuts[:all].each { |name, value|
21
+ msg += " _#{name}: #{value}_\n"
22
+ }
23
+ end
24
+ if @shortcuts_global[:all].keys.size > 0
25
+ @shortcuts_global[:all].each { |name, value|
26
+ msg += " _#{name} (global): #{value}_\n"
27
+ }
28
+ end
21
29
  respond msg, dest
22
30
  end
23
-
31
+ msg2 = ''
24
32
  if @shortcuts.keys.include?(from) and @shortcuts[from].keys.size > 0
25
33
  new_hash = @shortcuts[from].dup
26
34
  @shortcuts[:all].keys.each { |k| new_hash.delete(k) }
27
35
  if new_hash.keys.size > 0
28
- msg = "*Available shortcuts for #{from}:*\n"
36
+ msg2 = "*Available shortcuts for #{from}:*\n"
29
37
  new_hash.each { |name, value|
30
- msg += " _#{name}: #{value}_\n"
38
+ msg2 += " _#{name}: #{value}_\n"
39
+ }
40
+ end
41
+ end
42
+ if @shortcuts_global.keys.include?(from) and @shortcuts_global[from].keys.size > 0
43
+ new_hash = @shortcuts_global[from].dup
44
+ @shortcuts_global[:all].keys.each { |k| new_hash.delete(k) }
45
+ if new_hash.keys.size > 0
46
+ msg2 = "*Available shortcuts for #{from}:*\n" if msg2 == ''
47
+ new_hash.each { |name, value|
48
+ msg2 += " _#{name} (global): #{value}_\n"
31
49
  }
32
- respond msg, dest
33
50
  end
34
51
  end
35
- respond "No shortcuts found", dest if msg == ""
52
+ respond msg2 unless msg2 == ''
53
+ respond "No shortcuts found" if (msg + msg2) == ""
36
54
  end
37
55
  end
38
56
  end
@@ -7,7 +7,15 @@ class SlackSmartBot
7
7
  respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
8
8
  else
9
9
  if typem == :on_extended or typem == :on_call #for the other cases above.
10
- help_filtered = get_help(rules_file, dest, from, true)
10
+
11
+ if help_command.to_s != ''
12
+ help_command = '' if help_command.to_s.match?(/^\s*expanded\s*$/i) or help_command.to_s.match?(/^\s*extended\s*$/i)
13
+ expanded = true
14
+ else
15
+ expanded = false
16
+ end
17
+
18
+ help_filtered = get_help(rules_file, dest, from, true, expanded)
11
19
 
12
20
  if help_command.to_s != ""
13
21
  help_found = false
@@ -38,6 +46,11 @@ class SlackSmartBot
38
46
  def git_project() "" end
39
47
  def project_folder() "" end
40
48
  end
49
+ unless expanded
50
+ message_not_expanded = "*If you want to see the expanded version of `bot rules`, please call `bot rules expanded`*\n"
51
+ message_not_expanded += "*Also to get specific expanded help for a specific command or rule call `bot rules COMMAND`*\n"
52
+ respond message_not_expanded
53
+ end
41
54
  end
42
55
  end
43
56
  end
@@ -11,10 +11,10 @@ class SlackSmartBot
11
11
  save_stats(__method__)
12
12
  if config.on_master_bot
13
13
  if config.admins.include?(from) #admin user
14
- unless @questions.keys.include?(from)
14
+ if answer.empty?
15
15
  ask("are you sure?", command, from, dest)
16
16
  else
17
- case @questions[from]
17
+ case answer
18
18
  when /yes/i, /yep/i, /sure/i
19
19
  respond "Game over!", dest
20
20
  respond "Ciao #{display_name}!", dest
@@ -33,7 +33,7 @@ class SlackSmartBot
33
33
  exit!
34
34
  end
35
35
  when /no/i, /nope/i, /cancel/i
36
- @questions.delete(from)
36
+ answer_delete(from)
37
37
  respond "Thanks, I'm happy to be alive", dest
38
38
  else
39
39
  ask("I don't understand, are you sure do you want me to close? (yes or no)", command, from, dest)
@@ -18,7 +18,7 @@ class SlackSmartBot
18
18
  end
19
19
  respond "Bot channels have been notified", dest
20
20
  elsif where == "all" #all
21
- myconv = client.web_client.users_conversations(exclude_archived: true, limit: 100, types: "im, public_channel,private_channel").channels
21
+ myconv = get_channels(bot_is_in: true)
22
22
  myconv.each do |c|
23
23
  respond message, c.id unless c.name == config.master_channel
24
24
  end
@@ -0,0 +1,41 @@
1
+ class SlackSmartBot
2
+ # helpmaster: ----------------------------------------------
3
+ # helpmaster: `set maintenance on`
4
+ # helpmaster: `set maintenance on MESSAGE`
5
+ # helpmaster: `set maintenance off`
6
+ # helpmaster: `turn maintenance on`
7
+ # helpmaster: `turn maintenance on MESSAGE`
8
+ # helpmaster: `turn maintenance off`
9
+ # helpmaster: The SmartBot will be on maintenance and responding with a generic message
10
+ # helpmaster: Only works if you are on Master channel and you are a master admin user
11
+ # helpmaster:
12
+ def set_maintenance(from, status, message)
13
+ save_stats(__method__)
14
+ if config.on_master_bot
15
+ if config.admins.include?(from) #admin user
16
+ if message == ''
17
+ config.on_maintenance_message = "Sorry I'm on maintenance so I cannot attend your request."
18
+ else
19
+ config.on_maintenance_message = message
20
+ end
21
+
22
+ if status == 'on'
23
+ config.on_maintenance = true
24
+ respond "From now on I'll be on maintenance status so I won't be responding accordingly."
25
+ else
26
+ config.on_maintenance = false
27
+ respond "From now on I won't be on maintenance. Everything is back to normal!"
28
+ end
29
+
30
+ file = File.open("#{config.path}/config_tmp.status", "w")
31
+ file.write config.inspect
32
+ file.close
33
+
34
+ else
35
+ respond 'Only master admins on master channel can use this command.'
36
+ end
37
+ else
38
+ respond 'Only master admins on master channel can use this command.'
39
+ end
40
+ end
41
+ end
@@ -24,13 +24,9 @@ class SlackSmartBot
24
24
  channel_id = @channels_id[channel]
25
25
  end
26
26
  #todo: add pagination for case more than 1000 channels on the workspace
27
- channels = client.web_client.conversations_list(
28
- types: "private_channel,public_channel",
29
- limit: "1000",
30
- exclude_archived: "true",
31
- ).channels
27
+ channels = get_channels()
32
28
  channel_found = channels.detect { |c| c.name == channel }
33
- members = client.web_client.conversations_members(channel: @channels_id[channel]).members unless channel_found.nil?
29
+ members = get_channel_members(@channels_id[channel]) unless channel_found.nil?
34
30
 
35
31
  if channel_id.nil?
36
32
  respond "There is no channel with that name: #{channel}, please be sure is written exactly the same", dest
@@ -39,7 +35,7 @@ class SlackSmartBot
39
35
  elsif @bots_created.keys.include?(channel_id)
40
36
  respond "There is already a bot in this channel: #{channel}, kill it before", dest
41
37
  elsif config[:nick_id] != channel_found.creator and !members.include?(config[:nick_id])
42
- respond "You need to add first to the channel the smart bot user: #{config[:nick]}", dest
38
+ respond "You need to add first to the channel the smart bot user: <@#{config[:nick_id]}>", dest
43
39
  else
44
40
  if channel_id != config[:channel]
45
41
  begin
@@ -60,7 +56,7 @@ class SlackSmartBot
60
56
  FileUtils.copy_file(default_rules, config.path + rules_file) unless File.exist?(config.path + rules_file)
61
57
  FileUtils.copy_file(default_general_rules, config.path + general_rules_file) unless File.exist?(config.path + general_rules_file)
62
58
  admin_users = Array.new()
63
- creator_info = client.web_client.users_info(user: channel_found.creator)
59
+ creator_info = get_user_info(channel_found.creator)
64
60
  admin_users = [from, creator_info.user.name] + config.masters
65
61
  admin_users.uniq!
66
62
  @logger.info "ruby #{config.file_path} \"#{channel}\" \"#{admin_users.join(",")}\" \"#{rules_file}\" on"
@@ -6,7 +6,7 @@ class SlackSmartBot
6
6
  get_bots_created()
7
7
  @buffer_complete = [] unless defined?(@buffer_complete)
8
8
  b = File.read("#{config.path}/buffer_complete.log")
9
- result = b.scan(/^\|(\w+)\|(\w+)\|([^~]+)~~~/m)
9
+ result = b.scan(/^\|(\w+)\|(\w+)\|(\w+)\|([^~]+)~~~/m)
10
10
  result.delete(nil)
11
11
  new_messages = result[@buffer_complete.size..-1]
12
12
  unless new_messages.nil? or new_messages.empty?
@@ -14,7 +14,8 @@ class SlackSmartBot
14
14
  new_messages.each do |message|
15
15
  channel = message[0].strip
16
16
  user = message[1].strip
17
- command = message[2].to_s.strip
17
+ user_name = message[2].strip
18
+ command = message[3].to_s.strip
18
19
  # take in consideration that on simulation we are treating all messages even those that are not populated on real cases like when the message is not populated to the specific bot connection when message is sent with the bot
19
20
  @logger.info "treat message: #{message}" if config.testing
20
21
 
@@ -23,18 +24,18 @@ class SlackSmartBot
23
24
  command.scan(/`([^`]+)`/).flatten.each do |cmd|
24
25
  if cmd.to_s!=''
25
26
  cmd = "^#{cmd}"
26
- treat_message({channel: channel, user: user, text: cmd}, false)
27
+ treat_message({channel: channel, user: user, text: cmd, user_name: user_name}, false)
27
28
  end
28
29
  end
29
30
  elsif command.match?(/^\s*\-!/)
30
31
  command.scan(/`([^`]+)`/).flatten.each do |cmd|
31
32
  if cmd.to_s!=''
32
33
  cmd = "!#{cmd}"
33
- treat_message({channel: channel, user: user, text: cmd}, false)
34
+ treat_message({channel: channel, user: user, text: cmd, user_name: user_name}, false)
34
35
  end
35
36
  end
36
37
  else
37
- treat_message({channel: channel, user: user, text: command})
38
+ treat_message({channel: channel, user: user, text: command, user_name: user_name})
38
39
  end
39
40
  end
40
41
  end
@@ -1,11 +1,15 @@
1
1
  class SlackSmartBot
2
2
  def process(user, command, dest, dchannel, rules_file, typem, files, ts)
3
3
  from = user.name
4
-
5
- if user.profile.display_name.to_s.match?(/\A\s*\z/)
6
- user.profile.display_name = user.profile.real_name
4
+ if config.simulate
5
+ display_name = user.profile.display_name
6
+ else
7
+ if user.profile.display_name.to_s.match?(/\A\s*\z/)
8
+ user.profile.display_name = user.profile.real_name
9
+ end
10
+ display_name = user.profile.display_name
7
11
  end
8
- display_name = user.profile.display_name
12
+
9
13
  processed = true
10
14
 
11
15
  on_demand = false
@@ -23,205 +27,240 @@ class SlackSmartBot
23
27
  command = command2
24
28
  on_demand = true
25
29
  end
30
+ if (on_demand or
31
+ (@listening.key?(from) and (@listening[from].key?(dest) or @listening[from].key?(Thread.current[:thread_ts])) )) and
32
+ config.on_maintenance and !command.match?(/\A(set|turn)\s+maintenance\s+off\s*\z/)
33
+ respond config.on_maintenance_message, dest
34
+ processed = true
35
+ end
26
36
 
27
- #todo: check :on_pg in this case
28
- if typem == :on_master or typem == :on_bot or typem == :on_pg or typem == :on_dm
29
- case command
37
+ if !config.on_maintenance or (config.on_maintenance and command.match?(/\A(set|turn)\s+maintenance\s+off\s*\z/))
38
+ #todo: check :on_pg in this case
39
+ if typem == :on_master or typem == :on_bot or typem == :on_pg or typem == :on_dm
40
+
41
+ case command
30
42
 
31
- when /^\s*(Hello|Hallo|Hi|Hola|What's\sup|Hey|Hæ)\s(#{@salutations.join("|")})\s*$/i
32
- hi_bot(user, dest, dchannel, from, display_name)
33
- when /^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i
34
- bye_bot(dest, from, display_name)
35
- when /^\s*bot\s+(rules|help)\s*(.+)?$/i, /^bot,? what can I do/i
36
- $1.to_s.match?(/rules/i) ? specific = true : specific = false
37
- help_command = $2
43
+ when /^\s*(Hello|Hallo|Hi|Hola|What's\sup|Hey|Hæ)\s+(#{@salutations.join("|")})\s*$/i
44
+ hi_bot(user, dest, dchannel, from, display_name)
45
+ when /^\s*what's\s+new\s*$/i
46
+ whats_new(user, dest, dchannel, from, display_name)
47
+ when /^\s*(Bye|Bæ|Good\s+Bye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s+(#{@salutations.join("|")})\s*$/i
48
+ bye_bot(dest, from, display_name)
49
+ when /^\s*bot\s+(rules|help)\s*(.+)?$/i, /^bot,? what can I do/i
50
+ $1.to_s.match?(/rules/i) ? specific = true : specific = false
51
+ help_command = $2
38
52
 
39
- bot_help(user, from, dest, dchannel, specific, help_command, rules_file)
40
- when /^\s*use\s+(rules\s+)?(from\s+)?<#C\w+\|(.+)>\s*$/i, /^use\s+(rules\s+)?(from\s+)?([^\s]+\s*$)/i
41
- channel = $3
42
- use_rules(dest, channel, user, dchannel)
43
- when /^\s*stop using rules (from\s+)<#\w+\|(.+)>/i, /^stop using rules (from\s+)(.+)/i
44
- channel = $2
45
- stop_using_rules(dest, channel, user, dchannel)
46
- when /^\s*extend\s+rules\s+(to\s+)<#C\w+\|(.+)>/i, /^extend\s+rules\s+(to\s+)(.+)/i,
47
- /^\s*use\s+rules\s+(on\s+)<#C\w+\|(.+)>/i, /^use\s+rules\s+(on\s+)(.+)/i
48
- channel = $2
49
- extend_rules(dest, user, from, channel, typem)
50
- when /^\s*stop using rules (on\s+)<#\w+\|(.+)>/i, /^stop using rules (on\s+)(.+)/i
51
- channel = $2
52
- stop_using_rules_on(dest, user, from, channel, typem)
53
- when /^\s*exit\sbot\s*$/i, /^quit\sbot\s*$/i, /^close\sbot\s*$/i
54
- exit_bot(command, from, dest, display_name)
55
- when /^\s*start\s(this\s)?bot$/i
56
- start_bot(dest, from)
57
- when /^\s*pause\s(this\s)?bot$/i
58
- pause_bot(dest, from)
59
- when /^\s*bot\sstatus/i
60
- bot_status(dest, user)
61
- when /\Anotify\s+<#(C\w+)\|.+>\s+(.+)\s*\z/im, /\Anotify\s+(all)?\s*(.+)\s*\z/im
62
- where = $1
63
- message = $2
64
- notify_message(dest, from, where, message)
65
- when /^\s*create\s+(cloud\s+)?bot\s+on\s+<#C\w+\|(.+)>\s*/i, /^create\s+(cloud\s+)?bot\s+on\s+(.+)\s*/i
66
- cloud = !$1.nil?
67
- channel = $2
68
- create_bot(dest, user, cloud, channel)
69
- when /^\s*kill\sbot\son\s<#C\w+\|(.+)>\s*$/i, /^kill\sbot\son\s(.+)\s*$/i
70
- channel = $1
71
- kill_bot_on_channel(dest, from, channel)
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<#(C\w+)\|.+>\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<#(C\w+)\|.+>\s*)?(\s.+)?\s*$/i,
74
- /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s<#(C\w+)\|.+>\s*)?(\s.+)?\s*$/i
75
- silent = $2.to_s!=''
76
- name = $3.downcase
77
- type = $4
78
- number_time = $5
79
- period = $6
80
- channel = $8
81
- command_to_run = $9
82
- add_routine(dest, from, user, name, type, number_time, period, command_to_run, files, silent, channel)
83
- when /^\s*(kill|delete|remove)\s+routine\s+(\w+)\s*$/i
84
- name = $2.downcase
85
- remove_routine(dest, from, name)
86
- when /^\s*(run|execute)\s+routine\s+(\w+)\s*$/i
87
- name = $2.downcase
88
- run_routine(dest, from, name)
89
- when /^\s*pause\s+routine\s+(\w+)\s*$/i
90
- name = $1.downcase
91
- pause_routine(dest, from, name)
92
- when /^\s*start\s+routine\s+(\w+)\s*$/i
93
- name = $1.downcase
94
- start_routine(dest, from, name)
95
- when /^\s*see\s+(all\s+)?routines\s*$/i
96
- all = $1.to_s != ""
97
- see_routines(dest, from, user, all)
98
- when /^\s*get\s+bot\s+logs?\s*$/i
99
- get_bot_logs(dest, from, typem)
100
- when /^\s*bot\s+stats\s*(.*)\s*$/i
101
- opts = $1.to_s
102
- all_opts = opts.downcase.split(' ')
103
- st_channel = opts.scan(/<#(\w+)\|.+>/).join
104
- st_from = opts.scan(/from\s+(\d\d\d\d[\/\-\.]\d\d[\/\-\.]\d\d)/).join
105
- st_from = st_from.gsub('.','-').gsub('/','-')
106
- st_to = opts.scan(/to\s+(\d\d\d\d[\/\-\.]\d\d[\/\-\.]\d\d)/).join
107
- st_to = st_to.gsub('.','-').gsub('/','-')
108
- st_user = opts.scan(/<@([^>]+)>/).join
109
- exclude_masters = opts.match?(/exclude\s+masters?/i)
110
- monthly = false
111
- if all_opts.include?('today')
112
- st_from = st_to = "#{Time.now.strftime("%Y-%m-%d")}"
113
- elsif all_opts.include?('monthly')
114
- monthly = true
53
+ bot_help(user, from, dest, dchannel, specific, help_command, rules_file)
54
+ when /^\s*use\s+(rules\s+)?(from\s+)?<#C\w+\|(.+)>\s*$/i, /^use\s+(rules\s+)?(from\s+)?([^\s]+\s*$)/i
55
+ channel = $3
56
+ use_rules(dest, channel, user, dchannel)
57
+ when /^\s*stop\s+using\s+rules\s+(from\s+)<#\w+\|(.+)>/i, /^stop\s+using\s+rules\s+(from\s+)(.+)/i
58
+ channel = $2
59
+ stop_using_rules(dest, channel, user, dchannel)
60
+ when /^\s*extend\s+rules\s+(to\s+)<#C\w+\|(.+)>/i, /^extend\s+rules\s+(to\s+)(.+)/i,
61
+ /^\s*use\s+rules\s+(on\s+)<#C\w+\|(.+)>/i, /^use\s+rules\s+(on\s+)(.+)/i
62
+ channel = $2
63
+ extend_rules(dest, user, from, channel, typem)
64
+ when /^\s*stop\s+using\s+rules\s+(on\s+)<#\w+\|(.+)>/i, /^stop\s+using\s+rules\s+(on\s+)(.+)/i
65
+ channel = $2
66
+ stop_using_rules_on(dest, user, from, channel, typem)
67
+ when /^\s*exit\s+bot\s*$/i, /^quit\s+bot\s*$/i, /^close\s+bot\s*$/i
68
+ exit_bot(command, from, dest, display_name)
69
+ when /^\s*start\s+(this\s+)?bot$/i
70
+ start_bot(dest, from)
71
+ when /^\s*pause\s+(this\s+)?bot$/i
72
+ pause_bot(dest, from)
73
+ when /^\s*bot\s+status/i
74
+ bot_status(dest, user)
75
+ when /\Anotify\s+<#(C\w+)\|.+>\s+(.+)\s*\z/im, /\Anotify\s+(all)?\s*(.+)\s*\z/im
76
+ where = $1
77
+ message = $2
78
+ notify_message(dest, from, where, message)
79
+ when /^\s*create\s+(cloud\s+)?bot\s+on\s+<#C\w+\|(.+)>\s*/i, /^create\s+(cloud\s+)?bot\s+on\s+(.+)\s*/i
80
+ cloud = !$1.nil?
81
+ channel = $2
82
+ create_bot(dest, user, cloud, channel)
83
+ when /^\s*kill\s+bot\s+on\s+<#C\w+\|(.+)>\s*$/i, /^kill\s+bot\s+on\s+(.+)\s*$/i
84
+ channel = $1
85
+ kill_bot_on_channel(dest, from, channel)
86
+ 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<#(C\w+)\|.+>\s*)?(\s.+)?\s*$/i,
87
+ /^\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<#(C\w+)\|.+>\s*)?(\s.+)?\s*$/i,
88
+ /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s<#(C\w+)\|.+>\s*)?(\s.+)?\s*$/i
89
+ silent = $2.to_s!=''
90
+ name = $3.downcase
91
+ type = $4
92
+ number_time = $5
93
+ period = $6
94
+ channel = $8
95
+ command_to_run = $9
96
+ add_routine(dest, from, user, name, type, number_time, period, command_to_run, files, silent, channel)
97
+ when /^\s*(kill|delete|remove)\s+routine\s+(\w+)\s*$/i
98
+ name = $2.downcase
99
+ remove_routine(dest, from, name)
100
+ when /^\s*(run|execute)\s+routine\s+(\w+)\s*$/i
101
+ name = $2.downcase
102
+ run_routine(dest, from, name)
103
+ when /^\s*pause\s+routine\s+(\w+)\s*$/i
104
+ name = $1.downcase
105
+ pause_routine(dest, from, name)
106
+ when /^\s*start\s+routine\s+(\w+)\s*$/i
107
+ name = $1.downcase
108
+ start_routine(dest, from, name)
109
+ when /^\s*see\s+(all\s+)?routines\s*$/i
110
+ all = $1.to_s != ""
111
+ see_routines(dest, from, user, all)
112
+ when /^\s*get\s+bot\s+logs?\s*$/i
113
+ get_bot_logs(dest, from, typem)
114
+ when /^\s*bot\s+stats\s*(.*)\s*$/i
115
+ opts = $1.to_s
116
+ all_opts = opts.downcase.split(' ')
117
+ all_data = all_opts.include?('alldata')
118
+ st_channel = opts.scan(/<#(\w+)\|.+>/).join
119
+ st_from = opts.scan(/from\s+(\d\d\d\d[\/\-\.]\d\d[\/\-\.]\d\d)/).join
120
+ st_from = st_from.gsub('.','-').gsub('/','-')
121
+ st_to = opts.scan(/to\s+(\d\d\d\d[\/\-\.]\d\d[\/\-\.]\d\d)/).join
122
+ st_to = st_to.gsub('.','-').gsub('/','-')
123
+ st_user = opts.scan(/<@([^>]+)>/).join
124
+ st_command = opts.scan(/\s+command\s+(\w+)/i).join.downcase
125
+ st_command = opts.scan(/^command\s+(\w+)/i).join.downcase if st_command == ''
126
+ exclude_masters = all_opts.include?('exclude') && all_opts.include?('masters')
127
+ exclude_routines = all_opts.include?('exclude') && all_opts.include?('routines')
128
+ if exclude_masters
129
+ opts.gsub!(/\s+masters$/,'')
130
+ opts.gsub!(/\s+masters\s+/,'')
131
+ end
132
+ if exclude_routines
133
+ opts.gsub!(/\s+routines$/,'')
134
+ opts.gsub!(/\s+routines\s+/,'')
135
+ end
136
+ monthly = false
137
+ if all_opts.include?('today')
138
+ st_from = st_to = "#{Time.now.strftime("%Y-%m-%d")}"
139
+ elsif all_opts.include?('monthly')
140
+ monthly = true
141
+ end
142
+ exclude_command = opts.scan(/exclude\s+([^\s]+)/i).join
143
+ unless @master_admin_users_id.include?(user.id)
144
+ st_user = user.id
145
+ end
146
+ if (typem == :on_master or typem == :on_bot) and dest[0]!='D' #routine bot stats to be published on DM
147
+ st_channel = dchannel
148
+ end
149
+ bot_stats(dest, user, typem, st_channel, st_from, st_to, st_user, st_command, exclude_masters, exclude_routines, exclude_command, monthly, all_data)
150
+ when /\A(set|turn)\s+maintenance\s+(on|off)\s*()\z/im, /\A(set|turn)\s+maintenance\s+(on)\s*(.+)\s*\z/im
151
+ status = $2.downcase
152
+ message = $3.to_s
153
+ set_maintenance(from, status, message)
154
+ else
155
+ processed = false
115
156
  end
116
- exclude_command = opts.scan(/exclude\s+([^\s]+)/i).join
117
- exclude_command = '' if exclude_command == 'masters'
118
- bot_stats(dest, from, typem, st_channel, st_from, st_to, st_user, exclude_masters, exclude_command, monthly)
119
157
  else
120
158
  processed = false
121
159
  end
122
- else
123
- processed = false
124
- end
125
160
 
126
- # only when :on and (listening or on demand or direct message)
127
- if @status == :on and
128
- (@questions.key?(from) or
129
- (@repl_sessions.key?(from) and dest==@repl_sessions[from][:dest] and
130
- ((@repl_sessions[from][:on_thread] and Thread.current[:thread_ts] == @repl_sessions[from][:thread_ts]) or
131
- (!@repl_sessions[from][:on_thread] and !Thread.current[:on_thread]))) or
132
- (@listening.key?(from) and typem != :on_extended and
133
- ((@listening[from].key?(dest) and !Thread.current[:on_thread]) or
134
- (@listening[from].key?(Thread.current[:thread_ts]) and Thread.current[:on_thread] ) )) or
135
- typem == :on_dm or typem == :on_pg or on_demand)
136
- processed2 = true
161
+ # only when :on and (listening or on demand or direct message)
162
+ if @status == :on and
163
+ (!answer.empty? or
164
+ (@repl_sessions.key?(from) and dest==@repl_sessions[from][:dest] and
165
+ ((@repl_sessions[from][:on_thread] and Thread.current[:thread_ts] == @repl_sessions[from][:thread_ts]) or
166
+ (!@repl_sessions[from][:on_thread] and !Thread.current[:on_thread]))) or
167
+ (@listening.key?(from) and typem != :on_extended and
168
+ ((@listening[from].key?(dest) and !Thread.current[:on_thread]) or
169
+ (@listening[from].key?(Thread.current[:thread_ts]) and Thread.current[:on_thread] ) )) or
170
+ typem == :on_dm or typem == :on_pg or on_demand)
171
+ processed2 = true
172
+
173
+ case command
137
174
 
138
- case command
175
+ # bot rules for extended channels
176
+ when /^bot\s+rules\s*(.+)?$/i
177
+ help_command = $1
178
+ bot_rules(dest, help_command, typem, rules_file, user)
179
+ when /^\s*(add\s+)?(global\s+|generic\s+)?shortcut\s+(for\sall)?\s*([^:]+)\s*:\s*(.+)/i,
180
+ /^(add\s+)(global\s+|generic\s+)?sc\s+(for\sall)?\s*([^:]+)\s*:\s*(.+)/i
181
+ for_all = $3
182
+ shortcut_name = $4.to_s.downcase
183
+ command_to_run = $5
184
+ global = $2.to_s != ''
185
+ add_shortcut(dest, user, typem, for_all, shortcut_name, command, command_to_run, global)
186
+ when /^\s*(delete|remove)\s+(global\s+|generic\s+)?shortcut\s+(.+)/i,
187
+ /^(delete|remove)\s+(global\s+|generic\s+)?sc\s+(.+)/i
188
+ shortcut = $3.to_s.downcase
189
+ global = $2.to_s != ''
139
190
 
140
- # bot rules for extended channels
141
- when /^bot\s+rules\s*(.+)?$/i
142
- help_command = $1
143
- bot_rules(dest, help_command, typem, rules_file, user)
144
- when /^\s*(add\s)?shortcut\s(for\sall)?\s*([^:]+)\s*:\s*(.+)/i, /^(add\s)sc\s(for\sall)?\s*([^:]+)\s*:\s*(.+)/i
145
- for_all = $2
146
- shortcut_name = $3.to_s.downcase
147
- command_to_run = $4
148
- add_shortcut(dest, user, typem, for_all, shortcut_name, command, command_to_run)
149
- when /^\s*(delete|remove)\s+shortcut\s+(.+)/i, /^(delete|remove)\s+sc\s+(.+)/i
150
- shortcut = $2.to_s.downcase
151
- delete_shortcut(dest, user, shortcut, typem, command)
152
- when /^\s*see\sshortcuts/i, /^see\ssc/i
153
- see_shortcuts(dest, user, typem)
191
+ delete_shortcut(dest, user, shortcut, typem, command, global)
192
+ when /^\s*see\s+shortcuts/i, /^see\ssc/i
193
+ see_shortcuts(dest, user, typem)
154
194
 
155
- #kept to be backwards compatible
156
- when /^\s*id\schannel\s<#C\w+\|(.+)>\s*/i, /^id channel (.+)/
157
- unless typem == :on_extended
158
- channel_name = $1
159
- get_channels_name_and_id()
160
- if @channels_id.keys.include?(channel_name)
161
- respond "the id of #{channel_name} is #{@channels_id[channel_name]}", dest
162
- else
163
- respond "channel: #{channel_name} not found", dest
195
+ #kept to be backwards compatible
196
+ when /^\s*id\schannel\s<#C\w+\|(.+)>\s*/i, /^id channel (.+)/
197
+ unless typem == :on_extended
198
+ channel_name = $1
199
+ get_channels_name_and_id()
200
+ if @channels_id.keys.include?(channel_name)
201
+ respond "the id of #{channel_name} is #{@channels_id[channel_name]}", dest
202
+ else
203
+ respond "channel: #{channel_name} not found", dest
204
+ end
164
205
  end
165
- end
166
- when /^\s*ruby\s(.+)/im, /^\s*code\s(.+)/im
167
- code = $1
168
- code.gsub!("\\n", "\n")
169
- code.gsub!("\\r", "\r")
170
- @logger.info code
171
- ruby_code(dest, user, code, rules_file)
172
- when /^\s*(private\s+)?(repl|irb|live)\s*()()()$/i,
173
- /^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)()()\s*$/i,
174
- /^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"()\s*$/i,
175
- /^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"\s+(.+)\s*$/i,
176
- /^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)()\s+(.+)\s*$/i,
177
- /^\s*(private\s+)?(repl|irb|live)()\s+()(.+)\s*$/i
178
- if $1.to_s!=''
179
- type = :private
206
+ when /^\s*ruby\s(.+)/im, /^\s*code\s(.+)/im
207
+ code = $1
208
+ code.gsub!("\\n", "\n")
209
+ code.gsub!("\\r", "\r")
210
+ @logger.info code
211
+ ruby_code(dest, user, code, rules_file)
212
+ when /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s*()()()$/i,
213
+ /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)()()\s*$/i,
214
+ /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"()\s*$/i,
215
+ /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"\s+(.+)\s*$/i,
216
+ /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)()\s+(.+)\s*$/i,
217
+ /^\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)()\s+()(.+)\s*$/i
218
+ opts_type = $1.to_s.downcase.split(' ')
219
+ opts_type.include?('private') ? type = :private : type = :public
220
+ type = "#{type}_clean".to_sym if opts_type.include?('clean')
221
+
222
+ session_name = $3
223
+ description = $4
224
+ opts = " #{$5}"
225
+ env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
226
+ opts.scan(/\s+[\w\-]+=[^'"\s]+/i).flatten.each do |ev|
227
+ env_vars << ev.gsub('=',"='") + "'"
228
+ end
229
+ env_vars.each_with_index do |ev, idx|
230
+ ev.gsub!("=","']=")
231
+ ev.lstrip!
232
+ env_vars[idx] = "ENV['#{ev}"
233
+ end
234
+ repl(dest, user, session_name, env_vars.flatten, rules_file, command, description, type)
235
+ when /^\s*get\s+(repl|irb|live)\s+([\w\-]+)\s*/i
236
+ session_name = $2
237
+ get_repl(dest, user, session_name)
238
+ when /^\s*run\s+(repl|irb|live)\s+([\w\-]+)()\s*$/i,
239
+ /^\s*run\s+(repl|irb|live)\s+([\w\-]+)\s+(.+)\s*$/i
240
+ session_name = $2
241
+ opts = " #{$3}"
242
+ env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
243
+ opts.scan(/\s+[\w\-]+=[^'"\s]+/i).flatten.each do |ev|
244
+ env_vars << ev.gsub('=',"='") + "'"
245
+ end
246
+ env_vars.each_with_index do |ev, idx|
247
+ ev.gsub!("=","']=")
248
+ ev.lstrip!
249
+ env_vars[idx] = "ENV['#{ev}"
250
+ end
251
+ run_repl(dest, user, session_name, env_vars.flatten, rules_file)
252
+ when /^\s*(delete|remove)\s+(repl|irb|live)\s+([\w\-]+)\s*$/i
253
+ repl_name = $3
254
+ delete_repl(dest, user, repl_name)
255
+ when /^\s*see\s+(repls|repl|irb|irbs)\s*$/i
256
+ see_repls(dest, user, typem)
180
257
  else
181
- type = :public
182
- end
183
- session_name = $3
184
- description = $4
185
- opts = " #{$5}"
186
- env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
187
- opts.scan(/\s+[\w\-]+=[^'"\s]+/i).flatten.each do |ev|
188
- env_vars << ev.gsub('=',"='") + "'"
189
- end
190
- env_vars.each_with_index do |ev, idx|
191
- ev.gsub!("=","']=")
192
- ev.lstrip!
193
- env_vars[idx] = "ENV['#{ev}"
194
- end
195
- repl(dest, user, session_name, env_vars.flatten, rules_file, command, description, type)
196
- when /^\s*get\s+(repl|irb|live)\s+([\w\-]+)\s*/i
197
- session_name = $2
198
- get_repl(dest, user, session_name)
199
- when /^\s*run\s+(repl|irb|live)\s+([\w\-]+)()\s*$/i,
200
- /^\s*run\s+(repl|irb|live)\s+([\w\-]+)\s+(.+)\s*$/i
201
- session_name = $2
202
- opts = " #{$3}"
203
- env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
204
- opts.scan(/\s+[\w\-]+=[^'"\s]+/i).flatten.each do |ev|
205
- env_vars << ev.gsub('=',"='") + "'"
206
- end
207
- env_vars.each_with_index do |ev, idx|
208
- ev.gsub!("=","']=")
209
- ev.lstrip!
210
- env_vars[idx] = "ENV['#{ev}"
211
- end
212
- run_repl(dest, user, session_name, env_vars.flatten, rules_file)
213
- when /^\s*(delete|remove)\s+(repl|irb|live)\s+([\w\-]+)\s*$/i
214
- repl_name = $3
215
- delete_repl(dest, user, repl_name)
216
- when /^\s*see\s+(repls|repl|irb|irbs)\s*$/i
217
- see_repls(dest, user, typem)
218
- else
219
- processed2 = false
220
- end #of case
258
+ processed2 = false
259
+ end #of case
221
260
 
222
- processed = true if processed or processed2
261
+ processed = true if processed or processed2
262
+ end
223
263
  end
224
-
225
264
  return processed
226
265
  end
227
266
  end