Created
September 15, 2009 01:41
-
-
Save sorah/187057 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-*- coding: utf-8 -*- | |
=begin | |
lingr.rb | |
Author:: Sora Harakami <sora134@gmail.com> | |
License:: MIT License (X11 License) | |
http://soralabo.net/ | |
http://codnote.net/ | |
======================== | |
this code is imported WebAPI::JsonParser. | |
JsonParser http://rubyforge.org/snippet/detail.php?type=snippet&id=148 | |
JsonParser license is public-domain. | |
=end | |
require "net/http" | |
require "thread" | |
require 'strscan' | |
require 'time' | |
class Lingr | |
def initialize(params = {}) | |
@debug = false | |
@cookie_key = "__lingr" | |
@params = params | |
@session = Lingr::Session.new(self) | |
@c_error = 0 | |
@session_id = nil | |
@nickname = nil | |
@public_session_id = nil | |
@counter = nil | |
@booting = false | |
@booted = false | |
@local_say_count = 0 | |
@events = Lingr::Event.new(self) | |
@room = Lingr::Room.new(self) | |
@user = Lingr::User.new(self) | |
end | |
def boot | |
@booting = true | |
puts "debug: booting..." if @debug | |
puts "debug: session start" if @debug | |
e_session_cv = lambda{|e,l| | |
if l.booting | |
puts "debug: get rooms" if @debug | |
l.user.get_rooms | |
end | |
} | |
@events.register('session_created','boot',e_session_cv) | |
@events.register('session_verified','boot',e_session_cv) | |
@events.register('get_rooms_complete','boot',lambda{|e,l| | |
if l.booting | |
puts "debug: room show" if @debug | |
l.room.show(l.user.rooms.join(',')) | |
end | |
}) | |
@events.register('room_show_complete','boot',lambda{|e,l| | |
if l.booting | |
puts "debug: unsubscribe" if @debug | |
l.room.unsubscribe(l.user.rooms.join(','),true) | |
end | |
}) | |
@events.register('unsubscribe_complete','boot',lambda{|e,l| | |
if l.booting | |
puts "debug: unsubscribe complete" if @debug | |
puts "debug: subscribe" if @debug | |
l.room.subscribe(l.user.rooms.join(',')) | |
end | |
}) | |
@events.register('subscribe_complete','boot',lambda{|e,l| | |
if l.booting | |
puts "debug: observe start" if @debug | |
l.booting = false | |
l.booted = true | |
l.events.add('boot_complete') | |
puts "debug: booted!" if @debug | |
l.room.observe | |
end | |
}) | |
puts "debug: event added" if @debug | |
@session.start() | |
end | |
def shutdown | |
puts "debug: shutdown going now.." | |
@session.end() | |
puts "debug: shutdowned." | |
@booted = false | |
@events.add('shutdown_complete') | |
end | |
def rooms | |
return nil unless @booted | |
return @user.rooms | |
end | |
def say(room_id,text) | |
@room.say(room_id,text,nil,@local_say_count) | |
@local_say_count += 1 | |
end | |
def request(path, params = {}, options = {}) | |
Thread.new do | |
puts "debug: request begin" if @debug | |
options["success"] ||= lambda{|json,lingr|} | |
options["failure"] ||= lambda{|json,lingr|} | |
options["complete"] ||= lambda{|json,lingr|} | |
options["observe"] ||= false | |
params["callback"] = "foo" | |
req = Net::HTTP::Get.new("/api"+path+"?"+params.map{|k,v| "#{k}=#{v}" }.join("&")) | |
unless @session_id.nil? | |
req['Cookie'] = @cookie_key+"="+@session_id | |
end | |
if options["observe"] | |
n_http = Net::HTTP.new("lingr.com",8080) | |
else | |
n_http = Net::HTTP.new("lingr.com") | |
end | |
puts "debug: "+req.path if @debug | |
i = 0 | |
begin | |
n_http.request(req) do |h| | |
puts "debug: requested" if @debug | |
raw_json = h.body.gsub(/foo\(/,"").gsub(/\)/,"") | |
json = WebAPI::JsonParser.new.parse(raw_json) | |
if json["status"] == 'ok' | |
puts "debug: request call success" if @debug | |
t = Thread.new {options["success"].call(json,self)} | |
else | |
puts "debug: request call failure" if @debug | |
t = Thread.new {options["failure"].call(json,self)} | |
end | |
puts "debug: request call complete" if @debug | |
Thread.new {options["complete"].call(json,self)}.join | |
t.join | |
puts "debug: request complete" if @debug | |
Thread.exit | |
end | |
rescue EOFError => e | |
i += 1 | |
puts "debug: request rescue (#{i.to_s}) (#{req.path})" if @debug | |
puts "debug: reconnect" if @debug | |
n_http.finish | |
n_http.start | |
puts "debug: retry request" if @debug | |
retry | |
end | |
end.join | |
end | |
class Event | |
def initialize(lingr) | |
@lingr = lingr | |
@event_ary = [] | |
@registers = {} | |
end | |
def add(name,data = nil) | |
puts "debug: added #{name} event" if @lingr.debug | |
@event_ary << [name,data] | |
put_event() | |
end | |
def register(ev,n,l,s=nil) | |
puts "debug: registered event capture #{ev} #{n}" if @lingr.debug | |
@registers[ev] ||= [] | |
if @registers[ev].map{|x|x[0]}.index(n).nil? | |
@registers[ev] << [n,l,s] | |
end | |
end | |
def release(ev,n) | |
@registers[ev].reject!{|p| | |
p[0] == n | |
} | |
end | |
private | |
def recieve() | |
@event_ary.shift | |
end | |
def put_event() | |
puts "debug: put_event" if @lingr.debug | |
threads = [] | |
while @event_ary.length > 0 | |
tmp = recieve | |
puts "debug: put_event loop" if @lingr.debug | |
@registers[tmp[0]] ||= [] | |
print "debug: " if @lingr.debug | |
p @registers[tmp[0]] if @lingr.debug | |
@registers[tmp[0]].each do |e| | |
puts "debug: put event" if @lingr.debug | |
print "debug: " if @lingr.debug | |
p e if @lingr.debug | |
threads << Thread.new do | |
if e[2].nil? | |
puts "debug: call lambda" if @lingr.debug | |
e[1].call(tmp[1],@lingr) | |
else | |
puts "debug: call lambda with self" if @lingr.debug | |
e[1].call(tmp[1],e[2],@lingr) | |
end | |
end | |
end | |
end | |
threads.each{|t|t.join} | |
end | |
end | |
class Room | |
def initialize(lingr) | |
@lingr = lingr | |
end | |
def show(room_id) | |
@lingr.request('/room/show',{ | |
"session" => @lingr.session_id, | |
"room" => room_id | |
},{ | |
"success" => lambda{|json,lingr| | |
lingr.events.add('room_show_complete',json) | |
}, | |
"failure" => lambda{|json,lingr| | |
lingr.events.add('api_failure',json) | |
} | |
}) | |
end | |
def subscribe(room_id) | |
puts "debug: called subscribe #{room_id}" if @lingr.debug | |
@lingr.request('/room/subscribe',{ | |
"session" => @lingr.session_id, | |
"room" => room_id | |
},{ | |
"success" => lambda{|json,lingr| | |
@lingr.counter = json["counter"] | |
@lingr.events.add('subscribe_complete',json) | |
}, | |
"failure" => lambda{|json,lingr| | |
@lingr.events.add('api_failure',json) | |
} | |
}) | |
end | |
def unsubscribe(room_id,n=nil) | |
puts "debug: called unsubscribe #{room_id}" if @lingr.debug | |
params = { | |
"session" => @lingr.session_id, | |
"room" => room_id | |
} | |
params["not"] = n unless n.nil? | |
@lingr.request('/room/unsubscribe', params, { | |
"success" => lambda{|json,lingr| | |
@lingr.counter = json["counter"] | |
@lingr.events.add('unsubscribe_complete',json) | |
}, | |
"failure" => lambda{|json,lingr| | |
@lingr.events.add('api_failure',json) | |
} | |
}) | |
end | |
def say(room_id,text,nickname=nil,local_echo_count) | |
nickname = @lingr.nickname if nickname.nil? | |
@lingr.request('/room/say',{ | |
"session" => @lingr.session_id, | |
"room" => room_id, | |
"nickname" => nickname, | |
"text" => text, | |
"local_id" => local_echo_count | |
}, { | |
"success" => lambda{|json,lingr| | |
@lingr.events.add('say_complete',json) | |
}, | |
"failure" => lambda{|json,lingr| | |
@lingr.events.add('api_failure',json) | |
} | |
}) | |
end | |
def observe | |
@lingr.request('/event/observe', { | |
"session" => @lingr.session_id, | |
"counter" => @lingr.counter | |
}, { | |
"observe" => true, | |
"success" => lambda{|json,lingr| | |
@lingr.counter = [json["counter"],@lingr.counter].max unless json["counter"].nil? | |
@lingr.events.add('observe_complete', json) | |
@lingr.c_error = 0 | |
unless json["events"].nil? | |
ary = [] | |
json["events"].each do |m| | |
unless m["message"].nil? | |
tmp = Message.new( | |
:timestamp => Time.parse(m["message"]["timestamp"]), | |
:icon_url => m["message"]["icon_url"], | |
:nickname => m["message"]["nickname"], | |
:text => m["message"]["text"], | |
:username => m["message"]["speaker_id"] | |
) | |
ary << tmp | |
end | |
end | |
@lingr.events.add('new_message',ary) if ary.length > 0 | |
ary2 = [] | |
json["events"].each do |m| | |
if m["message"].nil? | |
n = m["offline"] if m["online"].nil? | |
n = m["online"] if m["offline"].nil? | |
tmp = Message.new( | |
:timestamp => Time.parse(n["timestamp"]), | |
:icon_url => n["icon_url"], | |
:nickname => n["nickname"], | |
:username |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment