trabajo-afectivo/lib/session.rb

860 lines
26 KiB
Ruby
Raw Normal View History

2012-07-23 22:22:23 +00:00
require 'json'
2013-04-18 12:51:07 +00:00
require 'rss'
2013-05-05 22:54:06 +00:00
require 'session_helper'
2012-07-23 22:22:23 +00:00
module Session
2013-01-24 01:01:47 +00:00
# get application root directory
@root = Dir.pwd.to_s
2013-02-01 00:01:20 +00:00
if !@root || @root.empty? || @root == '/'
2013-01-24 01:01:47 +00:00
@root = Rails.root
end
# get working directories
@path = @root + '/tmp/websocket'
@pid = @root + '/tmp/pids/sessionworker.pid'
# create global vars for threads
2012-08-03 22:46:05 +00:00
@@user_threads = {}
@@client_threads = {}
2012-07-23 22:22:23 +00:00
2012-11-26 05:04:44 +00:00
def self.create( client_id, session, meta )
2012-07-23 22:22:23 +00:00
path = @path + '/' + client_id.to_s
FileUtils.mkpath path
2012-11-26 05:04:44 +00:00
meta[:last_ping] = Time.new.to_i.to_s
2013-04-08 18:56:59 +00:00
File.open( path + '/session', 'wb' ) { |file|
2012-11-26 05:04:44 +00:00
data = {
:user => {
:id => session['id'],
},
:meta => meta,
}
# puts 'CREATE' + Marshal.dump(data)
2013-04-08 18:56:59 +00:00
file.write Marshal.dump(data)
2012-07-23 22:22:23 +00:00
}
2012-11-02 16:10:22 +00:00
# send update to browser
if session['id']
2012-11-26 05:04:44 +00:00
self.send( client_id, {
2012-11-02 16:10:22 +00:00
:event => 'ws:login',
:data => { :success => true },
})
end
2012-07-23 22:22:23 +00:00
end
def self.spool_create( msg )
path = @path + '/spool/'
FileUtils.mkpath path
file = Time.new.to_f.to_s + '-' + rand(99999).to_s
File.open( path + '/' + file , 'wb' ) { |file|
data = {
:msg => msg,
:timestamp => Time.now.to_i,
}
# puts 'CREATE' + Marshal.dump(data)
file.write data.to_json
}
end
def self.spool_list( timestamp, current_user_id )
path = @path + '/spool/'
FileUtils.mkpath path
data = []
to_delete = []
files = []
Dir.foreach( path ) {|entry|
next if entry == '.' || entry == '..'
files.push entry
}
files.sort.each {|entry|
filename = path + '/' + entry
next if !File::exists?( filename )
File.open( filename, 'rb' ) { |file|
all = file.read
spool = JSON.parse( all )
begin
message_parsed = JSON.parse( spool['msg'] )
rescue => e
log 'error', "can't parse spool message: #{ message }, #{ e.inspect }"
next
end
# ignore message older then 48h
if spool['timestamp'] + (2 * 86400) < Time.now.to_i
to_delete.push path + '/' + entry
next
end
# add spool attribute to push spool info to clients
2013-06-28 22:26:04 +00:00
message_parsed['spool'] = true
# only send not already now messages
if !timestamp || timestamp < spool['timestamp']
# spool to recipient list
2013-06-28 22:26:04 +00:00
if message_parsed['recipient'] && message_parsed['recipient']['user_id']
message_parsed['recipient']['user_id'].each { |user_id|
if current_user_id == user_id
item = {
:type => 'direct',
:message => message_parsed,
}
data.push item
end
}
# spool to every client
else
item = {
:type => 'broadcast',
:message => message_parsed,
}
data.push item
end
end
}
}
to_delete.each {|file|
File.delete(file)
}
return data
end
2012-11-26 05:04:44 +00:00
def self.list
client_ids = self.sessions
session_list = {}
client_ids.each { |client_id|
data = self.get(client_id)
next if !data
session_list[client_id] = data
}
return session_list
end
2012-11-26 23:22:52 +00:00
def self.touch( client_id )
data = self.get(client_id)
2013-07-26 22:43:07 +00:00
return if !data
2012-11-26 23:22:52 +00:00
path = @path + '/' + client_id.to_s
data[:meta][:last_ping] = Time.new.to_i.to_s
2013-04-08 18:56:59 +00:00
File.open( path + '/session', 'wb' ) { |file|
file.write Marshal.dump(data)
2012-11-26 23:22:52 +00:00
}
return true
end
2012-07-23 22:22:23 +00:00
def self.get( client_id )
session_file = @path + '/' + client_id.to_s + '/session'
data = nil
return if !File.exist? session_file
2013-04-17 23:45:23 +00:00
begin
File.open( session_file, 'rb' ) { |file|
file.flock( File::LOCK_EX )
all = file.read
file.flock( File::LOCK_UN )
2012-07-23 22:22:23 +00:00
data = Marshal.load( all )
2013-04-17 23:45:23 +00:00
}
rescue Exception => e
2013-04-18 12:51:07 +00:00
File.delete(session_file)
2013-04-17 23:45:23 +00:00
puts "Error reading '#{session_file}':"
puts e.inspect
return
end
2012-07-23 22:22:23 +00:00
return data
end
2012-11-26 05:04:44 +00:00
def self.send( client_id, data )
2012-08-03 23:35:21 +00:00
path = @path + '/' + client_id.to_s + '/'
filename = 'send-' + Time.new().to_f.to_s# + '-' + rand(99999999).to_s
2013-02-19 19:04:35 +00:00
check = true
count = 0
2013-02-19 19:04:35 +00:00
while check
2012-08-03 23:35:21 +00:00
if File::exists?( path + filename )
count += 1
filename = filename + '-' + count
# filename = filename + '-' + rand(99999).to_s
# filename = filename + '-' + rand(99999).to_s
2013-02-19 19:04:35 +00:00
else
check = false
end
2012-07-23 22:22:23 +00:00
end
2012-08-03 23:35:21 +00:00
return false if !File.directory? path
2013-04-08 18:56:59 +00:00
File.open( path + 'a-' + filename, 'wb' ) { |file|
2013-01-23 07:22:27 +00:00
file.flock( File::LOCK_EX )
2013-04-08 18:56:59 +00:00
file.write data.to_json
2013-01-23 07:22:27 +00:00
file.flock( File::LOCK_UN )
file.close
2012-07-23 22:22:23 +00:00
}
2013-02-28 21:38:03 +00:00
return false if !File.exists?( path + 'a-' + filename )
2013-02-19 19:04:35 +00:00
FileUtils.mv( path + 'a-' + filename, path + filename )
2012-07-23 22:22:23 +00:00
return true
end
def self.jobs
# just make sure that spool path exists
2013-01-15 23:10:27 +00:00
if !File::exists?( @path )
FileUtils.mkpath @path
end
2012-08-03 22:46:05 +00:00
Thread.abort_on_exception = true
2012-07-23 22:22:23 +00:00
while true
client_ids = self.sessions
client_ids.each { |client_id|
2012-08-07 21:53:43 +00:00
# connection already open
next if @@client_threads[client_id]
# get current user
2012-11-26 05:04:44 +00:00
session_data = Session.get( client_id )
next if !session_data
next if !session_data[:user]
next if !session_data[:user][:id]
user = User.find( session_data[:user][:id] )
2012-08-03 22:46:05 +00:00
next if !user
# start user thread
start_user_thread = false
2012-08-03 22:46:05 +00:00
if !@@user_threads[user.id]
start_user_thread = true
2012-08-03 22:46:05 +00:00
@@user_threads[user.id] = Thread.new {
UserState.new(user.id)
@@user_threads[user.id] = nil
2012-11-26 23:22:52 +00:00
puts "close user(#{user.id}) thread"
2012-08-03 22:46:05 +00:00
# raise "Exception from thread"
}
2012-07-23 22:22:23 +00:00
end
# wait with client thread unil user thread has done some little work
if start_user_thread
2012-08-07 21:53:43 +00:00
sleep 0.5
end
2012-08-03 22:46:05 +00:00
# start client thread
if !@@client_threads[client_id]
@@client_threads[client_id] = Thread.new {
ClientState.new(client_id)
@@client_threads[client_id] = nil
2012-11-26 23:22:52 +00:00
puts "close client(#{client_id}) thread"
2012-08-03 22:46:05 +00:00
# raise "Exception from thread"
}
end
2012-07-23 22:22:23 +00:00
}
2012-08-07 06:43:15 +00:00
# system settings
2012-11-26 23:22:52 +00:00
sleep 0.5
2012-07-23 22:22:23 +00:00
end
end
2012-08-03 22:46:05 +00:00
def self.sessions
path = @path + '/'
2013-01-15 23:10:27 +00:00
# just make sure that spool path exists
if !File::exists?( path )
FileUtils.mkpath path
end
2012-08-03 22:46:05 +00:00
data = []
Dir.foreach( path ) do |entry|
next if entry == '.' || entry == '..' || entry == 'spool'
data.push entry.to_s
2012-07-30 14:50:54 +00:00
end
2012-08-03 22:46:05 +00:00
return data
2012-07-30 14:50:54 +00:00
end
2012-08-03 22:46:05 +00:00
def self.queue( client_id )
path = @path + '/' + client_id.to_s + '/'
data = []
2013-06-17 11:00:26 +00:00
files = []
Dir.foreach( path ) {|entry|
next if entry == '.' || entry == '..'
files.push entry
}
files.sort.each {|entry|
filename = path + '/' + entry
2012-11-26 05:04:44 +00:00
if /^send/.match( entry )
2012-08-03 23:35:21 +00:00
data.push Session.queue_file( path, entry )
2012-08-03 22:46:05 +00:00
end
2013-06-17 11:00:26 +00:00
}
2012-08-03 22:46:05 +00:00
return data
end
2012-07-30 14:50:54 +00:00
2012-08-03 23:35:21 +00:00
def self.queue_file( path, filename )
file_old = path + filename
file_new = path + 'a-' + filename
FileUtils.mv( file_old, file_new )
2012-08-03 22:46:05 +00:00
data = nil
2012-08-03 23:35:21 +00:00
all = ''
2013-04-08 18:56:59 +00:00
File.open( file_new, 'rb' ) { |file|
all = file.read
2012-08-03 22:46:05 +00:00
}
2012-08-03 23:35:21 +00:00
File.delete( file_new )
data = JSON.parse( all )
2012-08-03 22:46:05 +00:00
return data
end
2012-07-30 14:50:54 +00:00
def self.broadcast( data )
# list all current clients
client_list = self.list
client_list.each {|local_client_id, local_client|
Session.send( local_client_id, data )
}
return true
end
2012-08-03 22:46:05 +00:00
def self.destory( client_id )
path = @path + '/' + client_id.to_s
FileUtils.rm_rf path
2012-07-30 14:50:54 +00:00
end
2012-08-03 22:46:05 +00:00
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
module CacheIn
@@data = {}
2012-08-07 06:43:15 +00:00
@@data_time = {}
2012-08-03 22:46:05 +00:00
@@expires_in = {}
@@expires_in_ttl = {}
2012-08-07 06:43:15 +00:00
2012-08-03 22:46:05 +00:00
def self.set( key, value, params = {} )
# puts 'CacheIn.set:' + key + '-' + value.inspect
if params[:expires_in]
@@expires_in[key] = Time.now + params[:expires_in]
@@expires_in_ttl[key] = params[:expires_in]
2012-07-30 14:50:54 +00:00
end
2012-08-03 22:46:05 +00:00
@@data[ key ] = value
2012-08-07 06:43:15 +00:00
@@data_time[ key ] = Time.now
2012-08-03 22:46:05 +00:00
end
2012-08-07 06:43:15 +00:00
def self.expired( key, params = {} )
# expire if value never was set
return true if !@@data.include? key
2012-08-07 07:30:29 +00:00
# ignore_expire
return false if params[:ignore_expire]
2012-08-07 06:43:15 +00:00
# set re_expire
if params[:re_expire]
if @@expires_in[key]
@@expires_in[key] = Time.now + @@expires_in_ttl[key]
end
return false
end
# check if expired
2012-08-03 22:46:05 +00:00
if @@expires_in[key]
return true if @@expires_in[key] < Time.now
return false
end
2012-08-07 06:43:15 +00:00
# return false if key was set without expires_in
return false
end
def self.get_time( key, params = {} )
data = self.get( key, params )
if data
return @@data_time[key]
end
2012-08-07 07:30:29 +00:00
return nil
2012-08-03 22:46:05 +00:00
end
2012-08-07 06:43:15 +00:00
2012-08-03 22:46:05 +00:00
def self.get( key, params = {} )
# puts 'CacheIn.get:' + key + '-' + @@data[ key ].inspect
2012-08-07 06:43:15 +00:00
return if self.expired( key, params )
2012-08-03 22:46:05 +00:00
@@data[ key ]
2012-07-30 14:50:54 +00:00
end
2012-08-03 22:46:05 +00:00
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
class UserState
def initialize( user_id )
@user_id = user_id
@data = {}
@cache_key = 'user_' + user_id.to_s
self.log 'notify', "---user started user state"
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
CacheIn.set( 'last_run_' + user_id.to_s , true, { :expires_in => 20.seconds } )
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
self.fetch
end
2012-08-03 22:46:05 +00:00
def fetch
user = User.find( @user_id )
return if !user
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
while true
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# check if user is still with min one open connection
if !CacheIn.get( 'last_run_' + user.id.to_s )
self.log 'notify', "---user - closeing thread - no open user connection"
2012-08-03 22:46:05 +00:00
return
end
2012-08-02 12:42:50 +00:00
self.log 'notice', "---user - fetch user data"
2012-08-03 22:46:05 +00:00
# overview
cache_key = @cache_key + '_overview'
if CacheIn.expired(cache_key)
overview = Ticket::Overviews.list(
2012-09-04 21:28:49 +00:00
:current_user => user,
2012-08-03 22:46:05 +00:00
)
overview_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch overview - ' + cache_key
2012-08-03 22:46:05 +00:00
if overview != overview_cache
self.log 'notify', 'fetch overview changed - ' + cache_key
2012-08-03 22:46:05 +00:00
# puts overview.inspect
# puts '------'
# puts overview_cache.inspect
CacheIn.set( cache_key, overview, { :expires_in => 4.seconds } )
2012-08-03 22:46:05 +00:00
end
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# overview lists
overviews = Ticket::Overviews.all(
2012-09-04 21:28:49 +00:00
:current_user => user,
2012-08-03 22:46:05 +00:00
)
overviews.each { |overview|
2013-02-01 00:01:20 +00:00
cache_key = @cache_key + '_overview_data_' + overview.link
2012-08-03 22:46:05 +00:00
if CacheIn.expired(cache_key)
overview_data = Ticket::Overviews.list(
2013-02-01 00:01:20 +00:00
:view => overview.link,
2012-09-04 21:28:49 +00:00
:current_user => user,
:array => true,
2012-08-03 22:46:05 +00:00
)
overview_data_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch overview_data - ' + cache_key
2012-08-03 22:46:05 +00:00
if overview_data != overview_data_cache
self.log 'notify', 'fetch overview_data changed - ' + cache_key
2012-08-03 22:46:05 +00:00
CacheIn.set( cache_key, overview_data, { :expires_in => 5.seconds } )
end
end
}
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# create_attributes
cache_key = @cache_key + '_ticket_create_attributes'
if CacheIn.expired(cache_key)
ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change(
2012-08-03 22:46:05 +00:00
:current_user_id => user.id,
)
ticket_create_attributes_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch ticket_create_attributes - ' + cache_key
2012-08-03 22:46:05 +00:00
if ticket_create_attributes != ticket_create_attributes_cache
self.log 'notify', 'fetch ticket_create_attributes changed - ' + cache_key
2012-08-03 22:46:05 +00:00
CacheIn.set( cache_key, ticket_create_attributes, { :expires_in => 2.minutes } )
end
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# recent viewed
cache_key = @cache_key + '_recent_viewed'
if CacheIn.expired(cache_key)
recent_viewed = RecentView.list_fulldata( user, 10 )
2012-08-03 22:46:05 +00:00
recent_viewed_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch recent_viewed - ' + cache_key
2012-08-03 22:46:05 +00:00
if recent_viewed != recent_viewed_cache
self.log 'notify', 'fetch recent_viewed changed - ' + cache_key
2012-07-30 14:50:54 +00:00
recent_viewed_full = RecentView.list_fulldata( user, 10 )
2012-08-04 10:34:47 +00:00
CacheIn.set( cache_key, recent_viewed, { :expires_in => 5.seconds } )
2012-08-03 22:46:05 +00:00
CacheIn.set( cache_key + '_push', recent_viewed_full )
end
end
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# activity steam
cache_key = @cache_key + '_activity_stream'
if CacheIn.expired(cache_key)
activity_stream = History.activity_stream( user )
activity_stream_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch activity_stream - ' + cache_key
2012-08-03 22:46:05 +00:00
if activity_stream != activity_stream_cache
self.log 'notify', 'fetch activity_stream changed - ' + cache_key
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
activity_stream_full = History.activity_stream_fulldata( user )
2012-08-04 10:34:47 +00:00
CacheIn.set( cache_key, activity_stream, { :expires_in => 0.75.minutes } )
2012-08-03 22:46:05 +00:00
CacheIn.set( cache_key + '_push', activity_stream_full )
end
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# rss
cache_key = @cache_key + '_rss'
if CacheIn.expired(cache_key)
url = 'http://www.heise.de/newsticker/heise-atom.xml'
rss_items = RSS.fetch( url, 8 )
rss_items_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', 'fetch rss - ' + cache_key
2012-08-03 22:46:05 +00:00
if rss_items != rss_items_cache
self.log 'notify', 'fetch rss changed - ' + cache_key
2012-08-03 22:46:05 +00:00
CacheIn.set( cache_key, rss_items, { :expires_in => 2.minutes } )
CacheIn.set( cache_key + '_push', {
head: 'Heise ATOM',
items: rss_items,
})
end
end
# auto population of default collections
self.log 'notice', "---user - fetch push_collection data"
# get available collections
cache_key = @cache_key + '_push_collections'
collections = CacheIn.get( cache_key )
if !collections
collections = {}
2012-10-23 20:25:42 +00:00
push_collection = SessionHelper::push_collections(user)
push_collection.each { | key, value |
collections[ key ] = true
}
CacheIn.set( cache_key, collections, { :expires_in => 2.minutes } )
end
# check all collections to push
push_collection = {}
collections.each { | key, v |
cache_key = @cache_key + '_push_collections_' + key
if CacheIn.expired(cache_key)
if push_collection.empty?
2012-10-23 20:25:42 +00:00
push_collection = SessionHelper::push_collections(user)
end
push_collection_cache = CacheIn.get( cache_key, { :re_expire => true } )
self.log 'notice', "---user - fetch push_collection data " + cache_key
if !push_collection[key] || !push_collection_cache || push_collection[key] != push_collection_cache || !push_collection[ key ].zip( push_collection_cache ).all? { |x, y| x.attributes == y.attributes }
self.log 'notify', 'fetch push_collection changed - ' + cache_key
CacheIn.set( cache_key, push_collection[key], { :expires_in => 1.minutes } )
end
end
}
self.log 'notice', "---/user-"
2012-08-04 10:01:26 +00:00
sleep 1
2012-07-30 14:50:54 +00:00
end
end
def log( level, data )
return if level == 'notice'
2012-08-03 22:46:05 +00:00
puts "#{Time.now}:user_id(#{ @user_id }) #{ data }"
end
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
class ClientState
def initialize( client_id )
@client_id = client_id
@cache_key = ''
2012-08-03 22:46:05 +00:00
@data = {}
@pushed = {}
self.log 'notify', "---client start ws connection---"
2012-08-03 22:46:05 +00:00
self.fetch
self.log 'notify', "---client exiting ws connection---"
2012-08-03 22:46:05 +00:00
end
2012-08-03 22:46:05 +00:00
def fetch
2012-08-06 04:37:08 +00:00
loop_count = 0
2012-08-03 22:46:05 +00:00
while true
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# get connection user
2012-11-26 05:04:44 +00:00
session_data = Session.get( @client_id )
return if !session_data
return if !session_data[:user]
return if !session_data[:user][:id]
2013-01-04 22:31:13 +00:00
user = User.lookup( :id => session_data[:user][:id] )
2012-08-03 22:46:05 +00:00
return if !user
# set cache key
@cache_key = 'user_' + user.id.to_s
2012-08-06 04:37:08 +00:00
loop_count += 1
self.log 'notice', "---client - looking for data of user #{user.id}"
2012-08-03 22:46:05 +00:00
# remember last run
CacheIn.set( 'last_run_' + user.id.to_s , true, { :expires_in => 20.seconds } )
# verify already pushed data
if !CacheIn.get( 'pushed_users' + @client_id.to_s )
CacheIn.set( 'pushed_users' + @client_id.to_s , true, { :expires_in => 20.seconds } )
if @pushed[:users]
users = {}
@pushed[:users].each {|user_id, user_o|
self.user( user_id, users )
}
if !users.empty?
users.each {|user_id, user_data|
self.log 'notify', "push update of already pushed user id #{user_id}"
}
# send update to browser
self.send({
:data => {
:collections => {
:User => users,
},
},
:event => [ 'loadCollection', 'ticket_overview_rebuild' ],
});
end
end
end
# verify already pushed data
if !CacheIn.get( 'pushed_tickets' + @client_id.to_s )
CacheIn.set( 'pushed_tickets' + @client_id.to_s , true, { :expires_in => 20.seconds } )
if @pushed[:tickets]
tickets = {}
users = {}
@pushed[:tickets].each {|ticket_id, ticket_data|
self.ticket( ticket_id, tickets, users )
}
if !tickets.empty?
tickets.each {|id, ticket|
self.log 'notify', "push update of already pushed ticket id #{id}"
}
# send update to browser
self.send({
:data => {
:collections => {
:Ticket => tickets,
:User => users,
},
},
:event => [ 'loadCollection', 'ticket_overview_rebuild' ],
});
end
end
end
2012-08-03 22:46:05 +00:00
# overview
cache_key = @cache_key + '_overview'
2012-08-07 07:30:29 +00:00
overview_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if overview_time && @data[:overview_time] != overview_time
@data[:overview_time] = overview_time
2012-08-07 07:30:29 +00:00
overview = CacheIn.get( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
self.log 'notify', "push overview for user #{user.id}"
2012-08-03 22:46:05 +00:00
# send update to browser
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:event => 'navupdate_ticket_overview',
:data => overview,
})
end
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# overview_data
overviews = Ticket::Overviews.all(
2012-09-04 21:28:49 +00:00
:current_user => user,
2012-08-02 12:42:50 +00:00
)
2012-08-03 22:46:05 +00:00
overviews.each { |overview|
2013-02-01 00:01:20 +00:00
cache_key = @cache_key + '_overview_data_' + overview.link
2012-08-03 22:46:05 +00:00
2012-08-07 07:30:29 +00:00
overview_data_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if overview_data_time && @data[cache_key] != overview_data_time
@data[cache_key] = overview_data_time
2012-08-07 07:30:29 +00:00
overview_data = CacheIn.get( cache_key, { :ignore_expire => true } )
2013-02-01 00:01:20 +00:00
self.log 'notify', "push overview_data #{overview.link} for user #{user.id}"
2012-08-03 22:46:05 +00:00
users = {}
tickets = {}
overview_data[:ticket_ids].each {|ticket_id|
2012-08-03 22:46:05 +00:00
self.ticket( ticket_id, tickets, users )
}
2012-09-13 00:43:45 +00:00
# get groups
group_ids = []
Group.where( :active => true ).each { |group|
group_ids.push group.id
}
agents = {}
Ticket::ScreenOptions.agents.each { |user|
agents[ user.id ] = 1
}
groups_users = {}
groups_users[''] = []
group_ids.each {|group_id|
groups_users[ group_id ] = []
Group.find(group_id).users.each {|user|
next if !agents[ user.id ]
groups_users[ group_id ].push user.id
if !users[user.id]
users[user.id] = User.user_data_full(user.id)
end
}
}
2012-09-13 00:43:45 +00:00
2012-08-03 22:46:05 +00:00
# send update to browser
self.send({
:data => {
:users => users,
:tickets => tickets,
},
:event => [ 'loadAssets' ]
})
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:data => {
:overview => overview_data[:overview],
:ticket_ids => overview_data[:ticket_ids],
2012-08-03 22:46:05 +00:00
:tickets_count => overview_data[:tickets_count],
2012-09-13 00:43:45 +00:00
:bulk => {
:group_id__owner_id => groups_users,
:owner_id => [],
},
2012-08-03 22:46:05 +00:00
},
:event => [ 'ticket_overview_rebuild' ],
2013-02-01 00:01:20 +00:00
:collection => 'ticket_overview_' + overview.link.to_s,
2012-08-03 22:46:05 +00:00
})
end
}
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# ticket_create_attributes
cache_key = @cache_key + '_ticket_create_attributes'
2012-08-07 07:30:29 +00:00
ticket_create_attributes_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if ticket_create_attributes_time && @data[:ticket_create_attributes_time] != ticket_create_attributes_time
@data[:ticket_create_attributes_time] = ticket_create_attributes_time
2012-09-13 00:43:45 +00:00
create_attributes = CacheIn.get( cache_key, { :ignore_expire => true } )
users = {}
create_attributes[:owner_id].each {|user_id|
if !users[user_id]
users[user_id] = User.user_data_full(user_id)
end
}
data = {
:users => users,
:edit_form => create_attributes,
}
self.log 'notify', "push ticket_create_attributes for user #{user.id}"
2012-08-03 22:46:05 +00:00
# send update to browser
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:collection => 'ticket_create_attributes',
2012-09-13 00:43:45 +00:00
:data => data,
2012-08-03 22:46:05 +00:00
})
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# recent viewed
cache_key = @cache_key + '_recent_viewed'
2012-08-07 07:30:29 +00:00
recent_viewed_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if recent_viewed_time && @data[:recent_viewed_time] != recent_viewed_time
@data[:recent_viewed_time] = recent_viewed_time
2012-08-07 07:30:29 +00:00
recent_viewed = CacheIn.get( cache_key, { :ignore_expire => true } )
self.log 'notify', "push recent_viewed for user #{user.id}"
2012-08-03 22:46:05 +00:00
# send update to browser
2012-08-07 07:30:29 +00:00
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:event => 'update_recent_viewed',
:data => r,
})
end
2012-07-30 14:50:54 +00:00
2012-08-03 22:46:05 +00:00
# activity stream
cache_key = @cache_key + '_activity_stream'
2012-08-07 07:30:29 +00:00
activity_stream_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if activity_stream_time && @data[:activity_stream_time] != activity_stream_time
@data[:activity_stream_time] = activity_stream_time
2012-08-07 07:30:29 +00:00
activity_stream = CacheIn.get( cache_key, { :ignore_expire => true } )
self.log 'notify', "push activity_stream for user #{user.id}"
2012-08-03 22:46:05 +00:00
# send update to browser
2012-08-07 07:30:29 +00:00
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:event => 'activity_stream_rebuild',
:collection => 'activity_stream',
:data => r,
})
end
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# rss
cache_key = @cache_key + '_rss'
2012-08-07 07:30:29 +00:00
rss_items_time = CacheIn.get_time( cache_key, { :ignore_expire => true } )
2012-08-07 06:43:15 +00:00
if rss_items_time && @data[:rss_time] != rss_items_time
@data[:rss_time] = rss_items_time
2012-08-07 07:30:29 +00:00
rss_items = CacheIn.get( cache_key, { :ignore_expire => true } )
self.log 'notify', "push rss for user #{user.id}"
2012-08-03 22:46:05 +00:00
# send update to browser
2012-08-07 07:30:29 +00:00
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
2012-11-26 05:04:44 +00:00
self.send({
2012-08-03 22:46:05 +00:00
:event => 'rss_rebuild',
:collection => 'dashboard_rss',
:data => r,
})
end
# push_collections
cache_key = @cache_key + '_push_collections'
collections = CacheIn.get( cache_key ) || {}
collections.each { | key, v |
collection_cache_key = @cache_key + '_push_collections_' + key
collection_time = CacheIn.get_time( collection_cache_key, { :ignore_expire => true } )
if collection_time && @data[ collection_cache_key + '_time' ] != collection_time
@data[ collection_cache_key + '_time' ] = collection_time
push_collections = CacheIn.get( collection_cache_key, { :ignore_expire => true } )
self.log 'notify', "push push_collections #{key} for user #{user.id}"
# send update to browser
data = {}
data['collections'] = {}
data['collections'][key] = push_collections
2012-11-26 05:04:44 +00:00
self.send({
:event => 'resetCollection',
:data => data,
})
end
}
self.log 'notice', "---/client-"
2012-08-06 04:37:08 +00:00
# start faster in the beginnig
if loop_count < 20
2012-08-07 21:53:43 +00:00
sleep 0.6
2012-08-06 04:37:08 +00:00
else
sleep 1
end
2012-08-02 12:42:50 +00:00
end
2012-08-03 22:46:05 +00:00
end
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# add ticket if needed
def ticket( ticket_id, tickets, users )
if !@pushed[:tickets]
@pushed[:tickets] = {}
2012-08-02 12:42:50 +00:00
end
ticket = Ticket.lookup( :id => ticket_id )
if @pushed[:tickets][ticket_id] != ticket['updated_at']
@pushed[:tickets][ticket_id] = ticket['updated_at']
tickets[ticket_id] = ticket
2012-08-02 12:42:50 +00:00
end
2012-08-03 22:46:05 +00:00
# add users if needed
self.user( ticket['owner_id'], users )
self.user( ticket['customer_id'], users )
self.user( ticket['created_by_id'], users )
self.user( ticket['updated_by_id'], users )
2012-08-02 12:42:50 +00:00
end
2012-08-03 22:46:05 +00:00
# add user if needed
def user( user_id, users )
if !@pushed[:users]
@pushed[:users] = {}
end
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# get user
user = User.user_data_full( user_id )
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# user is already on client and not changed
return if @pushed[:users][ user_id ] == user['updated_at']
@pushed[:users][user_id] = user['updated_at']
2012-08-02 12:42:50 +00:00
2012-08-03 22:46:05 +00:00
# user not on client or different
self.log 'notice', 'push user ... ' + user['login']
2012-08-03 22:46:05 +00:00
users[ user_id ] = user
2012-07-23 22:22:23 +00:00
end
2012-08-03 22:46:05 +00:00
# send update to browser
2012-11-26 05:04:44 +00:00
def send( data )
Session.send( @client_id, data )
2012-07-23 22:22:23 +00:00
end
def log( level, data )
return if level == 'notice'
2012-08-03 22:46:05 +00:00
puts "#{Time.now}:client(#{ @client_id }) #{ data }"
2012-07-23 22:22:23 +00:00
end
end