pousse 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -3,6 +3,12 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in pousse.gemspec
4
4
  gemspec
5
5
 
6
+ group :development do
7
+ gem 'coffee-script', '>= 2.2.0'
8
+ gem 'uglifier', '>= 2.1.1'
9
+ end
10
+
6
11
  group :test do
7
12
  gem 'rspec'
13
+ gem 'therubyracer', require: 'v8'
8
14
  end
data/README.md CHANGED
@@ -28,15 +28,9 @@ end
28
28
  Add this line to your layout :
29
29
 
30
30
  ```
31
- <div data-pousse="<%= Pousse::layout([:everybody]) %>">
31
+ <script><%= Pousse::js([:everybody], [server], [secret]) %></script>
32
32
  ```
33
33
 
34
- Include the javascript :
35
-
36
- ```
37
- //require pousse
38
-
39
- ```
40
34
 
41
35
  Create a new mailer in app/mailer/pousse.rb
42
36
  ```
@@ -44,16 +38,24 @@ class AlertMailer < Pousse::Mailer
44
38
  def send_alert
45
39
  mail(
46
40
  to: 'everybody',
47
- body: 'alert("Hello World !")'
41
+ body: 'alert("Hello World !");'
48
42
  )
49
43
  end
50
44
  end
51
45
  ```
52
46
 
47
+ ### Your node server on heroku :
48
+
49
+ ```
50
+ git clone ...
51
+ heroku ...
52
+ ```
53
53
 
54
54
  ### TODO :
55
55
 
56
- Should add some logging when redis is not available.
56
+ - Should add some logging when redis is not available.
57
+ - Should add some spec for the configuration.
58
+ - Should try again every 30 second or something when the poussette server is offline.
57
59
 
58
60
  ## Contributing
59
61
 
data/Rakefile CHANGED
@@ -1 +1,26 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ namespace :pousse do
4
+
5
+ desc 'Precompile pousse.js'
6
+ task :precompile do
7
+ require './lib/pousse'
8
+ require 'erb'
9
+ require 'coffee-script'
10
+ require 'uglifier'
11
+ template = File.read(Pousse::TEMPLATE_SOURCE)
12
+ token = "<%= token %>"
13
+ iv = "<%= iv %>"
14
+ server = "<%= server %>"
15
+ script = CoffeeScript.compile(ERB.new(template, 0).result(binding))
16
+ script = script.gsub("\n", '')
17
+ .gsub(" ", ' ')
18
+ .gsub(" ", ' ')
19
+ .gsub(" ", ' ')
20
+ .gsub(" ", ' ')
21
+ #TODO : Here we should use the next line with the right parameters.
22
+ #script = Uglifier.compile(script)
23
+ File.open(Pousse::TEMPLATE_MIN, 'w') { |file| file.write(script) }
24
+ end
25
+
26
+ end
@@ -0,0 +1,21 @@
1
+ async = (u, c) ->
2
+ script = document.createElement('script')
3
+ script.async = true
4
+ script.src = u
5
+ other = document.getElementsByTagName('script')[0]
6
+ script.addEventListener "load", ((e) ->
7
+ c null, e
8
+ ), false
9
+ other.parentNode.insertBefore(script, other)
10
+ async('<%= server %>/socket.io/socket.io.js', ()->
11
+ socket = io.connect('<%= server %>')
12
+ socket.on('connect', (data)->
13
+ socket.emit('auth',
14
+ token: '<%= token %>',
15
+ iv: '<%= iv %>'
16
+ )
17
+ )
18
+ socket.on('code', (data)->
19
+ eval(data)
20
+ )
21
+ )
@@ -0,0 +1 @@
1
+ (function() { var async; async = function(u, c) { var other, script; script = document.createElement('script'); script.async = true; script.src = u; other = document.getElementsByTagName('script')[0]; script.addEventListener("load", (function(e) { return c(null, e); }), false); return other.parentNode.insertBefore(script, other); }; async('<%= server %>/socket.io/socket.io.js', function() { var socket; socket = io.connect('<%= server %>'); socket.on('connect', function(data) { return socket.emit('auth', { token: '<%= token %>', iv: '<%= iv %>' }); }); return socket.on('code', function(data) { return eval(data); }); });}).call(this);
@@ -1,8 +1,10 @@
1
1
  module Pousse
2
2
  class Configuration
3
3
  def initialize
4
- redis = {}
4
+ @redis = {}
5
+ @server = ''
6
+ @secret = nil
5
7
  end
6
- attr_accessor :redis
8
+ attr_accessor :redis, :server, :secret
7
9
  end
8
10
  end
@@ -0,0 +1,34 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+ require 'openssl/cipher'
4
+ require 'openssl/digest'
5
+
6
+ module Pousse
7
+ module Crypt
8
+
9
+ def self.decrypt(data, key, iv)
10
+ aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
11
+ aes.decrypt
12
+ aes.reset
13
+ aes.key = Digest::SHA256.digest(key)
14
+ aes.iv = Base64.strict_decode64(iv)
15
+
16
+ data = Base64.strict_decode64(data)
17
+ return aes.update(data) + aes.final
18
+ end
19
+
20
+ def self.encrypt(data, key, iv = nil)
21
+ aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
22
+ iv ||= aes.random_iv
23
+ aes.encrypt
24
+ aes.reset
25
+ aes.key = Digest::SHA256.digest(key)
26
+ aes.iv = iv
27
+
28
+ encrypted_data = aes.update(data) + aes.final
29
+ res = Base64.strict_encode64( encrypted_data )
30
+ return [res, Base64.strict_encode64(iv)]
31
+ end
32
+
33
+ end
34
+ end
@@ -7,13 +7,11 @@ module Pousse
7
7
  end
8
8
 
9
9
  def deliver!(mail)
10
- puts "DELIVER ??"
11
10
  begin
12
- redis = Redis.new
11
+ redis = Redis.new @redis_config
13
12
  mail.to.each do |to|
14
13
  redis.publish(to, mail.body.decoded)
15
14
  end
16
- @redis_config
17
15
  rescue Exception => e
18
16
  #TODO: Use a real logguer ??
19
17
  puts "NOTIFICATION NOT DELIVERED: #{e.message}"
@@ -1,3 +1,3 @@
1
1
  module Pousse
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/pousse.rb CHANGED
@@ -4,12 +4,21 @@ require "pousse/version"
4
4
  require 'pousse/configuration'
5
5
  require 'pousse/redis_delivery'
6
6
  require 'pousse/mailer'
7
+ require 'pousse/crypt'
7
8
 
8
9
  module Pousse
10
+ TEMPLATE_SOURCE = File.join(
11
+ File.dirname(__FILE__), '..', 'app', 'assets', 'javascript', 'pousse.js.coffee.erb'
12
+ )
13
+
14
+ TEMPLATE_MIN = File.join(
15
+ File.dirname(__FILE__), '..', 'app', 'assets', 'javascript', 'pousse.min.js.erb'
16
+ )
9
17
  class << self
10
18
 
11
19
  attr_accessor :configuration
12
20
 
21
+
13
22
  def configuration
14
23
  @configuration ||= Configuration.new
15
24
  end
@@ -17,5 +26,15 @@ module Pousse
17
26
  def configure
18
27
  yield configuration
19
28
  end
29
+
30
+ def js(channels, server, secret = nil)
31
+ require 'erb'
32
+ require 'json'
33
+ secret ||= configuration.secret
34
+ raise 'You should configure your secret or specify it.' if secret == nil
35
+ token, iv = Pousse::Crypt.encrypt(channels.to_json, secret)
36
+ return ERB.new(File.read(TEMPLATE_MIN)).result(binding)
37
+ end
38
+
20
39
  end
21
40
  end
data/pousse.gemspec CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Pousse::VERSION
9
9
  spec.authors = ["Julien Lerpscher", "Luc Boissaye"]
10
10
  spec.email = ["julien@studyka.com", "luc@studyka.com"]
11
- spec.description = %q{Pousse, simple realtime for rails applications}
11
+ spec.description = %q{Add Realtime to your application}
12
12
  spec.summary = %q{Pousse, simple realtime for rails applications}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/Studyka/pousse"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_dependency('redis', '>= 3.0.4')
24
24
  spec.add_dependency('actionmailer', '>= 3.2.13')
25
+
25
26
  end
@@ -0,0 +1,34 @@
1
+ #encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Pousse::Crypt do
5
+
6
+
7
+ describe '#encrypt' do
8
+
9
+
10
+ it 'encrypt a string' do
11
+ source = '["test"]'
12
+ key = 'superKey'
13
+ iv = '1234567890123456'
14
+ res, iv = Pousse::Crypt::encrypt(source, key, iv)
15
+ Pousse::Crypt::decrypt(res, key, iv).should == source
16
+ end
17
+
18
+ it 'encrypt a string' do
19
+ source = '["test", "asdasd"]'
20
+ key = 'poussette'
21
+ res, iv = Pousse::Crypt::encrypt(source, key)
22
+ Pousse::Crypt::decrypt(res, key, iv).should == source
23
+ end
24
+
25
+ it 'encrypt and decrypt a string' do
26
+ source = 'Here is some data for the coding'
27
+ key = 'superKey'
28
+ enc, iv = Pousse::Crypt::encrypt(source, key)
29
+ res = Pousse::Crypt::decrypt(enc, key, iv)
30
+ res.should == source
31
+ end
32
+ end
33
+
34
+ end
@@ -35,23 +35,57 @@ describe Pousse do
35
35
  .with('everybody', 'alert("Générale !");')
