]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/core/basics.rb
basics: UI command to send NOTICEs
[user/henk/code/ruby/rbot.git] / lib / rbot / core / basics.rb
index 4c18037e15e236217cbb9dedc238c9fadbbcf257..0473028aceff3899813b029ea60bbd2370367e30 100644 (file)
-#-- vim:sw=2:et\r
-#++\r
-\r
-\r
-class BasicsModule < CoreBotModule\r
-\r
-  def listen(m)\r
-    return unless m.kind_of?(PrivMessage)\r
-    if(m.private? && m.message =~ /^\001PING\s+(.+)\001/)\r
-      @bot.notice m.sourcenick, "\001PING #$1\001"\r
-      @bot.irclog "@ #{m.sourcenick} pinged me"\r
-      return\r
-    end\r
-  end\r
-\r
-  def bot_join(m, param)\r
-    if param[:pass]\r
-      @bot.join param[:chan], param[:pass]\r
-    else\r
-      @bot.join param[:chan]\r
-    end\r
-  end\r
-\r
-  def bot_part(m, param)\r
-    if param[:chan]\r
-      @bot.part param[:chan]\r
-    else\r
-      @bot.part m.target if m.public?\r
-    end\r
-  end\r
-\r
-  def bot_quit(m, param)\r
-    @bot.quit(param[:msg] ? param[:msg].join(" ") : nil)\r
-  end\r
-\r
-  def bot_restart(m, param)\r
-    @bot.restart(param[:msg] ? param[:msg].join(" ") : nil)\r
-  end\r
-\r
-  def bot_hide(m, param)\r
-    @bot.join 0\r
-  end\r
-\r
-  def bot_say(m, param)\r
-    @bot.say param[:where], param[:what].join(" ")\r
-  end\r
-\r
-  def bot_action(m, param)\r
-    @bot.action param[:where], param[:what].join(" ")\r
-  end\r
-\r
-  def bot_mode(m, param)\r
-    @bot.mode param[:where], param[:what], param[:who].join(" ")\r
-  end\r
-\r
-  def bot_ping(m, param)\r
-    m.reply "pong"\r
-  end\r
-\r
-  def bot_quiet(m, param)\r
-    if param.has_key?(:where)\r
-      @bot.set_quiet param[:where].sub(/^here$/, m.target)\r
-    else\r
-      @bot.set_quiet\r
-    end\r
-  end\r
-\r
-  def bot_talk(m, param)\r
-    if param.has_key?(:where)\r
-      @bot.reset_quiet param[:where].sub(/^here$/, m.target)\r
-    else\r
-      @bot.reset_quiet\r
-    end\r
-  end\r
-\r
-  def bot_help(m, param)\r
-    m.reply @bot.help(param[:topic].join(" "))\r
-  end\r
-\r
-  #TODO move these to a "chatback" plugin\r
-  # when (/^(botsnack|ciggie)$/i)\r
-  #   @bot.say m.replyto, @lang.get("thanks_X") % m.sourcenick if(m.public?)\r
-  #   @bot.say m.replyto, @lang.get("thanks") if(m.private?)\r
-  # when (/^(hello|howdy|hola|salut|bonjour|sup|niihau|hey|hi(\W|$)|yo(\W|$)).*/i)\r
-  #   @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick if(m.public?)\r
-  #   @bot.say m.replyto, @lang.get("hello") if(m.private?)\r
-  # when (/^\s*(hello|howdy|hola|salut|bonjour|sup|niihau|hey|hi|yo(\W|$))[\s,-.]+#{Regexp.escape(@bot.nick)}$/i)\r
-  #   @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick\r
-  # when (/^#{Regexp.escape(@bot.nick)}!*$/)\r
-  #   @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick\r
-\r
-  # handle help requests for "core" topics\r
-  def help(cmd, topic="")\r
-    case cmd\r
-    when "quit"\r
-      return "quit [<message>] => quit IRC with message <message>"\r
-    when "restart"\r
-      return "restart => completely stop and restart the bot (including reconnect)"\r
-    when "join"\r
-      return "join <channel> [<key>] => join channel <channel> with secret key <key> if specified. #{myself} also responds to invites if you have the required access level"\r
-    when "part"\r
-      return "part <channel> => part channel <channel>"\r
-    when "hide"\r
-      return "hide => part all channels"\r
-    when "save"\r
-      return "save => save current dynamic data and configuration"\r
-    when "rescan"\r
-      return "rescan => reload modules and static facts"\r
-    when "nick"\r
-      return "nick <nick> => attempt to change nick to <nick>"\r
-    when "say"\r
-      return "say <channel>|<nick> <message> => say <message> to <channel> or in private message to <nick>"\r
-    when "action"\r
-      return "action <channel>|<nick> <message> => does a /me <message> to <channel> or in private message to <nick>"\r
-    when "quiet"\r
-      return "quiet [in here|<channel>] => with no arguments, stop speaking in all channels, if \"in here\", stop speaking in this channel, or stop speaking in <channel>"\r
-    when "talk"\r
-      return "talk [in here|<channel>] => with no arguments, resume speaking in all channels, if \"in here\", resume speaking in this channel, or resume speaking in <channel>"\r
-    when "version"\r
-      return "version => describes software version"\r
-    when "ping"\r
-      return "ping => replies with a pong"\r
-    #     when "botsnack"\r
-    #       return "botsnack => reward #{myself} for being good"\r
-    #     when "hello"\r
-    #       return "hello|hi|hey|yo [#{myself}] => greet the bot"\r
-    else\r
-      return "#{name}: quit, restart, join, part, hide, save, rescan, nick, say, action, topic, quiet, talk, version, ping"#, botsnack, hello"\r
-    end\r
-  end\r
-end\r
-\r
-basics = BasicsModule.new\r
-\r
-basics.map "quit *msg",\r
-  :action => 'bot_quit',\r
-  :defaults => { :msg => nil },\r
-  :auth_path => 'quit'\r
-basics.map "restart *msg",\r
-  :action => 'bot_restart',\r
-  :defaults => { :msg => nil },\r
-  :auth_path => 'quit'\r
-\r
-basics.map "quiet",\r
-  :action => 'bot_quiet',\r
-  :auth_path => 'talk::set'\r
-basics.map "quiet in :chan",\r
-  :action => 'bot_quiet',\r
-  :auth_path => 'talk::set'\r
-basics.map "talk",\r
-  :action => 'bot_talk',\r
-  :auth_path => 'talk::set'\r
-basics.map "quiet in :chan",\r
-  :action => 'bot_quiet',\r
-  :auth_path => 'talk::set'\r
-\r
-basics.map "say :where *what",\r
-  :action => 'bot_say',\r
-  :auth_path => 'talk::do'\r
-basics.map "action :where *what",\r
-  :action => 'bot_action',\r
-  :auth_path => 'talk::do'\r
-basics.map "mode :where :what *who",\r
-  :action => 'bot_mode',\r
-  :auth_path => 'talk::do'\r
-\r
-basics.map "join :chan :pass", \r
-  :action => 'bot_join',\r
-  :defaults => {:pass => nil},\r
-  :auth_path => 'move'\r
-basics.map "part :chan",\r
-  :action => 'bot_part',\r
-  :defaults => {:chan => nil},\r
-  :auth_path => 'move'\r
-basics.map "hide",\r
-  :action => 'bot_hide',\r
-  :auth_path => 'move'\r
-\r
-basics.map "ping",\r
-  :action => 'bot_ping',\r
-  :auth_path => '!ping!'\r
-basics.map "help *topic",\r
-  :action => 'bot_help',\r
-  :defaults => { :topic => [""] },\r
-  :auth_path => '!help!'\r
-\r
-basics.default_auth('*', false)\r
-\r
+#-- vim:sw=2:et
+#++
+#
+# :title: rbot basic management from IRC
+#
+# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
+
+class BasicsModule < CoreBotModule
+
+  Config.register Config::BooleanValue.new('irc.join_after_identify',
+    :default => false, :wizard => true, :requires_restart => true,
+    :desc => "Should the bot wait until its identification is confirmed before joining any channels?")
+
+  def join_channels
+    @bot.config['irc.join_channels'].each { |c|
+      debug "autojoining channel #{c}"
+      if(c =~ /^(\S+)\s+(\S+)$/i)
+        @bot.join $1, $2
+      else
+        @bot.join c if(c)
+      end
+    }
+  end
+
+  def identified
+    join_channels
+  end
+
+  # on connect, we join the default channels unless we have to wait for
+  # identification. Observe that this means the bot may not connect any channels
+  # until the 'identified' method gets delegated
+  def connect
+    if @bot.config['irc.join_after_identify']
+      log "waiting for identififcation before JOINing default channels"
+    else
+      join_channels
+    end
+  end
+
+  def ctcp_listen(m)
+    who = m.private? ? "me" : m.target
+    case m.ctcp.intern
+    when :PING
+      m.ctcp_reply m.message
+    when :TIME
+      m.ctcp_reply Time.now.to_s
+    end
+  end
+
+  def bot_join(m, param)
+    if param[:pass]
+      @bot.join param[:chan], param[:pass]
+    else
+      @bot.join param[:chan]
+    end
+  end
+
+  def invite(m)
+    if @bot.auth.allow?(:"basics::move::join", m.source, m.source)
+      @bot.join m.channel
+    end
+  end
+
+  def bot_part(m, param)
+    if param[:chan]
+      @bot.part param[:chan]
+    else
+      @bot.part m.target if m.public?
+    end
+  end
+
+  def bot_channel_list(m, param)
+    ret = _('I am in: ')
+    # sort the channels by the base name and then map with prefixes for the
+    # mode and display.
+    ret << @bot.channels.compact.sort { |a,b|
+        a.name.downcase <=> b.name.downcase
+    }.map { |c|
+        c.modes_of(@bot.myself).map{ |mo|
+          m.server.prefix_for_mode(mo)
+        }.to_s + c.name
+    }.join(', ')
+    m.reply ret
+  end
+
+  def bot_quit(m, param)
+    @bot.quit param[:msg].to_s
+  end
+
+  def bot_restart(m, param)
+    @bot.restart param[:msg].to_s
+  end
+
+  def bot_reconnect(m, param)
+    @bot.reconnect param[:msg].to_s
+  end
+
+  def bot_hide(m, param)
+    @bot.join 0
+  end
+
+  def bot_say(m, param)
+    @bot.say param[:where], param[:what].to_s
+  end
+
+  def bot_notify(m, param)
+    @bot.notice param[:where], param[:what].to_s
+  end
+
+  def bot_action(m, param)
+    @bot.action param[:where], param[:what].to_s
+  end
+
+  def bot_mode(m, param)
+    @bot.mode param[:where], param[:what], param[:who].join(" ")
+  end
+
+  def bot_ping(m, param)
+    m.reply "pong"
+  end
+
+  def bot_quiet(m, param)
+    if param.has_key?(:where)
+      @bot.set_quiet param[:where].sub(/^here$/, m.target.downcase)
+    else
+      @bot.set_quiet
+    end
+    # Make sense when the commmand is given in private or in a non-quieted
+    # channel
+    m.okay
+  end
+
+  def bot_talk(m, param)
+    if param.has_key?(:where)
+      @bot.reset_quiet param[:where].sub(/^here$/, m.target.downcase)
+    else
+      @bot.reset_quiet
+    end
+    # Make sense when the commmand is given in private or in a non-quieted
+    # channel
+    m.okay
+  end
+
+  def bot_help(m, param)
+    m.reply @bot.help(param[:topic].join(" "))
+  end
+
+  #TODO move these to a "chatback" plugin
+  # when (/^(botsnack|ciggie)$/i)
+  #   @bot.say m.replyto, @lang.get("thanks_X") % m.sourcenick if(m.public?)
+  #   @bot.say m.replyto, @lang.get("thanks") if(m.private?)
+  # when (/^#{Regexp.escape(@bot.nick)}!*$/)
+  #   @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick
+
+  # handle help requests for "core" topics
+  def help(cmd, topic="")
+    case cmd
+    when "quit"
+      _("quit [<message>] => quit IRC with message <message>")
+    when "restart"
+      _("restart => completely stop and restart the bot (including reconnect)")
+    when "reconnect"
+      _("reconnect => ask the bot to disconnect and then connect again")
+    when "join"
+      _("join <channel> [<key>] => join channel <channel> with secret key <key> if specified. #{@bot.myself} also responds to invites if you have the required access level")
+    when "part"
+      _("part <channel> => part channel <channel>")
+    when "hide"
+      _("hide => part all channels")
+    when "say"
+      _("say <channel>|<nick> <message> => say <message> to <channel> or in private message to <nick>")
+    when "action"
+      _("action <channel>|<nick> <message> => does a /me <message> to <channel> or in private message to <nick>")
+    when "quiet"
+      _("quiet [in here|<channel>] => with no arguments, stop speaking in all channels, if \"in here\", stop speaking in this channel, or stop speaking in <channel>")
+    when "talk"
+      _("talk [in here|<channel>] => with no arguments, resume speaking in all channels, if \"in here\", resume speaking in this channel, or resume speaking in <channel>")
+    when "ping"
+      _("ping => replies with a pong")
+    when "mode"
+      _("mode <channel> <mode> <nicks> => set channel modes for <nicks> on <channel> to <mode>")
+    #     when "botsnack"
+    #       return "botsnack => reward #{@bot.myself} for being good"
+    #     when "hello"
+    #       return "hello|hi|hey|yo [#{@bot.myself}] => greet the bot"
+    else
+      _("%{name}: quit, restart, join, part, hide, save, say, action, topic, quiet, talk, ping, mode") % {:name=>name}
+      #, botsnack, hello
+    end
+  end
+end
+
+basics = BasicsModule.new
+
+basics.map "quit *msg",
+  :action => 'bot_quit',
+  :defaults => { :msg => nil },
+  :auth_path => 'quit'
+basics.map "restart *msg",
+  :action => 'bot_restart',
+  :defaults => { :msg => nil },
+  :auth_path => 'quit'
+basics.map "reconnect *msg",
+  :action => 'bot_reconnect',
+  :defaults => { :msg => nil },
+  :auth_path => 'quit'
+
+basics.map "quiet [in] [:where]",
+  :action => 'bot_quiet',
+  :auth_path => 'talk::set'
+basics.map "talk [in] [:where]",
+  :action => 'bot_talk',
+  :auth_path => 'talk::set'
+
+basics.map "say :where *what",
+  :action => 'bot_say',
+  :auth_path => 'talk::do'
+basics.map "notify :where *what",
+  :action => 'bot_notify',
+  :auth_path => 'talk::do'
+basics.map "action :where *what",
+  :action => 'bot_action',
+  :auth_path => 'talk::do'
+basics.map "mode :where :what *who",
+  :action => 'bot_mode',
+  :auth_path => 'talk::do'
+
+basics.map "join :chan :pass",
+  :action => 'bot_join',
+  :defaults => {:pass => nil},
+  :auth_path => 'move'
+basics.map "part :chan",
+  :action => 'bot_part',
+  :defaults => {:chan => nil},
+  :auth_path => 'move'
+basics.map "channels",
+  :action => 'bot_channel_list',
+  :auth_path => 'move'
+basics.map "hide",
+  :action => 'bot_hide',
+  :auth_path => 'move'
+
+basics.map "ping",
+  :action => 'bot_ping',
+  :auth_path => '!ping!'
+basics.map "help *topic",
+  :action => 'bot_help',
+  :defaults => { :topic => [""] },
+  :auth_path => '!help!'
+
+basics.default_auth('*', false)
+