circus 0.0.0

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.
@@ -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