blather 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/Rakefile +30 -18
- data/ext/Makefile +149 -0
- data/ext/mkmf.log +30 -0
- data/ext/push_parser.bundle +0 -0
- data/ext/push_parser.c +231 -0
- data/ext/push_parser.o +0 -0
- data/lib/blather.rb +3 -7
- data/lib/blather/client.rb +247 -4
- data/lib/blather/roster.rb +0 -9
- data/lib/blather/stanza/{disco.rb → iq/disco.rb} +3 -1
- data/lib/blather/stanza/{disco → iq/discos}/disco_info.rb +5 -3
- data/lib/blather/stanza/{disco → iq/discos}/disco_items.rb +2 -0
- data/lib/blather/stanza/iq/query.rb +1 -1
- data/lib/blather/stanza/iq/roster.rb +2 -2
- data/lib/blather/xmpp_node.rb +1 -1
- data/spec/blather/stanza/{discos → iq/discos}/disco_info_spec.rb +12 -12
- data/spec/blather/stanza/{discos → iq/discos}/disco_items_spec.rb +1 -1
- data/spec/blather/stanza/iq/query_spec.rb +0 -7
- data/spec/blather/stanza/iq/roster_spec.rb +21 -21
- data/spec/blather/stanza/pubsub/event_spec.rb +13 -0
- data/spec/build_safe.rb +20 -0
- metadata +19 -68
- data/VERSION.yml +0 -4
- data/examples/pubsub/cli.rb +0 -64
- data/examples/pubsub/ping_pong.rb +0 -18
- data/examples/pubsub/pubsub_dsl.rb +0 -52
- data/examples/pubsub_client.rb +0 -39
- data/examples/rosterprint.rb +0 -14
- data/examples/xmpp4r/echo.rb +0 -35
- data/lib/blather/client/client.rb +0 -165
- data/lib/blather/client/dsl.rb +0 -99
- data/lib/blather/client/pubsub.rb +0 -53
- data/lib/blather/client/pubsub/node.rb +0 -27
- data/lib/blather/stanza/pubsub.rb +0 -33
- data/lib/blather/stanza/pubsub/affiliations.rb +0 -52
- data/lib/blather/stanza/pubsub/errors.rb +0 -9
- data/lib/blather/stanza/pubsub/event.rb +0 -21
- data/lib/blather/stanza/pubsub/items.rb +0 -59
- data/lib/blather/stanza/pubsub/owner.rb +0 -9
- data/lib/blather/stanza/pubsub/subscriptions.rb +0 -57
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +0 -46
- data/spec/blather/stanza/pubsub/items_spec.rb +0 -59
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +0 -63
- data/spec/blather/stanza/pubsub_spec.rb +0 -26
- data/spec/fixtures/pubsub.rb +0 -157
data/examples/rosterprint.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Prints out each roster entry
|
4
|
-
|
5
|
-
require 'blather/client'
|
6
|
-
|
7
|
-
when_ready do
|
8
|
-
roster.grouped.each do |group, items|
|
9
|
-
puts "#{'*'*3} #{group || 'Ungrouped'} #{'*'*3}"
|
10
|
-
items.each { |item| puts "- #{item.name} (#{item.jid})" }
|
11
|
-
puts
|
12
|
-
end
|
13
|
-
shutdown
|
14
|
-
end
|
data/examples/xmpp4r/echo.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
# This bot will reply to every message it receives. To end the game, send 'exit'
|
4
|
-
|
5
|
-
require 'xmpp4r/client'
|
6
|
-
include Jabber
|
7
|
-
|
8
|
-
# settings
|
9
|
-
if ARGV.length != 2
|
10
|
-
puts "Run with ./echo_thread.rb user@server/resource password"
|
11
|
-
exit 1
|
12
|
-
end
|
13
|
-
myJID = JID.new(ARGV[0])
|
14
|
-
myPassword = ARGV[1]
|
15
|
-
cl = Client.new(myJID)
|
16
|
-
cl.connect
|
17
|
-
cl.auth(myPassword)
|
18
|
-
cl.send(Presence.new)
|
19
|
-
puts "Connected ! send messages to #{myJID.strip.to_s}."
|
20
|
-
mainthread = Thread.current
|
21
|
-
cl.add_message_callback do |m|
|
22
|
-
if m.type != :error
|
23
|
-
m2 = Message.new(m.from, "You sent: #{m.body}")
|
24
|
-
m2.type = m.type
|
25
|
-
cl.send(m2)
|
26
|
-
if m.body == 'exit'
|
27
|
-
m2 = Message.new(m.from, "Exiting ...")
|
28
|
-
m2.type = m.type
|
29
|
-
cl.send(m2)
|
30
|
-
mainthread.wakeup
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
Thread.stop
|
35
|
-
cl.close
|
@@ -1,165 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), *%w[.. .. blather])
|
2
|
-
require File.join(File.dirname(__FILE__), 'pubsub')
|
3
|
-
|
4
|
-
module Blather #:nodoc:
|
5
|
-
|
6
|
-
class Client #:nodoc:
|
7
|
-
attr_accessor :jid,
|
8
|
-
:roster
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@state = :initializing
|
12
|
-
|
13
|
-
@status = Stanza::Presence::Status.new
|
14
|
-
@handlers = {}
|
15
|
-
@tmp_handlers = {}
|
16
|
-
@roster = Roster.new self
|
17
|
-
|
18
|
-
setup_initial_handlers
|
19
|
-
end
|
20
|
-
|
21
|
-
def setup?
|
22
|
-
@setup.is_a? Array
|
23
|
-
end
|
24
|
-
|
25
|
-
def setup(jid, password, host = nil, port = nil)
|
26
|
-
@setup = [JID.new(jid), password]
|
27
|
-
@setup << host if host
|
28
|
-
@setup << port if port
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def run
|
33
|
-
raise 'not setup!' unless setup?
|
34
|
-
trap(:INT) { EM.stop }
|
35
|
-
EM.run {
|
36
|
-
klass = @setup[0].node ? Blather::Stream::Client : Blather::Stream::Component
|
37
|
-
klass.start self, *@setup
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
def register_tmp_handler(id, &handler)
|
42
|
-
@tmp_handlers[id] = handler
|
43
|
-
end
|
44
|
-
|
45
|
-
def register_handler(type, *guards, &handler)
|
46
|
-
@handlers[type] ||= []
|
47
|
-
@handlers[type] << [guards, handler]
|
48
|
-
end
|
49
|
-
|
50
|
-
def status
|
51
|
-
@status.state
|
52
|
-
end
|
53
|
-
|
54
|
-
def status=(state)
|
55
|
-
state, msg, to = state
|
56
|
-
|
57
|
-
status = Stanza::Presence::Status.new state, msg
|
58
|
-
status.to = to
|
59
|
-
@status = status unless to
|
60
|
-
|
61
|
-
write status
|
62
|
-
end
|
63
|
-
|
64
|
-
def write(stanza)
|
65
|
-
stanza.from ||= jid if stanza.respond_to?(:from)
|
66
|
-
@stream.send(stanza) if @stream
|
67
|
-
end
|
68
|
-
|
69
|
-
def write_with_handler(stanza, &hanlder)
|
70
|
-
register_tmp_handler stanza.id, &handler
|
71
|
-
write stanza
|
72
|
-
end
|
73
|
-
|
74
|
-
def stream_started(stream)
|
75
|
-
@stream = stream
|
76
|
-
|
77
|
-
#retreive roster
|
78
|
-
if @stream.is_a?(Stream::Component)
|
79
|
-
@state = :ready
|
80
|
-
call_handler_for :ready, nil
|
81
|
-
else
|
82
|
-
r = Stanza::Iq::Roster.new
|
83
|
-
register_tmp_handler r.id do |node|
|
84
|
-
roster.process node
|
85
|
-
@state = :ready
|
86
|
-
write @status
|
87
|
-
call_handler_for :ready, nil
|
88
|
-
end
|
89
|
-
write r
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def stop
|
94
|
-
@stream.close_connection_after_writing
|
95
|
-
end
|
96
|
-
|
97
|
-
def stopped
|
98
|
-
EM.stop
|
99
|
-
end
|
100
|
-
|
101
|
-
def call(stanza)
|
102
|
-
if handler = @tmp_handlers.delete(stanza.id)
|
103
|
-
handler.call stanza
|
104
|
-
else
|
105
|
-
stanza.handler_heirarchy.each do |type|
|
106
|
-
break if call_handler_for(type, stanza) && (stanza.is_a?(BlatherError) || stanza.type == :iq)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def call_handler_for(type, stanza)
|
112
|
-
if @handlers[type]
|
113
|
-
@handlers[type].find { |guards, handler| handler.call(stanza) unless guarded?(guards, stanza) }
|
114
|
-
true
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
protected
|
119
|
-
def setup_initial_handlers
|
120
|
-
register_handler :error do |err|
|
121
|
-
raise err
|
122
|
-
end
|
123
|
-
|
124
|
-
register_handler :iq do |iq|
|
125
|
-
write(StanzaError::ServiceUnavailable.new(iq, :cancel).to_node) if [:set, :get].include?(iq.type)
|
126
|
-
end
|
127
|
-
|
128
|
-
register_handler :status do |status|
|
129
|
-
roster[status.from].status = status if roster[status.from]
|
130
|
-
end
|
131
|
-
|
132
|
-
register_handler :roster do |node|
|
133
|
-
roster.process node
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
##
|
138
|
-
# If any of the guards returns FALSE this returns true
|
139
|
-
def guarded?(guards, stanza)
|
140
|
-
guards.find do |guard|
|
141
|
-
case guard
|
142
|
-
when Symbol
|
143
|
-
!stanza.__send__(guard)
|
144
|
-
when Array
|
145
|
-
# return FALSE if any item is TRUE
|
146
|
-
!guard.detect { |condition| !guarded?([condition], stanza) }
|
147
|
-
when Hash
|
148
|
-
# return FALSE unless any inequality is found
|
149
|
-
guard.find do |method, value|
|
150
|
-
if value.is_a?(Regexp)
|
151
|
-
!stanza.__send__(method).to_s.match(value)
|
152
|
-
else
|
153
|
-
stanza.__send__(method) != value
|
154
|
-
end
|
155
|
-
end
|
156
|
-
when Proc
|
157
|
-
!guard.call(stanza)
|
158
|
-
else
|
159
|
-
raise "Bad guard: #{guard.inspect}"
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
end #Client
|
165
|
-
end #Blather
|
data/lib/blather/client/dsl.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'client')
|
2
|
-
|
3
|
-
module Blather
|
4
|
-
module DSL
|
5
|
-
def client
|
6
|
-
@client ||= Client.new
|
7
|
-
end
|
8
|
-
module_function :client
|
9
|
-
|
10
|
-
##
|
11
|
-
# Prepare server settings
|
12
|
-
# setup [node@domain/resource], [password], [host], [port]
|
13
|
-
# host and port are optional defaulting to the domain in the JID and 5222 respectively
|
14
|
-
def setup(jid, password, host = nil, port = nil)
|
15
|
-
client.setup(jid, password, host, port)
|
16
|
-
at_exit { client.run }
|
17
|
-
end
|
18
|
-
|
19
|
-
##
|
20
|
-
# Shutdown the connection.
|
21
|
-
# Flushes the write buffer then stops EventMachine
|
22
|
-
def shutdown
|
23
|
-
client.stop
|
24
|
-
end
|
25
|
-
|
26
|
-
##
|
27
|
-
# Set handler for a stanza type
|
28
|
-
def handle(stanza_type, *guards, &block)
|
29
|
-
client.register_handler stanza_type, *guards, &block
|
30
|
-
end
|
31
|
-
|
32
|
-
##
|
33
|
-
# Wrapper for "handle :ready" (just a bit of syntactic sugar)
|
34
|
-
def when_ready(&block)
|
35
|
-
handle :ready, &block
|
36
|
-
end
|
37
|
-
|
38
|
-
##
|
39
|
-
# Set current status
|
40
|
-
def status(state = nil, msg = nil)
|
41
|
-
client.status = state, msg
|
42
|
-
end
|
43
|
-
|
44
|
-
##
|
45
|
-
# Direct access to the roster
|
46
|
-
def roster
|
47
|
-
client.roster
|
48
|
-
end
|
49
|
-
|
50
|
-
##
|
51
|
-
# Write data to the stream
|
52
|
-
# Anything that resonds to #to_s can be paseed to the stream
|
53
|
-
def write(stanza)
|
54
|
-
client.write(stanza)
|
55
|
-
end
|
56
|
-
|
57
|
-
##
|
58
|
-
# Helper method to make sending basic messages easier
|
59
|
-
# say [jid], [msg]
|
60
|
-
def say(to, msg)
|
61
|
-
client.write Blather::Stanza::Message.new(to, msg)
|
62
|
-
end
|
63
|
-
|
64
|
-
##
|
65
|
-
# Wrapper to grab the current JID
|
66
|
-
def jid
|
67
|
-
client.jid
|
68
|
-
end
|
69
|
-
|
70
|
-
##
|
71
|
-
#
|
72
|
-
def discover(what, who, where, &callback)
|
73
|
-
stanza = Blather::Stanza.class_from_registration(:query, "http://jabber.org/protocol/disco##{what}").new
|
74
|
-
stanza.to = who
|
75
|
-
stanza.node = where
|
76
|
-
|
77
|
-
client.temporary_handler stanza.id, &callback
|
78
|
-
write stanza
|
79
|
-
end
|
80
|
-
|
81
|
-
##
|
82
|
-
# PubSub proxy
|
83
|
-
def pubsub
|
84
|
-
client.pubsub
|
85
|
-
end
|
86
|
-
|
87
|
-
##
|
88
|
-
# Checks to see if the method is part of the handlers list.
|
89
|
-
# If so it creates a handler, otherwise it'll pass it back
|
90
|
-
# to Ruby's method_missing handler
|
91
|
-
def method_missing(method, *args, &block)
|
92
|
-
if Blather::Stanza.handler_list.include?(method)
|
93
|
-
handle method, *args, &block
|
94
|
-
else
|
95
|
-
super
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end #DSL
|
99
|
-
end #Blather
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Blather
|
2
|
-
class Client
|
3
|
-
|
4
|
-
class PubSub
|
5
|
-
attr_accessor :host
|
6
|
-
|
7
|
-
def affiliations(&callback)
|
8
|
-
request Stanza::PubSub::Affiliations.new(:get, @host), :affiliates, callback
|
9
|
-
end
|
10
|
-
|
11
|
-
def subscriptions(&callback)
|
12
|
-
request Stanza::PubSub::Subscriptions.new(:get, @host), :subscriptions, callback
|
13
|
-
end
|
14
|
-
|
15
|
-
def nodes(path, &callback)
|
16
|
-
stanza = Stanza::DiscoItems.new(:get, path)
|
17
|
-
stanza.to = @host
|
18
|
-
request stanza, :items, callback
|
19
|
-
end
|
20
|
-
|
21
|
-
def node(path)
|
22
|
-
stanza = Stanza::DiscoInfo.new(:get, path)
|
23
|
-
stanza.to = @host
|
24
|
-
request(stanza) { |node| yield Stanza::PubSub::Node.import(node) }
|
25
|
-
end
|
26
|
-
|
27
|
-
def items(path, list = [], max = nil, &callback)
|
28
|
-
request Stanza::PubSub.items(@host, path, list, max), :items, callback
|
29
|
-
end
|
30
|
-
=begin
|
31
|
-
def create(node)
|
32
|
-
end
|
33
|
-
|
34
|
-
def publish(node, payload)
|
35
|
-
end
|
36
|
-
|
37
|
-
def subscribe(node)
|
38
|
-
DSL.client.write Stanza::PubSub::Subscribe.new(:set, host, node, DSL.client.jid)
|
39
|
-
end
|
40
|
-
|
41
|
-
def unsubscribe(node)
|
42
|
-
DSL.client.write Stanza::PubSub::Unsubscribe.new(:set, host, node, DSL.client.jid)
|
43
|
-
end
|
44
|
-
=end
|
45
|
-
private
|
46
|
-
def request(node, method = nil, callback, &block)
|
47
|
-
block = lambda { |node| callback.call node.__send__(method) } unless block_given?
|
48
|
-
DSL.client.write_with_handler(node, &block)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Blather
|
2
|
-
class Client
|
3
|
-
class PubSub
|
4
|
-
|
5
|
-
class Node
|
6
|
-
attr_accessor :path
|
7
|
-
|
8
|
-
def initialize(path)
|
9
|
-
@path = path
|
10
|
-
end
|
11
|
-
|
12
|
-
def info(&block)
|
13
|
-
DSL.client.write_with_handler Stanza::DiscoInfo.new(:get, path), &block
|
14
|
-
end
|
15
|
-
|
16
|
-
def items(&block)
|
17
|
-
DSL.client.write_with_handler Stanza::PubSub.items(path), &block
|
18
|
-
end
|
19
|
-
|
20
|
-
def nodes(&block)
|
21
|
-
DSL.client.write_with_handler Stanza::DiscoItems.new(:get, path), &block
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end #PubSub
|
26
|
-
end #Client
|
27
|
-
end #Blather
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Blather
|
2
|
-
class Stanza
|
3
|
-
|
4
|
-
class PubSub < Iq
|
5
|
-
register :pubsub, :pubsub, 'http://jabber.org/protocol/pubsub'
|
6
|
-
|
7
|
-
##
|
8
|
-
# Ensure the namespace is set to the query node
|
9
|
-
def initialize(type = nil, host = nil)
|
10
|
-
super type
|
11
|
-
self.to = host
|
12
|
-
pubsub.namespace = self.class.ns unless pubsub.namespace
|
13
|
-
end
|
14
|
-
|
15
|
-
##
|
16
|
-
# Kill the pubsub node before running inherit
|
17
|
-
def inherit(node)
|
18
|
-
pubsub.remove!
|
19
|
-
super
|
20
|
-
end
|
21
|
-
|
22
|
-
def pubsub
|
23
|
-
unless p = find_first('//pubsub', Stanza::PubSub::Affiliations.ns)
|
24
|
-
p = XMPPNode.new('pubsub')
|
25
|
-
p.namespace = self.class.ns
|
26
|
-
self << p
|
27
|
-
end
|
28
|
-
p
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end #Stanza
|
33
|
-
end #Blather
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Blather
|
2
|
-
class Stanza
|
3
|
-
class PubSub
|
4
|
-
|
5
|
-
class Affiliations < PubSub
|
6
|
-
register :pubsub_affiliations, :pubsub_affiliations, self.ns
|
7
|
-
|
8
|
-
include Enumerable
|
9
|
-
|
10
|
-
def initialize(type = nil, host = nil)
|
11
|
-
super
|
12
|
-
affiliations
|
13
|
-
end
|
14
|
-
|
15
|
-
##
|
16
|
-
# Kill the affiliations node before running inherit
|
17
|
-
def inherit(node)
|
18
|
-
affiliations.remove!
|
19
|
-
super
|
20
|
-
end
|
21
|
-
|
22
|
-
def affiliations
|
23
|
-
aff = pubsub.find_first('//pubsub_ns:affiliations', :pubsub_ns => self.class.ns)
|
24
|
-
(self.pubsub << (aff = XMPPNode.new('affiliations'))) unless aff
|
25
|
-
aff
|
26
|
-
end
|
27
|
-
|
28
|
-
def [](affiliation)
|
29
|
-
list[affiliation]
|
30
|
-
end
|
31
|
-
|
32
|
-
def each(&block)
|
33
|
-
list.each &block
|
34
|
-
end
|
35
|
-
|
36
|
-
def size
|
37
|
-
list.size
|
38
|
-
end
|
39
|
-
|
40
|
-
def list
|
41
|
-
items = affiliations.find('//pubsub_ns:affiliation', :pubsub_ns => self.class.ns)
|
42
|
-
items.inject({}) do |hash, item|
|
43
|
-
hash[item.attributes[:affiliation].to_sym] ||= []
|
44
|
-
hash[item.attributes[:affiliation].to_sym] << item.attributes[:node]
|
45
|
-
hash
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end #Affiliations
|
49
|
-
|
50
|
-
end #PubSub
|
51
|
-
end #Stanza
|
52
|
-
end #Blather
|