talker 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -27,8 +27,8 @@ A real-time Talker Ruby client.
27
27
  # Callbacks
28
28
  All arguments are optional.
29
29
 
30
- ## <code>on_connected</code>
31
- Called when the user is authenticated and ready to receive events.
30
+ ## <code>on_connected(user)</code>
31
+ Called when the user is authenticated and ready to receive events. "user" is a Hash containing your user info: <code>{"id"=>1, "name"=>"macournoyer", "email"=>"macournoyer@talkerapp.com"}</code>.
32
32
 
33
33
  ## <code>on_presence(users)</code>
34
34
  Called after <code>on_connected</code> with the list of connected users.
@@ -37,9 +37,13 @@ With <code>users</code> being something like this:
37
37
  [{"id"=>1, "name"=>"macournoyer", "email"=>"macournoyer@talkerapp.com"},
38
38
  {"id"=>2, "name"=>"gary", "email"=>"gary@talkerapp.com"}]
39
39
 
40
- ## <code>on_message(user, message, event)</code>
40
+ ## <code>on_message(user, message)</code>
41
41
  Called when a new message is received.
42
- <code>user</code> is the sender. <code>event</code> contains the full event sent by the server.
42
+ <code>user</code> is the sender.
43
+
44
+ ## <code>on_private_message(user, message)</code>
45
+ Called when a new private message is received.
46
+ <code>user</code> is the sender.
43
47
 
44
48
  ## <code>on_join(user)</code>
45
49
  Called when a user joins the room.
@@ -57,11 +61,19 @@ Called when a user leaves.
57
61
  Called when the connection is closed.
58
62
 
59
63
  ## <code>on_error(error_message)</code>
60
- Called an error is received from the Talker server.
64
+ Called when an error is received from the Talker server.
65
+
66
+ ## <code>on_event(event)</code>
67
+ Called when any kind of event (all of the above) is received. "event" is a Hash: <code>{"type":"event type","id":"unique ID",... event specific attributes}</code>.
61
68
 
62
69
  # Methods
63
70
  Methods of an instance of Talker class.
64
71
 
72
+ ## <code>current_user</code>
73
+ Info about the user currently connected, <code>nil</code> if not yet connected:
74
+
75
+ {"id"=>1, "name"=>"macournoyer", "email"=>"macournoyer@talkerapp.com"}
76
+
65
77
  ## <code>users</code>
66
78
  Array of users currently in the room. In the form:
67
79
 
data/bin/talker-cat CHANGED
@@ -21,12 +21,29 @@ usage: echo 'something' | talker-cat <room_id>
21
21
 
22
22
  EOS
23
23
 
24
- Talker.connect(:room => room, :token => token) do |client|
24
+ # Non-blocking reader for stdin
25
+ module Reader
26
+ attr_accessor :client
27
+
28
+ def notify_readable
29
+ @client.send_message @io.readline.chomp
30
+ rescue EOFError
31
+ detach
32
+ end
33
+
34
+ def unbind
35
+ @client.close
36
+ end
37
+ end
38
+
39
+ Talker.connect(:room => room.to_i, :token => token) do |client|
25
40
  client.on_connected do
26
- client.send_message STDIN.read
27
- client.close
41
+ conn = EM.watch STDIN, Reader
42
+ conn.client = client
43
+ conn.notify_readable = true
28
44
  end
29
45
  client.on_error do |error|
30
46
  puts error
31
47
  end
48
+ trap("INT") { client.close }
32
49
  end
data/bin/talker-shell CHANGED
@@ -22,7 +22,7 @@ module Process
22
22
  attr_accessor :name, :client
23
23
 
24
24
  def receive_data(data)
25
- log data
25
+ log data.chomp
26
26
  end
27
27
 
28
28
  def unbind
@@ -38,7 +38,7 @@ end
38
38
 
39
39
 
40
40
  EM.run do
41
- Talker.connect(:room => room, :token => token) do |client|
41
+ Talker.connect(:room => room.to_i, :token => token) do |client|
42
42
  @process = nil
43
43
 
44
44
  client.on_connected do
data/lib/talker.rb CHANGED
@@ -2,26 +2,27 @@ require "eventmachine"
2
2
  require "yajl"
3
3
 
4
4
  class Talker < EM::Connection
5
+ CALLBACKS = %w( connected message private_message join idle back leave presence error close event )
6
+
5
7
  class Error < RuntimeError; end
6
8
 
7
- attr_accessor :room, :token, :thread
9
+ attr_accessor :connect_options, :thread, :current_user
8
10
 
9
11
  def self.connect(options={})
10
- host = options[:host] || "talkerapp.com"
11
- port = (options[:port] || 8500).to_i
12
- room = options[:room].to_i
13
- token = options[:token]
14
-
12
+ host = options.delete(:host) || "talkerapp.com"
13
+ port = (options.delete(:port) || 8500).to_i
14
+
15
15
  thread = Thread.new { EM.run } unless EM.reactor_running?
16
16
 
17
- EM.connect host, port, self do |c|
17
+ connection = EM.connect host, port, self do |c|
18
18
  c.thread = thread
19
- c.room = room
20
- c.token = token
19
+ c.connect_options = options
21
20
  yield c if block_given?
22
21
  end
23
22
 
24
- thread.join unless thread.nil?
23
+ thread.join if thread
24
+
25
+ connection
25
26
  end
26
27
 
27
28
  def initialize
@@ -29,7 +30,7 @@ class Talker < EM::Connection
29
30
  end
30
31
 
31
32
  # Callbacks
32
- %w( connected message join idle back leave presence error close ).each do |method|
33
+ CALLBACKS.each do |method|
33
34
  class_eval <<-EOS
34
35
  def on_#{method}(&block)
35
36
  @on_#{method} = block
@@ -45,25 +46,19 @@ class Talker < EM::Connection
45
46
  send({ :type => "message", :content => message }.merge(attributes))
46
47
  end
47
48
 
49
+ def find_user!(user_name)
50
+ @users.values.detect { |user| user["name"] == user_name } || raise(Error, "User #{user_name} not found")
51
+ end
52
+
48
53
  def send_private_message(to, message)
49
54
  if to.is_a?(String)
50
- user = @users.values.detect { |user| user["name"] == to }
51
- raise Error, "User #{to} not found" unless user
52
- user_id = user["id"]
55
+ user_id = find_user!(to)["id"]
53
56
  else
54
57
  user_id = to
55
58
  end
56
59
  send_message message, :to => user_id
57
60
  end
58
61
 
59
-
60
- ## EventMachine callbacks
61
-
62
- def connection_completed
63
- send :type => "connect", :room => @room, :token => @token
64
- EM.add_periodic_timer(20) { send :type => "ping" }
65
- end
66
-
67
62
  def leave
68
63
  send :type => "close"
69
64
  close
@@ -73,6 +68,14 @@ class Talker < EM::Connection
73
68
  close_connection_after_writing
74
69
  end
75
70
 
71
+
72
+ ## EventMachine callbacks
73
+
74
+ def connection_completed
75
+ send @connect_options.merge(:type => "connect")
76
+ EM.add_periodic_timer(20) { send :type => "ping" }
77
+ end
78
+
76
79
  def post_init
77
80
  @parser = Yajl::Parser.new
78
81
  @parser.on_parse_complete = method(:event_parsed)
@@ -90,9 +93,12 @@ class Talker < EM::Connection
90
93
 
91
94
  private
92
95
  def event_parsed(event)
96
+ trigger :event, event
97
+
93
98
  case event["type"]
94
99
  when "connected"
95
- trigger :connected
100
+ @current_user = event["user"]
101
+ trigger :connected, event["user"]
96
102
  when "error"
97
103
  if @on_error
98
104
  @on_error.call(event["message"])
@@ -116,10 +122,15 @@ class Talker < EM::Connection
116
122
  trigger :back, event["user"]
117
123
  when "message"
118
124
  @users[event["user"]["id"]] ||= event["user"]
119
- trigger :message, event["user"], event["content"], event
125
+ if event["private"]
126
+ trigger :private_message, event["user"], event["content"]
127
+ else
128
+ trigger :message, event["user"], event["content"]
129
+ end
120
130
  else
121
131
  raise Error, "unknown event type received from server: " + event["type"]
122
132
  end
133
+
123
134
  rescue
124
135
  close
125
136
  raise
@@ -127,7 +138,7 @@ class Talker < EM::Connection
127
138
 
128
139
  def trigger(callback, *args)
129
140
  callback = instance_variable_get(:"@on_#{callback}")
130
- callback.call(*args[0,callback.arity]) if callback
141
+ callback.call(*args) if callback
131
142
  end
132
143
 
133
144
  def send(data)
data/spec/talker_spec.rb CHANGED
@@ -3,7 +3,8 @@ require File.dirname(__FILE__) + "/spec_helper"
3
3
  EM.describe Talker do
4
4
  it "should connect" do
5
5
  connect do |client|
6
- client.on_connected do
6
+ client.on_connected do |user|
7
+ user["name"].should == TALKER_CONFIG["user_name"]
7
8
  done
8
9
  end
9
10
  end
@@ -47,13 +48,21 @@ EM.describe Talker do
47
48
  client.on_presence do
48
49
  client.send_private_message TALKER_CONFIG["user_name"], "private magic"
49
50
  end
50
- client.on_message do |user, message|
51
+ client.on_private_message do |user, message|
51
52
  message.should == "private magic"
52
53
  done
53
54
  end
54
55
  end
55
56
  end
56
57
 
58
+ it "should receive events" do
59
+ connect do |client|
60
+ client.on_event do
61
+ done
62
+ end
63
+ end
64
+ end
65
+
57
66
  # Keep at the end, mmmkay?
58
67
  it "should leave" do
59
68
  connect do |client|
data/talker.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = %q{talker}
3
- s.version = "0.0.1"
2
+ s.name = "talker"
3
+ s.version = "0.0.2"
4
4
 
5
5
  s.authors = ["Marc-Andre Cournoyer"]
6
6
  s.email = "macournoyer@talkerapp.com"
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.homepage = "http://github.com/macournoyer/talker.rb"
9
9
  s.require_paths = ["lib"]
10
10
  s.bindir = "bin"
11
- s.executables = ["talker-cat", "talker-shell"]
11
+ s.executables = Dir["bin/*"].map { |f| File.basename(f) }
12
12
  s.summary = "A real-time Talker Ruby client."
13
13
  s.test_files = Dir["spec/**"]
14
14
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: talker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-Andre Cournoyer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-12 00:00:00 -05:00
12
+ date: 2009-12-14 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,7 +52,6 @@ files:
52
52
  - spec/talker.example.yml
53
53
  - spec/talker.yml
54
54
  - spec/talker_spec.rb
55
- - talker-0.0.1.gem
56
55
  - talker.gemspec
57
56
  has_rdoc: true
58
57
  homepage: http://github.com/macournoyer/talker.rb