class Pinkman::Broadcaster

Attributes

model[RW]
record[RW]
scope[RW]

Public Class Methods

broadcast(room, scope, action, record) click to toggle source
# File lib/pinkman/broadcaster.rb, line 21
def self.broadcast room, scope, action, record
  ActionCable.server.broadcast(room_name_from_record(room,record), {action: action, data: record.json_hash(scope)})
end
broadcasters() click to toggle source
# File lib/pinkman/broadcaster.rb, line 17
def self.broadcasters
  @broadcasters ||= {}
end
new(options) click to toggle source
# File lib/pinkman/broadcaster.rb, line 11
def initialize options
  self.scope = options[:scope]
  self.model = options[:model]
  true  
end
room_name_from_params(broadcaster, params) click to toggle source
# File lib/pinkman/broadcaster.rb, line 39
def self.room_name_from_params broadcaster, params
  if params[:filter_by].is_a?(String) or params[:filter_by].is_a?(Numeric)
    broadcaster.encrypt(broadcaster.room,params[:filter_by].to_s)
  elsif params[:filter_by].is_a? Array
    broadcaster.encrypt(broadcaster.room, params[:filter_by].map(&:to_s).join(' '))
  else
    broadcaster.room
  end
end
room_name_from_record(room_name, record) click to toggle source
# File lib/pinkman/broadcaster.rb, line 49
def self.room_name_from_record room_name, record
  broadcaster = broadcasters[room_name.to_sym]
  if broadcaster
    broadcaster.room_name(record)
  else
    raise "#{room_name} not found/declared"
  end
end
stream(channel, current_allowed_scopes, params) click to toggle source
# File lib/pinkman/broadcaster.rb, line 25
def self.stream channel, current_allowed_scopes, params
  if params[:room].present? and params[:scope].present?
    broadcaster = broadcasters[params[:room].to_sym]
    raise 'Unknown scope' unless params[:scope].is_a?(String)
    if broadcaster.present? and params[:scope].to_sym.in?(current_allowed_scopes)
      channel.stream_from(room_name_from_params(broadcaster,params))
    else
      raise "Insuficient permissions or room '#{params[:room]}' not found."
    end
  else
    raise 'Room or Scope not specified through client.'
  end
end

Public Instance Methods

encrypt(room_name, passphrase) click to toggle source
# File lib/pinkman/broadcaster.rb, line 91
def encrypt room_name, passphrase
  md5(room_name.to_s + 'pinkroom' + passphrase)
end
encrypt_room_name(record) click to toggle source
# File lib/pinkman/broadcaster.rb, line 86
def encrypt_room_name(record)
  passphrase = filter_by.map { |attribute| record.send(attribute) }.join(' ')
  encrypt(room,passphrase)
end
filter_by(*args) click to toggle source
# File lib/pinkman/broadcaster.rb, line 66
def filter_by *args
  if args.any?
    @filter_by = args
  else
    @filter_by ||= []
  end
end
get_record(params) click to toggle source
# File lib/pinkman/broadcaster.rb, line 78
def get_record params
  if filter_by.any? and params[:filter_by].present?
    where_hash = {}
    filter_by.each_with_index {|attribute,i| where_hash[attribute] = params[:filter_by][i] }
    model.where(where_hash).first if model.where(where_hash).any?
  end
end
md5(val) click to toggle source
# File lib/pinkman/broadcaster.rb, line 99
def md5 val
  Digest::MD5.hexdigest(val) 
end
room(room_name=nil) click to toggle source
# File lib/pinkman/broadcaster.rb, line 58
def room room_name=nil
  if room_name.present?
    @room = room_name
  else
    @room
  end
end
room_name(record=nil) click to toggle source
# File lib/pinkman/broadcaster.rb, line 95
def room_name(record=nil)
  (record.present? and filter_by.any?) ? encrypt_room_name(record) : room
end
save() click to toggle source
# File lib/pinkman/broadcaster.rb, line 74
def save
  valid? and (self.class.broadcasters[room.to_sym] = self) and set_callbacks
end
set_callbacks() click to toggle source
# File lib/pinkman/broadcaster.rb, line 103
def set_callbacks
  if valid?
    ['create','update','destroy'].each do |action|
      current_room = room
      current_scope = scope
      method_name = "broadcast_#{action}_to_#{room}".to_sym
      unless model.instance_methods.include?(method_name)
        model.define_method method_name do
          Pinkman::Broadcaster.broadcast(current_room, current_scope, action, self)
        end  
        model.send("after_#{action}".to_sym, method_name)
      end
    end
    true
  end
end