36
36
  mailer.send_alert.deliver
37
37
  end
38
-
39
38
  end
40
39
 
40
+ describe "#js" do
41
+
42
+ it 'returns some javascript' do
43
+ require 'v8'
44
+ script = Pousse::js(['test'], 'http://your-poussette-server.com', 'your secret')
45
+ cxt = V8::Context.new
46
+ expect {
47
+ # Javascript syntax should be valid.
48
+ cxt.eval( "test = function(){ #{script} }")
49
+ }.to_not raise_exception
50
+ end
51
+
52
+ context 'with global configuration' do
53
+
54
+ it 'returns some javascript' do
55
+ Pousse.configure do |config|
56
+ config.secret = 'your secret'
57
+ end
58
+ require 'v8'
59
+ script = Pousse::js(['test'], 'http://your-poussette-server.com')
60
+ cxt = V8::Context.new
61
+ expect {
62
+ # Javascript syntax should be valid.
63
+ cxt.eval( "test = function(){ #{script} }")
64
+ }.to_not raise_exception
65
+ end
66
+ end
67
+
68
+ context "without configuration" do
69
+ it 'raise an exception' do
70
+ Pousse.configure do |config|
71
+ config.secret = nil
72
+ end
73
+ expect {
74
+ Pousse::js(['test'], 'http://your-poussette-server.com')
75
+ }.to raise_exception
76
+ end
77
+
78
+ end
79
+ end
41
80
 
42
81
  describe '#configure' do
43
82
  it 'accept redis_configuration' do
44
83
  Pousse::configure do |config|
84
+ #config.should be instance_of Pousse::Configuration
45
85
  config.redis = {}
46
86
  end
47
87
  end
48
88
  end
49
89
 
50
- describe '#send' do
51
- it 'render and send a js message' do
52
- #Pousse::pousse('test', 'mytemplate')
53
- end
54
- end
55
-
56
90
  end
57
91
 
@@ -17,8 +17,8 @@ describe Pousse::RedisDelivery do
17
17
 
18
18
  let :mail do
19
19
  stub(
20
- to: 'everyone',
21
- body: 'alert("Générale !");'
20
+ to: ['everyone'],
21
+ body: stub(decoded: 'alert("Générale !");')
22
22
  )
23
23
  end
24
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pousse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -76,7 +76,7 @@ dependencies:
76
76
  - - ! '>='
77
77
  - !ruby/object:Gem::Version
78
78
  version: 3.2.13
79
- description: Pousse, simple realtime for rails applications
79
+ description: Add Realtime to your application
80
80
  email:
81
81
  - julien@studyka.com
82
82
  - luc@studyka.com
@@ -90,16 +90,20 @@ files:
90
90
  - LICENSE.txt
91
91
  - README.md
92
92
  - Rakefile
93
+ - app/assets/javascript/pousse.js.coffee.erb
94
+ - app/assets/javascript/pousse.min.js.erb
93
95
  - lib/pousse.rb
94
96
  - lib/pousse/configuration.rb
97
+ - lib/pousse/crypt.rb
95
98
  - lib/pousse/mailer.rb
96
99
  - lib/pousse/redis_delivery.rb
97
100
  - lib/pousse/version.rb
98
101
  - pousse.gemspec
102
+ - spec/pousse/crypt_spec.rb
99
103
  - spec/pousse/pousse_spec.rb
100
- - spec/redis_delivery_spec.rb
104
+ - spec/pousse/redis_delivery_spec.rb
101
105
  - spec/spec_helper.rb
102
- homepage: ''
106
+ homepage: https://github.com/Studyka/pousse
103
107
  licenses:
104
108
  - MIT
105
109
  post_install_message:
@@ -125,6 +129,7 @@ signing_key:
125
129
  specification_version: 3
126
130
  summary: Pousse, simple realtime for rails applications
127
131
  test_files:
132
+ - spec/pousse/crypt_spec.rb
128
133
  - spec/pousse/pousse_spec.rb
129
- - spec/redis_delivery_spec.rb
134
+ - spec/pousse/redis_delivery_spec.rb
130
135
  - spec/spec_helper.rb