circus 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ test.rb
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ This software is considered BEER-WARE:
2
+ Tim Sjoberg wrote this library. As long as you retain this notice you can do
3
+ whatever you want with this stuff. If we meet some day, and you think this
4
+ stuff is worth it, you can buy me a beer in return
@@ -0,0 +1,11 @@
1
+ = circus
2
+
3
+ An event driven IRC gem without a DSL or any EOF magick
4
+
5
+ == Author
6
+
7
+ Tim Sjoberg (bedlamp AT gmail.com)
8
+
9
+ == License
10
+
11
+ This software is distributed under the BEER-WARE license. See LICENSE for details.
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "circus"
8
+ gem.summary = %Q{A relatively simple event driven irc gem}
9
+ gem.description = %Q{A relatively simple event driven irc gem without a DSL or any EOF magick}
10
+ gem.email = "bedlamp@gmail.com"
11
+ gem.homepage = "http://github.com/timsjoberg/circus"
12
+ gem.authors = ["Tim Sjoberg"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "activesupport", ">= 2.3.5"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "circus #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{circus}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tim Sjoberg"]
12
+ s.date = %q{2010-07-01}
13
+ s.description = %q{A relatively simple event driven irc gem without a DSL or any EOF magick}
14
+ s.email = %q{bedlamp@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "circus.gemspec",
27
+ "lib/circus.rb",
28
+ "lib/irc.rb",
29
+ "lib/irc/commands.rb",
30
+ "lib/irc/connection.rb",
31
+ "lib/irc/errors.rb",
32
+ "lib/irc/event_manager.rb",
33
+ "lib/irc/messages/action.rb",
34
+ "lib/irc/messages/ctcp.rb",
35
+ "lib/irc/messages/ctcp_reply.rb",
36
+ "lib/irc/messages/join.rb",
37
+ "lib/irc/messages/kick.rb",
38
+ "lib/irc/messages/mode.rb",
39
+ "lib/irc/messages/nick.rb",
40
+ "lib/irc/messages/notice.rb",
41
+ "lib/irc/messages/part.rb",
42
+ "lib/irc/messages/pass.rb",
43
+ "lib/irc/messages/pong.rb",
44
+ "lib/irc/messages/privmsg.rb",
45
+ "lib/irc/messages/quit.rb",
46
+ "lib/irc/messages/raw.rb",
47
+ "lib/irc/messages/topic.rb",
48
+ "lib/irc/messages/user.rb",
49
+ "lib/irc/parser.rb",
50
+ "spec/circus_spec.rb",
51
+ "spec/spec.opts",
52
+ "spec/spec_helper.rb"
53
+ ]
54
+ s.homepage = %q{http://github.com/timsjoberg/circus}
55
+ s.rdoc_options = ["--charset=UTF-8"]
56
+ s.require_paths = ["lib"]
57
+ s.rubygems_version = %q{1.3.7}
58
+ s.summary = %q{A relatively simple event driven irc gem}
59
+ s.test_files = [
60
+ "spec/circus_spec.rb",
61
+ "spec/spec_helper.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
70
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
71
+ else
72
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
73
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
77
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
78
+ end
79
+ end
80
+
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'irc')
@@ -0,0 +1,61 @@
1
+ require 'active_support'
2
+
3
+ current_dir = File.dirname(__FILE__)
4
+
5
+ require File.join(current_dir, 'irc', 'connection')
6
+ require File.join(current_dir, 'irc', 'event_manager')
7
+
8
+ Dir[File.join(current_dir, 'irc', 'messages', '*.rb')].each do |klass|
9
+ require klass
10
+ end
11
+
12
+ module Circus
13
+ class IRC
14
+
15
+ def initialize(options = {})
16
+ @default = { :server => "za.shadowfire.org",
17
+ :port => 6667,
18
+ :nick => "Circus-IRC",
19
+ :username => "circus",
20
+ :realname => "Using ruby with Circus IRC",
21
+ :send_speed => 0.5,
22
+ :timeout => 15*60, #15 minutes
23
+ :eol => "\r\n",
24
+ :debug => false }
25
+
26
+ @config = @default.merge options
27
+ @event_manager = EventManager.new
28
+
29
+ default_subscriptions
30
+ end
31
+
32
+ def connect
33
+ @connection ||= Connection.new @event_manager, @config
34
+
35
+ pass @config[:password] if @config[:password]
36
+ nick @config[:nick]
37
+ user "#{@config[:username]} 0 * :#{@config[:realname]}"
38
+
39
+ @connection.connect
40
+ end
41
+
42
+ def subscribe(type, &block)
43
+ @event_manager.subscribe(type, &block)
44
+ end
45
+
46
+ def method_missing(name, *args)
47
+ message_class = "Circus::Messages::#{name.to_s.downcase.classify}"
48
+ message_class = message_class.constantize
49
+ @connection.send message_class.new *args
50
+ rescue
51
+ super
52
+ end
53
+
54
+ protected
55
+
56
+ def default_subscriptions
57
+ subscribe(:PING) { |msg| pong msg }
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,231 @@
1
+ module Circus
2
+ class Commands
3
+ class << self
4
+
5
+ COMMAND_MAP = {
6
+ # --- Text based ---------------------------------------
7
+ "error" => :ERROR,
8
+ "invite" => :INVITE,
9
+ "join" => :JOIN,
10
+ "kick" => :KICK,
11
+ "kill" => :KILL,
12
+ "mode" => :MODE,
13
+ "nick" => :NICK,
14
+ "notice" => :NOTICE,
15
+ "part" => :PART,
16
+ "ping" => :PING,
17
+ "privmsg" => :PRIVMSG,
18
+ "quit" => :QUIT,
19
+
20
+
21
+ # --- Some useful subclassy things ---------------------
22
+ "ctcp" => :CTCP,
23
+ "ctcp_reply" => :CTCPREPLY,
24
+ "action" => :ACTION,
25
+
26
+
27
+ # --- 0** Codes ----------------------------------------
28
+ "001" => :WELCOME,
29
+ "002" => :YOURHOST,
30
+ "003" => :CREATED,
31
+ "004" => :MYINFO,
32
+ "005" => :ISUPPORT,
33
+
34
+
35
+ # --- 2** Codes ----------------------------------------
36
+ "200" => :TRACELINK,
37
+ "201" => :TRACECONNECTING,
38
+ "202" => :TRACEHANDSHAKE,
39
+ "203" => :TRACEUNKNOWN,
40
+ "204" => :TRACEOPERATOR,
41
+ "205" => :TRACEUSER,
42
+ "206" => :TRACESERVER,
43
+ "207" => :TRACESERVICE,
44
+ "208" => :TRACENEWTYPE,
45
+ "209" => :TRACECLASS,
46
+ "210" => :TRACERECONNECT,
47
+ "211" => :STATSLINKINFO,
48
+ "212" => :STATSCOMMANDS,
49
+ "213" => :STATSCLINE,
50
+ "214" => :STATSNLINE,
51
+ "215" => :STATSILINE,
52
+ "216" => :STATSKLINE,
53
+ "217" => :STATSQLINE,
54
+ "218" => :STATSYLINE,
55
+ "219" => :ENDOFSTATS,
56
+ "221" => :UMODEIS,
57
+ "231" => :SERVICEINFO,
58
+ "232" => :ENDOFSERVICES,
59
+ "233" => :SERVICE,
60
+ "234" => :SERVLIST,
61
+ "235" => :SERVLISTEND,
62
+ "240" => :STATSVLINE,
63
+ "241" => :STATSLLINE,
64
+ "242" => :STATSUPTIME,
65
+ "243" => :STATSOLINE,
66
+ "244" => :STATSHLINE,
67
+ "245" => :STATSSLINE, # RFC 2812 seems to be erroneous, it assigns 244 double
68
+ "246" => :STATSPING,
69
+ "247" => :STATSBLINE,
70
+ "250" => :STATSCONN,
71
+ "251" => :LUSERCLIENT,
72
+ "252" => :LUSEROP,
73
+ "253" => :LUSERUNKNOWN,
74
+ "254" => :LUSERCHANNELS,
75
+ "255" => :LUSERME,
76
+ "256" => :ADMINME,
77
+ "257" => :ADMINLOC1,
78
+ "258" => :ADMINLOC2,
79
+ "259" => :ADMINEMAIL,
80
+ "261" => :TRACELOG,
81
+ "262" => :TRACEEND,
82
+ "263" => :TRYAGAIN,
83
+ "265" => :LOCALUSERS,
84
+ "266" => :GLOBALUSERS,
85
+ "290" => :IDENTIFY,
86
+
87
+
88
+ # --- 3** Codes ----------------------------------------
89
+ "300" => :NONE,
90
+ "301" => :AWAY,
91
+ "302" => :USERHOST,
92
+ "303" => :ISON,
93
+ "305" => :UNAWAY,
94
+ "306" => :NOWAWAY,
95
+ "311" => :WHOISUSER,
96
+ "312" => :WHOISSERVER,
97
+ "313" => :WHOISOPERATOR,
98
+ "314" => :WHOWASUSER,
99
+ "315" => :ENDOFWHO,
100
+ "316" => :WHOISCHANOP,
101
+ "317" => :WHOISIDLE,
102
+ "318" => :ENDOFWHOIS,
103
+ "319" => :WHOISCHANNELS,
104
+ "320" => :IDENTIFIED_TO_SERVICES,
105
+ "321" => :LISTSTART,
106
+ "322" => :LIST,
107
+ "323" => :LISTEND,
108
+ "324" => :CHANNELMODEIS,
109
+ "325" => :UNIQOPIS,
110
+ "328" => :UNK_328, # freenode.net, on join
111
+ "329" => :CHANNEL_INFO,
112
+ "331" => :NOTOPIC,
113
+ "332" => :TOPIC,
114
+ "333" => :TOPIC_INFO,
115
+ "341" => :INVITING,
116
+ "342" => :SUMMONING,
117
+ "343" => :MAINTENANCE,
118
+ "346" => :INVITELIST,
119
+ "347" => :ENDOFINVITELIST,
120
+ "348" => :EXCEPTLIST,
121
+ "349" => :ENDOFEXCEPTLIST,
122
+ "351" => :VERSION,
123
+ "352" => :WHOREPLY,
124
+ "353" => :NAMEREPLY,
125
+ "361" => :KILLDONE,
126
+ "362" => :CLOSING,
127
+ "363" => :CLOSEEND,
128
+ "364" => :LINKS,
129
+ "365" => :ENDOFLINKS,
130
+ "366" => :ENDOFNAMES,
131
+ "367" => :BANLIST,
132
+ "369" => :ENDOFWHOWAS,
133
+ "368" => :ENDOFBANLIST,
134
+ "371" => :INFO,
135
+ "372" => :MOTD,
136
+ "373" => :INFOSTART,
137
+ "374" => :ENDOFINFO,
138
+ "375" => :MOTDSTART,
139
+ "376" => :ENDOFMOTD,
140
+ "381" => :YOUREOPER,
141
+ "382" => :REHASHING,
142
+ "383" => :YOURESERVICE,
143
+ "384" => :MYPORTIS,
144
+ "391" => :TIME,
145
+ "392" => :USERSSTART,
146
+ "393" => :USERS,
147
+ "394" => :ENDOFUSERS,
148
+ "395" => :NOUSERS,
149
+ "396" => :HOSTHIDDEN, # undernet [ircu]: when hiding host is activated
150
+
151
+
152
+ # --- 4** Codes ----------------------------------------
153
+ "401" => :NOSUCHNICK,
154
+ "402" => :NOSUCHSERVER,
155
+ "403" => :NOSUCHCHANNEL,
156
+ "404" => :CANNOTSENDTOCHAN,
157
+ "405" => :TOOMANYCHANNELS,
158
+ "406" => :WASNOSUCHNICK,
159
+ "407" => :TOOMANYTARGETS,
160
+ "408" => :NOSUCHSERVICE,
161
+ "409" => :NOORIGIN,
162
+ "410" => :SERVICES_OFFLINE,
163
+ "411" => :NORECIPIENT,
164
+ "412" => :NOTEXTTOSEND,
165
+ "413" => :NOTOPLEVEL,
166
+ "414" => :WILDTOPLEVEL,
167
+ "415" => :BADMASK,
168
+ "421" => :UNKNOWNCOMMAND,
169
+ "422" => :NOMOTD,
170
+ "423" => :NOADMININFO,
171
+ "424" => :FILEERROR,
172
+ "431" => :NONICKNAMEGIVEN,
173
+ "432" => :ERRONEUSNICKNAME,
174
+ "433" => :NICKNAMEINUSE,
175
+ "436" => :NICKCOLLISION,
176
+ "437" => :UNAVAILRESOURCE,
177
+ "441" => :USERNOTINCHANNEL,
178
+ "442" => :NOTONCHANNEL,
179
+ "443" => :USERONCHANNEL,
180
+ "444" => :NOLOGIN,
181
+ "445" => :SUMMONDISABLED,
182
+ "446" => :USERSDISABLED,
183
+ "451" => :NOTREGISTERED,
184
+ "461" => :NEEDMOREPARAMS,
185
+ "462" => :ALREADYREGISTRED,
186
+ "463" => :NOPERMFORHOST,
187
+ "464" => :PASSWDMISMATCH,
188
+ "465" => :YOUREBANNEDCREEP,
189
+ "466" => :YOUWILLBEBANNED,
190
+ "467" => :KEYSET,
191
+ "471" => :CHANNELISFULL,
192
+ "472" => :UNKNOWNMODE,
193
+ "473" => :INVITEONLYCHAN,
194
+ "474" => :BANNEDFROMCHAN,
195
+ "475" => :BADCHANNELKEY,
196
+ "476" => :BADCHANMASK,
197
+ "477" => :NOCHANMODES,
198
+ "478" => :BANLISTFULL,
199
+ "481" => :NOPRIVILEGES,
200
+ "482" => :CHANOPRIVSNEEDED,
201
+ "483" => :CANTKILLSERVER,
202
+ "484" => :RESTRICTED,
203
+ "485" => :UNIQOPPRIVSNEEDED,
204
+ "491" => :NOOPERHOST,
205
+ "492" => :NOSERVICEHOST,
206
+
207
+
208
+ # --- 5** Codes ----------------------------------------
209
+ "501" => :UMODEUNKNOWNFLAG,
210
+ "502" => :USERSDONTMATCH,
211
+ "505" => :NOPRIVMSG,
212
+
213
+
214
+ # --- 9** Codes ----------------------------------------
215
+ "901" => :UNK_901 # irc.freenode.net: response to identification (/msg nickserv identify <pass>)
216
+ }
217
+
218
+ COMMAND_LIST = COMMAND_MAP.values
219
+
220
+ def get_command_symbol(command)
221
+ return COMMAND_MAP[command.downcase] if COMMAND_MAP[command.downcase]
222
+ nil
223
+ end
224
+
225
+ def is_valid_symbol?(symbol)
226
+ COMMAND_LIST.include? symbol
227
+ end
228
+
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,67 @@
1
+ require 'thread'
2
+ require 'socket'
3
+ require 'timeout'
4
+
5
+ current_dir = File.dirname(__FILE__)
6
+
7
+ require File.join(current_dir, 'parser')
8
+ require File.join(current_dir, 'errors')
9
+
10
+ module Circus
11
+ class Connection
12
+
13
+ def initialize(event_manager, config)
14
+ @parser = Parser.new(event_manager)
15
+ @config = config
16
+ @queue = Queue.new
17
+ end
18
+
19
+ def connect
20
+ @socket = TCPSocket.open(@config[:server], @config[:port])
21
+
22
+ @send_thread = Thread.new { dispatch }
23
+
24
+ begin
25
+ loop do
26
+ line = nil
27
+ Timeout::timeout(@config[:timeout]) do
28
+ line = @socket.gets(@config[:eol])
29
+ end
30
+ raise "Socket Closed" unless line
31
+ parse line.chomp
32
+ end
33
+ rescue Timeout::Error
34
+ raise PingTimeout
35
+ rescue Interrupt
36
+ @queue.clear
37
+ @queue << "QUIT :Circus-IRC out"
38
+ sleep 1
39
+ ensure
40
+ @send_thread.exit
41
+ @queue.clear
42
+ @socket.close unless @socket.nil? || @socket.closed?
43
+ end
44
+ end
45
+
46
+ def send(message)
47
+ @queue << message
48
+ end
49
+
50
+ protected
51
+
52
+ def dispatch
53
+ loop do
54
+ message = @queue.pop
55
+ puts "sending: \"#{message}\"" if @config[:debug]
56
+ @socket.write "#{message}#{@config[:eol]}"
57
+ sleep @config[:send_speed]
58
+ end
59
+ end
60
+
61
+ def parse(line)
62
+ puts line if @config[:debug]
63
+ @parser.parse line
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,8 @@
1
+ module Circus
2
+
3
+ class PingTimeout < StandardError
4
+ end
5
+
6
+
7
+
8
+ end
@@ -0,0 +1,66 @@
1
+ current_dir = File.dirname(__FILE__)
2
+
3
+ require File.join(current_dir, 'commands')
4
+
5
+ module Circus
6
+ class EventManager
7
+
8
+ def initialize
9
+ @subscription_id = "0"
10
+ @subscriptions = {}
11
+ @id_to_symbol = {}
12
+ @block_hash = {}
13
+ end
14
+
15
+ def subscribe(type, &block)
16
+ type = type.to_s if type.is_a? Fixnum
17
+
18
+ if type.is_a? String
19
+ if type =~ /^\d+$/
20
+ type = "0#{type}" while type.length < 3
21
+ end
22
+
23
+ type = Commands.get_command_symbol type
24
+ end
25
+
26
+ if type.is_a? Symbol
27
+ raise "Unknown message type" unless Commands.is_valid_symbol? type
28
+
29
+ return add_subscription(type, &block)
30
+ end
31
+ raise "Error in EventManager#subscribe: invalid type parameter"
32
+ end
33
+
34
+ def event(symbol, message, sender = nil, receiver = nil)
35
+ if @subscriptions[symbol]
36
+ @subscriptions[symbol].each do |event_id|
37
+ if sender.nil? && receiver.nil?
38
+ @block_hash[event_id].call(message)
39
+ elsif receiver.nil?
40
+ @block_hash[event_id].call(message, sender)
41
+ else
42
+ @block_hash[event_id].call(message, sender, receiver)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ protected
49
+
50
+ def add_subscription(type, &block)
51
+ @subscription_id.succ!
52
+
53
+ if @subscriptions[type]
54
+ @subscriptions[type] << @subscription_id.dup
55
+ else
56
+ @subscriptions[type] = [@subscription_id.dup]
57
+ end
58
+
59
+ @id_to_symbol[@subscription_id] = type
60
+ @block_hash[@subscription_id] = block
61
+
62
+ @subscription_id
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class Action
4
+
5
+ def initialize(recipient, message)
6
+ @recipient = recipient
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ "PRIVMSG #{@recipient} :\001ACTION #{@message}\001"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class Ctcp
4
+
5
+ def initialize(recipient, message)
6
+ @recipient = recipient
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ "PRIVMSG #{@recipient} :\001#{@message}\001"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class CtcpReply
4
+
5
+ def initialize(recipient, message)
6
+ @recipient = recipient
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ "NOTICE #{@recipient} :\001#{@message}\001"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Circus
2
+ module Messages
3
+ class Join
4
+
5
+ def initialize(channel)
6
+ @channel = channel
7
+ end
8
+
9
+ def to_s
10
+ if @channel =~ /^\#/
11
+ "JOIN #{@channel}"
12
+ else
13
+ "JOIN ##{@channel}"
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Circus
2
+ module Messages
3
+ class Kick
4
+
5
+ def initialize(channel, user, reason = "")
6
+ @channel = channel
7
+ @user = user
8
+ @reason = reason
9
+ end
10
+
11
+ def to_s
12
+ "KICK #{@channel} #{@user} :#{@reason}"
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Circus
2
+ module Messages
3
+ class Mode
4
+
5
+ def initialize(target, mode, users = nil)
6
+ @target = target
7
+ @mode = mode
8
+ @users = users
9
+ end
10
+
11
+ def to_s
12
+ if @users
13
+ "MODE #{@target} #{@mode} #{@users}"
14
+ else
15
+ "MODE #{@target} #{@mode}"
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Nick
4
+
5
+ def initialize(new_nick)
6
+ @new_nick = new_nick
7
+ end
8
+
9
+ def to_s
10
+ "NICK #{@new_nick}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class Notice
4
+
5
+ def initialize(recipient, message)
6
+ @recipient = recipient
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ "NOTICE #{@recipient} :#{@message}"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Part
4
+
5
+ def initialize(channel)
6
+ @channel = channel
7
+ end
8
+
9
+ def to_s
10
+ "PART #{@channel}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Pass
4
+
5
+ def initialize(password)
6
+ @password = password
7
+ end
8
+
9
+ def to_s
10
+ "PASS #{@password}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Pong
4
+
5
+ def initialize(message)
6
+ @message = message
7
+ end
8
+
9
+ def to_s
10
+ "PONG :#{@message}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class Privmsg
4
+
5
+ def initialize(recipient, message)
6
+ @recipient = recipient
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ "PRIVMSG #{@recipient} :#{@message}"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Quit
4
+
5
+ def initialize(message)
6
+ @message = message
7
+ end
8
+
9
+ def to_s
10
+ "QUIT :#{@message}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class Raw
4
+
5
+ def initialize(message)
6
+ @message = message
7
+ end
8
+
9
+ def to_s
10
+ "#{@message}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Circus
2
+ module Messages
3
+ class Topic
4
+
5
+ def initialize(channel, topic)
6
+ @channel = channel
7
+ @topic = topic
8
+ end
9
+
10
+ def to_s
11
+ "TOPIC #{@channel} :#{@topic}"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Circus
2
+ module Messages
3
+ class User
4
+
5
+ def initialize(new_user)
6
+ @new_user = new_user
7
+ end
8
+
9
+ def to_s
10
+ "USER #{@new_user}"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,61 @@
1
+ current_dir = File.dirname(__FILE__)
2
+
3
+ require File.join(current_dir, 'commands')
4
+
5
+ module Circus
6
+ class Parser
7
+
8
+ def initialize(event_manager)
9
+ @event_manager = event_manager
10
+ end
11
+
12
+ def parse(irc_message)
13
+ if irc_message =~ /^(\S+) \:(.+)$/
14
+ symbol = Commands.get_command_symbol $1
15
+ if symbol
16
+ @event_manager.event(symbol, $2)
17
+ else
18
+ puts "UNKNOWN MESSAGE TYPE: #{$2}"
19
+ end
20
+ elsif irc_message =~ /^\:(\S+) (\w+) \:(.+)$/
21
+ symbol = Commands.get_command_symbol $2
22
+ if symbol
23
+ @event_manager.event(symbol, $3, $1)
24
+ else
25
+ puts "UNKNOWN MESSAGE TYPE: #{$2}"
26
+ end
27
+ elsif irc_message =~ /^\:(\S+) (\w+) (\S+)(?: \:?(.+))?$/
28
+ message = $4 || ""
29
+ symbol = Commands.get_command_symbol $2
30
+ message_type = $2
31
+ sender = $1
32
+ receiver = $3
33
+
34
+ if symbol == :PRIVMSG #possible subclass to ctcp or even more to action
35
+ if message =~ /^\001(.*)\001$/
36
+ symbol = :CTCP
37
+ message = $1
38
+ if message =~ /^ACTION (.*)$/
39
+ symbol = :ACTION
40
+ message = $1
41
+ end
42
+ end
43
+ elsif symbol == :NOTICE #possible subclass to ctcp_reply
44
+ if message =~ /^\001(.*)\001$/
45
+ symbol = :CTCPREPLY
46
+ message = $1
47
+ end
48
+ end
49
+
50
+ if symbol
51
+ @event_manager.event(symbol, message, sender, receiver)
52
+ else
53
+ puts "UNKNOWN MESSAGE TYPE: #{message_type}"
54
+ end
55
+ else
56
+ puts "UNPARSED: #{irc_message}"
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Circus" do
4
+ it "passes. dummy spec" do
5
+ true
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'circus'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: circus
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Tim Sjoberg
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-01 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: activesupport
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 9
46
+ segments:
47
+ - 2
48
+ - 3
49
+ - 5
50
+ version: 2.3.5
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description: A relatively simple event driven irc gem without a DSL or any EOF magick
54
+ email: bedlamp@gmail.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files:
60
+ - LICENSE
61
+ - README.rdoc
62
+ files:
63
+ - .document
64
+ - .gitignore
65
+ - LICENSE
66
+ - README.rdoc
67
+ - Rakefile
68
+ - VERSION
69
+ - circus.gemspec
70
+ - lib/circus.rb
71
+ - lib/irc.rb
72
+ - lib/irc/commands.rb
73
+ - lib/irc/connection.rb
74
+ - lib/irc/errors.rb
75
+ - lib/irc/event_manager.rb
76
+ - lib/irc/messages/action.rb
77
+ - lib/irc/messages/ctcp.rb
78
+ - lib/irc/messages/ctcp_reply.rb
79
+ - lib/irc/messages/join.rb
80
+ - lib/irc/messages/kick.rb
81
+ - lib/irc/messages/mode.rb
82
+ - lib/irc/messages/nick.rb
83
+ - lib/irc/messages/notice.rb
84
+ - lib/irc/messages/part.rb
85
+ - lib/irc/messages/pass.rb
86
+ - lib/irc/messages/pong.rb
87
+ - lib/irc/messages/privmsg.rb
88
+ - lib/irc/messages/quit.rb
89
+ - lib/irc/messages/raw.rb
90
+ - lib/irc/messages/topic.rb
91
+ - lib/irc/messages/user.rb
92
+ - lib/irc/parser.rb
93
+ - spec/circus_spec.rb
94
+ - spec/spec.opts
95
+ - spec/spec_helper.rb
96
+ has_rdoc: true
97
+ homepage: http://github.com/timsjoberg/circus
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options:
102
+ - --charset=UTF-8
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirements: []
124
+
125
+ rubyforge_project:
126
+ rubygems_version: 1.3.7
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: A relatively simple event driven irc gem
130
+ test_files:
131
+ - spec/circus_spec.rb
132
+ - spec/spec_helper.rb