Skip to content

Instantly share code, notes, and snippets.

@sorah
Created September 15, 2009 01:41
Show Gist options
  • Save sorah/187057 to your computer and use it in GitHub Desktop.
Save sorah/187057 to your computer and use it in GitHub Desktop.
#-*- 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