class Silence
Constants
- ChannelReply
- DEFAULT_END_MESSAGE
- IRC_CTRL
- MAX_SECONDS
- MESSAGE_SEPARATOR
- STYLE_END_TITLE
- STYLE_TITLE
Public Class Methods
Source
# File plugins/silence.rb, line 151 def self.announcement_heading(seconds:, message:) "Let us now have #{format_duration(seconds)} silence for: #{message}" end
Source
# File plugins/silence.rb, line 60 def self.channel_lookup(channels) channels.map { |channel| [channel.to_s.downcase, channel.to_s] }.to_h end
Source
# File plugins/silence.rb, line 15 def self.command_pattern /silence(?: (.+))?$/i end
Source
# File plugins/silence.rb, line 94 def self.dispatch_command(args_text, user_channels:, bot_channels:) text = args_text.to_s.strip return { error: usage_message } if text.empty? prepared = prepare_silence(text, user_channels: user_channels, bot_channels: bot_channels) return prepared if prepared[:error] prepared.merge( private_message: format_private_acknowledgment( channel: prepared[:channel], seconds: prepared[:seconds] ) ) end
Source
# File plugins/silence.rb, line 163 def self.end_message_heading(end_message:) message = end_message.to_s.strip message = DEFAULT_END_MESSAGE if message.empty? "END OF SILENCE — #{message}" end
Source
# File plugins/silence.rb, line 155 def self.format_announcement(seconds:, message:) heading = announcement_heading(seconds: seconds, message: message) [ IrcFormat.report_header(tag: "SILENCE", title: heading, style: STYLE_TITLE), "Duration — #{format_duration(seconds)}" ].join("\n") end
Source
# File plugins/silence.rb, line 135 def self.format_duration(seconds) seconds = seconds.to_i return "#{seconds} seconds" if seconds < 60 minutes, remainder = seconds.divmod(60) if remainder.zero? minutes == 1 ? "1 minute" : "#{minutes} minutes" elsif minutes.zero? "#{remainder} seconds" elsif minutes == 1 remainder.zero? ? "1 minute" : "1 minute #{remainder} seconds" else "#{minutes} minutes #{remainder} seconds" end end
Source
# File plugins/silence.rb, line 170 def self.format_end_message(end_message:) heading = end_message_heading(end_message: end_message) "#{IrcFormat.bracket_label('SILENCE', label_style: IrcFormat.color(0, 10))} #{IrcFormat.menu_heading(heading, style: STYLE_END_TITLE)}" end
Source
# File plugins/silence.rb, line 90 def self.format_private_acknowledgment(channel:, seconds:) "Starting a #{format_duration(seconds)} moment of silence in #{channel}." end
Source
# File plugins/silence.rb, line 33 def self.parse_command(text) stripped = text.to_s.strip match = stripped.match(/\A(\d+)\s+(?:(#\S+)\s+)?(.+)\z/) return { error: usage_message } unless match seconds = match[1].to_i unless seconds.positive? && seconds <= MAX_SECONDS return { error: "Duration must be between 1 and #{MAX_SECONDS} seconds." } end channel = match[2]&.strip rest = match[3].strip unless rest.include?(MESSAGE_SEPARATOR) return { error: "End message is required. Separate message and end message with #{MESSAGE_SEPARATOR}." } end message, end_message = rest.split(MESSAGE_SEPARATOR, 2) message = message.to_s.strip end_message = end_message.to_s.strip return { error: "Message cannot be empty." } if message.empty? return { error: "End message cannot be empty." } if end_message.empty? result = { seconds: seconds, message: message, end_message: end_message } result[:channel] = channel unless channel.nil? || channel.empty? result end
Source
# File plugins/silence.rb, line 109 def self.prepare_silence(args, user_channels:, bot_channels:) parsed = parse_command(args) return parsed if parsed[:error] target = if parsed[:channel] resolve_explicit_channel( channel: parsed[:channel], user_channels: user_channels, bot_channels: bot_channels ) else resolve_target_channel(user_channels: user_channels, bot_channels: bot_channels) end return target if target[:error] { channel: target[:channel], seconds: parsed[:seconds], announcement: format_announcement( seconds: parsed[:seconds], message: parsed[:message] ), end_announcement: format_end_message(end_message: parsed[:end_message]) } end
Source
# File plugins/silence.rb, line 74 def self.resolve_explicit_channel(channel:, user_channels:, bot_channels:) target_key = channel.to_s.downcase user_by_key = channel_lookup(user_channels) bot_keys = bot_channels.map { |name| name.to_s.downcase } unless user_by_key.key?(target_key) return { error: "You must share a channel with Rabbot to start a moment of silence." } end unless bot_keys.include?(target_key) return { error: "You must share a channel with Rabbot to start a moment of silence." } end { channel: user_by_key[target_key] } end
Source
# File plugins/silence.rb, line 64 def self.resolve_target_channel(user_channels:, bot_channels:) user_by_key = channel_lookup(user_channels) bot_keys = bot_channels.map { |channel| channel.to_s.downcase } shared_keys = user_by_key.keys & bot_keys shared_keys.sort! return { error: "You must share a channel with Rabbot to start a moment of silence." } if shared_keys.empty? { channel: user_by_key[shared_keys.first] } end
Source
# File plugins/silence.rb, line 29 def self.usage_message "Usage: /msg Rabbot !silence <seconds> [#channel] <message>#{MESSAGE_SEPARATOR}<end message>" end
Public Instance Methods
Source
# File plugins/silence.rb, line 181 def execute(m, args_text = nil) result = self.class.dispatch_command( args_text, user_channels: m.user.channels.map(&:name), bot_channels: bot.channels.map(&:name) ) if result[:error] themed_flood_safe_reply(m, result[:error]) return end themed_flood_safe_reply(m, result[:private_message]) channel = Channel(result[:channel]) channel_reply = ChannelReply.new(channel) themed_flood_safe_reply(channel_reply, result[:announcement]) Timer(result[:seconds], shots: 1) do themed_flood_safe_reply(channel_reply, result[:end_announcement]) end end