smartkiosk-server 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,43 +3,54 @@ class TerminalPingsController < ApplicationController
3
3
 
4
4
  def create
5
5
  begin
6
- ping_data = params[:terminal_ping]
7
- providers = ping_data[:providers]
6
+ profile = @terminal.terminal_profile
8
7
 
9
- remote_timestamp = providers[:updated_at].blank? ? nil : DateTime.parse(providers[:updated_at])
10
- local_timestamp = [
11
- Provider.timestamp.value || DateTime.civil(0, 1, 1),
12
- ProviderGroup.timestamp.value || DateTime.civil(0, 1, 1),
13
- TerminalProfilePromotion.timestamp.value || DateTime.civil(0, 1, 1)
14
- ].max
8
+ ping_data = params[:terminal_ping]
9
+ remote_timestamp = ping_data[:providers_updated_at].blank? ? nil : DateTime.parse(ping_data[:providers_updated_at])
10
+ local_timestamp = nil
11
+ profile.cached_providers_lock.lock { local_timestamp = profile.actual_timestamp }
15
12
 
16
13
  @terminal.ping!(TerminalPing.new ping_data)
17
14
 
18
15
  response = {
19
16
  :time => DateTime.now,
20
17
  :profile => {
21
- :support_phone => @terminal.terminal_profile.support_phone,
22
- :logo => @terminal.terminal_profile.logo.url,
23
- :modified_at => @terminal.terminal_profile.updated_at
18
+ :support_phone => profile.support_phone,
19
+ :logo => profile.logo.url,
20
+ :modified_at => profile.updated_at
24
21
  },
25
22
  :orders => @terminal.terminal_orders.unsent.as_json(:only => [:id, :keyword, :args, :created_at]),
26
- :providers => {}
23
+ :update_providers => remote_timestamp.blank? || local_timestamp.to_i > remote_timestamp.to_i # to drop microseconds
27
24
  }
28
25
 
29
- unless providers[:ids].blank?
30
- response[:providers][:remove] = providers[:ids].map{|x| x.to_i} - Provider.select(:id).map(&:id)
31
- end
32
-
33
- if remote_timestamp.blank? || local_timestamp > remote_timestamp
34
- response[:providers][:update] = @terminal.providers_dump remote_timestamp
35
- response[:providers][:groups] = @terminal.provider_groups_dump
36
- response[:providers][:promotions] = @terminal.promotions_dump
37
- response[:providers][:updated_at] = local_timestamp.strftime('%Y-%m-%dT%H:%M:%S.%9N%z')
38
- end
39
-
40
26
  render :json => response
41
27
  rescue ActiveRecord::RecordInvalid
42
28
  render :text => nil, :status => 400
43
29
  end
44
30
  end
45
- end
31
+
32
+ def providers
33
+ profile = @terminal.terminal_profile
34
+
35
+ providers = nil
36
+ profile.cached_providers_lock.lock do
37
+ providers = profile.cached_providers.value
38
+
39
+ if providers.nil?
40
+ ActiveRecord::Base.transaction do
41
+ providers = {
42
+ :providers => profile.providers_dump,
43
+ :groups => profile.provider_groups_dump,
44
+ :promotions => profile.promotions_dump,
45
+ :updated_at => profile.actual_timestamp
46
+ }
47
+ end
48
+
49
+ providers = ActiveSupport::Gzip.compress(ActiveSupport::JSON.encode(providers))
50
+ profile.cached_providers.value = providers
51
+ end
52
+ end
53
+
54
+ send_data providers, :type => 'application/gzip', :disposition => 'inline'
55
+ end
56
+ end
data/app/models/agent.rb CHANGED
@@ -19,6 +19,6 @@ class Agent < ActiveRecord::Base
19
19
  #
20
20
  # VALIDATIONS
21
21
  #
22
- validates :title, :presence => true
22
+ validates :title, :presence => true, :uniqueness => true
23
23
 
24
24
  end
@@ -1,19 +1,17 @@
1
1
  class Provider < ActiveRecord::Base
2
2
  include Redis::Objects::RMap
3
3
 
4
- value :timestamp, :global => true, :marshal => true
5
-
6
4
  has_rmap({:id => lambda{|x| x.to_s}}, :title)
7
5
  has_paper_trail
8
6
 
9
7
  mount_uploader :icon, IconUploader
10
8
 
11
9
  after_save do
12
- self.class.timestamp = updated_at
10
+ TerminalProfile.invalidate_all_cached_providers!
13
11
  end
14
12
 
15
13
  after_destroy do
16
- self.class.timestamp = DateTime.now
14
+ TerminalProfile.invalidate_all_cached_providers!
17
15
  end
18
16
 
19
17
  #
@@ -37,8 +35,8 @@ class Provider < ActiveRecord::Base
37
35
  scope :gateway_ids_eq, lambda{|x| includes(:gateways).where(:gateways => {:id => x})}
38
36
  search_method :gateway_ids_eq
39
37
 
40
- scope :after, lambda{|x|
41
- x.blank? ? scoped
38
+ scope :after, lambda{|x|
39
+ x.blank? ? scoped
42
40
  : where(arel_table[:updated_at].gt x)
43
41
  }
44
42
 
@@ -3,14 +3,12 @@ class ProviderGroup < ActiveRecord::Base
3
3
 
4
4
  mount_uploader :icon, IconUploader
5
5
 
6
- value :timestamp, :global => true, :marshal => true
7
-
8
6
  after_save do
9
- self.class.timestamp = updated_at
7
+ TerminalProfile.invalidate_all_cached_providers!
10
8
  end
11
9
 
12
10
  after_destroy do
13
- self.class.timestamp = DateTime.now
11
+ TerminalProfile.invalidate_all_cached_providers!
14
12
  end
15
13
 
16
14
  belongs_to :provider_group
@@ -6,4 +6,6 @@ class ProviderProfile < ActiveRecord::Base
6
6
  has_many :providers
7
7
  has_many :limits
8
8
  has_many :commissions
9
+
10
+ validates :title, :presence => true, :uniqueness => true
9
11
  end
@@ -35,61 +35,6 @@ class Terminal < ActiveRecord::Base
35
35
  #
36
36
  # METHODS
37
37
  #
38
- def providers_dump(after=nil)
39
- providers = Provider.includes(:provider_fields).after(after)
40
-
41
- return [] if providers.blank?
42
-
43
- overload = Hash[*terminal_profile.terminal_profile_providers.map{|x| [x.provider_id, x]}.flatten]
44
-
45
- providers.map do |x|
46
- icon = overload[x.id].icon rescue nil
47
-
48
- if icon.blank?
49
- icon = x.icon.try(:url)
50
- else
51
- icon = icon.url
52
- end
53
-
54
- {
55
- :id => x.id,
56
- :title => x.title,
57
- :keyword => x.keyword,
58
- :icon => icon,
59
- :priority => overload[x.id].try(:priority),
60
- :fields => x.fields_dump,
61
- :group_id => x.provider_group_id,
62
- :requires_print => x.requires_print
63
- }
64
- end
65
- end
66
-
67
- def promotions_dump
68
- terminal_profile.terminal_profile_promotions.map{|x| x.provider_id}
69
- end
70
-
71
- def provider_groups_dump
72
- overload = Hash[*terminal_profile.terminal_profile_provider_groups.map{|x| [x.provider_group_id, x]}.flatten]
73
-
74
- ProviderGroup.all.map do |x|
75
- icon = overload[x.id].icon rescue nil
76
-
77
- if icon.blank?
78
- icon = x.icon.try(:url)
79
- else
80
- icon = icon.url
81
- end
82
-
83
- {
84
- :id => x.id,
85
- :title => x.title,
86
- :icon => icon,
87
- :priority => overload[x.id].try(:priority),
88
- :parent_id => x.provider_group_id
89
- }
90
- end
91
- end
92
-
93
38
  def title
94
39
  keyword
95
40
  end
@@ -1,9 +1,13 @@
1
1
  class TerminalProfile < ActiveRecord::Base
2
2
  include Redis::Objects::RMap
3
3
 
4
- has_rmap({:id => lambda{|x| x.to_s}}, :keyword)
4
+ has_rmap({:id => lambda{|x| x.to_s}}, :title)
5
5
  has_paper_trail
6
6
 
7
+ value :cached_providers
8
+ value :cached_providers_timestamp, :marshal => true
9
+ lock :cached_providers, :expiration => 15
10
+
7
11
  has_many :terminals, :conditions => "terminal_profile_id IS NOT NULL"
8
12
  has_many :terminal_profile_promotions, :dependent => :destroy, :order => :priority
9
13
  has_many :terminal_profile_providers, :dependent => :destroy, :order => :priority
@@ -15,6 +19,8 @@ class TerminalProfile < ActiveRecord::Base
15
19
  accepts_nested_attributes_for :terminal_profile_providers
16
20
  accepts_nested_attributes_for :terminal_profile_provider_groups
17
21
 
22
+ validates :title, :presence => true, :uniqueness => true
23
+
18
24
  def actualize_links!
19
25
  ProviderGroup.where(ProviderGroup.arel_table[:id].not_in TerminalProfileProviderGroup.arel_table.project(:provider_group_id)).each do |pg|
20
26
  terminal_profile_provider_groups << TerminalProfileProviderGroup.new(:provider_group_id => pg.id, :terminal_profile_id => id)
@@ -24,4 +30,81 @@ class TerminalProfile < ActiveRecord::Base
24
30
  terminal_profile_providers << TerminalProfileProvider.new(:provider_id => p.id, :terminal_profile_id => id)
25
31
  end
26
32
  end
33
+
34
+ def self.invalidate_all_cached_providers!
35
+ TerminalProfile.all.each(&:invalidate_cached_providers!)
36
+ end
37
+
38
+ def invalidate_cached_providers!
39
+ self.cached_providers_lock.lock do
40
+ self.cached_providers.value = nil
41
+ self.cached_providers_timestamp.value = DateTime.now
42
+ end
43
+ end
44
+
45
+ def actual_timestamp
46
+ local_timestamp = self.cached_providers_timestamp.value
47
+
48
+ if local_timestamp.nil? # Redis is not populated yet
49
+ self.cached_providers_timestamp.value = local_timestamp = DateTime.now
50
+ end
51
+
52
+ local_timestamp
53
+ end
54
+
55
+ def providers_dump
56
+ providers = Provider.includes(:provider_fields)
57
+
58
+ return [] if providers.blank?
59
+
60
+ overload = Hash[self.terminal_profile_providers.map{|x| [x.provider_id, x]}]
61
+
62
+ providers.map do |x|
63
+ icon = overload[x.id].icon rescue nil
64
+
65
+ if icon.blank?
66
+ icon = x.icon.try(:url)
67
+ else
68
+ icon = icon.url
69
+ end
70
+
71
+ {
72
+ :id => x.id,
73
+ :title => x.title,
74
+ :keyword => x.keyword,
75
+ :icon => icon,
76
+ :priority => overload[x.id].try(:priority),
77
+ :fields => x.fields_dump,
78
+ :group_id => x.provider_group_id,
79
+ :requires_print => x.requires_print
80
+ }
81
+ end
82
+ end
83
+
84
+ def promotions_dump
85
+ self.terminal_profile_promotions.map &:provider_id
86
+ end
87
+
88
+ def provider_groups_dump
89
+ overload = Hash[self.terminal_profile_provider_groups.map{|x| [x.provider_group_id, x]}]
90
+
91
+ ProviderGroup.all.map do |x|
92
+ icon = overload[x.id].icon rescue nil
93
+
94
+ if icon.blank?
95
+ icon = x.icon.try(:url)
96
+ else
97
+ icon = icon.url
98
+ end
99
+
100
+ {
101
+ :id => x.id,
102
+ :title => x.title,
103
+ :icon => icon,
104
+ :priority => overload[x.id].try(:priority),
105
+ :parent_id => x.provider_group_id
106
+ }
107
+ end
108
+ end
109
+
27
110
  end
@@ -1,18 +1,16 @@
1
1
  class TerminalProfilePromotion < ActiveRecord::Base
2
2
  include Redis::Objects::RMap
3
3
 
4
- value :timestamp, :global => true, :marshal => true
5
-
6
4
  belongs_to :terminal_profile
7
5
  belongs_to :provider
8
6
 
9
7
  validates :provider, :presence => true
10
8
 
11
9
  after_save do
12
- self.class.timestamp = updated_at
10
+ self.terminal_profile.invalidate_cached_providers!
13
11
  end
14
12
 
15
13
  after_destroy do
16
- self.class.timestamp = DateTime.now
14
+ self.terminal_profile.invalidate_cached_providers!
17
15
  end
18
16
  end
@@ -8,4 +8,12 @@ class TerminalProfileProvider < ActiveRecord::Base
8
8
  validates :provider_id, :uniqueness => {:scope => :terminal_profile_id}
9
9
  validates :provider, :presence => true
10
10
  validates :terminal_profile, :presence => true
11
+
12
+ after_save do
13
+ self.terminal_profile.invalidate_cached_providers!
14
+ end
15
+
16
+ after_destroy do
17
+ self.terminal_profile.invalidate_cached_providers!
18
+ end
11
19
  end
@@ -12,4 +12,12 @@ class TerminalProfileProviderGroup < ActiveRecord::Base
12
12
  validates :terminal_profile, :presence => true
13
13
 
14
14
  delegate :title, :to => :terminal_profile
15
+
16
+ after_save do
17
+ self.terminal_profile.invalidate_cached_providers!
18
+ end
19
+
20
+ after_destroy do
21
+ self.terminal_profile.invalidate_cached_providers!
22
+ end
15
23
  end
data/config/routes.rb CHANGED
@@ -7,8 +7,8 @@ Rails.application.class.routes.draw do
7
7
 
8
8
  devise_for :users, ActiveAdmin::Devise.config
9
9
 
10
- constraints lambda { |request|
11
- request.env["warden"].authenticate? and request.env['warden'].user.root?
10
+ constraints lambda { |request|
11
+ request.env["warden"].authenticate? and request.env['warden'].user.root?
12
12
  } do
13
13
  mount Sidekiq::Web => '/sidekiq'
14
14
  end
@@ -20,7 +20,13 @@ Rails.application.class.routes.draw do
20
20
  :log_to => Rails.root.join('log/webdav.log').to_s
21
21
  ) => '/builds/'
22
22
 
23
- resources :terminal_pings
23
+ resources :terminal_pings do
24
+ collection do
25
+ get :providers
26
+ end
27
+ end
28
+
29
+
24
30
  resources :collections
25
31
  resources :system_receipt_templates
26
32
 
@@ -1,5 +1,5 @@
1
1
  module Smartkiosk
2
2
  module Server
3
- VERSION = '0.9.3'
3
+ VERSION = '0.10.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,48 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartkiosk-server
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.9.3
4
+ version: 0.10.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Boris Staal
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-04 00:00:00.000000000 Z
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - '='
19
- - !ruby/object:Gem::Version
20
- version: 3.2.11
16
+ requirement: &70123420824880 !ruby/object:Gem::Requirement
21
17
  none: false
22
- requirement: !ruby/object:Gem::Requirement
23
18
  requirements:
24
- - - '='
19
+ - - =
25
20
  - !ruby/object:Gem::Version
26
21
  version: 3.2.11
27
- none: false
28
- prerelease: false
29
22
  type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70123420824880
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: matrioshka
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 0.1.1
27
+ requirement: &70123420824340 !ruby/object:Gem::Requirement
37
28
  none: false
38
- requirement: !ruby/object:Gem::Requirement
39
29
  requirements:
40
- - - ">="
30
+ - - ! '>='
41
31
  - !ruby/object:Gem::Version
42
32
  version: 0.1.1
43
- none: false
44
- prerelease: false
45
33
  type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70123420824340
46
36
  description: Smartkiosk server application
47
37
  email:
48
38
  - boris@roundlake.ru
@@ -50,8 +40,8 @@ executables: []
50
40
  extensions: []
51
41
  extra_rdoc_files: []
52
42
  files:
53
- - ".gitignore"
54
- - ".rspec"
43
+ - .gitignore
44
+ - .rspec
55
45
  - Capfile
56
46
  - Gemfile
57
47
  - Gemfile.lock
@@ -310,26 +300,24 @@ rdoc_options: []
310
300
  require_paths:
311
301
  - lib
312
302
  required_ruby_version: !ruby/object:Gem::Requirement
303
+ none: false
313
304
  requirements:
314
- - - ">="
305
+ - - ! '>='
315
306
  - !ruby/object:Gem::Version
307
+ version: '0'
316
308
  segments:
317
309
  - 0
318
- hash: 2
319
- version: !binary |-
320
- MA==
321
- none: false
310
+ hash: 4534525538031660803
322
311
  required_rubygems_version: !ruby/object:Gem::Requirement
312
+ none: false
323
313
  requirements:
324
- - - ">="
314
+ - - ! '>='
325
315
  - !ruby/object:Gem::Version
326
- version: !binary |-
327
- MA==
328
- none: false
316
+ version: '0'
329
317
  requirements: []
330
- rubyforge_project:
331
- rubygems_version: 1.8.24
332
- signing_key:
318
+ rubyforge_project:
319
+ rubygems_version: 1.8.15
320
+ signing_key:
333
321
  specification_version: 3
334
322
  summary: Smartkiosk server application
335
323
  test_files: