2012-07-23 22:22:23 +00:00
|
|
|
require 'json'
|
|
|
|
|
|
|
|
module Session
|
|
|
|
@path = '/tmp/websocket'
|
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
|
2012-07-23 22:22:23 +00:00
|
|
|
File.open( path + '/session', 'w' ) { |file|
|
2012-11-26 05:04:44 +00:00
|
|
|
data = {
|
|
|
|
:user => {
|
|
|
|
:id => session['id'],
|
|
|
|
},
|
|
|
|
:meta => meta,
|
|
|
|
}
|
|
|
|
# puts 'CREATE' + Marshal.dump(data)
|
|
|
|
file.puts 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
|
|
|
|
|
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)
|
|
|
|
path = @path + '/' + client_id.to_s
|
|
|
|
data[:meta][:last_ping] = Time.new.to_i.to_s
|
|
|
|
File.open( path + '/session', 'w' ) { |file|
|
|
|
|
file.puts Marshal.dump(data)
|
|
|
|
}
|
|
|
|
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
|
|
|
|
File.open( session_file, 'r' ) { |file|
|
|
|
|
all = ''
|
2012-08-03 22:46:05 +00:00
|
|
|
while line = file.gets
|
|
|
|
all = all + line
|
2012-07-23 22:22:23 +00:00
|
|
|
end
|
2012-08-03 22:46:05 +00:00
|
|
|
begin
|
2012-07-23 22:22:23 +00:00
|
|
|
data = Marshal.load( all )
|
|
|
|
rescue
|
|
|
|
return
|
|
|
|
end
|
|
|
|
}
|
|
|
|
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 + '/'
|
2012-11-26 05:04:44 +00:00
|
|
|
filename = 'send-' + Time.new().to_i.to_s + '-' + rand(999999).to_s
|
2012-08-03 23:35:21 +00:00
|
|
|
if File::exists?( path + filename )
|
|
|
|
filename = filename + '-1'
|
|
|
|
if File::exists?( path + filename )
|
|
|
|
filename = filename + '-1'
|
|
|
|
if File::exists?( path + filename )
|
|
|
|
filename = filename + '-1'
|
|
|
|
if File::exists?( path + filename )
|
|
|
|
filename = filename + '-' + rand(999999).to_s
|
2012-07-23 22:22:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-08-03 23:35:21 +00:00
|
|
|
return false if !File.directory? path
|
|
|
|
File.open( path + 'a-' + filename, 'w' ) { |file|
|
2012-07-23 22:22:23 +00:00
|
|
|
file.puts data.to_json
|
|
|
|
}
|
2012-08-03 23:35:21 +00:00
|
|
|
FileUtils.mv( path + 'a-' + filename, path + filename)
|
2012-07-23 22:22:23 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.jobs
|
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]
|
|
|
|
|
2012-07-23 22:22:23 +00:00
|
|
|
# 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
|
2012-08-04 09:38:18 +00:00
|
|
|
start_user_thread = false
|
2012-08-03 22:46:05 +00:00
|
|
|
if !@@user_threads[user.id]
|
2012-08-04 09:38:18 +00:00
|
|
|
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
|
|
|
|
|
2012-08-04 09:38:18 +00:00
|
|
|
# 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
|
2012-08-04 09:38:18 +00:00
|
|
|
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"
|
|
|
|
}
|
2012-07-30 12:05:46 +00:00
|
|
|
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 + '/'
|
|
|
|
data = []
|
|
|
|
Dir.foreach( path ) do |entry|
|
|
|
|
if entry != '.' && entry != '..'
|
|
|
|
data.push entry
|
|
|
|
end
|
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 = []
|
|
|
|
Dir.foreach( path ) do |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
|
2012-07-30 14:50:54 +00:00
|
|
|
end
|
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 = ''
|
|
|
|
File.open( file_new, 'r' ) { |file|
|
2012-08-03 22:46:05 +00:00
|
|
|
while line = file.gets
|
|
|
|
all = all + line
|
|
|
|
end
|
|
|
|
}
|
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
|
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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-11-12 15:17:39 +00:00
|
|
|
|
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 )
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
|
|
|
2012-10-23 19:12:00 +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.overview(
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notice', 'fetch overview - ' + cache_key
|
2012-08-03 22:46:05 +00:00
|
|
|
if overview != overview_cache
|
2012-10-23 19:12:00 +00:00
|
|
|
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 => 3.seconds } )
|
|
|
|
end
|
|
|
|
end
|
2012-07-30 14:50:54 +00:00
|
|
|
|
2012-08-03 22:46:05 +00:00
|
|
|
# overview lists
|
|
|
|
overviews = Ticket.overview_list(
|
2012-09-04 21:28:49 +00:00
|
|
|
:current_user => user,
|
2012-08-03 22:46:05 +00:00
|
|
|
)
|
|
|
|
overviews.each { |overview|
|
|
|
|
cache_key = @cache_key + '_overview_data_' + overview.meta[:url]
|
|
|
|
if CacheIn.expired(cache_key)
|
|
|
|
overview_data = Ticket.overview(
|
2012-09-04 21:28:49 +00:00
|
|
|
:view => overview.meta[:url],
|
|
|
|
# :view_mode => params[:view_mode],
|
|
|
|
:current_user => user,
|
|
|
|
:array => true,
|
2012-08-03 22:46:05 +00:00
|
|
|
)
|
|
|
|
overview_data_cache = CacheIn.get( cache_key, { :re_expire => true } )
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notice', 'fetch overview_data - ' + cache_key
|
2012-08-03 22:46:05 +00:00
|
|
|
if overview_data != overview_data_cache
|
2012-10-23 19:12:00 +00:00
|
|
|
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.create_attributes(
|
|
|
|
:current_user_id => user.id,
|
|
|
|
)
|
|
|
|
ticket_create_attributes_cache = CacheIn.get( cache_key, { :re_expire => true } )
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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 = History.recent_viewed(user)
|
|
|
|
recent_viewed_cache = CacheIn.get( cache_key, { :re_expire => true } )
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notice', 'fetch recent_viewed - ' + cache_key
|
2012-08-03 22:46:05 +00:00
|
|
|
if recent_viewed != recent_viewed_cache
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notify', 'fetch recent_viewed changed - ' + cache_key
|
2012-07-30 14:50:54 +00:00
|
|
|
|
2012-08-03 22:46:05 +00:00
|
|
|
recent_viewed_full = History.recent_viewed_fulldata(user)
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notice', 'fetch activity_stream - ' + cache_key
|
2012-08-03 22:46:05 +00:00
|
|
|
if activity_stream != activity_stream_cache
|
2012-10-23 19:12:00 +00:00
|
|
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notice', 'fetch rss - ' + cache_key
|
2012-08-03 22:46:05 +00:00
|
|
|
if rss_items != rss_items_cache
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
|
|
|
|
# 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)
|
2012-10-23 19:12:00 +00:00
|
|
|
push_collection.each { | key, value |
|
|
|
|
collections[ key ] = true
|
|
|
|
}
|
2012-11-12 15:17:39 +00:00
|
|
|
CacheIn.set( cache_key, collections, { :expires_in => 2.minutes } )
|
2012-10-23 19:12:00 +00:00
|
|
|
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)
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
|
|
|
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
@cache_key = ''
|
2012-08-03 22:46:05 +00:00
|
|
|
@data = {}
|
|
|
|
@pushed = {}
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notify', "---client start ws connection---"
|
2012-08-03 22:46:05 +00:00
|
|
|
self.fetch
|
2012-10-23 19:12:00 +00:00
|
|
|
self.log 'notify', "---client exiting ws connection---"
|
2012-08-03 22:46:05 +00:00
|
|
|
end
|
2012-11-12 15:17:39 +00:00
|
|
|
|
2012-08-03 22:46:05 +00:00
|
|
|
def fetch
|
2012-11-12 15:17:39 +00:00
|
|
|
|
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]
|
|
|
|
user = User.find( session_data[:user][:id] )
|
2012-08-03 22:46:05 +00:00
|
|
|
return if !user
|
|
|
|
|
2012-10-23 19:12:00 +00:00
|
|
|
# set cache key
|
|
|
|
@cache_key = 'user_' + user.id.to_s
|
|
|
|
|
2012-08-06 04:37:08 +00:00
|
|
|
loop_count += 1
|
2012-10-23 19:12:00 +00:00
|
|
|
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 } )
|
|
|
|
|
2012-12-14 23:02:58 +00:00
|
|
|
# verify already pushed data
|
|
|
|
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
|
|
|
|
|
|
|
|
# verify already pushed data
|
|
|
|
if @pushed[:tickets]
|
|
|
|
tickets = []
|
|
|
|
users = {}
|
|
|
|
@pushed[:tickets].each {|ticket_id, ticket_data|
|
|
|
|
self.ticket( ticket_id, tickets, users )
|
|
|
|
}
|
|
|
|
if !tickets.empty?
|
|
|
|
tickets.each {|ticket_id|
|
|
|
|
self.log 'notify', "push update of already pushed ticket id #{ticket_id}"
|
|
|
|
}
|
|
|
|
# send update to browser
|
|
|
|
self.send({
|
|
|
|
:data => {
|
|
|
|
:collections => {
|
|
|
|
:Ticket => tickets,
|
|
|
|
:User => users,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
:event => [ 'loadCollection', 'ticket_overview_rebuild' ],
|
|
|
|
});
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-03 22:46:05 +00:00
|
|
|
# overview
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
|
|
|
2012-10-23 19:12:00 +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.overview_list(
|
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|
|
2012-10-23 19:12:00 +00:00
|
|
|
cache_key = @cache_key + '_overview_data_' + overview.meta[:url]
|
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 } )
|
2012-10-23 19:21:06 +00:00
|
|
|
self.log 'notify', "push overview_data #{overview.meta[:url]} for user #{user.id}"
|
2012-08-03 22:46:05 +00:00
|
|
|
users = {}
|
|
|
|
tickets = []
|
2012-11-26 23:22:52 +00:00
|
|
|
overview_data[:ticket_list].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
|
|
|
|
2012-09-20 12:08:02 +00:00
|
|
|
# get groups
|
|
|
|
group_ids = []
|
|
|
|
Group.where( :active => true ).each { |group|
|
|
|
|
group_ids.push group.id
|
|
|
|
}
|
|
|
|
agents = {}
|
|
|
|
Ticket.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
|
2012-11-26 05:04:44 +00:00
|
|
|
self.send({
|
2012-08-03 22:46:05 +00:00
|
|
|
:data => {
|
|
|
|
:overview => overview_data[:overview],
|
2012-11-26 23:22:52 +00:00
|
|
|
:ticket_list => overview_data[:ticket_list],
|
2012-08-03 22:46:05 +00:00
|
|
|
:tickets_count => overview_data[:tickets_count],
|
|
|
|
:collections => {
|
|
|
|
:User => users,
|
|
|
|
:Ticket => tickets,
|
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 => [ 'loadCollection', 'ticket_overview_rebuild' ],
|
|
|
|
:collection => 'ticket_overview_' + overview.meta[:url].to_s,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
}
|
2012-07-30 14:50:54 +00:00
|
|
|
|
2012-08-03 22:46:05 +00:00
|
|
|
# ticket_create_attributes
|
2012-10-23 19:12:00 +00:00
|
|
|
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,
|
|
|
|
}
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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 } )
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
|
|
|
|
# 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({
|
2012-10-24 18:20:56 +00:00
|
|
|
:event => 'resetCollection',
|
2012-10-23 19:12:00 +00:00
|
|
|
: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
|
2012-08-03 22:46:05 +00:00
|
|
|
ticket = Ticket.full_data(ticket_id)
|
2012-12-14 23:02:58 +00:00
|
|
|
if @pushed[:tickets][ticket_id] != ticket['updated_at']
|
|
|
|
@pushed[:tickets][ticket_id] = ticket['updated_at']
|
2012-08-03 22:46:05 +00:00
|
|
|
tickets.push 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 )
|
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
|
2012-12-14 23:02:58 +00:00
|
|
|
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
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
|
|
|
|
2012-10-23 19:12:00 +00:00
|
|
|
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
|
2012-08-03 22:46:05 +00:00
|
|
|
end
|