Module: Danthes

Defined in:
lib/danthes.rb,
lib/danthes/engine.rb,
lib/danthes/version.rb,
lib/danthes/view_helpers.rb,
lib/danthes/faye_extension.rb,
lib/generators/danthes_generator.rb,
lib/generators/danthes/install_generator.rb,
lib/generators/danthes/redis_install_generator.rb

Defined Under Namespace

Modules: Generators, ViewHelpers Classes: Engine, Error, FayeExtension

Constant Summary collapse

ACCEPTED_KEYS =

List of accepted options in config file

%w(adapter server secret_token mount signature_expiration timeout)
REDIS_ACCEPTED_KEYS =

List of accepted options in redis config file

%w(host port password database namespace socket)
DEFAULT_OPTIONS =

Default options

{ mount: '/faye', timeout: 60, extensions: [FayeExtension.new] }
VERSION =
'2.0.1'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configObject (readonly)

Returns the value of attribute config.



13
14
15
# File 'lib/danthes.rb', line 13

def config
  @config
end

.envObject

Returns the value of attribute env.



14
15
16
# File 'lib/danthes.rb', line 14

def env
  @env
end

Class Method Details

.faye_appObject

Returns the Faye Rack application.



111
112
113
114
115
116
117
# File 'lib/danthes.rb', line 111

def faye_app
  rack_config = {}
  [:engine, :mount, :ping, :timeout, :extensions, :websocket_extensions ].each do |k|
    rack_config[k] = config[k] if config[k]
  end
  ::Faye::RackAdapter.new(rack_config)
end

.load_config(filename) ⇒ Object

Loads the configuration from a given YAML file



37
38
39
40
41
42
43
# File 'lib/danthes.rb', line 37

def load_config(filename)
  yaml = ::YAML.load(::ERB.new(::File.read(filename)).result)[env]
  fail ArgumentError, "The #{env} environment does not exist in #{filename}" if yaml.nil?
  yaml.each do |key, val|
    config[key.to_sym] = val if ACCEPTED_KEYS.include?(key)
  end
end

.load_redis_config(filename) ⇒ Object

Loads the options from a given YAML file



46
47
48
49
50
51
52
53
54
55
# File 'lib/danthes.rb', line 46

def load_redis_config(filename)
  require 'faye/redis'
  yaml = ::YAML.load(::ERB.new(::File.read(filename)).result)[env]
  # default redis options
  options = { type: Faye::Redis, host: 'localhost', port: 6379 }
  yaml.each do |key, val|
    options[key.to_sym] = val if REDIS_ACCEPTED_KEYS.include?(key)
  end
  config[:engine] = options
end

.message(channel, data) ⇒ Object

Returns a message hash for sending to Faye



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/danthes.rb', line 77

def message(channel, data)
  message = { channel: channel,
              data: { channel: channel },
              ext: { danthes_token: config[:secret_token] }
            }
  if data.is_a? String
    message[:data][:eval] = data
  else
    message[:data][:data] = data
  end
  message
end

.publish_message(message) ⇒ Object

Sends the given message hash to the Faye server using Net::HTTP.



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/danthes.rb', line 64

def publish_message(message)
  fail Error, 'No server specified, ensure danthes.yml was loaded properly.' unless config[:server]
  url = URI.parse(server_url)

  form = ::Net::HTTP::Post.new(url.path.empty? ? '/' : url.path)
  form.set_form_data(message: message.to_json)

  http = ::Net::HTTP.new(url.host, url.port)
  http.use_ssl = url.scheme == 'https'
  http.start { |h| h.request(form) }
end

.publish_to(channel, data) ⇒ Object

Publish the given data to a specific channel. This ends up sending a Net::HTTP POST request to the Faye server.



59
60
61
# File 'lib/danthes.rb', line 59

def publish_to(channel, data)
  publish_message(message(channel, data))
end

.server_urlObject



90
91
92
# File 'lib/danthes.rb', line 90

def server_url
  [config[:server], config[:mount].gsub(/^\//, '')].join('/')
end

.signature_expired?(timestamp) ⇒ Boolean

Determine if the signature has expired given a timestamp.

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/danthes.rb', line 105

def signature_expired?(timestamp)
  return false unless config[:signature_expiration]
  timestamp < ((Time.now.to_f - config[:signature_expiration]) * 1000).round
end

.startupObject

Resets the configuration to the default Set environment



27
28
29
30
31
32
33
34
# File 'lib/danthes.rb', line 27

def startup
  @config = DEFAULT_OPTIONS.dup
  @env = if defined? ::Rails
           ::Rails.env
         else
           ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
         end
end

.subscription(options = {}) ⇒ Object

Returns a subscription hash to pass to the PrivatePub.sign call in JavaScript. Any options passed are merged to the hash.



96
97
98
99
100
101
102
# File 'lib/danthes.rb', line 96

def subscription(options = {})
  sub = { server: server_url, timestamp: (Time.now.to_f * 1000).round }.merge(options)
  sub[:signature] = ::Digest::SHA1.hexdigest([config[:secret_token],
                                            sub[:channel],
                                            sub[:timestamp]].join)
  sub
end