skates 0.2.17 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/Rakefile +1 -2
- data/lib/skates/base/stanza.rb +27 -8
- data/lib/skates/runner.rb +39 -1
- data/lib/skates/xmpp_connection.rb +13 -7
- data/lib/skates.rb +0 -1
- data/spec/lib/skates/base/stanza_spec.rb +111 -6
- data/spec/lib/skates/runner_spec.rb +36 -14
- data/templates/skates/config/config.yaml +3 -0
- metadata +2 -13
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -13,10 +13,9 @@ begin
|
|
13
13
|
gem.add_dependency('eventmachine', ">= 0.12.10")
|
14
14
|
gem.add_dependency('log4r')
|
15
15
|
gem.add_dependency('nokogiri', ">= 1.4.1")
|
16
|
-
gem.add_dependency('superfeedr-sax-machine', ">= 0.0.23")
|
17
16
|
gem.add_dependency('templater')
|
18
17
|
gem.add_dependency('utf8cleaner')
|
19
|
-
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "
|
18
|
+
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "templater", "optparse", "digest/sha1", "base64", "resolv", "utf8cleaner"]
|
20
19
|
gem.executables = "skates"
|
21
20
|
gem.files = [ "bin/skates",
|
22
21
|
"lib/skates.rb",
|
data/lib/skates/base/stanza.rb
CHANGED
@@ -3,8 +3,9 @@ module Skates
|
|
3
3
|
##
|
4
4
|
# Class used to Parse a Stanza on the XMPP stream.
|
5
5
|
# You should have a Stanza subsclass for each of your controller actions, as they allow you to define which stanzas and which information is passed to yoru controllers.
|
6
|
-
#
|
7
|
-
# You can define your own
|
6
|
+
# These classes extend the Nokogiri::XML::Node
|
7
|
+
# You can define your own accessors to access the content uou need, using XPath.
|
8
|
+
|
8
9
|
# if your stanza is a message stanza, you can match the following for example:
|
9
10
|
# element :message, :value => :to, :as => :to
|
10
11
|
# element :message, :value => :from, :as => :from
|
@@ -12,14 +13,32 @@ module Skates
|
|
12
13
|
# element :message, :value => :type, :as => :stanza_type
|
13
14
|
# element :message, :value => :"xml:lang", :as => :lang
|
14
15
|
#
|
15
|
-
class Stanza
|
16
|
-
|
17
|
-
|
16
|
+
class Stanza
|
17
|
+
|
18
|
+
def initialize(node)
|
19
|
+
@node = node
|
20
|
+
end
|
21
|
+
|
22
|
+
def from
|
23
|
+
@node.at_xpath(".")["from"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def to
|
27
|
+
@node.at_xpath(".")["to"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def id
|
31
|
+
@node.at_xpath(".")["id"]
|
32
|
+
end
|
18
33
|
|
19
|
-
def
|
20
|
-
@
|
21
|
-
parse(xml.to_xml)
|
34
|
+
def type
|
35
|
+
@node.at_xpath(".")["type"]
|
22
36
|
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
@node.at_xpath(".").name
|
40
|
+
end
|
41
|
+
|
23
42
|
end
|
24
43
|
end
|
25
44
|
end
|
data/lib/skates/runner.rb
CHANGED
@@ -4,6 +4,8 @@ module Skates
|
|
4
4
|
# Runner is in charge of running the application.
|
5
5
|
class Runner
|
6
6
|
|
7
|
+
PHI = ((1+Math.sqrt(5))/2.0)
|
8
|
+
|
7
9
|
##
|
8
10
|
# Prepares the Application to run.
|
9
11
|
def self.prepare(env)
|
@@ -27,6 +29,9 @@ module Skates
|
|
27
29
|
# Caching views
|
28
30
|
Skates.cache_views
|
29
31
|
|
32
|
+
#Setting failed connection attemts
|
33
|
+
@failed_connections = 0
|
34
|
+
|
30
35
|
end
|
31
36
|
|
32
37
|
##
|
@@ -93,6 +98,9 @@ module Skates
|
|
93
98
|
connection_observers.each do |observer|
|
94
99
|
Skates.router.execute_route(observer, "on_connected")
|
95
100
|
end
|
101
|
+
|
102
|
+
# Connected so reset failed connection attempts
|
103
|
+
@failed_connections = 0
|
96
104
|
end
|
97
105
|
|
98
106
|
##
|
@@ -103,7 +111,20 @@ module Skates
|
|
103
111
|
observer = conn_obs.new
|
104
112
|
observer.on_disconnected if observer.respond_to?("on_disconnected")
|
105
113
|
end
|
106
|
-
|
114
|
+
|
115
|
+
if Skates.config["auto-reconnect"]
|
116
|
+
# Increment failed connection attempts and calculate time to next re-connect
|
117
|
+
@failed_connections += 1
|
118
|
+
reconnect_in = fib(@failed_connections)
|
119
|
+
|
120
|
+
EventMachine.add_timer( reconnect_in ) {reconnect} if EM.reactor_running?
|
121
|
+
|
122
|
+
Skates.logger.error {
|
123
|
+
"Disconnected - trying to reconnect in #{reconnect_in} seconds."
|
124
|
+
}
|
125
|
+
else
|
126
|
+
EM.stop_event_loop
|
127
|
+
end
|
107
128
|
end
|
108
129
|
|
109
130
|
##
|
@@ -123,5 +144,22 @@ module Skates
|
|
123
144
|
end
|
124
145
|
end
|
125
146
|
|
147
|
+
##
|
148
|
+
# Tries to reconnect
|
149
|
+
def self.reconnect
|
150
|
+
#Try to reconnect
|
151
|
+
case Skates.config["application_type"]
|
152
|
+
when "client"
|
153
|
+
Skates::ClientConnection.connect(Skates.config, self)
|
154
|
+
else # By default, we assume it's a component
|
155
|
+
Skates::ComponentConnection.connect(Skates.config, self)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# Helper to calculate the fibonnacci number.
|
161
|
+
def self.fib(n)
|
162
|
+
(Skates::Runner::PHI**n).round
|
163
|
+
end
|
126
164
|
end
|
127
165
|
end
|
@@ -149,13 +149,19 @@ module Skates
|
|
149
149
|
##
|
150
150
|
# Sends the Nokogiri::XML data (after converting to string) on the stream. Eventually it displays this data for debugging purposes.
|
151
151
|
def send_xml(xml)
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
152
|
+
begin
|
153
|
+
if xml.is_a? Nokogiri::XML::NodeSet
|
154
|
+
xml.each do |element|
|
155
|
+
send_chunk(element.to_s)
|
156
|
+
end
|
157
|
+
else
|
158
|
+
send_chunk(xml.to_s)
|
159
|
+
end
|
160
|
+
rescue
|
161
|
+
Skates.logger.error {
|
162
|
+
"SENDING FAILED: #{$!}"
|
163
|
+
}
|
164
|
+
end
|
159
165
|
end
|
160
166
|
|
161
167
|
private
|
data/lib/skates.rb
CHANGED
@@ -1,15 +1,120 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
2
|
|
3
3
|
describe Skates::Base::Stanza do
|
4
|
-
|
4
|
+
|
5
5
|
describe "initialize" do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
context "when the stanza is an IQ" do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
xml = <<-EOXML
|
11
|
+
<iq type='get'
|
12
|
+
from='romeo@montague.net/orchard'
|
13
|
+
to='plays.shakespeare.lit'
|
14
|
+
id='info1'>
|
15
|
+
<query xmlns='http://jabber.org/protocol/disco#configuration'/>
|
16
|
+
</iq>
|
17
|
+
EOXML
|
18
|
+
xml = Nokogiri::XML(xml)
|
19
|
+
@stanza = Skates::Base::Stanza.new(xml.root)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have the right from" do
|
23
|
+
@stanza.from.should == "romeo@montague.net/orchard"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have the right id" do
|
27
|
+
@stanza.id.should == "info1"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have the right to" do
|
31
|
+
@stanza.to.should == "plays.shakespeare.lit"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have the right type" do
|
35
|
+
@stanza.type.should == "get"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have the right name" do
|
39
|
+
@stanza.name.should == "iq"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
context "when the stanza is a presence" do
|
47
|
+
|
48
|
+
before(:each) do
|
49
|
+
xml = <<-EOXML
|
50
|
+
<presence from='firehoser-test.superfeedr.com' to='testparsr@superfeedr.com/skates_client_7008465' type='error' />
|
51
|
+
EOXML
|
52
|
+
xml = Nokogiri::XML(xml)
|
53
|
+
@stanza = Skates::Base::Stanza.new(xml.root)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should have the right from" do
|
57
|
+
@stanza.from.should == "firehoser-test.superfeedr.com"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should have the right id" do
|
61
|
+
@stanza.id.should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should have the right to" do
|
65
|
+
@stanza.to.should == "testparsr@superfeedr.com/skates_client_7008465"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should have the right type" do
|
69
|
+
@stanza.type.should == "error"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have the right name" do
|
73
|
+
@stanza.name.should == "presence"
|
74
|
+
end
|
75
|
+
|
9
76
|
end
|
10
77
|
|
11
|
-
|
78
|
+
context "when the stanza is a message" do
|
79
|
+
|
80
|
+
before(:each) do
|
81
|
+
xml = <<-EOXML
|
82
|
+
<message to="monitor@superfeedr.com" from="test-firehoser.superfeedr.com">
|
83
|
+
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
84
|
+
<status xmlns="http://superfeedr.com/xmpp-pubsub-ext" feed="http://domain.tld/feed.xml">
|
85
|
+
<http code="200">All went very fine. Thanks for asking!</http>
|
86
|
+
<next_fetch>2010-02-03T01:32:58+01:00</next_fetch>
|
87
|
+
<title></title>
|
88
|
+
</status>
|
89
|
+
</event>
|
90
|
+
</message>
|
91
|
+
EOXML
|
92
|
+
xml = Nokogiri::XML(xml)
|
93
|
+
@stanza = Skates::Base::Stanza.new(xml.root)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have the right from" do
|
97
|
+
@stanza.from.should == "test-firehoser.superfeedr.com"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should have the right id" do
|
101
|
+
@stanza.id.should be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should have the right to" do
|
105
|
+
@stanza.to.should == "monitor@superfeedr.com"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should have the right type" do
|
109
|
+
@stanza.type.should be_nil
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should have the right name" do
|
113
|
+
@stanza.name.should == "message"
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
12
117
|
|
13
118
|
end
|
14
|
-
|
119
|
+
|
15
120
|
end
|
@@ -2,13 +2,11 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
2
|
require File.dirname(__FILE__) + '/../../em_mock'
|
3
3
|
|
4
4
|
describe Skates::Runner do
|
5
|
-
|
6
5
|
before(:all) do
|
7
6
|
FileUtils.chdir("#{FileUtils.pwd}/templates/skates") unless ("#{FileUtils.pwd}" =~ /\/templates\/skates/ )
|
8
7
|
end
|
9
|
-
|
8
|
+
|
10
9
|
describe ".prepare" do
|
11
|
-
|
12
10
|
before(:each) do
|
13
11
|
@stub_config_file = File.open("config/config.yaml")
|
14
12
|
@stub_config_content = File.read("config/config.yaml")
|
@@ -86,7 +84,6 @@ describe Skates::Runner do
|
|
86
84
|
end
|
87
85
|
|
88
86
|
describe ".run" do
|
89
|
-
|
90
87
|
before(:each) do
|
91
88
|
Skates::ClientConnection.stub!(:connect).and_return(true)
|
92
89
|
Skates::ComponentConnection.stub!(:connect).and_return(true)
|
@@ -182,23 +179,48 @@ describe Skates::Runner do
|
|
182
179
|
end
|
183
180
|
|
184
181
|
describe ".on_disconnected" do
|
185
|
-
it "should stop the event loop" do
|
186
|
-
connection = mock(Object)
|
187
|
-
EventMachine.should_receive(:stop_event_loop)
|
188
|
-
Skates::Runner.on_disconnected()
|
189
|
-
end
|
190
|
-
|
191
182
|
it "should call on_disconnected on the various observers" do
|
192
|
-
class MyObserver < Skates::Base::Controller
|
193
|
-
def on_disconnected
|
194
|
-
end
|
195
|
-
end
|
183
|
+
class MyObserver < Skates::Base::Controller; def on_disconnected; end; end
|
196
184
|
my_observer = MyObserver.new
|
197
185
|
Skates::Runner.add_connection_observer(MyObserver)
|
198
186
|
MyObserver.should_receive(:new).and_return(my_observer)
|
199
187
|
my_observer.should_receive(:on_disconnected)
|
200
188
|
Skates::Runner.on_disconnected
|
201
189
|
end
|
190
|
+
|
191
|
+
context "when the application should auto-reconnect" do
|
192
|
+
before(:each) do
|
193
|
+
Skates.config["auto-reconnect"] = true
|
194
|
+
EventMachine.stub!(:reactor_running?).and_return(false)
|
195
|
+
EventMachine.stub!(:add_timer).and_yield()
|
196
|
+
@delay = 15
|
197
|
+
Skates::Runner.stub!(:fib).and_return(@delay)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should determine when is the best time to reconnect with fibonacci" do
|
201
|
+
Skates::Runner.should_receive(:fib).and_return(@delay)
|
202
|
+
Skates::Runner.on_disconnected()
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should try to reconnect at the determined time" do
|
206
|
+
EventMachine.stub!(:reactor_running?).and_return(true)
|
207
|
+
Skates::Runner.should_receive(:reconnect)
|
208
|
+
EventMachine.should_receive(:add_timer).with(@delay).and_yield()
|
209
|
+
Skates::Runner.on_disconnected()
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context "when the application should not auto-reconnect" do
|
214
|
+
before(:each) do
|
215
|
+
Skates.config["auto-reconnect"] = false
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should stop the event loop" do
|
219
|
+
connection = mock(Object)
|
220
|
+
EventMachine.should_receive(:stop_event_loop)
|
221
|
+
Skates::Runner.on_disconnected()
|
222
|
+
end
|
223
|
+
end
|
202
224
|
end
|
203
225
|
|
204
226
|
describe ".on_stanza" do
|
@@ -10,15 +10,18 @@ development:
|
|
10
10
|
jid: user@server.com
|
11
11
|
password: password
|
12
12
|
application_type: client
|
13
|
+
auto-reconnect: true
|
13
14
|
|
14
15
|
test:
|
15
16
|
jid: component.server.com
|
16
17
|
password: password
|
17
18
|
host: localhost
|
18
19
|
port: 5278
|
20
|
+
auto-reconnect: true
|
19
21
|
|
20
22
|
production:
|
21
23
|
jid: component.server.com
|
22
24
|
password: password
|
23
25
|
host: localhost
|
24
26
|
port: 5278
|
27
|
+
auto-reconnect: true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- julien Genestoux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-10 00:00:00 -06:00
|
13
13
|
default_executable: skates
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,16 +42,6 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.4.1
|
44
44
|
version:
|
45
|
-
- !ruby/object:Gem::Dependency
|
46
|
-
name: superfeedr-sax-machine
|
47
|
-
type: :runtime
|
48
|
-
version_requirement:
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 0.0.23
|
54
|
-
version:
|
55
45
|
- !ruby/object:Gem::Dependency
|
56
46
|
name: templater
|
57
47
|
type: :runtime
|
@@ -138,7 +128,6 @@ requirements:
|
|
138
128
|
- fileutils
|
139
129
|
- log4r
|
140
130
|
- nokogiri
|
141
|
-
- superfeedr-sax-machine
|
142
131
|
- templater
|
143
132
|
- optparse
|
144
133
|
- digest/sha1
|