spunk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/spunk.rb ADDED
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'spunk/base_parser'
4
+ require 'spunk/ping_parser'
5
+ require 'spunk/helpers'
6
+ require 'spunk/origin'
7
+ require 'spunk/bot'
8
+
9
+ SPUNK_VERSION = '0.0.1'
10
+
@@ -0,0 +1,14 @@
1
+ module Spunk
2
+ module Processor
3
+ class Base
4
+ def call(bot, origin, command, parameters)
5
+ if command =~ /^INVITE #{bot.nickname}$/i
6
+ room = Spunk::Helpers.parse_room(parameters)
7
+ if room
8
+ bot.join_room(room)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/spunk/bot.rb ADDED
@@ -0,0 +1,157 @@
1
+ require 'socket'
2
+ require 'openssl'
3
+
4
+ module Spunk
5
+ class Bot
6
+ attr_accessor :nickname, :server, :joined_rooms, :ssl, :server, :rooms, :token
7
+ attr_reader :processors, :request_processors, :response_processors
8
+
9
+ def initialize(options = {})
10
+ options.each do |option, value|
11
+ instance_variable_set("@#{option}", value)
12
+ end
13
+ @token = options[:token] || nil
14
+ @ssl = options[:ssl] || false
15
+ @processors = []
16
+ @request_processors = []
17
+ @response_processors = []
18
+ @joined_rooms = []
19
+ @hostname = Socket.gethostname
20
+ @server ||= { :hostname => options[:hostname] || "localhost", :port => options[:port] || 6667 }
21
+ add_request_processor(Spunk::Processor::Ping.new)
22
+ add_request_processor(Spunk::Processor::Base.new)
23
+ @rooms = options[:rooms] ||= []
24
+ end
25
+
26
+ def start
27
+ loop do
28
+ @buffer ||= ""
29
+ if @ssl
30
+ @buffer += @socket.gets
31
+ else
32
+ @buffer += @socket.recv(1024)
33
+ end
34
+ messages = @buffer.split(/\r|\n/).collect { |s| s != "" && !s.nil? ? s : nil }.compact
35
+ if messages.any?
36
+ last_character = @buffer[-1..-1]
37
+ @buffer = if ["\n", "\r"].include?(last_character)
38
+ ""
39
+ else
40
+ messages.pop.to_s
41
+ end
42
+
43
+ messages.each do |message|
44
+ message.strip!
45
+ process_request(*parse_message(message))
46
+ end
47
+ end
48
+ sleep 0.25
49
+ end
50
+ end
51
+
52
+ def setup_connection
53
+ connect
54
+ authenticate
55
+ @rooms.each { |room| join_room room }
56
+ end
57
+
58
+ def run
59
+ setup_connection
60
+ start
61
+ end
62
+
63
+ def parse_message(message)
64
+ prefix, message = if message =~ /^\:([^\ ]*) (.*)/
65
+ message.scan(/^\:([^\ ]*) (.*)/)[0]
66
+ else
67
+ [ nil, message ]
68
+ end
69
+
70
+ command, parameters = message.split(/\:/, 2)
71
+ [ prefix, command, parameters ].map! { |s| s && s.strip }
72
+ end
73
+
74
+ def process_request(prefix, command, parameters)
75
+ origin = if !prefix.nil? && prefix != ""
76
+ Origin.new(prefix)
77
+ end
78
+
79
+ (@request_processors + @processors).each do |processor|
80
+ begin
81
+ processor.call(self, origin, command, parameters)
82
+ rescue => e
83
+ puts e.class.name + ": " + e.message
84
+ puts e.backtrace.join("\n")
85
+ end
86
+ end
87
+ end
88
+
89
+ def process_response(origin, command, parameters)
90
+ (@response_processors + @processors).each do |processor|
91
+ begin
92
+ processor.call(self, origin, command, parameters)
93
+ rescue => e
94
+ puts e.class.name + ": " + e.message
95
+ puts e.backtrace.join("\n")
96
+ end
97
+ end
98
+ @socket.print("#{command} :#{parameters}\r\n")
99
+ end
100
+
101
+ def origin
102
+ @origin ||= Origin.new("#{@nickname}!#{@username}@#{@hostname}")
103
+ end
104
+
105
+ def add_request_processor(processor = nil, &block)
106
+ @request_processors << (processor || block)
107
+ end
108
+
109
+ def add_response_processor(processor = nil, &block)
110
+ @response_processors << (processor || block)
111
+ end
112
+
113
+ def add_processor(processor = nil, &block)
114
+ @processors << (processor || block)
115
+ end
116
+
117
+ def connect
118
+ @socket = TCPSocket.new(@server[:hostname], @server[:port])
119
+ if @ssl == true
120
+ @ssl_context = OpenSSL::SSL::SSLContext.new()
121
+ @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
122
+ @socket = OpenSSL::SSL::SSLSocket.new(@socket, @ssl_context)
123
+ @socket.sync_close = true
124
+ @socket.connect
125
+ end
126
+ trap("INT") do
127
+ @socket.close
128
+ end
129
+ trap("KILL") do
130
+ @socket.close
131
+ end
132
+ end
133
+
134
+ def authenticate
135
+ unless @token.nil?
136
+ send_message "PASS #{@token}"
137
+ end
138
+ send_message "NICK #{@nickname}"
139
+ send_message "USER #{@username} #{@hostname} bla :#{@fullname}"
140
+ end
141
+
142
+ def join_room(room, password = nil)
143
+ @joined_rooms << room
144
+ @joined_rooms.uniq!
145
+ send_message("JOIN #{room}" + (password ? " #{password}" : ""))
146
+ end
147
+
148
+ def say(to, message)
149
+ send_message "PRIVMSG #{to} :#{message}"
150
+ end
151
+
152
+ def send_message(message)
153
+ command, parameters = message.strip.split(/\:/, 2)
154
+ process_response(origin, command.to_s.strip, parameters)
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,15 @@
1
+ module Spunk
2
+ module Helpers
3
+ def Helpers.parse_room(command)
4
+ command.match(/(\#\S+\b)/i)
5
+ return $1
6
+ end
7
+
8
+ def Helpers.hashify(bot, origin, command, msg)
9
+ hash = {:bot=>bot, :origin=>origin, :command => command, :msg => msg, :room => nil}
10
+ command.match(/(\#\S+\b)/i)
11
+ hash[:room] = $1
12
+ return hash
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Spunk
2
+ class Origin
3
+ attr_accessor :prefix
4
+
5
+ def initialize(prefix)
6
+ @prefix = prefix
7
+ end
8
+
9
+ def nickname
10
+ @prefix.to_s.split(/!/, 2)[0]
11
+ end
12
+
13
+ def to_s
14
+ case
15
+ when nickname != ""
16
+ nickname
17
+ when @prefix
18
+ @prefix
19
+ else
20
+ "-unknown-"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module Spunk
2
+ module Processor
3
+ class Ping
4
+ def call(bot, origin, command, parameters)
5
+ if command =~ /^PING$/
6
+ bot.send_message("PONG :#{parameters}")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spunk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Heijmans
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-21 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple little IRCbot framework based on Sprinkles
15
+ email: parabuzzle@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/spunk.rb
21
+ - lib/spunk/bot.rb
22
+ - lib/spunk/origin.rb
23
+ - lib/spunk/base_parser.rb
24
+ - lib/spunk/ping_parser.rb
25
+ - lib/spunk/helpers.rb
26
+ homepage: http://github.com/parabuzzle/spunk
27
+ licenses: []
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 1.8.25
47
+ signing_key:
48
+ specification_version: 3
49
+ summary: A simple little IRCbot framework based on Sprinkles
50
+ test_files: []