net-irc 0.0.7 → 0.0.8
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/ChangeLog +6 -0
- data/README +14 -15
- data/Rakefile +1 -1
- data/examples/client.rb +1 -1
- data/examples/echo_bot.rb +1 -1
- data/examples/gmail.rb +2 -1
- data/examples/hatena-star-stream.rb +56 -11
- data/examples/hig.rb +54 -22
- data/examples/iig.rb +63 -86
- data/examples/ircd.rb +358 -0
- data/examples/mixi.rb +2 -1
- data/examples/sig.rb +2 -1
- data/examples/tig.rb +1671 -524
- data/examples/wig.rb +27 -27
- data/lib/net/irc.rb +36 -21
- data/lib/net/irc/client.rb +8 -2
- data/lib/net/irc/client/channel_manager.rb +13 -13
- data/lib/net/irc/constants.rb +2 -2
- data/lib/net/irc/message.rb +17 -10
- data/lib/net/irc/message/modeparser.rb +5 -5
- data/lib/net/irc/message/serverconfig.rb +3 -3
- data/lib/net/irc/pattern.rb +2 -2
- data/lib/net/irc/server.rb +8 -5
- data/spec/net-irc_spec.rb +33 -8
- metadata +16 -18
- data/examples/lig.rb +0 -551
- data/examples/lingr.rb +0 -327
- data/examples/nig.rb +0 -154
data/examples/wig.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# vim:fileencoding=UTF-8:
|
3
3
|
=begin
|
4
4
|
|
5
5
|
# wig.rb
|
@@ -93,7 +93,7 @@ Ruby's by cho45
|
|
93
93
|
$LOAD_PATH << "lib"
|
94
94
|
$LOAD_PATH << "../lib"
|
95
95
|
|
96
|
-
$KCODE = "u" # json use this
|
96
|
+
$KCODE = "u" if RUBY_VERSION < "1.9" # json use this
|
97
97
|
|
98
98
|
require "rubygems"
|
99
99
|
require "net/irc"
|
@@ -145,7 +145,6 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
145
145
|
super
|
146
146
|
@channels = {}
|
147
147
|
@user_agent = "#{self.class}/#{server_version} (wig.rb)"
|
148
|
-
@map = nil
|
149
148
|
@counters = {} # for jabber fav
|
150
149
|
end
|
151
150
|
|
@@ -182,7 +181,7 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
182
181
|
log "Client Options: #{@opts.inspect}"
|
183
182
|
@log.info "Client Options: #{@opts.inspect}"
|
184
183
|
|
185
|
-
@ratio
|
184
|
+
@ratio = Struct.new(:timeline, :friends, :channel).new(*(@opts["ratio"] || "10:3:5").split(":").map {|ratio| ratio.to_f })
|
186
185
|
@footing = @ratio.inject {|r,i| r + i }
|
187
186
|
|
188
187
|
@timeline = []
|
@@ -251,7 +250,7 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
251
250
|
end
|
252
251
|
|
253
252
|
def on_privmsg(m)
|
254
|
-
return on_ctcp(m[0],
|
253
|
+
return m[1].ctcps.each {|ctcp| on_ctcp(m[0], ctcp) } if m.ctcp?
|
255
254
|
retry_count = 3
|
256
255
|
ret = nil
|
257
256
|
target, message = *m.params
|
@@ -259,7 +258,10 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
259
258
|
if target =~ /^#(.+)/
|
260
259
|
channel = Regexp.last_match[1]
|
261
260
|
reply = message[/\s+>(.+)$/, 1]
|
262
|
-
|
261
|
+
if @utf7
|
262
|
+
message = Iconv.iconv("UTF-7", "UTF-8", message).join
|
263
|
+
message = message.force_encoding("ASCII-8BIT") if message.respond_to?(:force_encoding)
|
264
|
+
end
|
263
265
|
if !reply && @opts.key?("alwaysim") && @im && @im.connected? # in jabber mode, using jabber post
|
264
266
|
message = "##{channel} #{message}" unless "##{channel}" == main_channel
|
265
267
|
ret = @im.deliver(jabber_bot_id, message)
|
@@ -314,8 +316,8 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
314
316
|
end
|
315
317
|
when "fav"
|
316
318
|
target = args[0]
|
317
|
-
st
|
318
|
-
id
|
319
|
+
st = @tmap[target]
|
320
|
+
id = rid_for(target)
|
319
321
|
if st || id
|
320
322
|
unless id
|
321
323
|
if @im && @im.connected?
|
@@ -357,7 +359,7 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
357
359
|
end
|
358
360
|
rescue ApiFailed => e
|
359
361
|
log e.inspect
|
360
|
-
end
|
362
|
+
end; private :on_ctcp
|
361
363
|
|
362
364
|
def on_whois(m)
|
363
365
|
nick = m.params[0]
|
@@ -482,8 +484,8 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
482
484
|
|
483
485
|
begin
|
484
486
|
require 'iconv'
|
485
|
-
mesg
|
486
|
-
mesg
|
487
|
+
mesg = mesg.sub(/^.+ > |^.+/) {|str| Iconv.iconv("UTF-8", "UTF-7", str).join }
|
488
|
+
mesg = "[utf7]: #{mesg}" if mesg =~ /[^a-z0-9\s]/i
|
487
489
|
rescue LoadError
|
488
490
|
rescue Iconv::IllegalSequence
|
489
491
|
end
|
@@ -575,8 +577,8 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
575
577
|
body = CGI.unescapeHTML(body)
|
576
578
|
begin
|
577
579
|
require 'iconv'
|
578
|
-
body
|
579
|
-
body
|
580
|
+
body = body.sub(/^.+ > |^.+/) {|str| Iconv.iconv("UTF-8", "UTF-7", str).join }
|
581
|
+
body = "[utf7]: #{body}" if body =~ /[^a-z0-9\s]/i
|
580
582
|
rescue LoadError
|
581
583
|
rescue Iconv::IllegalSequence
|
582
584
|
end
|
@@ -646,7 +648,7 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
646
648
|
|
647
649
|
case ret
|
648
650
|
when Net::HTTPOK # 200
|
649
|
-
ret = JSON.parse(ret.body
|
651
|
+
ret = JSON.parse(ret.body)
|
650
652
|
raise ApiFailed, "Server Returned Error: #{ret["error"]}" if ret.kind_of?(Hash) && ret["error"]
|
651
653
|
ret
|
652
654
|
when Net::HTTPNotModified # 304
|
@@ -700,20 +702,18 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
700
702
|
end
|
701
703
|
|
702
704
|
class TypableMap < Hash
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
when
|
708
|
-
|
709
|
-
else
|
710
|
-
%w|a i u e o|
|
705
|
+
Roman = %w[
|
706
|
+
k g ky gy s z sh j t d ch n ny h b p hy by py m my y r ry w v q
|
707
|
+
].unshift("").map do |consonant|
|
708
|
+
case consonant
|
709
|
+
when "y", /\A.{2}/ then %w|a u o|
|
710
|
+
when "q" then %w|a i e o|
|
711
|
+
else %w|a i u e o|
|
711
712
|
end.map {|vowel| "#{consonant}#{vowel}" }
|
712
|
-
|
713
|
+
end.flatten
|
713
714
|
|
714
|
-
def initialize(size=1)
|
715
|
-
@seq =
|
716
|
-
@map = {}
|
715
|
+
def initialize(size = 1)
|
716
|
+
@seq = Roman
|
717
717
|
@n = 0
|
718
718
|
@size = size
|
719
719
|
end
|
@@ -731,7 +731,7 @@ class WassrIrcGateway < Net::IRC::Server::Session
|
|
731
731
|
id = generate(@n)
|
732
732
|
self[id] = obj
|
733
733
|
@n += 1
|
734
|
-
@n
|
734
|
+
@n %= @seq.size ** @size
|
735
735
|
id
|
736
736
|
end
|
737
737
|
alias << push
|
data/lib/net/irc.rb
CHANGED
@@ -2,22 +2,21 @@
|
|
2
2
|
|
3
3
|
require "ostruct"
|
4
4
|
require "socket"
|
5
|
-
require "thread"
|
6
5
|
require "logger"
|
7
6
|
require "monitor"
|
8
7
|
|
9
8
|
module Net; end
|
10
9
|
|
11
10
|
module Net::IRC
|
12
|
-
VERSION = "0.0.
|
11
|
+
VERSION = "0.0.8".freeze
|
13
12
|
class IRCException < StandardError; end
|
14
13
|
|
15
14
|
require "net/irc/constants"
|
16
15
|
require "net/irc/pattern"
|
17
16
|
|
18
|
-
autoload :Message,
|
19
|
-
autoload :Client,
|
20
|
-
autoload :Server,
|
17
|
+
autoload :Message, "net/irc/message"
|
18
|
+
autoload :Client, "net/irc/client"
|
19
|
+
autoload :Server, "net/irc/server"
|
21
20
|
|
22
21
|
class Prefix < String
|
23
22
|
def nick
|
@@ -32,28 +31,44 @@ module Net::IRC
|
|
32
31
|
extract[2]
|
33
32
|
end
|
34
33
|
|
35
|
-
# Extract
|
34
|
+
# Extract Prefix String to [nick, user, host] Array.
|
36
35
|
def extract
|
37
|
-
_, *ret = *self.match(
|
36
|
+
_, *ret = *self.match(/\A([^\s!]+)(?:!([^\s@]+)@(\S+))?\z/)
|
38
37
|
ret
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
|
-
#
|
43
|
-
def
|
44
|
-
str
|
45
|
-
str = str.gsub(/\x10/, "\x10\x10").gsub(/\x00/, "\x10\x30").gsub(/\x0d/, "\x10r").gsub(/\x0a/, "\x10n")
|
46
|
-
"\x01#{str}\x01"
|
41
|
+
# Encode to CTCP message. Prefix and postfix \x01.
|
42
|
+
def ctcp_encode(str)
|
43
|
+
"\x01#{ctcp_quote(str)}\x01"
|
47
44
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
str
|
54
|
-
|
55
|
-
|
45
|
+
#alias :ctcp_encoding :ctcp_encode
|
46
|
+
module_function :ctcp_encode #, :ctcp_encoding
|
47
|
+
|
48
|
+
# Decode from CTCP message delimited with \x01.
|
49
|
+
def ctcp_decode(str)
|
50
|
+
ctcp_dequote(str.delete("\x01"))
|
51
|
+
end
|
52
|
+
#alias :ctcp_decoding :ctcp_decode
|
53
|
+
module_function :ctcp_decode #, :ctcp_decoding
|
54
|
+
|
55
|
+
def ctcp_quote(str)
|
56
|
+
low_quote(str.gsub("\\", "\\\\\\\\").gsub("\x01", "\\a"))
|
57
|
+
end
|
58
|
+
module_function :ctcp_quote
|
59
|
+
|
60
|
+
def ctcp_dequote(str)
|
61
|
+
low_dequote(str).gsub("\\a", "\x01").gsub(/\\(.|\z)/m, "\\1")
|
62
|
+
end
|
63
|
+
module_function :ctcp_dequote
|
64
|
+
|
65
|
+
private
|
66
|
+
def low_quote(str)
|
67
|
+
str.gsub("\x10", "\x10\x10").gsub("\x00", "\x10\x30").gsub("\r", "\x10r").gsub("\n", "\x10n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def low_dequote(str)
|
71
|
+
str.gsub("\x10n", "\n").gsub("\x10r", "\r").gsub("\x10\x30", "\x00").gsub("\x10\x10", "\x10")
|
56
72
|
end
|
57
|
-
module_function :ctcp_decoding
|
58
73
|
end
|
59
74
|
|
data/lib/net/irc/client.rb
CHANGED
@@ -66,7 +66,7 @@ class Net::IRC::Client
|
|
66
66
|
# Default RPL_WELCOME callback.
|
67
67
|
# This sets @prefix from the message.
|
68
68
|
def on_rpl_welcome(m)
|
69
|
-
@prefix = Prefix.new(m[1][/\S
|
69
|
+
@prefix = Prefix.new(m[1][/\S+\z/])
|
70
70
|
end
|
71
71
|
|
72
72
|
# Default RPL_ISUPPORT callback.
|
@@ -102,7 +102,13 @@ class Net::IRC::Client
|
|
102
102
|
# post PRIVMSG, "#channel", "foobar"
|
103
103
|
def post(command, *params)
|
104
104
|
m = Message.new(nil, command, params.map {|s|
|
105
|
-
|
105
|
+
if s
|
106
|
+
s.force_encoding("ASCII-8BIT") if s.respond_to? :force_encoding
|
107
|
+
#s.gsub(/\r\n|[\r\n]/, " ")
|
108
|
+
s.tr("\r\n", " ")
|
109
|
+
else
|
110
|
+
""
|
111
|
+
end
|
106
112
|
})
|
107
113
|
|
108
114
|
@log.debug "SEND: #{m.to_s.chomp}"
|
@@ -7,12 +7,12 @@ module Net::IRC::Client::ChannelManager
|
|
7
7
|
init_channel(channel)
|
8
8
|
|
9
9
|
@channels.synchronize do
|
10
|
-
m[3].split(
|
11
|
-
_, mode, nick = *u.match(
|
10
|
+
m[3].split(" ").each do |u|
|
11
|
+
_, mode, nick = *u.match(/\A([@+]?)(.+)/)
|
12
12
|
|
13
13
|
@channels[channel][:users] << nick
|
14
14
|
@channels[channel][:users].uniq!
|
15
|
-
|
15
|
+
|
16
16
|
op = @server_config.mode_parser.mark_to_op(mode)
|
17
17
|
if op
|
18
18
|
@channels[channel][:modes] << [op, nick]
|
@@ -64,10 +64,10 @@ module Net::IRC::Client::ChannelManager
|
|
64
64
|
|
65
65
|
# For managing channel
|
66
66
|
def on_kick(m)
|
67
|
-
users = m[1].split(
|
67
|
+
users = m[1].split(",")
|
68
68
|
|
69
69
|
@channels.synchronize do
|
70
|
-
m[0].split(
|
70
|
+
m[0].split(",").each do |chan|
|
71
71
|
init_channel(chan)
|
72
72
|
info = @channels[chan]
|
73
73
|
if info
|
@@ -105,8 +105,8 @@ module Net::IRC::Client::ChannelManager
|
|
105
105
|
info[:users].map! {|i|
|
106
106
|
(i == oldnick) ? newnick : i
|
107
107
|
}
|
108
|
-
info[:modes].map! {|
|
109
|
-
(target == oldnick) ? [
|
108
|
+
info[:modes].map! {|mode, target|
|
109
|
+
(target == oldnick) ? [mode, newnick] : [mode, target]
|
110
110
|
}
|
111
111
|
end
|
112
112
|
end
|
@@ -118,17 +118,17 @@ module Net::IRC::Client::ChannelManager
|
|
118
118
|
@channels.synchronize do
|
119
119
|
init_channel(channel)
|
120
120
|
|
121
|
-
|
122
|
-
|
123
|
-
@channels[channel][:modes].delete(
|
121
|
+
modes = @server_config.mode_parser.parse(m)
|
122
|
+
modes[:negative].each do |mode|
|
123
|
+
@channels[channel][:modes].delete(mode)
|
124
124
|
end
|
125
125
|
|
126
|
-
|
127
|
-
@channels[channel][:modes] <<
|
126
|
+
modes[:positive].each do |mode|
|
127
|
+
@channels[channel][:modes] << mode
|
128
128
|
end
|
129
129
|
|
130
130
|
@channels[channel][:modes].uniq!
|
131
|
-
[
|
131
|
+
[modes[:negative], modes[:positive]]
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
data/lib/net/irc/constants.rb
CHANGED
@@ -208,7 +208,7 @@ module Net::IRC::Constants # :nodoc:
|
|
208
208
|
ISON = 'ISON'
|
209
209
|
end
|
210
210
|
|
211
|
-
Net::IRC::COMMANDS = Net::IRC::Constants.constants.inject({}) {|r,i| # :nodoc:
|
212
|
-
r.update(Net::IRC::Constants.const_get(i).to_s => i.to_s)
|
211
|
+
Net::IRC::COMMANDS = Net::IRC::Constants.constants.inject({}) {|r, i| # :nodoc:
|
212
|
+
r.update(Net::IRC::Constants.const_get(i).to_s => i.to_s.freeze)
|
213
213
|
}
|
214
214
|
|
data/lib/net/irc/message.rb
CHANGED
@@ -58,13 +58,10 @@ class Net::IRC::Message
|
|
58
58
|
if @params
|
59
59
|
f = false
|
60
60
|
@params.each do |param|
|
61
|
+
f = !f && (param.empty? || param[0] == ?: || param.include?(" "))
|
61
62
|
str << " "
|
62
|
-
|
63
|
-
|
64
|
-
f = true
|
65
|
-
else
|
66
|
-
str << param
|
67
|
-
end
|
63
|
+
str << ":" if f
|
64
|
+
str << param
|
68
65
|
end
|
69
66
|
end
|
70
67
|
|
@@ -81,12 +78,22 @@ class Net::IRC::Message
|
|
81
78
|
|
82
79
|
# If the message is CTCP, return true.
|
83
80
|
def ctcp?
|
84
|
-
message = @params[1]
|
85
|
-
message[0] == ?\01 && message[
|
81
|
+
#message = @params[1]
|
82
|
+
#message[0] == ?\01 && message[-1] == ?\01
|
83
|
+
/\x01(?>[^\x00\x01\r\n]*)\x01/ === @params[1]
|
84
|
+
end
|
85
|
+
|
86
|
+
def ctcps
|
87
|
+
messages = []
|
88
|
+
@params[1].gsub!(/\x01(?>[^\x00\x01\r\n]*)\x01/) do
|
89
|
+
messages << ctcp_decode($&)
|
90
|
+
""
|
91
|
+
end
|
92
|
+
messages
|
86
93
|
end
|
87
94
|
|
88
95
|
def inspect
|
89
|
-
|
96
|
+
"#<%s:0x%x prefix:%s command:%s params:%s>" % [
|
90
97
|
self.class,
|
91
98
|
self.object_id,
|
92
99
|
@prefix,
|
@@ -97,6 +104,6 @@ class Net::IRC::Message
|
|
97
104
|
|
98
105
|
autoload :ModeParser, "net/irc/message/modeparser"
|
99
106
|
autoload :ServerConfig, "net/irc/message/serverconfig"
|
100
|
-
autoload :ISupportModeParser, "net/irc/message/isupportmodeparser"
|
107
|
+
#autoload :ISupportModeParser, "net/irc/message/isupportmodeparser"
|
101
108
|
end # Message
|
102
109
|
|
@@ -6,7 +6,7 @@ class Net::IRC::Message::ModeParser
|
|
6
6
|
NO_PARAM = 3
|
7
7
|
|
8
8
|
def initialize
|
9
|
-
@modes
|
9
|
+
@modes = {}
|
10
10
|
@op_to_mark_map = {}
|
11
11
|
@mark_to_op_map = {}
|
12
12
|
|
@@ -14,7 +14,7 @@ class Net::IRC::Message::ModeParser
|
|
14
14
|
set(:CHANMODES, 'beIR,k,l,imnpstaqr')
|
15
15
|
set(:PREFIX, '(ov)@+')
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def mark_to_op(mark)
|
19
19
|
mark.empty? ? nil : @mark_to_op_map[mark.to_sym]
|
20
20
|
end
|
@@ -22,7 +22,7 @@ class Net::IRC::Message::ModeParser
|
|
22
22
|
def set(key, value)
|
23
23
|
case key
|
24
24
|
when :PREFIX
|
25
|
-
if value =~
|
25
|
+
if value =~ /\A\(([a-zA-Z]+)\)(.+)\z/
|
26
26
|
@op_to_mark_map = {}
|
27
27
|
key, value = Regexp.last_match[1], Regexp.last_match[2]
|
28
28
|
key.scan(/./).zip(value.scan(/./)) {|pair|
|
@@ -32,7 +32,7 @@ class Net::IRC::Message::ModeParser
|
|
32
32
|
end
|
33
33
|
when :CHANMODES
|
34
34
|
@modes = {}
|
35
|
-
value.split(
|
35
|
+
value.split(",").each_with_index do |s, kind|
|
36
36
|
s.scan(/./).each {|c|
|
37
37
|
@modes[c.to_sym] = kind
|
38
38
|
}
|
@@ -41,7 +41,7 @@ class Net::IRC::Message::ModeParser
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def parse(arg)
|
44
|
-
params = arg.kind_of?(Net::IRC::Message) ? arg.to_a : arg.split(
|
44
|
+
params = arg.kind_of?(Net::IRC::Message) ? arg.to_a : arg.split(" ")
|
45
45
|
params.shift
|
46
46
|
|
47
47
|
ret = {
|
@@ -7,13 +7,13 @@ class Net::IRC::Message::ServerConfig
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def set(arg)
|
10
|
-
params = arg.kind_of?(Net::IRC::Message) ? arg.to_a : arg.split(
|
10
|
+
params = arg.kind_of?(Net::IRC::Message) ? arg.to_a : arg.split(" ")
|
11
11
|
|
12
12
|
params[1..-1].each do |s|
|
13
13
|
case s
|
14
|
-
when
|
14
|
+
when /\A:?are supported by this server\z/
|
15
15
|
# Ignore
|
16
|
-
when
|
16
|
+
when /\A([^=]+)=(.*)\z/
|
17
17
|
key = Regexp.last_match[1].to_sym
|
18
18
|
value = Regexp.last_match[2]
|
19
19
|
@config[key] = value
|
data/lib/net/irc/pattern.rb
CHANGED
@@ -6,7 +6,7 @@ module Net::IRC::PATTERN # :nodoc:
|
|
6
6
|
# special = %x5B-60 / %x7B-7D
|
7
7
|
# ; "[", "]", "\", "`", "_", "^", "{", "|", "}"
|
8
8
|
LETTER = 'A-Za-z'
|
9
|
-
DIGIT = '
|
9
|
+
DIGIT = '0-9'
|
10
10
|
HEXDIGIT = "#{DIGIT}A-Fa-f"
|
11
11
|
SPECIAL = '\x5B-\x60\x7B-\x7D'
|
12
12
|
|
@@ -21,7 +21,7 @@ module Net::IRC::PATTERN # :nodoc:
|
|
21
21
|
SERVERNAME = HOSTNAME
|
22
22
|
|
23
23
|
# nickname = ( letter / special ) *8( letter / digit / special / "-" )
|
24
|
-
#NICKNAME = "[#{LETTER}#{SPECIAL}
|
24
|
+
#NICKNAME = "[#{LETTER}#{SPECIAL}#{DIGIT}_][-#{LETTER}#{DIGIT}#{SPECIAL}]*"
|
25
25
|
NICKNAME = "\\S+" # for multibytes
|
26
26
|
|
27
27
|
# user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )
|