diff options
Diffstat (limited to 'bocelli')
| -rw-r--r-- | bocelli/base.rb | 83 | ||||
| -rw-r--r-- | bocelli/core/irc.rb | 53 | ||||
| -rw-r--r-- | bocelli/module/base.rb | 25 | 
3 files changed, 161 insertions, 0 deletions
diff --git a/bocelli/base.rb b/bocelli/base.rb new file mode 100644 index 0000000..dfb7875 --- /dev/null +++ b/bocelli/base.rb @@ -0,0 +1,83 @@ +require_relative 'core/irc' + +module Bocelli +  class Base +    def initialize(str, route, block, metadata) +      @bocelli = { +        str: str, +        route: route, +        block: block, +        metadata: metadata +      } +    end + +    def execute +      instance_eval(&@bocelli[:block]) +    end + +    def out(message) +      self.class.privmsg(@bocelli[:metadata][:channel], message) +    end + +    class << self +      include Bocelli::Core::IRC + +      def setup +        @routes = {} +        @modules = {} +      end + +      def inherited(subclass) +        super + +        subclass.setup +      end + +      def on(route, &block) +        name = "route #{route.inspect}" + +        @routes[route] = block +      end + +      def register(mod) +        @modules[mod.name[/[^:]+$/].downcase.intern] ||= mod +      end + +      def match(str, route) +        case route +        when Regexp +          str =~ route +        when String +          str == route +        end +      end + +      def process(str) +        routes = @modules.inject([]) { |m, (_, v)| m.push(*v.routes) } +        routes.push(*@routes) + +        if str =~ /(\S+) PRIVMSG (\S+) :?(.*)/ +          metadata = { +            user: $1, +            channel: $2, +            message: $3 +          } + +          if (match = routes.detect { |k, _| match(metadata[:message], k) }) +            route, block = match + +            new(str, route, block, metadata).execute +          end +        end +      end + +      def run +        while (str = sgets) +          pong($1) if str =~ /\APING (.*)\z/ + +          process(str) +        end +      end +    end +  end +end diff --git a/bocelli/core/irc.rb b/bocelli/core/irc.rb new file mode 100644 index 0000000..4264e2d --- /dev/null +++ b/bocelli/core/irc.rb @@ -0,0 +1,53 @@ +require 'socket' + +module Bocelli +  module Core +    module IRC +      def configure(host, port, nick, pass = nil) +        @host = host +        @port = port +        @nick = nick +        @pass = pass + +        @socket = nil +      end + +      def connect(&block) +        @socket = TCPSocket.new(@host, @port) + +        sputs("PASS #{@pass}") if @pass +        sputs("NICK #{@nick}") +        sputs("USER #{@nick} 0 * :#{@nick}") + +        instance_eval(&block) if block_given? +      end + +      def sgets +        str = @socket.gets +        str.chomp! unless str.nil? + +        puts '<< ' + str.inspect + +        str +      end + +      def sputs(str) +        puts '>> ' + str.inspect + +        @socket.puts(str) +      end + +      def pong(message) +        sputs("PONG #{message}") +      end + +      def join(channel) +        sputs("JOIN #{channel}") +      end + +      def privmsg(channel, message) +        sputs("PRIVMSG #{channel} :#{message}") +      end +    end +  end +end diff --git a/bocelli/module/base.rb b/bocelli/module/base.rb new file mode 100644 index 0000000..1306830 --- /dev/null +++ b/bocelli/module/base.rb @@ -0,0 +1,25 @@ +module Bocelli +  module Module +    module Base +      attr_reader :routes + +      def setup +        @routes = {} +      end + +      def on(route, &block) +        raise 'no block given' if block.nil? + +        @routes[route] = block +      end + +      class << self +        def extended(mod) +          super + +          mod.setup +        end +      end +    end +  end +end  | 
