net-irc2 0.0.10

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/examples/lingr.rb ADDED
@@ -0,0 +1,327 @@
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/mixi.rb ADDED
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+ =begin
4
+
5
+
6
+ ## Licence
7
+
8
+ Ruby's by cho45
9
+
10
+ =end
11
+
12
+ $LOAD_PATH << "lib"
13
+ $LOAD_PATH << "../lib"
14
+
15
+ $KCODE = "u" unless defined? ::Encoding # json use this
16
+
17
+ require "rubygems"
18
+ require "json"
19
+ require "net/irc"
20
+ require "mechanize"
21
+
22
+ # Mixi from mixi.vim by ujihisa!
23
+ class Mixi
24
+ def initialize(email, password, mixi_premium = false, image_dir = '~/.vim/mixi_images')
25
+ require 'kconv'
26
+ require 'rubygems'
27
+ require 'mechanize'
28
+
29
+ @image_dir = File.expand_path image_dir
30
+ @email, @password, @mixi_premium =
31
+ email, password, mixi_premium
32
+ end
33
+
34
+ def post(title, body, images)
35
+ @agent = WWW::Mechanize.new
36
+ @agent.user_agent_alias = 'Mac Safari'
37
+ page = @agent.get 'http://mixi.jp/home.pl'
38
+ form = page.forms[0]
39
+ form.email = @email
40
+ form.password = @password
41
+ @agent.submit form
42
+
43
+ page = @agent.get "http://mixi.jp/home.pl"
44
+ #page = @agent.get page.links[18].uri
45
+ page = @agent.get page.links[14].uri
46
+ form = page.forms[1]
47
+ #form = page.forms[(@mixi_premium ? 1 : 0)]
48
+ form.diary_title = title
49
+ form.diary_body = self.class.magic_body(body)
50
+ get_image images
51
+ images[0, 3].each_with_index do |img, i|
52
+ if /darwin/ =~ RUBY_PLATFORM && /\.png$/i =~ img
53
+ imgjpg = '/tmp/mixi-vim-' << File.basename(img).sub(/\.png$/i, '.jpg')
54
+ system "sips -s format jpeg --out #{imgjpg} #{img} > /dev/null 2>&1"
55
+ img = imgjpg
56
+ end
57
+ form.file_uploads[i].file_name = img
58
+ end
59
+ page = @agent.submit form
60
+ page = @agent.submit page.forms[1]
61
+ end
62
+
63
+ def get_latest
64
+ page = @agent.get 'http://mixi.jp/list_diary.pl'
65
+ ["http://mixi.jp/" << page.links[33].uri.to_s.toutf8,
66
+ page.links[33].text.toutf8]
67
+ end
68
+
69
+ def self.magic_body(body)
70
+ body.gsub(/^( )+/) {|i| ' '.toeuc * (i.length/2) }
71
+ end
72
+
73
+ def get_image(images)
74
+ images.each_with_index do |img, i|
75
+ if img =~ %r{^http://}
76
+ path =
77
+ File.join @image_dir, i.to_s + File.extname(img)
78
+ unless File.exist? @image_dir
79
+ Dir.mkdir @image_dir
80
+ else
81
+ Dir.chdir(@image_dir) do
82
+ Dir.entries(@image_dir).
83
+ each {|f| File.unlink f if File.file? f }
84
+ end
85
+ end
86
+ system "wget -O #{path} #{img} > /dev/null 2>&1"
87
+ if File.exist? path and !File.zero? path
88
+ images[i] = path
89
+ else
90
+ images.delete_at i
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ class MixiDiary < Net::IRC::Server::Session
98
+ def server_name
99
+ "mixi"
100
+ end
101
+
102
+ def server_version
103
+ "0.0.0"
104
+ end
105
+
106
+ def main_channel
107
+ "#mixi"
108
+ end
109
+
110
+ def initialize(*args)
111
+ super
112
+ @ua = WWW::Mechanize.new
113
+ end
114
+
115
+ def on_user(m)
116
+ super
117
+ post @prefix, JOIN, main_channel
118
+ post server_name, MODE, main_channel, "+o", @prefix.nick
119
+
120
+ @real, *@opts = @opts.name || @real.split(/\s+/)
121
+ @opts ||= []
122
+
123
+ @mixi = Mixi.new(@real, @pass)
124
+ @cont = []
125
+ end
126
+
127
+ def on_disconnected
128
+ @observer.kill rescue nil
129
+ end
130
+
131
+ def on_privmsg(m)
132
+ super
133
+
134
+ # CTCP にしたほうがよくないか?
135
+ case m[1]
136
+ when "."
137
+ title, *body = *@cont
138
+ @mixi.post ">_<× < #{title}".toeuc, body.join("\n").toeuc, []
139
+ @mixi.get_latest.each do |line|
140
+ post server_name, NOTICE, main_channel, line.chomp
141
+ end
142
+ when "c"
143
+ @cont.clear
144
+ post server_name, NOTICE, main_channel, "cleared."
145
+ when "p"
146
+ @cont.each do |l|
147
+ post server_name, NOTICE, main_channel, l
148
+ end
149
+ post server_name, NOTICE, main_channel, "^^end"
150
+ when "d"
151
+ post server_name, NOTICE, main_channel, "Deleted last line: #{@cont.pop}"
152
+ else
153
+ @cont << m[1]
154
+ if @cont.size == 1
155
+ post server_name, NOTICE, main_channel, "start with title: #{@cont.first}"
156
+ else
157
+ end
158
+ end
159
+ end
160
+
161
+ def on_ctcp(target, message)
162
+ end
163
+
164
+ def on_whois(m)
165
+ end
166
+
167
+ def on_who(m)
168
+ end
169
+
170
+ def on_join(m)
171
+ end
172
+
173
+ def on_part(m)
174
+ end
175
+ end
176
+
177
+ if __FILE__ == $0
178
+ require "optparse"
179
+
180
+ opts = {
181
+ :port => 16701,
182
+ :host => "localhost",
183
+ :log => nil,
184
+ :debug => false,
185
+ :foreground => false,
186
+ }
187
+
188
+ OptionParser.new do |parser|
189
+ parser.instance_eval do
190
+ self.banner = <<-EOB.gsub(/^\t+/, "")
191
+ Usage: #{$0} [opts]
192
+
193
+ EOB
194
+
195
+ separator ""
196
+
197
+ separator "Options:"
198
+ on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
199
+ opts[:port] = port
200
+ end
201
+
202
+ on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
203
+ opts[:host] = host
204
+ end
205
+
206
+ on("-l", "--log LOG", "log file") do |log|
207
+ opts[:log] = log
208
+ end
209
+
210
+ on("--debug", "Enable debug mode") do |debug|
211
+ opts[:log] = $stdout
212
+ opts[:debug] = true
213
+ end
214
+
215
+ on("-f", "--foreground", "run foreground") do |foreground|
216
+ opts[:log] = $stdout
217
+ opts[:foreground] = true
218
+ end
219
+
220
+ parse!(ARGV)
221
+ end
222
+ end
223
+
224
+ opts[:logger] = Logger.new(opts[:log], "daily")
225
+ opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
226
+
227
+ def daemonize(foreground=false)
228
+ trap("SIGINT") { exit! 0 }
229
+ trap("SIGTERM") { exit! 0 }
230
+ trap("SIGHUP") { exit! 0 }
231
+ return yield if $DEBUG || foreground
232
+ Process.fork do
233
+ Process.setsid
234
+ Dir.chdir "/"
235
+ File.open("/dev/null") {|f|
236
+ STDIN.reopen f
237
+ STDOUT.reopen f
238
+ STDERR.reopen f
239
+ }
240
+ yield
241
+ end
242
+ exit! 0
243
+ end
244
+
245
+ daemonize(opts[:debug] || opts[:foreground]) do
246
+ Net::IRC::Server.new(opts[:host], opts[:port], MixiDiary, opts).start
247
+ end
248
+ end
249
+
250
+ # Local Variables:
251
+ # coding: utf-8
252
+ # End: