smartkiosk-server 0.12.1 → 0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.ruby-version +1 -1
  2. data/Gemfile +9 -6
  3. data/Gemfile.lock +36 -9
  4. data/app/assets/images/sort-asc.png +0 -0
  5. data/app/assets/images/sort-desc.png +0 -0
  6. data/app/assets/javascripts/application.js +1 -1
  7. data/app/assets/javascripts/monitoring.js.coffee +25 -0
  8. data/app/assets/javascripts/monitoring/helpers/application.js.coffee +12 -0
  9. data/app/assets/javascripts/monitoring/layouts/application.js.coffee +2 -0
  10. data/app/assets/javascripts/monitoring/pages/application.js.coffee +1 -0
  11. data/app/assets/javascripts/monitoring/pages/welcome/index.js.coffee +229 -0
  12. data/app/assets/javascripts/monitoring/resources/.gitkeep +0 -0
  13. data/app/assets/javascripts/monitoring/routes.js.coffee +8 -0
  14. data/app/assets/javascripts/monitoring/templates/layouts/.gitkeep +0 -0
  15. data/app/assets/javascripts/monitoring/templates/layouts/application.jst.hamlc +1 -0
  16. data/app/assets/javascripts/monitoring/templates/pages/welcome/_row.jst.hamlc +28 -0
  17. data/app/assets/javascripts/monitoring/templates/pages/welcome/_tbody.jst.hamlc +3 -0
  18. data/app/assets/javascripts/monitoring/templates/pages/welcome/index.jst.hamlc +37 -0
  19. data/app/assets/javascripts/monitoring/templates/widgets/.gitkeep +0 -0
  20. data/app/assets/javascripts/monitoring/widgets/.gitkeep +0 -0
  21. data/app/assets/javascripts/monitoring_preloader.js.coffee.erb +17 -0
  22. data/app/assets/stylesheets/active_admin.css.scss +4 -4
  23. data/app/assets/stylesheets/{fonts.css.scss → active_admin/fonts.css.scss} +0 -0
  24. data/app/assets/stylesheets/active_admin/provider_groups.css.scss +12 -0
  25. data/app/assets/stylesheets/{provider_receipt_templates.css.scss → active_admin/provider_receipt_templates.css.scss} +0 -0
  26. data/app/assets/stylesheets/{terminals.css.scss → active_admin/terminals.css.scss} +0 -0
  27. data/app/assets/stylesheets/monitoring.css.scss +4 -0
  28. data/app/assets/stylesheets/monitoring/bootstrap.css +9 -0
  29. data/app/assets/stylesheets/monitoring/theme.css.scss +35 -0
  30. data/app/controllers/monitoring_controller.rb +31 -0
  31. data/app/controllers/payments_controller.rb +1 -1
  32. data/app/controllers/terminal_builds_controller.rb +2 -0
  33. data/app/controllers/welcome_controller.rb +5 -2
  34. data/app/models/ability.rb +6 -4
  35. data/app/models/agent.rb +6 -0
  36. data/app/models/collection.rb +2 -2
  37. data/app/models/payment.rb +3 -3
  38. data/app/models/provider_gateway.rb +1 -1
  39. data/app/models/report_result.rb +1 -1
  40. data/app/models/report_template.rb +3 -3
  41. data/app/models/role.rb +51 -10
  42. data/app/models/terminal.rb +25 -1
  43. data/app/models/terminal_build.rb +1 -1
  44. data/app/models/terminal_order.rb +1 -1
  45. data/app/models/terminal_ping.rb +3 -0
  46. data/app/models/terminal_profile.rb +6 -0
  47. data/app/models/user_role.rb +1 -1
  48. data/app/views/monitoring/index.html.erb +28 -0
  49. data/config.ru +7 -0
  50. data/config/deploy.rb +1 -1
  51. data/config/environments/development.rb +2 -0
  52. data/config/environments/production.rb +1 -1
  53. data/config/initializers/monitoring.rb +3 -0
  54. data/config/initializers/redis.rb +1 -1
  55. data/config/locales/activerecord.ru.yml +14 -0
  56. data/config/locales/smartkiosk.ru.yml +38 -0
  57. data/config/routes.rb +1 -1
  58. data/db/migrate/20130419125334_add_ping_to_terminals.rb +22 -0
  59. data/db/schema.rb +25 -7
  60. data/lib/blueprints.rb +2 -0
  61. data/lib/monitorer.rb +41 -0
  62. data/lib/seeder.rb +1 -1
  63. data/lib/smartkiosk/server/version.rb +1 -1
  64. data/vendor/assets/javascripts/chosen.jquery.js +1 -1
  65. data/vendor/assets/javascripts/cookie.jquery.js +95 -0
  66. data/vendor/assets/javascripts/copypaste.js +148 -0
  67. data/vendor/assets/javascripts/event-drag.jquery.js +402 -0
  68. data/vendor/assets/javascripts/sheetclip.js +87 -0
  69. data/vendor/assets/javascripts/slick.cellrangedecorator.js +64 -0
  70. data/vendor/assets/javascripts/slick.cellrangeselector.js +111 -0
  71. data/vendor/assets/javascripts/slick.cellselectionmodel.js +152 -0
  72. data/vendor/assets/javascripts/slick.core.js +458 -0
  73. data/vendor/assets/javascripts/slick.grid.js +3287 -0
  74. data/vendor/assets/stylesheets/slick.grid.css +167 -0
  75. metadata +42 -9
  76. data/app/assets/stylesheets/provider_groups.css.scss +0 -12
  77. data/app/views/layouts/application.html.erb +0 -1
  78. data/app/views/welcome/index.html.erb +0 -25
@@ -1 +1 @@
1
- 1.9.3-p385
1
+ 1.9.3-p392
data/Gemfile CHANGED
@@ -1,10 +1,17 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
+ gem 'oj'
4
+
3
5
  gem 'matrioshka'
6
+ gem 'joosy', :git => 'git://github.com/joosy/joosy.git'
7
+ gem 'i18n-js', :git => 'git://github.com/fnando/i18n-js.git'
4
8
 
5
9
  gem 'trinidad', :require => nil, :platform => :jruby
6
10
  gem 'thin', :require => nil, :platform => :ruby
7
11
 
12
+ gem 'eventmachine'
13
+ gem 'em-websocket'
14
+
8
15
  gem 'rails', '3.2.12'
9
16
  gem 'sinatra', :require => nil
10
17
  gem 'jruby-openssl', :platform => :jruby
@@ -25,7 +32,7 @@ gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
25
32
  gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
26
33
  gem 'redis-objects', :require => 'redis/objects'
27
34
  gem 'redis-objects-rmap'
28
- gem 'active_attr'
35
+ gem 'active_attr'
29
36
 
30
37
  gem 'payzilla', '0.0.4'
31
38
 
@@ -61,15 +68,11 @@ gem 'database_cleaner'
61
68
 
62
69
  group :assets do
63
70
  gem 'sass-rails', '~> 3.2.3'
71
+ gem 'bootstrap-sass', '~> 2.3.1.0'
64
72
  gem 'coffee-rails', '~> 3.2.1'
65
73
  gem 'uglifier', '>= 1.0.3'
66
74
  end
67
75
 
68
- group :development do
69
- gem 'better_errors'
70
- gem 'i18n_yaml_sorter'
71
- end
72
-
73
76
  gem 'iso8583-mkb', '0.0.3'
74
77
 
75
78
  gem 'bundler', '~> 1.3'
@@ -1,3 +1,10 @@
1
+ GIT
2
+ remote: git://github.com/fnando/i18n-js.git
3
+ revision: eeec14066b50f72876aa789c9b1f226172452798
4
+ specs:
5
+ i18n-js (2.1.2)
6
+ i18n
7
+
1
8
  GIT
2
9
  remote: git://github.com/gregbell/active_admin.git
3
10
  revision: 4e291e385bdcaa9fee2c37d5a344975101d6f15f
@@ -16,6 +23,14 @@ GIT
16
23
  rails (>= 3.0.0)
17
24
  sass (>= 3.1.0)
18
25
 
26
+ GIT
27
+ remote: git://github.com/joosy/joosy.git
28
+ revision: 90acc4ab8ac16c391fd98ab7d0a0855b789b2f29
29
+ specs:
30
+ joosy (1.1.0.alpha.3)
31
+ haml_coffee_assets
32
+ sprockets
33
+
19
34
  GIT
20
35
  remote: https://github.com/guard/guard-spork.git
21
36
  revision: dbaa8531850347474d5a7ee626a9a2a64f7e653c
@@ -81,11 +96,10 @@ GEM
81
96
  rubyzip (>= 0.9.5)
82
97
  bcrypt-ruby (3.0.1)
83
98
  bcrypt-ruby (3.0.1-java)
84
- better_errors (0.3.2)
85
- coderay (>= 1.0.0)
86
- erubis (>= 2.7.0)
99
+ bootstrap-sass (2.3.1.0)
100
+ sass (~> 3.2)
87
101
  bouncy-castle-java (1.5.0146.1)
88
- bourbon (3.1.0)
102
+ bourbon (3.1.3)
89
103
  sass (>= 3.2.0)
90
104
  thor
91
105
  builder (3.0.4)
@@ -137,6 +151,9 @@ GEM
137
151
  warden (~> 1.2.1)
138
152
  diff-lcs (1.1.3)
139
153
  digest-crc (0.3.0)
154
+ em-websocket (0.5.0)
155
+ eventmachine (>= 0.12.9)
156
+ http_parser.rb (~> 0.5.3)
140
157
  erubis (2.7.0)
141
158
  eventmachine (1.0.0)
142
159
  eventmachine (1.0.0-java)
@@ -162,17 +179,22 @@ GEM
162
179
  gyoku (1.0.0)
163
180
  builder (>= 2.1.2)
164
181
  haml (3.1.7)
182
+ haml_coffee_assets (1.12.0)
183
+ coffee-script (>= 1.0.0)
184
+ sprockets (>= 2.0.3)
185
+ tilt (>= 1.3.3)
165
186
  has_scope (0.5.1)
166
187
  highline (1.6.15)
167
188
  hike (1.2.1)
168
189
  htmlentities (4.3.1)
190
+ http_parser.rb (0.5.3)
191
+ http_parser.rb (0.5.3-java)
169
192
  httpi (2.0.2)
170
193
  rack
171
194
  i18n (0.6.4)
172
- i18n_yaml_sorter (0.2.0)
173
- inherited_resources (1.3.1)
195
+ inherited_resources (1.4.0)
174
196
  has_scope (~> 0.5.0)
175
- responders (~> 0.6)
197
+ responders (~> 0.9)
176
198
  iso8583 (0.1.4)
177
199
  iso8583-mkb (0.0.3)
178
200
  eventmachine
@@ -220,6 +242,7 @@ GEM
220
242
  nokogiri (1.5.6)
221
243
  nokogiri (1.5.6-java)
222
244
  nori (2.0.3)
245
+ oj (2.0.7)
223
246
  orm_adapter (0.4.0)
224
247
  paper_trail (2.7.0)
225
248
  activerecord (~> 3.0)
@@ -388,7 +411,7 @@ DEPENDENCIES
388
411
  activerecord-jdbcpostgresql-adapter
389
412
  activerecord-jdbcsqlite3-adapter
390
413
  axlsx
391
- better_errors
414
+ bootstrap-sass (~> 2.3.1.0)
392
415
  bundler (~> 1.3)
393
416
  capistrano
394
417
  carrierwave
@@ -397,12 +420,15 @@ DEPENDENCIES
397
420
  coffee-rails (~> 3.2.1)
398
421
  database_cleaner
399
422
  dav4rack (= 0.2.11)
423
+ em-websocket
424
+ eventmachine
400
425
  ffaker
401
426
  guard-rspec
402
427
  guard-spork!
403
428
  haml
404
- i18n_yaml_sorter
429
+ i18n-js!
405
430
  iso8583-mkb (= 0.0.3)
431
+ joosy!
406
432
  jquery-rails
407
433
  jruby-openssl
408
434
  liquid
@@ -410,6 +436,7 @@ DEPENDENCIES
410
436
  matrioshka
411
437
  meta_search (>= 1.1.0)
412
438
  money
439
+ oj
413
440
  paper_trail
414
441
  payzilla (= 0.0.4)
415
442
  pg
@@ -12,4 +12,4 @@
12
12
  //
13
13
  //= require jquery
14
14
  //= require jquery_ujs
15
- //= require_tree .
15
+ //= require_tree .
@@ -0,0 +1,25 @@
1
+ #= require hamlcoffee
2
+ #= require jquery
3
+ #= require jquery-ui
4
+ #= require joosy
5
+ #= require bootstrap
6
+ #= require chosen.jquery
7
+ #= require cookie.jquery
8
+ #= require event-drag.jquery
9
+ #= require slick.core
10
+ #= require slick.grid
11
+ #= require slick.cellselectionmodel
12
+ #= require slick.cellrangedecorator
13
+ #= require slick.cellrangeselector
14
+ #= require copypaste
15
+ #= require sheetclip
16
+ #= require i18n
17
+ #= require i18n/translations
18
+ #
19
+ #= require_tree ./monitoring/helpers
20
+ #= require_tree ./monitoring/templates
21
+ #= require_tree ./monitoring/resources
22
+ #= require_tree ./monitoring/widgets
23
+ #= require_tree ./monitoring/layouts
24
+ #= require_tree ./monitoring/pages
25
+ #= require_tree ./monitoring
@@ -0,0 +1,12 @@
1
+ Joosy.helpers 'Application', ->
2
+
3
+ @hardwareError = (device, code) ->
4
+ return "" unless code?
5
+
6
+ errors = I18n.t("smartkiosk.hardware.#{device}.errors")
7
+ message = if errors[code] then errors[code] else "#{I18n.t("smartkiosk.unlocalized")}"
8
+
9
+ if code < 1000
10
+ "<span class='badge badge-important'>#{code}: #{message}</span>"
11
+ else
12
+ "<span class='badge'>#{code}: #{message}</span>"
@@ -0,0 +1,2 @@
1
+ class @ApplicationLayout extends Joosy.Layout
2
+ @view 'application'
@@ -0,0 +1 @@
1
+ class @ApplicationPage extends Joosy.Page
@@ -0,0 +1,229 @@
1
+ Joosy.namespace 'Welcome', ->
2
+
3
+ class @IndexPage extends ApplicationPage
4
+ @layout ApplicationLayout
5
+ @view 'index'
6
+
7
+ hardware: [
8
+ 'printer',
9
+ 'cash_acceptor',
10
+ 'modem',
11
+ 'card_reader',
12
+ 'watchdog'
13
+ ]
14
+
15
+ defaultColumns: [
16
+ 'keyword',
17
+ 'address',
18
+ 'printer_error',
19
+ 'printer_model',
20
+ 'printer_version',
21
+ 'cash_acceptor_error',
22
+ 'cash_acceptor_version',
23
+ 'cash_acceptor_model',
24
+ 'modem_error',
25
+ 'modem_signal_level',
26
+ 'modem_balance',
27
+ 'card_reader_error',
28
+ 'card_reader_version',
29
+ 'card_reader_model',
30
+ 'watchdog_error',
31
+ 'collected_at',
32
+ 'notified_at',
33
+ 'issues_started_at',
34
+ 'agent_id',
35
+ 'terminal_profile_id',
36
+ 'version',
37
+ 'banknotes',
38
+ 'cash',
39
+ 'cashless',
40
+ 'upstream',
41
+ 'downstream',
42
+ 'ip',
43
+ 'juristic_name',
44
+ 'contract_number',
45
+ 'rent',
46
+ 'rent_finish_date'
47
+ ]
48
+
49
+ elements:
50
+ 'listing': '#listing'
51
+ 'inputs': 'input'
52
+ 'keyword': '#keyword'
53
+ 'error': '#error'
54
+ 'agent': '#agent'
55
+ 'terminalProfile': '#terminal_profile'
56
+ 'address': '#address'
57
+ 'date': '.brand small'
58
+
59
+ events:
60
+ 'click #filter': 'filter'
61
+
62
+ @fetch (done) ->
63
+ @data.agents = []
64
+ @data.profiles = []
65
+ @data.hardware = @hardware
66
+
67
+ @allowedFields = Object.keys(window.terminals.first())
68
+
69
+ @terminals = window.terminals.clone()
70
+ @index = Object.extended()
71
+
72
+ window.terminals.each (t) =>
73
+ @index[t.id] = t
74
+ @data.agents.push t['agent_title'] if t['agent_title']
75
+ @data.profiles.push t['terminal_profile_title'] if t['terminal_profile_title']
76
+
77
+ @data.agents = @data.agents.unique()
78
+ @data.profiles = @data.profiles.unique()
79
+
80
+ @widths = $.cookie('widths') || {}
81
+ @sorter = $.cookie('sorter') || ['keyword', true]
82
+ @columns = $.cookie('columns') || @defaultColumns
83
+
84
+ @columns.add @defaultColumns.subtract(@columns)
85
+ @columns = @columns.intersect(@defaultColumns).intersect(@allowedFields)
86
+
87
+ done()
88
+
89
+ @afterLoad ->
90
+ $('select').chosen
91
+ allow_single_deselect: true
92
+
93
+ @fixHeight(); $(window).resize => @fixHeight()
94
+
95
+ @sort()
96
+ @setupCopier()
97
+ @displayGrid()
98
+
99
+ @socket = new WebSocket("ws://localhost:3001/")
100
+ @socket.onmessage = (msg) =>
101
+ terminal = JSON.parse(msg.data)
102
+ Object.merge @index[terminal.id], terminal
103
+ @grid.invalidate()
104
+ @date.html Date.create().format(undefined, I18n.locale)
105
+
106
+ setupCopier: ->
107
+ @copier = new CopyPaste()
108
+
109
+ @inputs.focus => @copier.disabled = true
110
+ @inputs.blur => @copier.disabled = false
111
+
112
+ @copier.prepare (arg) =>
113
+ range = @grid.getSelectionModel().getSelectedRanges().first()
114
+ return "" unless range
115
+
116
+ data = []
117
+
118
+ for row in [range.fromRow..range.toRow]
119
+ do (row) =>
120
+ rowData = []
121
+
122
+ for cell in [range.fromCell..range.toCell]
123
+ do (cell) =>
124
+ rowData.push $(@grid.getCellNode(row, cell)).text()
125
+
126
+ data.push rowData
127
+
128
+ SheetClip.stringify data
129
+
130
+ displayGrid: ->
131
+ columns = @columns.map (x) =>
132
+ {
133
+ field: x,
134
+ id: x,
135
+ name: I18n.t("activerecord.attributes.terminal.#{x}"),
136
+ sortable: true,
137
+ width: @widths[x] || 150
138
+ }
139
+
140
+ columns[@columns.indexOf('terminal_profile_title')]?.name = I18n.t("activerecord.attributes.terminal.terminal_profile")
141
+ columns[@columns.indexOf('agent_title')]?.name = I18n.t("activerecord.attributes.terminal.agent")
142
+
143
+ @hardware.each (device) =>
144
+ offset = @columns.indexOf("#{device}_error")
145
+ if columns[offset]
146
+ columns[offset].name = I18n.t("smartkiosk.hardware.#{device}.title")
147
+ columns[offset].formatter = (r, c, v) -> Joosy.Helpers.Application.hardwareError(device, v)
148
+
149
+ columns[@columns.indexOf('banknotes')]?.formatter = (r, c, v) ->
150
+ return "" unless v
151
+ sum = 0
152
+ list = Object.keys(v).map((banknote) ->
153
+ sum += banknote.toNumber() * v[banknote].toNumber()
154
+ "<b>#{banknote}</b>: #{v[banknote]}"
155
+ ).join(", ")
156
+
157
+ "#{sum} &mdash; #{list}"
158
+
159
+ @grid = new Slick.Grid @listing, @terminals, columns,
160
+ enableCellNavigation: true
161
+ enableColumnReorder: true
162
+
163
+ @grid.setSortColumn(@sorter[0], @sorter[1])
164
+
165
+ @grid.setSelectionModel(new Slick.CellSelectionModel())
166
+
167
+ @grid.onSort.subscribe (e, args) =>
168
+ @sorter = [args.sortCol.field, args.sortAsc]
169
+ $.cookie('sorter', @sorter)
170
+ @sort()
171
+ @grid.invalidate()
172
+
173
+ @grid.onColumnsResized.subscribe (e, args) =>
174
+ args.grid.getColumns().each (c) => @widths[c.id] = c.width
175
+ $.cookie('widths', @widths)
176
+
177
+ @grid.onColumnsReordered.subscribe (e, args) =>
178
+ $.cookie 'columns', args.grid.getColumns().map (x) -> x.id
179
+
180
+ fixHeight: ->
181
+ @listing.height "#{$(window).height() - 145}px"
182
+ @grid?.resizeCanvas()
183
+
184
+ filter: ->
185
+ keyword = @keyword.val()
186
+ errors = Object.extended()
187
+ agent = @agent.val()
188
+ terminalProfile = @terminalProfile.val()
189
+ address = @address.val()
190
+
191
+ @error.val()?.each (e) =>
192
+ e = e.split('-')
193
+ errors[e[0]] ||= []
194
+ errors[e[0]].push e[1].toNumber()
195
+
196
+ @terminals = window.terminals.filter (x) =>
197
+ hardware = !@hardware.map( (h) =>
198
+ !errors[h]? || errors[h].some(x["#{h}_error"])
199
+ ).some(false)
200
+
201
+ return (
202
+ hardware &&
203
+ (keyword.length == 0 || x['keyword'].startsWith(keyword, 0, false)) &&
204
+ (agent.length == 0 || x['agent_title'] == agent) &&
205
+ (terminalProfile.length == 0 || x['terminal_profile_title'] == terminalProfile) &&
206
+ (address.length == 0 || x['address'].startsWith(address, 0, false))
207
+ )
208
+
209
+ @sort()
210
+ @grid.setData @terminals
211
+ @grid.invalidate()
212
+
213
+ sort: ->
214
+ if @sorter[0].endsWith('_error')
215
+ @terminals.sort (a, b) =>
216
+ a = a[@sorter[0]] || '99999'
217
+ b = b[@sorter[0]] || '99999'
218
+
219
+ return 0 if a == b
220
+
221
+ result = if a > b then 1 else -1
222
+ result = -result if !@sorter[1]
223
+ result
224
+ else
225
+ @terminals.sort (a, b) =>
226
+ return 0 if a[@sorter[0]] == b[@sorter[0]]
227
+ result = if a[@sorter[0]] > b[@sorter[0]] then 1 else -1
228
+ result = -result if !@sorter[1]
229
+ result