ircbot 0.0.2

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,242 @@
1
+ =begin header
2
+ Internet Relay Chat Protocol Library -- Constants
3
+
4
+ $Author: igarashi $
5
+ $Date: 2000/06/12 15:52:00 $
6
+
7
+ Copyright (C) 1998-2000 Hiroshi IGARASHI
8
+ =end
9
+
10
+ module IRC
11
+ module Constants
12
+ =begin
13
+ module in which IRC constants are defined
14
+ =end
15
+
16
+ ERR_NOSUCHNICK = "401"
17
+ ERR_NOSUCHSERVE = "402"
18
+ ERR_NOSUCHCHANNEL = "403"
19
+ ERR_CANNOTSENDTOCHAN = "404"
20
+ ERR_TOOMANYCHANNELS = "405"
21
+ ERR_WASNOSUCHNICK = "406"
22
+ ERR_TOOMANYTARGETS = "407"
23
+ ERR_NOORIGIN = "409"
24
+ ERR_NORECIPIENT = "411"
25
+ ERR_NOTEXTTOSEND = "412"
26
+ ERR_NOTOPLEVE = "413"
27
+ ERR_WILDTOPLEVEL = "414"
28
+ ERR_UNKNOWNCOMMAND = "421"
29
+ ERR_NOMOTD = "422"
30
+ ERR_NOADMININFO = "423"
31
+ ERR_FILEERROR = "424"
32
+ ERR_NONICKNAMEGIVEN = "431"
33
+ ERR_ERRONEUSNICKNAME = "432"
34
+ ERR_NICKNAMEINUSE = "433"
35
+ ERR_NICKCOLLISION = "436"
36
+ ERR_USERNOTINCHANNEL = "441"
37
+ ERR_NOTONCHANNE = "442"
38
+ ERR_USERONCHANNEL = "443"
39
+ ERR_NOLOGIN = "444"
40
+ ERR_SUMMONDISABLED = "445"
41
+ ERR_USERSDISABLED = "446"
42
+ ERR_NOTREGISTERED = "451"
43
+ ERR_NEEDMOREPARAM = "461"
44
+ ERR_ALREADYREGISTRE = "462"
45
+ ERR_NOPERMFORHOST = "463"
46
+ ERR_PASSWDMISMATCH = "464"
47
+ ERR_YOUREBANNEDCREEP = "465"
48
+ ERR_KEYSET = "467"
49
+ ERR_CHANNELISFULL = "471"
50
+ ERR_UNKNOWNMODE = "472"
51
+ ERR_INVITEONLYCHAN = "473"
52
+ ERR_BANNEDFROMCHAN = "474"
53
+ ERR_BADCHANNELKEY = "475"
54
+ ERR_NOPRIVILEGES = "481"
55
+ ERR_CHANOPRIVSNEEDED = "482"
56
+ ERR_CANTKILLSERVER = "483"
57
+ ERR_NOOPERHOST = "491"
58
+ ERR_UMODEUNKNOWNFLAG = "501"
59
+ ERR_USERSDONTMATCH = "502"
60
+ =begin
61
+ Error Replies
62
+ =end
63
+
64
+ RPL_NONE = "300"
65
+ RPL_USERHOST = "302"
66
+ RPL_ISON = "303"
67
+ RPL_AWAY = "301"
68
+ RPL_UNAWAY = "305"
69
+ RPL_NOWAWAY = "306"
70
+ RPL_WHOISUSER = "311"
71
+ RPL_WHOISSERVER = "312"
72
+ RPL_WHOISOPERATOR = "313"
73
+ RPL_WHOISIDLE = "317"
74
+ RPL_ENDOFWHOIS = "318"
75
+ RPL_WHOISCHANNELS = "319"
76
+ RPL_WHOWASUSER = "314"
77
+ RPL_ENDOFWHOWAS = "369"
78
+ RPL_LISTSTART = "321"
79
+ RPL_LIST = "322"
80
+ RPL_LISTEND = "323"
81
+ RPL_CHANNELMODEIS = "324"
82
+ RPL_NOTOPIC = "331"
83
+ RPL_TOPIC = "332"
84
+ RPL_INVITING = "341"
85
+ RPL_SUMMONING = "342"
86
+ RPL_VERSION = "351"
87
+ RPL_WHOREPLY = "352"
88
+ RPL_ENDOFWHO = "315"
89
+ RPL_NAMREPLY = "353"
90
+ RPL_ENDOFNAME = "366"
91
+ RPL_LINKS = "364"
92
+ RPL_ENDOFLINKS = "365"
93
+ RPL_BANLIST = "367"
94
+ RPL_ENDOFBANLIST = "368"
95
+ RPL_INFO = "371"
96
+ RPL_ENDOFINFO = "374"
97
+ RPL_MOTDSTART = "375"
98
+ RPL_MOTD = "372"
99
+ RPL_ENDOFMOTD = "376"
100
+ RPL_YOUREOPER = "381"
101
+ RPL_REHASHING = "382"
102
+ RPL_TIME = "391"
103
+ RPL_USERSSTART = "392"
104
+ RPL_USERS = "393"
105
+ RPL_ENDOFUSERS = "394"
106
+ RPL_NOUSERS = "395"
107
+
108
+ RPL_TRACELINK = "200"
109
+ RPL_TRACECONNECTING = "201"
110
+ RPL_TRACEHANDSHAKE = "202"
111
+ RPL_TRACEUNKNOWN = "203"
112
+ RPL_TRACEOPERATOR = "204"
113
+ RPL_TRACEUSER = "205"
114
+ RPL_TRACESERVER = "206"
115
+ RPL_TRACENEWTYPE = "208"
116
+ RPL_TRACELOG = "261"
117
+ RPL_STATSLINKINF = "211"
118
+ RPL_STATSCOMMANDS = "212"
119
+ RPL_STATSCLINE = "213"
120
+ RPL_STATSNLINE = "214"
121
+ RPL_STATSILINE = "215"
122
+ RPL_STATSKLINE = "216"
123
+ RPL_STATSYLINE = "218"
124
+ RPL_ENDOFSTATS = "219"
125
+ RPL_STATSLLINE = "241"
126
+ RPL_STATSUPTIME = "242"
127
+ RPL_STATSOLINE = "243"
128
+ RPL_STATSHLINE = "244"
129
+ RPL_UMODEIS = "221"
130
+ RPL_LUSERCLIENT = "251"
131
+ RPL_LUSEROP = "252"
132
+ RPL_LUSERUNKNOWN = "253"
133
+ RPL_LUSERCHANNELS = "254"
134
+ RPL_LUSERME = "255"
135
+ RPL_ADMINME = "256"
136
+ RPL_ADMINLOC1 = "257"
137
+ RPL_ADMINLOC2 = "258"
138
+ RPL_ADMINEMAIL = "259"
139
+ =begin
140
+ Message Replies
141
+ =end
142
+
143
+ # generating mapping "XXX" -> <error name>
144
+ table = {}
145
+ constants.each { |name|
146
+ table[const_get(name)] = name
147
+ }
148
+ NAME_TABLE = table
149
+ =begin
150
+ Mapping "XXX" -> <error name>
151
+ =end
152
+
153
+ #
154
+ # Message Commands
155
+ #
156
+ CMD_PASS = "PASS"
157
+ CMD_NICK = "NICK"
158
+ CMD_USER = "USER"
159
+ CMD_SERVER = "SERVER"
160
+ CMD_OPER = "OPER"
161
+ CMD_QUIT = "QUIT"
162
+ CMD_SQUIT = "SQUIT"
163
+ =begin
164
+ Connection messages
165
+ =end
166
+
167
+ CMD_JOIN = "JOIN"
168
+ CMD_PART = "PART"
169
+ CMD_MODE = "MODE"
170
+ CMD_TOPIC = "TOPIC"
171
+ CMD_NAMES = "NAMES"
172
+ CMD_LIST = "LIST"
173
+ CMD_INVITE = "INVITE"
174
+ CMD_KICK = "KICK"
175
+ =begin
176
+ Channel control messages
177
+ =end
178
+
179
+ CMD_VERSION = "VERSION"
180
+ CMD_STATS = "STATS"
181
+ CMD_LINK = "LINK"
182
+ CMD_TIME = "TIME"
183
+ CMD_CONNECT = "CONNECT"
184
+ CMD_TRACE = "TRACE"
185
+ CMD_ADMIN = "ADMIN"
186
+ CMD_INFO = "INFO"
187
+ =begin
188
+ Query and messages for server
189
+ =end
190
+
191
+ CMD_PRIVMSG = "PRIVMSG"
192
+ CMD_NOTICE = "NOTICE"
193
+ =begin
194
+ Message sending
195
+ =end
196
+
197
+ CMD_WHO = "WHO"
198
+ CMD_WHOIS = "WHOIS"
199
+ CMD_WHOWAS = "WHOWAS"
200
+ =begin
201
+ Request for user information
202
+ =end
203
+
204
+ CMD_KILL = "KILL"
205
+ CMD_PING = "PING"
206
+ CMD_PONG = "PONG"
207
+ CMD_ERROR = "ERROR"
208
+ =begin
209
+ Others
210
+ =end
211
+
212
+ CMD_AWAY = "AWAY"
213
+ CMD_REHASH = "REHASH"
214
+ CMD_RESTART = "RESTART"
215
+ CMD_SUMMON = "SUMMON"
216
+ CMD_USERS = "USERS"
217
+ CMD_WALLOPS = "WALLOPS"
218
+ CMD_USERHOST = "USERHOST"
219
+ CMD_ISON = "ISON"
220
+ =begin
221
+ Optional
222
+ =end
223
+
224
+ #
225
+ # Other constants
226
+ #
227
+
228
+ CRLF = "\r\n"
229
+ =begin
230
+ Message separator
231
+ =end
232
+
233
+ DEFAULT_PORT = 6667
234
+ =begin
235
+ Default TCP Port
236
+ =end
237
+
238
+ end
239
+ end
240
+
241
+ #p IRC::Constants::NAME_TABLE
242
+
@@ -0,0 +1,324 @@
1
+ =begin header
2
+ Internet Relay Chat Protocol Library -- Main Part
3
+
4
+ $Author: knu $
5
+ $Date: 2001/01/31 10:55:28 $
6
+
7
+ Copyright (C) 1998-2000 Hiroshi IGARASHI
8
+ =end
9
+
10
+ require 'socket'
11
+ require 'thread'
12
+ require 'kconv'
13
+ require 'irc/localize'
14
+ require 'irc/const'
15
+
16
+ module IRC
17
+ class Message
18
+ =begin
19
+ IRC messages in IRC protocol
20
+ =end
21
+
22
+ include Constants
23
+
24
+ attr_accessor(:prefix)
25
+ attr_accessor(:command)
26
+ attr_accessor(:params)
27
+ attr_accessor(:trailing)
28
+ attr_accessor(:str) # for debug
29
+ =begin
30
+ =end
31
+
32
+ def initialize(command, trailing=nil, prefix=nil, *params)
33
+ =begin
34
+ initialize Message
35
+ command:String
36
+ trailing=nil:String
37
+ prefix=nil:String
38
+ *params:String
39
+ =end
40
+ @prefix = prefix
41
+ @command = command
42
+ @params = params
43
+ @trailing = trailing
44
+ @str = to_s
45
+ end
46
+
47
+ def to_s
48
+ =begin
49
+ String representation suitable for sending
50
+ =end
51
+ buf = ''
52
+ buf << ":" << @prefix << ' ' unless @prefix.nil?
53
+ buf << @command
54
+ buf << ' ' << @params.join(' ') unless @params.empty?
55
+ buf << " :" << @trailing unless @trailing.nil?
56
+ buf
57
+ end
58
+
59
+ alias_method(:to_extern, :to_s)
60
+ =begin
61
+ alias of to_s
62
+ =end
63
+ end
64
+
65
+ class << Message
66
+ def parse(str)
67
+ =begin
68
+ parse IRC message and create a new Message object.
69
+ =end
70
+ strbuf = str.dup
71
+ strbuf.sub!(/^:(\S+)\s+/, '')
72
+ prefix = $1 if $1
73
+ strbuf.sub!(/^(\S+)/, '')
74
+ command = $1 if $1
75
+ params = []
76
+ #while strbuf.sub!(/^\s+([^\s:]+)/, '')
77
+ while strbuf.sub!(/^\s+([^\s:][^\s]*)/, '')
78
+ params << $1
79
+ end
80
+ strbuf.sub!(/^\s+:([^\r\n]+)(\r\n|\r|\n)?$/, '')
81
+ trailing = $1 if $1
82
+ msg = new(command, trailing, prefix, *params)
83
+ msg.str = str # for debug
84
+ msg
85
+ end
86
+ end
87
+
88
+ class User
89
+ =begin
90
+ represent IRC user
91
+ =end
92
+ attr_reader(:nick)
93
+ attr_reader(:user)
94
+ attr_reader(:host)
95
+ def initialize(nick, user=nil, host=nil)
96
+ @nick, @user, @host = nick, user, host
97
+ end
98
+ def to_s
99
+ "#{@nick}(#{user}) at #{@host}"
100
+ end
101
+ def ==(other)
102
+ case other
103
+ when User
104
+ @nick == other.nick && @user == other.user && @host == other.host
105
+ else
106
+ false
107
+ end
108
+ end
109
+ end
110
+ class << User
111
+ def parse(str)
112
+ str =~ /([^\s!@]+)(?:!([^\s@]+))?(?:@(\S+))?/
113
+ User::new($1, $2, $3)
114
+ end
115
+ end
116
+
117
+ class LogMessage
118
+ =begin
119
+ class which represents log message
120
+ =end
121
+ attr_reader(:timestamp)
122
+ =begin
123
+ :Time the time when this object was sent
124
+ =end
125
+ attr_reader(:sender)
126
+ =begin
127
+ :Object the object which sent object
128
+ =end
129
+ attr_reader(:ident)
130
+ =begin
131
+ :String identifier for message type
132
+ =end
133
+ attr_reader(:message)
134
+ =begin
135
+ :String log message string
136
+ =end
137
+ def initialize(sender, ident, message)
138
+ =begin
139
+ initialization
140
+ sender:Object the object which sent object
141
+ ident:String identifier for message type
142
+ message:String string as message
143
+ message:Message message object
144
+ =end
145
+ @timestamp = Time.now
146
+ @sender, @ident, @message = sender, ident, message
147
+ end
148
+ def to_s
149
+ =begin
150
+ string in standard output form
151
+ =end
152
+ buf = @timestamp.to_s
153
+ case @sender
154
+ when Connection, Client
155
+ buf << " <#{@ident}> #{@message}"
156
+ when Agent
157
+ buf << " [#{@sender.nick}] #{@message}"
158
+ end
159
+ buf
160
+ end
161
+ end
162
+
163
+ class Connection
164
+ =begin
165
+ represent IRC connection
166
+ =end
167
+
168
+ include Constants
169
+
170
+ def Message(command, trailing=nil, prefix=nil, *params)
171
+ =begin
172
+ alias of IRC::Message::new
173
+ =end
174
+ Message.new(command, trailing, prefix, *params)
175
+ end
176
+
177
+ def initialize(log_queue=nil)
178
+ =begin
179
+ initialize Connection
180
+ log_queue:Queue -- queue object into which log message are put.
181
+ =end
182
+ @log_queue = log_queue
183
+ end
184
+
185
+ private
186
+ def putlog(ident, str)
187
+ =begin
188
+ put a log message.
189
+ =end
190
+ #@log_queue.push(Time.now.to_s+": "+str.to_s) unless @log_queue.nil?
191
+ @log_queue.push(LogMessage.new(self, ident, str)) unless @log_queue.nil?
192
+ end
193
+ public
194
+
195
+ def connect(server, port=DEFAULT_PORT)
196
+ =begin
197
+ Connect to server which has hostname given by argument server.
198
+ If sub-class of BasicSocket is given, it will be used.
199
+ server:String -- server name.
200
+ server:BasicSocket -- socket already connected to server.
201
+ port=DEFAULT_PORT:Fixnum -- TCP port number. 6667 will be used when omitted.
202
+ =end
203
+ if server.is_a?(BasicSocket)
204
+ @socket = server
205
+ else
206
+ @server = server
207
+ @port = port
208
+ @socket = TCPsocket.open(@server, @port)
209
+ end
210
+ @socket.set_codesys("JIS")
211
+ end
212
+
213
+ def disconnect
214
+ =begin
215
+ =end
216
+ @socket.flush
217
+ @socket.shutdown(2)
218
+ @socket.close
219
+ end
220
+
221
+ def send(*args)
222
+ =begin
223
+ send IRC message.
224
+ send(message)
225
+ message:Message a IRC message to be send
226
+ send(command, trailing, prefix, *params)
227
+ Send a message which consists of given arguments.
228
+ Refer to Message#initialize about the meaning of the arguments.
229
+ =end
230
+ case args.length
231
+ when 1
232
+ case args[0]
233
+ when Message
234
+ message = args[0]
235
+ @socket.lprint(message, CRLF)
236
+ putlog("send", message)
237
+ when String
238
+ command = args[0]
239
+ message = Message(command)
240
+ @socket.lprint(message, CRLF)
241
+ putlog("send1", message)
242
+ else
243
+ putlog("send", "Type error(#{message.inspect}).")
244
+ end
245
+ when 0, 2
246
+ putlog("send", "Argument number error.")
247
+ else
248
+ message = Message(*args)
249
+ @socket.lprint(message, CRLF)
250
+ putlog("send1", message)
251
+ end
252
+ end
253
+ # def send(message)
254
+ # @socket.lprint(message, CRLF)
255
+ # putlog("send", message.to_s)
256
+ # end
257
+
258
+ def recv
259
+ =begin
260
+ Receive IRC message and return as Message object.
261
+ This method will block.
262
+ =end
263
+ str = @socket.lgets
264
+ unless str.nil?
265
+ message = Message.parse(str)
266
+ else
267
+ message = nil
268
+ end
269
+ putlog("recv", message)
270
+ message
271
+ end
272
+
273
+ def sendPASS(password)
274
+ send(Message(CMD_PASS, nil, nil, password))
275
+ end
276
+ def sendNICK(nick)
277
+ send(Message(CMD_NICK, nil, nil, nick))
278
+ end
279
+ def sendUSER(nick, username, hostname, servername, realname)
280
+ send(Message(CMD_USER, realname, nick,
281
+ username, hostname, servername))
282
+ end
283
+ def sendQUIT(nick, quit_message)
284
+ send(Message(CMD_QUIT, quit_message, nick))
285
+ end
286
+ =begin
287
+ send IRC messages about IRC connection.
288
+ =end
289
+
290
+ def sendPING(nick, servers)
291
+ send(Message(CMD_PING, nil, nick, servers))
292
+ end
293
+ def sendPONG(nick, daemons, phrase=nil)
294
+ send(Message(CMD_PONG, phrase, nick, daemons))
295
+ end
296
+ =begin
297
+ send IRC messages PING/PONG.
298
+ =end
299
+
300
+ # # send IRC messages about channel
301
+ # def sendJOIN(nick, channels, keys)
302
+ # if channels.is_a?(Array)
303
+ # channels = channels.join(",")
304
+ # end
305
+ # if keys.is_a?(Array)
306
+ # keys = keys.join(",")
307
+ # end
308
+ # send(Message(CMD_JOIN, nil, nick, channels, keys))
309
+ # end
310
+ # def sendPART(nick, channels)
311
+ # if channels.is_a?(Array)
312
+ # channels = channels.join(",")
313
+ # end
314
+ # send(Message(CMD_PART, nil, nick, channels))
315
+ # end
316
+
317
+ # # send IRC messages about sending messages
318
+ # def sendPRIVMSG(nick, message, *channels)
319
+ # send(Message(CMD_PRIVMSG, message, nick, *channels))
320
+ # end
321
+
322
+ end
323
+ end
324
+