spunk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []