web_socket.rb 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. require 'json'
  2. module Session
  3. @path = '/tmp/websocket'
  4. def self.create( client_id, session )
  5. path = @path + '/' + client_id.to_s
  6. FileUtils.mkpath path
  7. File.open( path + '/session', 'w' ) { |file|
  8. user = { :id => session['id'] }
  9. file.puts Marshal.dump(user)
  10. }
  11. end
  12. def self.get( client_id )
  13. session_file = @path + '/' + client_id.to_s + '/session'
  14. data = nil
  15. return if !File.exist? session_file
  16. File.open( session_file, 'r' ) { |file|
  17. all = ''
  18. while line = file.gets
  19. all = all + line
  20. end
  21. begin
  22. data = Marshal.load( all )
  23. rescue
  24. return
  25. end
  26. }
  27. return data
  28. end
  29. def self.transaction( client_id, data )
  30. filename = @path + '/' + client_id.to_s + '/transaction-' + Time.new().to_i.to_s
  31. if File::exists?( filename )
  32. filename = @path + '/' + client_id.to_s + '/transaction-' + Time.new().to_i.to_s + '-1'
  33. if File::exists?( filename )
  34. filename = @path + '/' + client_id.to_s + '/transaction-' + Time.new().to_i.to_s + '-2'
  35. if File::exists?( filename )
  36. filename = @path + '/' + client_id.to_s + '/transaction-' + Time.new().to_i.to_s + '-3'
  37. if File::exists?( filename )
  38. filename = @path + '/' + client_id.to_s + '/transaction-' + Time.new().to_i.to_s + '-4'
  39. end
  40. end
  41. end
  42. end
  43. File.open( filename, 'w' ) { |file|
  44. file.puts data.to_json
  45. }
  46. return true
  47. end
  48. def self.jobs
  49. state_client_ids = {}
  50. while true
  51. client_ids = self.sessions
  52. client_ids.each { |client_id|
  53. if !state_client_ids[client_id]
  54. state_client_ids[client_id] = {}
  55. end
  56. # get current user
  57. user_session = Session.get( client_id )
  58. next if !user_session
  59. next if !user_session[:id]
  60. user = User.find( user_session[:id] )
  61. # overview meta data
  62. overview = Ticket.overview(
  63. :current_user_id => user.id,
  64. )
  65. if state_client_ids[client_id][:overview] != overview
  66. state_client_ids[client_id][:overview] = overview
  67. # send update to browser
  68. Session.transaction( client_id, {
  69. :data => overview,
  70. :event => 'navupdate_ticket_overview',
  71. })
  72. end
  73. # ticket overview lists
  74. overviews = Ticket.overview_list(
  75. :current_user_id => user.id,
  76. )
  77. if !state_client_ids[client_id][:overview_data]
  78. state_client_ids[client_id][:overview_data] = {}
  79. end
  80. overviews.each { |overview|
  81. overview_data = Ticket.overview(
  82. :view => overview.meta[:url],
  83. # :view_mode => params[:view_mode],
  84. :current_user_id => user.id,
  85. :array => true,
  86. )
  87. if state_client_ids[client_id][:overview_data][ overview.meta[:url] ] != overview_data
  88. state_client_ids[client_id][:overview_data][ overview.meta[:url] ] = overview_data
  89. puts 'push overview ' + overview.meta[:url].to_s
  90. users = {}
  91. tickets = []
  92. overview_data[:tickets].each {|ticket|
  93. self.jobs_ticket( ticket.id, state_client_ids[client_id], tickets, users )
  94. }
  95. # send update to browser
  96. Session.transaction( client_id, {
  97. :data => {
  98. :overview => overview_data[:overview],
  99. :tickets => tickets,
  100. :tickets_count => overview_data[:tickets_count],
  101. :users => users,
  102. },
  103. :event => 'ticket_overview_rebuild',
  104. :collection => 'ticket_overview_' + overview.meta[:url].to_s,
  105. })
  106. end
  107. }
  108. # recent viewed
  109. self.jobs_recent_viewed(
  110. user,
  111. client_id,
  112. state_client_ids[client_id],
  113. )
  114. # activity stream
  115. self.jobs_activity_stream(
  116. user,
  117. client_id,
  118. state_client_ids[client_id],
  119. )
  120. # ticket create
  121. self.jobs_create_attributes(
  122. user,
  123. client_id,
  124. state_client_ids[client_id],
  125. )
  126. # system settings
  127. # rss view
  128. self.jobs_rss(
  129. user,
  130. client_id,
  131. state_client_ids[client_id],
  132. 'http://www.heise.de/newsticker/heise-atom.xml'
  133. )
  134. sleep 1
  135. }
  136. end
  137. end
  138. def self.jobs_ticket(ticket_id, client_state, tickets, users)
  139. puts 'check :overview'
  140. if !client_state['tickets']
  141. client_state['tickets'] = {}
  142. end
  143. # add ticket if needed
  144. data = Ticket.full_data(ticket_id)
  145. if client_state['tickets'][ticket_id] != data
  146. client_state['tickets'][ticket_id] = data
  147. tickets.push data
  148. end
  149. # add users if needed
  150. self.jobs_user( data['owner_id'], client_state, users )
  151. self.jobs_user( data['customer_id'], client_state, users )
  152. self.jobs_user( data['created_by_id'], client_state, users )
  153. end
  154. def self.jobs_user(user_id, client_state, users)
  155. if !client_state['users']
  156. client_state['users'] = {}
  157. end
  158. # get user
  159. user = User.user_data_full( user_id )
  160. # user is already on client and not changed
  161. return if client_state['users'][ user_id ] == user
  162. puts 'push user ... ' + user['login']
  163. # user not on client or different
  164. users[ user_id ] = user
  165. client_state['users'][ user_id ] = user
  166. end
  167. # rss view
  168. def self.jobs_rss(user_id, client_id, client_state, url)
  169. # name space
  170. if !client_state[:rss_items]
  171. client_state[:rss_items] = {}
  172. end
  173. # only fetch every 5 minutes
  174. return if client_state[:rss_items][:last_run] && Time.new - client_state[:rss_items][:last_run] < 5.minutes
  175. # remember last run
  176. client_state[:rss_items][:last_run] = Time.new
  177. puts 'check :rss'
  178. # fetch rss
  179. rss_items = RSS.fetch( url, 8 )
  180. if client_state[:rss_items][:data] != rss_items
  181. client_state[:rss_items][:data] = rss_items
  182. # send update to browser
  183. Session.transaction( client_id, {
  184. :event => 'rss_rebuild',
  185. :collection => 'dashboard_rss',
  186. :data => {
  187. head: 'Heise ATOM',
  188. items: rss_items,
  189. },
  190. })
  191. end
  192. end
  193. def self.jobs_recent_viewed(user, client_id, client_state)
  194. # name space
  195. if !client_state[:recent_viewed]
  196. client_state[:recent_viewed] = {}
  197. end
  198. # only fetch every x seconds
  199. return if client_state[:recent_viewed][:last_run] && Time.new - client_state[:recent_viewed][:last_run] < 10.seconds
  200. # remember last run
  201. client_state[:recent_viewed][:last_run] = Time.new
  202. puts 'check :recent_viewed'
  203. recent_viewed = History.recent_viewed(user)
  204. if client_state[:recent_viewed][:data] != recent_viewed
  205. client_state[:recent_viewed][:data] = recent_viewed
  206. # tickets and users
  207. recent_viewed = History.recent_viewed_fulldata(user)
  208. # send update to browser
  209. Session.transaction( client_id, {
  210. :data => recent_viewed,
  211. :event => 'update_recent_viewed',
  212. })
  213. end
  214. end
  215. def self.jobs_activity_stream(user, client_id, client_state)
  216. # name space
  217. if !client_state[:activity_stream]
  218. client_state[:activity_stream] = {}
  219. end
  220. # only fetch every x seconds
  221. return if client_state[:activity_stream][:last_run] && Time.new - client_state[:activity_stream][:last_run] < 20.seconds
  222. # remember last run
  223. client_state[:activity_stream][:last_run] = Time.new
  224. puts 'check :activity_stream'
  225. activity_stream = History.activity_stream(user)
  226. if client_state[:activity_stream][:data] != activity_stream
  227. client_state[:activity_stream][:data] = activity_stream
  228. activity_stream = History.activity_stream_fulldata(user)
  229. # send update to browser
  230. Session.transaction( client_id, {
  231. :event => 'activity_stream_rebuild',
  232. :collection => 'activity_stream',
  233. :data => activity_stream,
  234. })
  235. end
  236. end
  237. def self.jobs_create_attributes(user, client_id, client_state)
  238. # name space
  239. if !client_state[:create_attributes]
  240. client_state[:create_attributes] = {}
  241. end
  242. # only fetch every x seconds
  243. return if client_state[:create_attributes][:last_run] && Time.new - client_state[:create_attributes][:last_run] < 15.seconds
  244. # remember last run
  245. client_state[:create_attributes][:last_run] = Time.new
  246. puts 'check :create_attributes'
  247. ticket_create_attributes = Ticket.create_attributes(
  248. :current_user_id => user.id,
  249. )
  250. if client_state[:create_attributes][:data] != ticket_create_attributes
  251. client_state[:create_attributes][:data] = ticket_create_attributes
  252. # send update to browser
  253. Session.transaction( client_id, {
  254. :data => ticket_create_attributes,
  255. :collection => 'ticket_create_attributes',
  256. })
  257. end
  258. end
  259. def self.sessions
  260. path = @path + '/'
  261. data = []
  262. Dir.foreach( path ) do |entry|
  263. if entry != '.' && entry != '..'
  264. data.push entry
  265. end
  266. end
  267. return data
  268. end
  269. def self.queue( client_id )
  270. path = @path + '/' + client_id.to_s + '/'
  271. data = []
  272. Dir.foreach( path ) do |entry|
  273. if /^transaction/.match( entry )
  274. data.push Session.queue_file( path + entry )
  275. end
  276. end
  277. return data
  278. end
  279. def self.queue_file( filename )
  280. data = nil
  281. File.open( filename, 'r' ) { |file|
  282. all = ''
  283. while line = file.gets
  284. all = all + line
  285. end
  286. data = JSON.parse( all )
  287. }
  288. File.delete( filename )
  289. return data
  290. end
  291. def self.destory( client_id )
  292. path = @path + '/' + client_id.to_s
  293. FileUtils.rm_rf path
  294. end
  295. end