net-irc 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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/lingr.rb
DELETED
@@ -1,327 +0,0 @@
|
|
1
|
-
# Ruby client for the Lingr[http://www.lingr.com] API. For more details and tutorials, see the
|
2
|
-
# {Lingr API Reference}[http://wiki.lingr.com/dev/show/API+Reference] pages on the {Lingr Developer Wiki}[http://wiki.lingr.com].
|
3
|
-
#
|
4
|
-
# All methods return a hash with two keys:
|
5
|
-
# * :succeeded - <tt>true</tt> if the method succeeded, <tt>false</tt> otherwise
|
6
|
-
# * :response - a Hash version of the response document received from the server
|
7
|
-
#
|
8
|
-
# = api_client.rb
|
9
|
-
#
|
10
|
-
# Lingr API client
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# Original written by Lingr.
|
14
|
-
# Modified by cho45 <cho45@lowreal.net>
|
15
|
-
# * Use json gem instead of gsub/eval.
|
16
|
-
# * Raise APIError when api fails.
|
17
|
-
# * Rename class name to Lingr::Client.
|
18
|
-
|
19
|
-
$KCODE = 'u' # used by json
|
20
|
-
require "rubygems"
|
21
|
-
require "net/http"
|
22
|
-
require "json"
|
23
|
-
require "uri"
|
24
|
-
require "timeout"
|
25
|
-
|
26
|
-
module Lingr
|
27
|
-
class Client
|
28
|
-
class ClientError < StandardError; end
|
29
|
-
class APIError < ClientError
|
30
|
-
def initialize(error)
|
31
|
-
@error = error || {
|
32
|
-
"message" => "socket error",
|
33
|
-
"code" => 0,
|
34
|
-
}
|
35
|
-
super(@error["message"])
|
36
|
-
end
|
37
|
-
|
38
|
-
def code
|
39
|
-
@error["code"]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
attr_accessor :api_key
|
44
|
-
# 0 = quiet, 1 = some debug info, 2 = more debug info
|
45
|
-
attr_accessor :verbosity
|
46
|
-
attr_accessor :session
|
47
|
-
attr_accessor :timeout
|
48
|
-
|
49
|
-
def initialize(api_key, verbosity=0, hostname='www.lingr.com')
|
50
|
-
@api_key = api_key
|
51
|
-
@host = hostname
|
52
|
-
@verbosity = verbosity
|
53
|
-
@timeout = 60
|
54
|
-
end
|
55
|
-
|
56
|
-
# Create a new API session
|
57
|
-
#
|
58
|
-
def create_session(client_type='automaton')
|
59
|
-
if @session
|
60
|
-
@error_info = nil
|
61
|
-
raise ClientError, "already in a session"
|
62
|
-
end
|
63
|
-
|
64
|
-
ret = do_api :post, 'session/create', { :api_key => @api_key, :client_type => client_type }, false
|
65
|
-
@session = ret["session"]
|
66
|
-
ret
|
67
|
-
end
|
68
|
-
|
69
|
-
# Verify a session id. If no session id is passed, verifies the current session id for this ApiClient
|
70
|
-
#
|
71
|
-
def verify_session(session_id=nil)
|
72
|
-
do_api :get, 'session/verify', { :session => session_id || @session }, false
|
73
|
-
end
|
74
|
-
|
75
|
-
# Destroy the current API session
|
76
|
-
#
|
77
|
-
def destroy_session
|
78
|
-
ret = do_api :post, 'session/destroy', { :session => @session }
|
79
|
-
@session = nil
|
80
|
-
ret
|
81
|
-
end
|
82
|
-
|
83
|
-
# Get a list of the currently hot rooms
|
84
|
-
#
|
85
|
-
def get_hot_rooms(count=nil)
|
86
|
-
do_api :get, 'explore/get_hot_rooms', { :api_key => @api_key }.merge(count ? { :count => count} : {}), false
|
87
|
-
end
|
88
|
-
|
89
|
-
# Get a list of the newest rooms
|
90
|
-
#
|
91
|
-
def get_new_rooms(count=nil)
|
92
|
-
do_api :get, 'explore/get_new_rooms', { :api_key => @api_key }.merge(count ? { :count => count} : {}), false
|
93
|
-
end
|
94
|
-
|
95
|
-
# Get a list of the currently hot tags
|
96
|
-
#
|
97
|
-
def get_hot_tags(count=nil)
|
98
|
-
do_api :get, 'explore/get_hot_tags', { :api_key => @api_key }.merge(count ? { :count => count} : {}), false
|
99
|
-
end
|
100
|
-
|
101
|
-
# Get a list of all tags
|
102
|
-
#
|
103
|
-
def get_all_tags(count=nil)
|
104
|
-
do_api :get, 'explore/get_all_tags', { :api_key => @api_key }.merge(count ? { :count => count} : {}), false
|
105
|
-
end
|
106
|
-
|
107
|
-
# Search room name, description, and tags for keywords. Keywords can be a String or an Array.
|
108
|
-
#
|
109
|
-
def search(keywords)
|
110
|
-
do_api :get, 'explore/search', { :api_key => @api_key, :q => keywords.is_a?(Array) ? keywords.join(',') : keywords }, false
|
111
|
-
end
|
112
|
-
|
113
|
-
# Search room tags. Tagnames can be a String or an Array.
|
114
|
-
#
|
115
|
-
def search_tags(tagnames)
|
116
|
-
do_api :get, 'explore/search_tags', { :api_key => @api_key, :q => tagnames.is_a?(Array) ? tagnames.join(',') : tagnames }, false
|
117
|
-
end
|
118
|
-
|
119
|
-
# Search archives. If room_id is non-nil, the search is limited to the archives of that room.
|
120
|
-
#
|
121
|
-
def search_archives(query, room_id=nil)
|
122
|
-
params = { :api_key => @api_key, :q => query }
|
123
|
-
params.merge!({ :id => room_id }) if room_id
|
124
|
-
do_api :get, 'explore/search_archives', params, false
|
125
|
-
end
|
126
|
-
|
127
|
-
# Authenticate a user within the current API session
|
128
|
-
#
|
129
|
-
def login(email, password)
|
130
|
-
do_api :post, 'auth/login', { :session => @session, :email => email, :password => password }
|
131
|
-
end
|
132
|
-
|
133
|
-
# Log out the currently-authenticated user in the session, if any
|
134
|
-
#
|
135
|
-
def logout
|
136
|
-
do_api :post, 'auth/logout', { :session => @session }
|
137
|
-
end
|
138
|
-
|
139
|
-
# Get information about the currently-authenticated user
|
140
|
-
#
|
141
|
-
def get_user_info
|
142
|
-
do_api :get, 'user/get_info', { :session => @session }
|
143
|
-
end
|
144
|
-
|
145
|
-
# Start observing the currently-authenticated user
|
146
|
-
#
|
147
|
-
def start_observing_user
|
148
|
-
do_api :post, 'user/start_observing', { :session => @session }
|
149
|
-
end
|
150
|
-
|
151
|
-
# Observe the currently-authenticated user, watching for profile changes
|
152
|
-
#
|
153
|
-
def observe_user(ticket, counter)
|
154
|
-
do_api :get, 'user/observe', { :session => @session, :ticket => ticket, :counter => counter }
|
155
|
-
end
|
156
|
-
|
157
|
-
# Stop observing the currently-authenticated user
|
158
|
-
#
|
159
|
-
def stop_observing_user(ticket)
|
160
|
-
do_api :post, 'user/stop_observing', { :session => @session, :ticket =>ticket }
|
161
|
-
end
|
162
|
-
|
163
|
-
# Get information about a chatroom, including room description, current occupants, recent messages, etc.
|
164
|
-
#
|
165
|
-
def get_room_info(room_id, counter=nil, password=nil)
|
166
|
-
params = { :api_key => @api_key, :id => room_id }
|
167
|
-
params.merge!({ :counter => counter }) if counter
|
168
|
-
params.merge!({ :password => password }) if password
|
169
|
-
do_api :get, 'room/get_info', params, false
|
170
|
-
end
|
171
|
-
|
172
|
-
# Create a chatroom
|
173
|
-
#
|
174
|
-
# options is a Hash containing any of the parameters allowed for room.create. If the :image key is present
|
175
|
-
# in options, its value must be a hash with the keys :filename, :mime_type, and :io
|
176
|
-
#
|
177
|
-
def create_room(options)
|
178
|
-
do_api :post, 'room/create', options.merge({ :session => @session })
|
179
|
-
end
|
180
|
-
|
181
|
-
# Change the settings for a chatroom
|
182
|
-
#
|
183
|
-
# options is a Hash containing any of the parameters allowed for room.create. If the :image key is present
|
184
|
-
# in options, its value must be a hash with the keys :filename, :mime_type, and :io. To change the id for
|
185
|
-
# a room, use the key :new_id
|
186
|
-
#
|
187
|
-
def change_settings(room_id, options)
|
188
|
-
do_api :post, 'room/change_settings', options.merge({ :session => @session })
|
189
|
-
end
|
190
|
-
|
191
|
-
# Delete a chatroom
|
192
|
-
#
|
193
|
-
def delete_room(room_id)
|
194
|
-
do_api :post, 'room/delete', { :id => room_id, :session => @session }
|
195
|
-
end
|
196
|
-
|
197
|
-
# Enter a chatroom
|
198
|
-
#
|
199
|
-
def enter_room(room_id, nickname=nil, password=nil, idempotent=false)
|
200
|
-
params = { :session => @session, :id => room_id }
|
201
|
-
params.merge!({ :nickname => nickname }) if nickname
|
202
|
-
params.merge!({ :password => password }) if password
|
203
|
-
params.merge!({ :idempotent => 'true' }) if idempotent
|
204
|
-
do_api :post, 'room/enter', params
|
205
|
-
end
|
206
|
-
|
207
|
-
# Poll for messages in a chatroom
|
208
|
-
#
|
209
|
-
def get_messages(ticket, counter, user_messages_only=false)
|
210
|
-
do_api :get, 'room/get_messages', { :session => @session, :ticket => ticket, :counter => counter, :user_messages_only => user_messages_only }
|
211
|
-
end
|
212
|
-
|
213
|
-
# Observe a chatroom, waiting for events to occur in the room
|
214
|
-
#
|
215
|
-
def observe_room(ticket, counter)
|
216
|
-
do_api :get, 'room/observe', { :session => @session, :ticket => ticket, :counter => counter }
|
217
|
-
end
|
218
|
-
|
219
|
-
# Set your nickname in a chatroom
|
220
|
-
#
|
221
|
-
def set_nickname(ticket, nickname)
|
222
|
-
do_api :post, 'room/set_nickname', { :session => @session, :ticket => ticket, :nickname => nickname }
|
223
|
-
end
|
224
|
-
|
225
|
-
# Say something in a chatroom. If target_occupant_id is not nil, a private message
|
226
|
-
# is sent to the indicated occupant.
|
227
|
-
#
|
228
|
-
def say(ticket, msg, target_occupant_id = nil)
|
229
|
-
params = { :session => @session, :ticket => ticket, :message => msg }
|
230
|
-
params.merge!({ :occupant_id => target_occupant_id}) if target_occupant_id
|
231
|
-
do_api :post, 'room/say', params
|
232
|
-
end
|
233
|
-
|
234
|
-
# Exit a chatroom
|
235
|
-
#
|
236
|
-
def exit_room(ticket)
|
237
|
-
do_api :post, 'room/exit', { :session => @session, :ticket => ticket }
|
238
|
-
end
|
239
|
-
|
240
|
-
private
|
241
|
-
|
242
|
-
def do_api(method, path, parameters, require_session=true)
|
243
|
-
if require_session and !@session
|
244
|
-
raise ClientError, "not in a session"
|
245
|
-
end
|
246
|
-
|
247
|
-
response = Timeout.timeout(@timeout) {
|
248
|
-
JSON.parse(self.send(method, url_for(path), parameters.merge({ :format => 'json' })))
|
249
|
-
}
|
250
|
-
|
251
|
-
unless success?(response)
|
252
|
-
raise APIError, response["error"]
|
253
|
-
end
|
254
|
-
|
255
|
-
response
|
256
|
-
end
|
257
|
-
|
258
|
-
def url_for(method)
|
259
|
-
"http://#{@host}/#{@@PATH_BASE}#{method}"
|
260
|
-
end
|
261
|
-
|
262
|
-
def get(url, params)
|
263
|
-
uri = URI.parse(url)
|
264
|
-
path = uri.path
|
265
|
-
q = params.inject("?") {|s, p| s << "#{p[0].to_s}=#{URI.encode(p[1].to_s, /./)}&"}.chop
|
266
|
-
path << q if q.length > 0
|
267
|
-
|
268
|
-
Net::HTTP.start(uri.host, uri.port) do |http|
|
269
|
-
http.read_timeout = @timeout
|
270
|
-
req = Net::HTTP::Get.new(path)
|
271
|
-
req.basic_auth(uri.user, uri.password) if uri.user
|
272
|
-
parse_result http.request(req)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
def post(url, params)
|
277
|
-
if !params.find {|p| p[1].is_a?(Hash)}
|
278
|
-
params = params.inject({}){|hash,(k,v)| hash[k.to_s] = v; hash}
|
279
|
-
parse_result Net::HTTP.post_form(URI.parse(url), params)
|
280
|
-
else
|
281
|
-
boundary = 'lingr-api-client' + (0x1000000 + rand(0x1000000).to_s(16))
|
282
|
-
|
283
|
-
query = params.collect { |p|
|
284
|
-
ret = ["--#{boundary}"]
|
285
|
-
|
286
|
-
if p[1].is_a?(Hash)
|
287
|
-
ret << "Content-Disposition: form-data; name=\"#{URI.encode(p[0].to_s)}\"; filename=\"#{p[1][:filename]}\""
|
288
|
-
ret << "Content-Transfer-Encoding: binary"
|
289
|
-
ret << "Content-Type: #{p[1][:mime_type]}"
|
290
|
-
ret << ""
|
291
|
-
ret << p[1][:io].read
|
292
|
-
else
|
293
|
-
ret << "Content-Disposition: form-data; name=\"#{URI.encode(p[0].to_s)}\""
|
294
|
-
ret << ""
|
295
|
-
ret << p[1]
|
296
|
-
end
|
297
|
-
|
298
|
-
ret.join("\r\n")
|
299
|
-
}.join('') + "--#{boundary}--\r\n"
|
300
|
-
|
301
|
-
uri = URI.parse(url)
|
302
|
-
Net::HTTP.start(uri.host, uri.port) do |http|
|
303
|
-
http.read_timeout = @timeout
|
304
|
-
parse_result http.post2(uri.path, query, "Content-Type" => "multipart/form-data; boundary=#{boundary}")
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
def parse_result(result)
|
310
|
-
return nil if !result || result.code != '200' || (!result['Content-Type'] || result['Content-Type'].index('text/javascript') != 0)
|
311
|
-
# puts
|
312
|
-
# puts
|
313
|
-
# puts result.body
|
314
|
-
# puts
|
315
|
-
# puts
|
316
|
-
result.body
|
317
|
-
end
|
318
|
-
|
319
|
-
def success?(response)
|
320
|
-
return false if !response
|
321
|
-
response["status"] and response["status"] == 'ok'
|
322
|
-
end
|
323
|
-
|
324
|
-
|
325
|
-
@@PATH_BASE = 'api/'
|
326
|
-
end
|
327
|
-
end
|
data/examples/nig.rb
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
=begin
|
3
|
-
|
4
|
-
# nig.rb
|
5
|
-
|
6
|
-
nowa IRC Gateway
|
7
|
-
|
8
|
-
## Launch
|
9
|
-
|
10
|
-
$ ruby nig.rb # daemonized
|
11
|
-
|
12
|
-
If you want to help:
|
13
|
-
|
14
|
-
$ ruby nig.rb --help
|
15
|
-
|
16
|
-
## Configuration
|
17
|
-
|
18
|
-
Options specified by after irc realname.
|
19
|
-
|
20
|
-
Configuration example for Tiarra ( http://coderepos.org/share/wiki/Tiarra ).
|
21
|
-
|
22
|
-
nowa {
|
23
|
-
host: localhost
|
24
|
-
port: 16671
|
25
|
-
name: username@example.com athack
|
26
|
-
password: password on nowa
|
27
|
-
in-encoding: utf8
|
28
|
-
out-encoding: utf8
|
29
|
-
}
|
30
|
-
|
31
|
-
### athack
|
32
|
-
|
33
|
-
If `athack` client option specified,
|
34
|
-
all nick in join message is leading with @.
|
35
|
-
|
36
|
-
So if you complemente nicks (ex. Irssi),
|
37
|
-
it's good for twitter like reply command (@nick).
|
38
|
-
|
39
|
-
In this case, you will see torrent of join messages after connected,
|
40
|
-
because NAMES list can't send @ leading nick (it interpreted op.)
|
41
|
-
|
42
|
-
## Licence
|
43
|
-
|
44
|
-
Ruby's by cho45
|
45
|
-
|
46
|
-
=end
|
47
|
-
|
48
|
-
$LOAD_PATH << File.dirname(__FILE__)
|
49
|
-
|
50
|
-
require "tig.rb"
|
51
|
-
|
52
|
-
class NowaIrcGateway < TwitterIrcGateway
|
53
|
-
def server_name
|
54
|
-
"nowagw"
|
55
|
-
end
|
56
|
-
|
57
|
-
def server_version
|
58
|
-
"0.0.0"
|
59
|
-
end
|
60
|
-
|
61
|
-
def main_channel
|
62
|
-
"#nowa"
|
63
|
-
end
|
64
|
-
|
65
|
-
def api_base
|
66
|
-
URI("https://api.nowa.jp:443/")
|
67
|
-
end
|
68
|
-
|
69
|
-
def api_source
|
70
|
-
"nig.rb"
|
71
|
-
end
|
72
|
-
|
73
|
-
def jabber_bot_id
|
74
|
-
nil
|
75
|
-
end
|
76
|
-
|
77
|
-
def hourly_limit
|
78
|
-
30
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
if __FILE__ == $0
|
83
|
-
require "optparse"
|
84
|
-
|
85
|
-
opts = {
|
86
|
-
:port => 16671,
|
87
|
-
:host => "localhost",
|
88
|
-
:log => nil,
|
89
|
-
:debug => false,
|
90
|
-
:foreground => false,
|
91
|
-
}
|
92
|
-
|
93
|
-
OptionParser.new do |parser|
|
94
|
-
parser.instance_eval do
|
95
|
-
self.banner = <<-EOB.gsub(/^\t+/, "")
|
96
|
-
Usage: #{$0} [opts]
|
97
|
-
|
98
|
-
EOB
|
99
|
-
|
100
|
-
separator ""
|
101
|
-
|
102
|
-
separator "Options:"
|
103
|
-
on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
|
104
|
-
opts[:port] = port
|
105
|
-
end
|
106
|
-
|
107
|
-
on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
|
108
|
-
opts[:host] = host
|
109
|
-
end
|
110
|
-
|
111
|
-
on("-l", "--log LOG", "log file") do |log|
|
112
|
-
opts[:log] = log
|
113
|
-
end
|
114
|
-
|
115
|
-
on("--debug", "Enable debug mode") do |debug|
|
116
|
-
opts[:log] = $stdout
|
117
|
-
opts[:debug] = true
|
118
|
-
end
|
119
|
-
|
120
|
-
on("-f", "--foreground", "run foreground") do |foreground|
|
121
|
-
opts[:log] = $stdout
|
122
|
-
opts[:foreground] = true
|
123
|
-
end
|
124
|
-
|
125
|
-
parse!(ARGV)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
opts[:logger] = Logger.new(opts[:log], "daily")
|
130
|
-
opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
|
131
|
-
|
132
|
-
def daemonize(foreground=false)
|
133
|
-
trap("SIGINT") { exit! 0 }
|
134
|
-
trap("SIGTERM") { exit! 0 }
|
135
|
-
trap("SIGHUP") { exit! 0 }
|
136
|
-
return yield if $DEBUG || foreground
|
137
|
-
Process.fork do
|
138
|
-
Process.setsid
|
139
|
-
Dir.chdir "/"
|
140
|
-
File.open("/dev/null") {|f|
|
141
|
-
STDIN.reopen f
|
142
|
-
STDOUT.reopen f
|
143
|
-
STDERR.reopen f
|
144
|
-
}
|
145
|
-
yield
|
146
|
-
end
|
147
|
-
exit! 0
|
148
|
-
end
|
149
|
-
|
150
|
-
daemonize(opts[:debug] || opts[:foreground]) do
|
151
|
-
Net::IRC::Server.new(opts[:host], opts[:port], NowaIrcGateway, opts).start
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|