communicator 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +4 -0
- data/README.rdoc +5 -0
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/communicator.gemspec +7 -1
- data/lib/communicator/active_record_integration.rb +15 -3
- data/lib/communicator/server.rb +20 -2
- data/lib/communicator.rb +14 -1
- data/test/config.ru +1 -0
- data/test/helper.rb +4 -0
- data/test/lib/comment.rb +7 -0
- data/test/lib/test_server_database/comment.rb +4 -0
- data/test/migrate/20101103120519_create_comments.rb +13 -0
- data/test/test_client.rb +16 -0
- metadata +9 -3
data/Gemfile.lock
CHANGED
@@ -6,6 +6,7 @@ PATH
|
|
6
6
|
httparty (>= 0.6.1)
|
7
7
|
json (>= 1.4.0)
|
8
8
|
sinatra (~> 1.1.0)
|
9
|
+
sinatra-basic-auth
|
9
10
|
|
10
11
|
GEM
|
11
12
|
remote: http://rubygems.org/
|
@@ -25,6 +26,8 @@ GEM
|
|
25
26
|
sinatra (1.1.0)
|
26
27
|
rack (~> 1.1)
|
27
28
|
tilt (~> 1.1)
|
29
|
+
sinatra-basic-auth (0.1.0)
|
30
|
+
sinatra
|
28
31
|
sqlite3-ruby (1.3.2)
|
29
32
|
tilt (1.1)
|
30
33
|
|
@@ -41,4 +44,5 @@ DEPENDENCIES
|
|
41
44
|
rack-test (>= 0.5.6)
|
42
45
|
shoulda (= 2.10.3)
|
43
46
|
sinatra (~> 1.1.0)
|
47
|
+
sinatra-basic-auth
|
44
48
|
sqlite3-ruby (>= 1.3.0)
|
data/README.rdoc
CHANGED
@@ -59,6 +59,11 @@ class receives updates from like this:
|
|
59
59
|
class Post < ActiveRecord::Base
|
60
60
|
receives_from :post
|
61
61
|
end
|
62
|
+
|
63
|
+
If you want to skip some remote attributes and not let them progapate into local instances,
|
64
|
+
use `receives_from :post, :except => [:user_id]`.
|
65
|
+
|
66
|
+
Attributes that are not physically present in the local database will be skipped automatically.
|
62
67
|
|
63
68
|
Use the automatically added `publish` instance method on your models to push changes
|
64
69
|
to the other side. They will be enqueued in the local `outbound_messages` table and
|
data/Rakefile
CHANGED
@@ -54,7 +54,10 @@ namespace :test_server do
|
|
54
54
|
Thread.new do
|
55
55
|
# Capture sinatra output (to hide it away...)
|
56
56
|
require "open3"
|
57
|
-
|
57
|
+
rackup = "bundle exec rackup test/config.ru -p 20359 --pid=#{File.join(File.dirname(__FILE__), 'test', 'rack.pid')}"
|
58
|
+
Open3.popen3(rackup)
|
59
|
+
#`#{rackup}` # Uncomment to see actual server output
|
60
|
+
|
58
61
|
end
|
59
62
|
sleep 2.0
|
60
63
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/communicator.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{communicator}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Christoph Olszowka"]
|
@@ -39,11 +39,14 @@ Gem::Specification.new do |s|
|
|
39
39
|
"test/config.ru",
|
40
40
|
"test/factories.rb",
|
41
41
|
"test/helper.rb",
|
42
|
+
"test/lib/comment.rb",
|
42
43
|
"test/lib/post.rb",
|
44
|
+
"test/lib/test_server_database/comment.rb",
|
43
45
|
"test/lib/test_server_database/inbound_message.rb",
|
44
46
|
"test/lib/test_server_database/outbound_message.rb",
|
45
47
|
"test/lib/test_server_database/post.rb",
|
46
48
|
"test/migrate/20101101093519_create_posts.rb",
|
49
|
+
"test/migrate/20101103120519_create_comments.rb",
|
47
50
|
"test/test_client.rb",
|
48
51
|
"test/test_message_models.rb",
|
49
52
|
"test/test_server.rb"
|
@@ -56,11 +59,14 @@ Gem::Specification.new do |s|
|
|
56
59
|
s.test_files = [
|
57
60
|
"test/factories.rb",
|
58
61
|
"test/helper.rb",
|
62
|
+
"test/lib/comment.rb",
|
59
63
|
"test/lib/post.rb",
|
64
|
+
"test/lib/test_server_database/comment.rb",
|
60
65
|
"test/lib/test_server_database/inbound_message.rb",
|
61
66
|
"test/lib/test_server_database/outbound_message.rb",
|
62
67
|
"test/lib/test_server_database/post.rb",
|
63
68
|
"test/migrate/20101101093519_create_posts.rb",
|
69
|
+
"test/migrate/20101103120519_create_comments.rb",
|
64
70
|
"test/test_client.rb",
|
65
71
|
"test/test_message_models.rb",
|
66
72
|
"test/test_server.rb"
|
@@ -8,8 +8,18 @@ module Communicator::ActiveRecordIntegration
|
|
8
8
|
# receives_from :post
|
9
9
|
# end
|
10
10
|
#
|
11
|
-
def receives_from(source)
|
12
|
-
Communicator.register_receiver(self, source)
|
11
|
+
def receives_from(source, options={})
|
12
|
+
Communicator.register_receiver(self, source, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def skipped_remote_attributes
|
16
|
+
@skipped_remote_attributes ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
def skip_remote_attributes(*attr_names)
|
20
|
+
attr_names.each do |attr_name|
|
21
|
+
skipped_remote_attributes << attr_name.to_sym
|
22
|
+
end
|
13
23
|
end
|
14
24
|
end
|
15
25
|
|
@@ -24,11 +34,13 @@ module Communicator::ActiveRecordIntegration
|
|
24
34
|
end
|
25
35
|
|
26
36
|
# Processes the given message body by applying all contained attributes and their values
|
27
|
-
# and saving
|
37
|
+
# and saving. When the setter instance method is missing on the local record, skip that attribute.
|
28
38
|
def process_message(input)
|
29
39
|
# When the input is still json, parse it. Otherwise we're assuming it's already a demarshalled hash
|
30
40
|
input = JSON.parse(input) if input.kind_of?(String)
|
31
41
|
input.each do |attr_name, value|
|
42
|
+
# Exclude skipped attributes
|
43
|
+
next if self.class.skipped_remote_attributes.include?(attr_name.to_sym) or !attributes.has_key?(attr_name)
|
32
44
|
self.send("#{attr_name}=", value)
|
33
45
|
end
|
34
46
|
self.updated_from_message = true
|
data/lib/communicator/server.rb
CHANGED
@@ -16,12 +16,28 @@ class Communicator::Server < Sinatra::Base
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
use Rack::Auth::Basic do |username, password|
|
20
|
-
|
19
|
+
# use Rack::Auth::Basic do |username, password|
|
20
|
+
# [username, password] == [Communicator::Server.username, Communicator::Server.password]
|
21
|
+
# end
|
22
|
+
|
23
|
+
helpers do
|
24
|
+
def protected!
|
25
|
+
unless authorized?
|
26
|
+
response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth")
|
27
|
+
throw(:halt, [401, "Not authorized\n"])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def authorized?
|
32
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
33
|
+
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [Communicator::Server.username, Communicator::Server.password]
|
34
|
+
end
|
21
35
|
end
|
36
|
+
|
22
37
|
|
23
38
|
# PULL
|
24
39
|
get '/messages.json' do
|
40
|
+
protected!
|
25
41
|
# Require from_id attribute
|
26
42
|
return [409, "Specify from_id!"] unless params[:from_id]
|
27
43
|
|
@@ -39,6 +55,8 @@ class Communicator::Server < Sinatra::Base
|
|
39
55
|
|
40
56
|
# PUSH
|
41
57
|
post '/messages.json' do
|
58
|
+
protected!
|
59
|
+
|
42
60
|
body = request.body.read.strip
|
43
61
|
# Make sure a message body is given!
|
44
62
|
return [409, "No data given"] if body.length < 2
|
data/lib/communicator.rb
CHANGED
@@ -20,15 +20,28 @@ module Communicator
|
|
20
20
|
# Register a given class as a receiver from source (underscored name). Will then
|
21
21
|
# mix in the instance methods from Communicator::ActiveRecord::InstanceMethods so
|
22
22
|
# message processing and publishing functionality is included
|
23
|
-
def register_receiver(target, source)
|
23
|
+
def register_receiver(target, source, options={})
|
24
24
|
receivers[source] = target
|
25
25
|
target.send(:include, Communicator::ActiveRecordIntegration::InstanceMethods)
|
26
|
+
|
27
|
+
target.skip_remote_attributes(*options[:except]) if options[:except]
|
28
|
+
|
29
|
+
target
|
26
30
|
end
|
27
31
|
|
28
32
|
# Tries to find the receiver for given source, raising Communicator::ReceiverUnknown
|
29
33
|
# on failure
|
30
34
|
def receiver_for(source)
|
31
35
|
return receivers[source] if receivers[source]
|
36
|
+
|
37
|
+
# If not found in the first place, maybe the class just isn't loaded yet and
|
38
|
+
# thus hasn't registered - let's require all models and try again
|
39
|
+
if defined?(Rails)
|
40
|
+
Dir[File.join(Rails.root, 'app/models/**/*.rb')].each {|model| require model}
|
41
|
+
return receivers[source] if receivers[source]
|
42
|
+
end
|
43
|
+
|
44
|
+
# When everything else fails, just throw an exception...
|
32
45
|
raise Communicator::ReceiverUnknown.new("No receiver registered for '#{source}'")
|
33
46
|
end
|
34
47
|
end
|
data/test/config.ru
CHANGED
@@ -9,6 +9,7 @@ require 'communicator'
|
|
9
9
|
|
10
10
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => "db/test_server.sqlite3")
|
11
11
|
require 'lib/post'
|
12
|
+
require 'lib/comment'
|
12
13
|
|
13
14
|
Communicator::Server.username = 'testuser'
|
14
15
|
Communicator::Server.password = 'pwd'
|
data/test/helper.rb
CHANGED
@@ -16,12 +16,14 @@ require 'factories'
|
|
16
16
|
# Connect to client test database
|
17
17
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => "db/test_client.sqlite3")
|
18
18
|
require 'lib/post'
|
19
|
+
require 'lib/comment'
|
19
20
|
|
20
21
|
# Connect to server database too so we can peek into what's happening over there
|
21
22
|
class TestServerDatabase < ActiveRecord::Base
|
22
23
|
establish_connection(:adapter => 'sqlite3', :database => "db/test_server.sqlite3")
|
23
24
|
end
|
24
25
|
require 'lib/test_server_database/post'
|
26
|
+
require 'lib/test_server_database/comment'
|
25
27
|
require 'lib/test_server_database/inbound_message'
|
26
28
|
require 'lib/test_server_database/outbound_message'
|
27
29
|
|
@@ -39,9 +41,11 @@ class Test::Unit::TestCase
|
|
39
41
|
Communicator::InboundMessage.delete_all
|
40
42
|
Communicator::OutboundMessage.delete_all
|
41
43
|
Post.delete_all
|
44
|
+
Comment.delete_all
|
42
45
|
|
43
46
|
TestServerDatabase::InboundMessage.delete_all
|
44
47
|
TestServerDatabase::OutboundMessage.delete_all
|
45
48
|
TestServerDatabase::Post.delete_all
|
49
|
+
TestServerDatabase::Comment.delete_all
|
46
50
|
end
|
47
51
|
end
|
data/test/lib/comment.rb
ADDED
data/test/test_client.rb
CHANGED
@@ -121,6 +121,22 @@ class TestClient < Test::Unit::TestCase
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
+
# Make sure attributes skipped with :except are not saved at remote
|
125
|
+
context "PUSHing a new comment" do
|
126
|
+
setup do
|
127
|
+
assert @comment = Comment.create(:title => 'my comment', :body => 'some comment')
|
128
|
+
Communicator::Client.push
|
129
|
+
end
|
130
|
+
|
131
|
+
should "have created the comment at remote" do
|
132
|
+
assert_equal 'some comment', TestServerDatabase::Comment.first.body
|
133
|
+
end
|
134
|
+
|
135
|
+
should "have skipped permissions attribute when processing at remote" do
|
136
|
+
assert_nil TestServerDatabase::Comment.first.title
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
124
140
|
context "when an update message is created at remote" do
|
125
141
|
setup do
|
126
142
|
@remote_msg = TestServerDatabase::OutboundMessage.create!(:body => {:post => {:id => 25, :title => 'new title', :body => 'remote body'}}.to_json)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: communicator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christoph Olszowka
|
@@ -194,11 +194,14 @@ files:
|
|
194
194
|
- test/config.ru
|
195
195
|
- test/factories.rb
|
196
196
|
- test/helper.rb
|
197
|
+
- test/lib/comment.rb
|
197
198
|
- test/lib/post.rb
|
199
|
+
- test/lib/test_server_database/comment.rb
|
198
200
|
- test/lib/test_server_database/inbound_message.rb
|
199
201
|
- test/lib/test_server_database/outbound_message.rb
|
200
202
|
- test/lib/test_server_database/post.rb
|
201
203
|
- test/migrate/20101101093519_create_posts.rb
|
204
|
+
- test/migrate/20101103120519_create_comments.rb
|
202
205
|
- test/test_client.rb
|
203
206
|
- test/test_message_models.rb
|
204
207
|
- test/test_server.rb
|
@@ -239,11 +242,14 @@ summary: Data push/pull between apps with local inbound/outbound queue and easy
|
|
239
242
|
test_files:
|
240
243
|
- test/factories.rb
|
241
244
|
- test/helper.rb
|
245
|
+
- test/lib/comment.rb
|
242
246
|
- test/lib/post.rb
|
247
|
+
- test/lib/test_server_database/comment.rb
|
243
248
|
- test/lib/test_server_database/inbound_message.rb
|
244
249
|
- test/lib/test_server_database/outbound_message.rb
|
245
250
|
- test/lib/test_server_database/post.rb
|
246
251
|
- test/migrate/20101101093519_create_posts.rb
|
252
|
+
- test/migrate/20101103120519_create_comments.rb
|
247
253
|
- test/test_client.rb
|
248
254
|
- test/test_message_models.rb
|
249
255
|
- test/test_server.rb
|