smartkiosk-server 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: