class Singai
Constants
- NOTHING_PLAYING_MESSAGE
- STOPPED_MESSAGE
Public Class Methods
Source
# File plugins/singai.rb, line 28 def self.command_pattern /singai(?:\s+(.+))?$/i end
Source
# File plugins/singai.rb, line 32 def self.run_compose(query:, network:, channel:, asker:, fetch:, profiles:, runner: nil) SingaiCore.compose( query: query, network: network, channel: channel, asker: asker, fetch: fetch, runner: runner || AiAgent.method(:default_runner), profiles: profiles ) end
Public Instance Methods
Source
# File plugins/singai.rb, line 108 def bots_dir File.join(repo_root, "config", "bots") end
Source
# File plugins/singai.rb, line 99 def discover_profiles(message) SingaiContext.discover_profiles( channel_users: message.channel&.users, bot_nicks: [bot.nick], bots_dir: bots_dir, root: repo_root ) end
Source
# File plugins/singai.rb, line 56 def execute(m, query = nil) unless m.channel m.reply "Use !singai in a channel" return end command = self.class.parse_command(query) return unless command channel = reply_channel_key(m) if command[:action] == :stop result = self.class.stop_session(channel, sessions: sessions_store) flood_safe_reply(m, result[:message]) return end unless AiAccess.user_allowed?( channel: m.channel, user: m.user, network: bot.config.server, nick: m.user.nick ) flood_safe_reply(m, AiAccess.denial_message) return end session = self.class.begin_session(channel, sessions: sessions_store) flood_safe_reply(m, SingaiCore::COMPOSE_ACK) profiles = discover_profiles(m) AsyncJob.run(label: "singai") do outcome = self.class.run_compose( query: command[:query], network: bot.config.server, channel: m.channel.name, asker: m.user.nick, fetch: method(:fetch_json), profiles: profiles ) sing_reply(m, outcome[:text], channel: channel, token: session[:token]) rescue StandardError sing_reply(m, "AI lyric rewrite failed.", channel: channel, token: session[:token]) end end
Source
# File plugins/singai.rb, line 50 def fetch_json(url) RabbotHttp.fetch(url, user_agent: SingConstants::USER_AGENT) rescue OpenURI::HTTPError => e e.io.read if e.io end
Source
# File plugins/singai.rb, line 46 def lookup(query, fetch: method(:fetch_json)) SingaiCore.fetch_lyrics(query, fetch: fetch) end
Source
# File plugins/singai.rb, line 116 def reply_channel_key(message) if message.channel message.channel.name else message.user.nick end end
Source
# File plugins/singai.rb, line 112 def repo_root File.expand_path("..", __dir__) end
Source
# File plugins/singai.rb, line 124 def sessions_store self.class.sessions_store end
Source
# File plugins/singai.rb, line 128 def sing_reply(message, text, channel:, token:) pieces = reply_pieces( text, message: message, with_progress: :auto, skip_prefix_lines: 1, line_byte_limit: self.class.scaled_line_byte_limit(outgoing_line_limit(message)) ) return if pieces.empty? pieces.each_with_index do |piece, index| delay = FloodSafe::CHUNK_DELAY_SEC * index if delay.zero? next if self.class.session_stopped?(channel, token, sessions: sessions_store) message.reply(piece) else Timer(delay, shots: 1) do next if self.class.session_stopped?(channel, token, sessions: sessions_store) message.reply(piece) end end end end