### Home Classes Methods

### In Files

- lib/rbot/core/irclog.rb

### Parent

CoreBotModule

### Methods

- ::new
- #can_log_on
- #cleanup
- #event_irclog_list_changed
- #irclog
- #listen
- #log_join
- #log_kick
- #log_message
- #log_nick
- #log_notice
- #log_part
- #log_quit
- #log_topic
- #logfile_close
- #logfilepath
- #loggers_thread
- #modechange
- #motd
- #sent
- #timestamp
- #unknown_message
- #welcome

### Class/Module Index

Quicksearch

- Irc
- Irc::AsciiCasemap
- Irc::BanlistMessage
- Irc::BasicUserMessage
- Irc::Bot
- Irc::Bot::Auth
- Irc::Bot::Auth::BotOwnerClass
- Irc::Bot::Auth::BotUser
- Irc::Bot::Auth::Command
- Irc::Bot::Auth::DefaultBotUserClass
- Irc::Bot::Auth::InvalidPassword
- Irc::Bot::Auth::ManagerClass
- Irc::Bot::Auth::PermissionSet
- Irc::Bot::Config
- Irc::Bot::Config::ArrayValue
- Irc::Bot::Config::BooleanValue
- Irc::Bot::Config::EnumValue
- Irc::Bot::Config::FloatValue
- Irc::Bot::Config::IntegerValue
- Irc::Bot::Config::ManagerClass
- Irc::Bot::Config::StringValue
- Irc::Bot::Config::Value
- Irc::Bot::Config::Wizard
- Irc::Bot::DataFilter
- Irc::Bot::DataStream
- Irc::Bot::Language
- Irc::Bot::MessageMapper
- Irc::Bot::MessageMapper::Failure
- Irc::Bot::MessageMapper::FriendlyFailure
- Irc::Bot::MessageMapper::NoActionFailure
- Irc::Bot::MessageMapper::NoMatchFailure
- Irc::Bot::MessageMapper::NotPrivateFailure
- Irc::Bot::MessageMapper::NotPublicFailure
- Irc::Bot::MessageMapper::PartialMatchFailure
- Irc::Bot::MessageParameter
- Irc::Bot::MessageTemplate
- Irc::Bot::Plugins
- Irc::Bot::Plugins::BotModule
- Irc::Bot::Plugins::CoreBotModule
- Irc::Bot::Plugins::Plugin
- Irc::Bot::Plugins::PluginManagerClass
- Irc::Bot::Plugins::RecurseTooDeep
- Irc::Bot::Plugins::RemoteBotModule
- Irc::Bot::Plugins::RemoteCoreBotModule
- Irc::Bot::Plugins::RemotePlugin
- Irc::Bot::Registry
- Irc::Bot::Registry::Accessor
- Irc::Bot::RemoteDispatcher
- Irc::Bot::RemoteMessage
- Irc::Bot::RemoteObject
- Irc::Bot::Wordlist
- Irc::BotConfig
- Irc::Casemap
- Irc::Channel
- Irc::Channel::Mode
- Irc::Channel::ModeHash
- Irc::Channel::ModeTypeA
- Irc::Channel::ModeTypeB
- Irc::Channel::ModeTypeC
- Irc::Channel::ModeTypeD
- Irc::Channel::Topic
- Irc::Channel::UserMode
- Irc::ChannelList
- Irc::Client
- Irc::DBHash
- Irc::DBTree
- Irc::InviteMessage
- Irc::JoinMessage
- Irc::KickMessage
- Irc::MessageQueue
- Irc::ModeChangeMessage
- Irc::MotdMessage
- Irc::NamesMessage
- Irc::Netmask
- Irc::NetmaskDb
- Irc::NetmaskDb::Tree
- Irc::NetmaskList
- Irc::NickMessage
- Irc::NoSuchTargetMessage
- Irc::NoticeMessage
- Irc::PartMessage
- Irc::PrivMessage
- Irc::QueueRing
- Irc::QuitMessage
- Irc::RfcCasemap
- Irc::Server
- Irc::ServerOrCasemap
- Irc::Socket
- Irc::Socket::IdentityFilter
- Irc::StrictRfcCasemap
- Irc::TopicMessage
- Irc::UnknownMessage
- Irc::User
- Irc::UserList
- Irc::UserMessage
- Irc::Utils
- Irc::Utils::HttpUtil
- Irc::Utils::HttpUtil::CachedObject
- Irc::Utils::ParseTime
- Irc::WelcomeMessage
- Irc::WhoisMessage
- BDB
- BDB::CIBtree
- MonitorMixin
- MonitorMixin::ConditionVariable
- Net
- Net::HTTPResponse
- Regexp
- Regexp::Irc
- Singleton
- Singleton::SingletonClassMethods
- Timer
- Timer::Action
- TokyoCabinet
- TokyoCabinet::CIBDB
- UnicodePlugin
- UnicodePlugin::UnicodeFilter
- Array
- ArrayOf
- AuthModule
- BasicsModule
- ConditionVariable
- ConfigModule
- DottedIndex
- Enumerable
- Exception
- FiltersModule
- GetText
- GetTextVersionError
- HttpUtilPlugin
- IrcLogModule
- Module
- Numeric
- Object
- Range
- RemoteModule
- ServerError
- String
- Symbol
- UserDataModule
- WordlistModule
- YAML

No matching classes.

# IrcLogModule

Author | Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>

### Attributes

nolog_rx[RW]

### Public Class Methods

new() click to toggle source

    # File lib/rbot/core/irclog.rb, line 31
    def initialize
      super
      @queue = Queue.new
      @thread = Thread.new { loggers_thread }
      @logs = Hash.new
      logdir = @bot.path 'logs'
      Dir.mkdir(logdir) unless File.exist?(logdir)
      # TODO what shall we do if the logdir couldn't be created? (e.g. it existed as a file)
      event_irclog_list_changed(@bot.config['irclog.no_log'], @bot.config['irclog.do_log'])
      @fn_format = @bot.config['irclog.filename_format']
    end

### Public Instance Methods

can_log_on(where) click to toggle source

    # File lib/rbot/core/irclog.rb, line 43
    def can_log_on(where)
      return true if @dolog_rx and where.match @dolog_rx
      return false if @nolog_rx and where.match @nolog_rx
      return true
    end

cleanup() click to toggle source

    # File lib/rbot/core/irclog.rb, line 77
    def cleanup
      @queue << nil
      @thread.join
      @thread = nil
    end

event_irclog_list_changed(nolist, dolist) click to toggle source

    # File lib/rbot/core/irclog.rb, line 53
    def event_irclog_list_changed(nolist, dolist)
      @nolog_rx = nolist.empty? ? nil : Regexp.union(*(nolist.map { |r| r.to_irc_regexp }))
      debug "no log: #{@nolog_rx}"
      @dolog_rx = dolist.empty? ? nil : Regexp.union(*(dolist.map { |r| r.to_irc_regexp }))
      debug "do log: #{@dolog_rx}"
      @logs.inject([]) { |ar, kv|
        ar << kv.first unless can_log_on(kv.first)
        ar
      }.each { |w| logfile_close(w, 'logging disabled here') }
    end

irclog(message, where="server") click to toggle source

log IRC-related message `message` to a file determined by `where`. `where` can be a channel name, or a nick for private message logging

    # File lib/rbot/core/irclog.rb, line 73
    def irclog(message, where="server")
      @queue.push [message, where]
    end

listen(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 118
    def listen(m)
      case m
      when PrivMessage
        method = 'log_message'
      else
        method = 'log_' + m.class.name.downcase.match(/^irc::(\w+)message$/).captures.first
      end
      if self.respond_to?(method)
        self.__send__(method, m)
      else
        warning "unhandled logging for #{m.pretty_inspect} (no such method #{method})"
        unknown_message(m)
      end
    end

log_join(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 194
    def log_join(m)
      if m.address?
        debug "joined channel #{m.channel}"
        irclog "@ Joined channel #{m.channel}", m.channel
      else
        irclog "@ #{m.source} joined channel #{m.channel}", m.channel
      end
    end

log_kick(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 212
    def log_kick(m)
      if(m.address?)
        debug "kicked from channel #{m.channel}"
        irclog "@ You have been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel
      else
        irclog "@ #{m.target} has been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel
      end
    end

log_message(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 133
    def log_message(m)
      if m.ctcp
        who = m.private? ? "me" : m.target
        logtarget = m.private? ? m.source : m.target
        case m.ctcp.intern
        when :ACTION
          if m.public?
            irclog "* #{m.source} #{m.logmessage}", m.target
          else
            irclog "* #{m.source}(#{m.sourceaddress}) #{m.logmessage}", m.source
          end
        when :VERSION
          irclog "@ #{m.source} asked #{who} about version info", logtarget
        when :SOURCE
          irclog "@ #{m.source} asked #{who} about source info", logtarget
        when :PING
          irclog "@ #{m.source} pinged #{who}", logtarget
        when :TIME
          irclog "@ #{m.source} asked #{who} what time it is", logtarget
        else
          irclog "@ #{m.source} asked #{who} about #{[m.ctcp, m.message].join(' ')}", logtarget
        end
      else
        if m.public?
          irclog "<#{m.source}> #{m.logmessage}", m.target
        else
          irclog "<#{m.source}(#{m.sourceaddress})> #{m.logmessage}", m.source
        end
      end
    end

log_nick(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 178
    def log_nick(m)
      (m.is_on & @bot.myself.channels).each { |ch|
        irclog "@ #{m.oldnick} is now known as #{m.newnick}", ch
      }
    end

log_notice(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 164
    def log_notice(m)
      if m.private?
        irclog "-#{m.source}(#{m.sourceaddress})- #{m.logmessage}", m.source
      else
        irclog "-#{m.source}- #{m.logmessage}", m.target
      end
    end

log_part(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 203
    def log_part(m)
      if(m.address?)
        debug "left channel #{m.channel}"
        irclog "@ Left channel #{m.channel} (#{m.logmessage})", m.channel
      else
        irclog "@ #{m.source} left channel #{m.channel} (#{m.logmessage})", m.channel
      end
    end

log_quit(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 184
    def log_quit(m)
      (m.was_on & @bot.myself.channels).each { |ch|
        irclog "@ Quit: #{m.source}: #{m.logmessage}", ch
      }
    end

log_topic(m) click to toggle source

def log_invite(m)

    # TODO

end

    # File lib/rbot/core/irclog.rb, line 225
    def log_topic(m)
      case m.info_or_set
      when :set
        if m.source == @bot.myself
          irclog "@ I set topic \"#{m.topic}\"", m.channel
        else
          irclog "@ #{m.source} set topic \"#{m.topic}\"", m.channel
        end
      when :info
        topic = m.channel.topic
        irclog "@ Topic is \"#{m.topic}\"", m.channel
        irclog "@ Topic set by #{topic.set_by} on #{topic.set_on}", m.channel
      end
    end

logfile_close(where_str, reason = 'unknown reason') click to toggle source

    # File lib/rbot/core/irclog.rb, line 64
    def logfile_close(where_str, reason = 'unknown reason')
      f = @logs.delete(where_str) or return
      stamp = timestamp(Time.now)
      f[1].puts "#{stamp} @ Log closed by #{@bot.myself.nick} (#{reason})"
      f[1].close
    end

logfilepath(where_str, now) click to toggle source

    # File lib/rbot/core/irclog.rb, line 248
    def logfilepath(where_str, now)
      @bot.path('logs', now.strftime(@fn_format) % { :where => where_str })
    end

modechange(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 190
    def modechange(m)
      irclog "@ Mode #{m.logmessage} by #{m.source}", m.target
    end

motd(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 172
    def motd(m)
      m.message.each_line { |line|
        irclog "MOTD: #{line}", "server"
      }
    end

sent(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 83
    def sent(m)
      case m
      when NoticeMessage
        irclog "-#{m.source}- #{m.message}", m.target
      when PrivMessage
        logtarget = who = m.target
        if m.ctcp
          case m.ctcp.intern
          when :ACTION
            irclog "* #{m.source} #{m.logmessage}", logtarget
          when :VERSION
            irclog "@ #{m.source} asked #{who} about version info", logtarget
          when :SOURCE
            irclog "@ #{m.source} asked #{who} about source info", logtarget
          when :PING
            irclog "@ #{m.source} pinged #{who}", logtarget
          when :TIME
            irclog "@ #{m.source} asked #{who} what time it is", logtarget
          else
            irclog "@ #{m.source} asked #{who} about #{[m.ctcp, m.message].join(' ')}", logtarget
          end
        else
          irclog "<#{m.source}> #{m.logmessage}", logtarget
        end
      when QuitMessage
        m.was_on.each { |ch|
          irclog "@ quit (#{m.message})", ch
        }
      end
    end

timestamp(time) click to toggle source

    # File lib/rbot/core/irclog.rb, line 49
    def timestamp(time)
      return time.strftime(@bot.config['irclog.timestamp_format'])
    end

unknown_message(m) click to toggle source

def names(m)

    # TODO

end

    # File lib/rbot/core/irclog.rb, line 244
    def unknown_message(m)
      irclog m.logmessage, ".unknown"
    end

welcome(m) click to toggle source

    # File lib/rbot/core/irclog.rb, line 114
    def welcome(m)
      irclog "joined server #{m.server} as #{m.target}", "server"
    end

### Protected Instance Methods

loggers_thread() click to toggle source

    # File lib/rbot/core/irclog.rb, line 253
    def loggers_thread
      ls = nil
      debug 'loggers_thread starting'
      while ls = @queue.pop
        message, where = ls
        message = message.chomp
        now = Time.now
        stamp = timestamp(now)
        if where.class <= Server
          where_str = "server"
        else
          where_str = where.downcase.gsub(/[:!?$*()\/\\<>|"']/, "_")
        end
        next unless can_log_on(where_str)

        # close the previous logfile if we're rotating
        if @logs.has_key? where_str
          fp = logfilepath(where_str, now)
          logfile_close(where_str, 'log rotation') if fp != @logs[where_str][1].path
        end

        # (re)open the logfile if necessary
        unless @logs.has_key? where_str
          if @logs.size > @bot.config['irclog.max_open_files']
            @logs.keys.sort do |a, b|
              @logs[a][0] <=> @logs[b][0]
            end.slice(0, @logs.size - @bot.config['irclog.max_open_files']).each do |w|
              logfile_close w, "idle since #{@logs[w][0]}"
            end
          end
          fp = logfilepath(where_str, now)
          begin
            dir = File.dirname(fp)
            # first of all, we check we're not trying to build a directory structure
            # where one of the components exists already as a file, so we
            # backtrack along dir until we come across the topmost existing name.
            # If it's a file, we rename to filename.old.filedate
            up = dir.dup
            until File.exist? up
              up.replace(File.dirname(up))
            end
            unless File.directory? up
              backup = up.dup
              backup << ".old." << File.atime(up).strftime('%Y%m%d%H%M%S')
              debug "#{up} is not a directory! renaming to #{backup}"
              File.rename(up, backup)
            end
            FileUtils.mkdir_p(dir)
            # conversely, it may happen that fp exists and is a directory, in
            # which case we rename the directory instead
            if File.directory? fp
              backup = fp.dup
              backup << ".old." << File.atime(fp).strftime('%Y%m%d%H%M%S')
              debug "#{fp} is not a file! renaming to #{backup}"
              File.rename(fp, backup)
            end
            # it should be fine to create the file now
            f = File.new(fp, "a")
            f.sync = true
            f.puts "#{stamp} @ Log started by #{@bot.myself.nick}"
          rescue Exception => e
            error e
            next
          end
          @logs[where_str] = [now, f]
        end
        @logs[where_str][1].puts "#{stamp} #{message}"
        @logs[where_str][0] = now
        #debug "#{stamp} <#{where}> #{message}"
      end
      @logs.keys.each { |w| logfile_close(w, 'rescan or shutdown') }
      debug 'loggers_thread terminating'
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.