smartkiosk-client 0.0.1

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.
Files changed (75) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +176 -0
  3. data/Rakefile +4 -0
  4. data/app/controllers/banners.rb +14 -0
  5. data/app/controllers/collections.rb +10 -0
  6. data/app/controllers/config.rb +23 -0
  7. data/app/controllers/payments.rb +30 -0
  8. data/app/controllers/receipts.rb +13 -0
  9. data/app/controllers/terminal.rb +104 -0
  10. data/app/models/admin.rb +3 -0
  11. data/app/models/banner.rb +5 -0
  12. data/app/models/collection.rb +53 -0
  13. data/app/models/customer.rb +3 -0
  14. data/app/models/group.rb +37 -0
  15. data/app/models/order.rb +25 -0
  16. data/app/models/payment.rb +80 -0
  17. data/app/models/phone_range.rb +3 -0
  18. data/app/models/promotion.rb +11 -0
  19. data/app/models/provider.rb +42 -0
  20. data/app/models/receipt.rb +21 -0
  21. data/app/models/receipt_template.rb +5 -0
  22. data/app/models/terminal.rb +152 -0
  23. data/app/uploaders/icon_uploader.rb +9 -0
  24. data/app/views/banners.haml +50 -0
  25. data/app/workers/orders/acknowledge_worker.rb +22 -0
  26. data/app/workers/orders/complete_worker.rb +20 -0
  27. data/app/workers/orders/disable_worker.rb +16 -0
  28. data/app/workers/orders/enable_worker.rb +16 -0
  29. data/app/workers/orders/reboot_worker.rb +18 -0
  30. data/app/workers/orders/reload_worker.rb +18 -0
  31. data/app/workers/orders/upgrade_worker.rb +108 -0
  32. data/app/workers/payments/check_worker.rb +35 -0
  33. data/app/workers/payments/collect_worker.rb +23 -0
  34. data/app/workers/payments/pay_worker.rb +21 -0
  35. data/app/workers/ping_worker.rb +180 -0
  36. data/app/workers/startup_worker.rb +11 -0
  37. data/app/workers/sync/icons_worker.rb +20 -0
  38. data/app/workers/sync/receipt_templates_worker.rb +27 -0
  39. data/config/boot.rb +104 -0
  40. data/config/services/application.yml +4 -0
  41. data/config/services/database.yml +17 -0
  42. data/config/services/database.yml.sample +33 -0
  43. data/config/services/smartware.yml +28 -0
  44. data/config/services/smartware.yml.sample +13 -0
  45. data/config/sidekiq.yml +12 -0
  46. data/db/development.sqlite3 +0 -0
  47. data/db/migrate/20121230080152_create_customers.rb +8 -0
  48. data/db/migrate/20121230080159_create_admins.rb +11 -0
  49. data/db/migrate/20130106150707_create_orders.rb +14 -0
  50. data/db/migrate/20130106155321_create_providers.rb +19 -0
  51. data/db/migrate/20130106160834_create_groups.rb +11 -0
  52. data/db/migrate/20130106181512_create_receipt_templates.rb +9 -0
  53. data/db/migrate/20130106181548_create_payments.rb +26 -0
  54. data/db/migrate/20130106181729_create_collections.rb +10 -0
  55. data/db/migrate/20130106181803_create_receipts.rb +15 -0
  56. data/db/migrate/20130106181844_create_phone_ranges.rb +14 -0
  57. data/db/migrate/20130108110546_create_promotions.rb +9 -0
  58. data/db/migrate/20130110025256_create_banners.rb +12 -0
  59. data/init.rb +1 -0
  60. data/lib/pinger.rb +22 -0
  61. data/lib/sidekiq.rb +20 -0
  62. data/lib/smartkiosk/client/version.rb +7 -0
  63. data/lib/smartkiosk/client.rb +1 -0
  64. data/lib/smartkiosk/config/chunk.rb +7 -0
  65. data/lib/smartkiosk/config/yaml.rb +26 -0
  66. data/lib/tasks/db.rb +15 -0
  67. data/lib/tasks/pack.rb +27 -0
  68. data/lib/tasks/scheduler.rb +27 -0
  69. data/lib/tasks/services.rb +20 -0
  70. data/server.rb +11 -0
  71. data/smartkiosk-client.gemspec +55 -0
  72. data/tmp/pids/.gitkeep +0 -0
  73. data/tmp/pids/sidekiq.pid +1 -0
  74. data/vendor/assets/javascripts/jquery.js +9555 -0
  75. metadata +444 -0
@@ -0,0 +1,11 @@
1
+ Application.load 'lib/sidekiq'
2
+
3
+ class StartupWorker
4
+ include Sidekiq::Worker
5
+
6
+ sidekiq_options :queue => :startup, :retry => false
7
+
8
+ def perform(klass, method, args=[])
9
+ klass.constantize.send method, *args
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ require 'rest-client'
2
+
3
+ Application.load 'lib/sidekiq'
4
+
5
+ module Sync
6
+ class IconsWorker
7
+ include Sidekiq::Worker
8
+
9
+ sidekiq_options :retry => false, :queue => :sync
10
+
11
+ def perform(model, id, url)
12
+ entity = model.constantize.find(id)
13
+ attempt = entity.update_attributes :remote_icon_url => "#{Terminal.config.host}/#{url}"
14
+
15
+ unless attempt
16
+ Sync::IconsWorker.perform_in(1.minute, model, id, url)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'rest-client'
2
+
3
+ Application.load 'lib/sidekiq'
4
+
5
+ module Sync
6
+ class ReceiptTemplatesWorker
7
+ include Sidekiq::Worker
8
+
9
+ sidekiq_options :retry => false, :queue => :sync
10
+
11
+ def perform
12
+ params = {
13
+ :terminal => Terminal.config.keyword
14
+ }
15
+
16
+ response = RestClient.get "#{Terminal.config.host}/system_receipt_templates?#{params.to_query}"
17
+ templates = JSON.parse(response.to_s, :symbolize_names => true)
18
+
19
+ templates.each do |entry|
20
+ ReceiptTemplate.find_or_create_by_keyword(entry[:keyword]).
21
+ update_attributes :template => entry[:template]
22
+ end
23
+
24
+ nil
25
+ end
26
+ end
27
+ end
data/config/boot.rb ADDED
@@ -0,0 +1,104 @@
1
+ require 'pry'
2
+ require 'active_support/all'
3
+ require 'sass'
4
+ require 'sprockets'
5
+ require 'sprockets/sass'
6
+ require 'sprockets/helpers'
7
+
8
+ require 'sinatra/base'
9
+ require 'sinatra/activerecord'
10
+ require 'sinatra/reloader'
11
+ require 'sinatra/json'
12
+
13
+ module Smartkiosk
14
+ class Client < Sinatra::Base
15
+ register Sinatra::ActiveRecordExtension
16
+
17
+ helpers do
18
+ include Sprockets::Helpers
19
+ end
20
+
21
+ configure do
22
+ set :assets_types, %w(javascripts stylesheets images)
23
+ set :root, Pathname.new(File.expand_path '../..', __FILE__)
24
+ set :sprockets, Sprockets::Environment.new(root)
25
+ set :database_file, '../config/services/database.yml'
26
+ set :views, [File.expand_path('../../app/views', __FILE__)]
27
+ set :logging, true
28
+
29
+ assets_types.map do |x|
30
+ sprockets.append_path root.join("app/assets/#{x}")
31
+ sprockets.append_path root.join("vendor/assets/#{x}")
32
+ end
33
+
34
+ ActiveRecord::Base.include_root_in_json = false
35
+ ActiveRecord::Migrator.migrations_paths = [root.join('db/migrate')]
36
+ end
37
+
38
+ configure :development do
39
+ register Sinatra::Reloader
40
+
41
+ Sprockets::Helpers.configure do |config|
42
+ config.environment = sprockets
43
+ config.expand = true
44
+ end
45
+ end
46
+
47
+ configure :production do
48
+ Sprockets::Helpers.configure do |config|
49
+ config.environment = sprockets
50
+ config.expand = false
51
+ config.digest = true
52
+ end
53
+ end
54
+
55
+ def find_template(views, name, engine, &block)
56
+ Array(views).each { |v| super(v.to_s, name, engine, &block) }
57
+ end
58
+
59
+ def json(data)
60
+ content_type :json
61
+ data.to_json
62
+ end
63
+
64
+ get "/assets/*" do
65
+ env["PATH_INFO"].sub!(%r{^/assets}, "")
66
+ settings.sprockets.call(env)
67
+ end
68
+
69
+ def self.load(path)
70
+ require File.expand_path File.join('../..', path), __FILE__
71
+ end
72
+
73
+ def self.run!(*args)
74
+ load 'lib/sidekiq'
75
+ Sidekiq.startup!
76
+ super
77
+ end
78
+
79
+ def self.load_tasks!
80
+ require "sinatra/activerecord/rake"
81
+ Dir[File.expand_path "../../lib/tasks/*.rb", __FILE__].each {|file| require file}
82
+ end
83
+
84
+ def self.load_app!
85
+ %w(uploaders models workers controllers).each do |dir|
86
+ Dir[File.expand_path "../../app/#{dir}/**/*.rb", __FILE__].each {|file| require file }
87
+ end
88
+ end
89
+
90
+ def self.expand!(path)
91
+ set :root, Pathname.new(File.expand_path '../..', path)
92
+ set :database_file, root.join('config/services/database.yml')
93
+ set :views, views + [root.join('app/views')]
94
+
95
+ assets_types.map do |x|
96
+ sprockets.append_path root.join("app/assets/#{x}")
97
+ sprockets.append_path root.join("vendor/assets/#{x}")
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ Application = Smartkiosk::Client
104
+ Application.load_app!
@@ -0,0 +1,4 @@
1
+ ---
2
+ smartguard_host: druby://localhost:10000
3
+ keyword: LOCAL
4
+ host: http://localhost:3000
@@ -0,0 +1,17 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: db/development.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+
7
+ test:
8
+ adapter: sqlite3
9
+ database: db/test.sqlite3
10
+ pool: 5
11
+ timeout: 5000
12
+
13
+ production:
14
+ adapter: sqlite3
15
+ database: db/production.sqlite3
16
+ pool: 5
17
+ timeout: 5000
@@ -0,0 +1,33 @@
1
+ development:
2
+ adapter: postgresql
3
+ host: localhost
4
+ port: 5432
5
+ username: smartkiosk-dev
6
+ password: smartkiosk-dev
7
+ database: smartkiosk-dev
8
+ schema_search_path: public
9
+ encoding: utf8
10
+ pool: 30
11
+
12
+ test:
13
+ adapter: postgresql
14
+ host: localhost
15
+ port: 5432
16
+ username: smartkiosk-tst
17
+ password: smartkiosk-tst
18
+ database: smartkiosk-tst
19
+ schema_search_path: public
20
+ encoding: utf8
21
+ pool: 30
22
+
23
+ production:
24
+ adapter: postgresql
25
+ host: localhost
26
+ port: 5432
27
+ username: smartkiosk-prd
28
+ password: smartkiosk-prd
29
+ database: smartkiosk-prd
30
+ schema_search_path: public
31
+ encoding: utf8
32
+ pool: 30
33
+
@@ -0,0 +1,28 @@
1
+ ---
2
+ connection_timeout: ''
3
+ interfaces:
4
+ - name: Modem
5
+ uri: druby://localhost:6002
6
+ status_channel: ''
7
+ ppp_channel: ''
8
+ poll_interval: ''
9
+ balance_interval: ''
10
+ driver: Dummy
11
+ port: ''
12
+ apn: ''
13
+ balance_ussd: ''
14
+ - name: CashAcceptor
15
+ uri: druby://localhost:6001
16
+ driver: Dummy
17
+ port: ''
18
+ - name: Printer
19
+ uri: druby://localhost:6005
20
+ driver: Dummy
21
+ port: ''
22
+ - name: Watchdog
23
+ uri: druby://localhost:6003
24
+ pidfile: /var/run/watchdogd.pid
25
+ driver: Dummy
26
+ - name: CardReader
27
+ uri: druby://localhost:6004
28
+ driver: Dummy
@@ -0,0 +1,13 @@
1
+ interfaces:
2
+ - name: CashAcceptor
3
+ uri: druby://localhost:6001
4
+ driver: CCNET
5
+ port: /dev/ttyS0
6
+ - name: Modem
7
+ uri: druby://localhost:6002
8
+ driver: Dummy
9
+ port: /dev/mux1
10
+ - name: Printer
11
+ uri: druby://localhost:6005
12
+ driver: TG24XX
13
+ port: /dev/ttyS4
@@ -0,0 +1,12 @@
1
+ ---
2
+ :verbose: false
3
+ :pidfile: tmp/pids/sidekiq.pid
4
+ :namespace: sidekiq_namespace
5
+ :concurrency: 25
6
+ :queues:
7
+ - [pings, 1]
8
+ - [payments, 1]
9
+ - [orders, 1]
10
+ - [sync, 1]
11
+ - [scheduled, 1]
12
+ - [default, 1]
Binary file
@@ -0,0 +1,8 @@
1
+ class CreateCustomers < ActiveRecord::Migration
2
+ def change
3
+ create_table :customers do |t|
4
+
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ class CreateAdmins < ActiveRecord::Migration
2
+ def change
3
+ create_table :admins do |t|
4
+ t.string :login
5
+ t.string :password_hash
6
+ t.string :password_salt
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ class CreateOrders < ActiveRecord::Migration
2
+ def change
3
+ create_table :orders do |t|
4
+ t.integer :foreign_id
5
+ t.string :keyword
6
+ t.text :args
7
+ t.string :error
8
+ t.boolean :acknowledged
9
+ t.boolean :complete
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ class CreateProviders < ActiveRecord::Migration
2
+ def change
3
+ create_table :providers do |t|
4
+ t.integer :foreign_id
5
+
6
+ t.belongs_to :group
7
+ t.string :keyword
8
+ t.string :title
9
+ t.string :icon
10
+ t.integer :priority
11
+ t.text :fields
12
+ t.integer :fields_count, :null => false, :default => 0
13
+ t.boolean :requires_print, :null => false, :default => false
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :providers, :foreign_id, :unique => true
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ class CreateGroups < ActiveRecord::Migration
2
+ def change
3
+ create_table :groups do |t|
4
+ t.belongs_to :group
5
+ t.string :title
6
+ t.string :icon
7
+ t.integer :priority
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class CreateReceiptTemplates < ActiveRecord::Migration
2
+ def change
3
+ create_table :receipt_templates do |t|
4
+ t.string :keyword
5
+ t.text :template
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ class CreatePayments < ActiveRecord::Migration
2
+ def change
3
+ create_table :payments do |t|
4
+ t.integer :foreign_id
5
+ t.belongs_to :provider
6
+ t.belongs_to :collection
7
+ t.string :account
8
+ t.string :fields
9
+ t.string :banknotes
10
+ t.string :limit
11
+ t.string :commissions
12
+ t.text :receipt_template
13
+ t.boolean :error, :default => false
14
+ t.boolean :checked, :default => false
15
+ t.boolean :processed, :default => false
16
+ t.boolean :failed, :default => false
17
+
18
+ t.decimal :paid_amount, :precision => 38, :scale => 2
19
+ t.decimal :commission_amount, :precision => 38, :scale => 2
20
+
21
+ t.timestamps
22
+ end
23
+
24
+ add_index :payments, :provider_id
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ class CreateCollections < ActiveRecord::Migration
2
+ def change
3
+ create_table :collections do |t|
4
+ t.text :payment_ids
5
+ t.text :banknotes
6
+ t.datetime :reported_at
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ class CreateReceipts < ActiveRecord::Migration
2
+ def change
3
+ create_table :receipts do |t|
4
+ t.text :fields
5
+ t.text :template
6
+ t.string :keyword
7
+ t.boolean :printed, :default => false
8
+ t.integer :document_id
9
+ t.string :document_type
10
+
11
+ t.timestamps
12
+ end
13
+ add_index :receipts, [:document_id, :document_type]
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ class CreatePhoneRanges < ActiveRecord::Migration
2
+ def change
3
+ create_table :phone_ranges do |t|
4
+ t.decimal :start # it`s decimal because mysql do magic for integer
5
+ t.decimal :end
6
+ t.belongs_to :provider
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :phone_ranges, :start
11
+ add_index :phone_ranges, :end
12
+ add_index :phone_ranges, :provider_id
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ class CreatePromotions < ActiveRecord::Migration
2
+ def change
3
+ create_table :promotions do |t|
4
+ t.belongs_to :provider
5
+ t.integer :priority
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class CreateBanners < ActiveRecord::Migration
2
+ def change
3
+ create_table :banners do |t|
4
+ t.boolean :visible, :default => false
5
+ t.decimal :duration
6
+ t.integer :playorder
7
+ t.string :filename
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'smartkiosk/client'
data/lib/pinger.rb ADDED
@@ -0,0 +1,22 @@
1
+ class Pinger
2
+ def self.http(uri)
3
+ result = true
4
+
5
+ begin
6
+ RestClient.get uri
7
+ rescue RestClient::Forbidden
8
+ rescue Exception => e
9
+ result = e.to_s
10
+ end
11
+
12
+ result
13
+ end
14
+
15
+ def self.external(host)
16
+ result = false
17
+ ping = `ping -q -c 1 #{host}`
18
+
19
+ result = ping.split("\n").last.split("=").last.split('/')[1] if $?.exitstatus == 0
20
+ result
21
+ end
22
+ end
data/lib/sidekiq.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'sidekiq'
2
+
3
+ module Sidekiq
4
+ module Logging
5
+
6
+ class Pretty < Logger::Formatter
7
+ def call(severity, time, progname, msg)
8
+ msg = "(TID-#{Thread.current.object_id.to_s(36)}#{context}) #{msg}"
9
+ Smartkiosk::Common::Logging.format "Sidekiq", severity, time, progname, msg
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.startup!
15
+ jobs = Sidekiq::Queue.new("startup").map do |job|
16
+ job.delete
17
+ job.klass.constantize.new.perform(*job.args)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ require 'sinatra/base'
2
+
3
+ module Smartkiosk
4
+ class Client < Sinatra::Base
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require_relative "../../config/boot"
@@ -0,0 +1,7 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Smartkiosk
4
+ module Config
5
+ class Chunk < RecursiveOpenStruct; end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require 'yaml'
2
+ require_relative 'chunk'
3
+
4
+ module Smartkiosk
5
+ module Config
6
+ class YAML < Chunk
7
+
8
+ def initialize(file)
9
+ super load_yml(@file = file)
10
+ end
11
+
12
+ def save!
13
+ File.open(@file, 'wb') do |file|
14
+ file.write(self.marshal_dump.to_yaml)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def load_yml(file)
21
+ ::YAML.load(File.read file).to_hash
22
+ end
23
+
24
+ end
25
+ end
26
+ end
data/lib/tasks/db.rb ADDED
@@ -0,0 +1,15 @@
1
+ namespace :db do
2
+ task :seed do
3
+ load("db/seeds.rb") if File.exists?("db/seeds.rb")
4
+ end
5
+
6
+ task :install do
7
+ ActiveRecord::Base.connection.tables.each do |x|
8
+ ActiveRecord::Base.connection.drop_table x
9
+ end
10
+
11
+ Redis.current.flushall
12
+ Rake::Task['db:migrate'].invoke
13
+ Rake::Task['db:seed'].invoke
14
+ end
15
+ end
data/lib/tasks/pack.rb ADDED
@@ -0,0 +1,27 @@
1
+ require "zip/zip"
2
+
3
+ task :pack do
4
+ exclude = [
5
+ 'tmp/',
6
+ 'config/services/',
7
+ 'config/database.yml',
8
+ 'test/',
9
+ 'spec/',
10
+ 'doc/'
11
+ ]
12
+
13
+ builds = Pathname.new("tmp/builds/")
14
+ zip_file = builds.join(File.read(Application.root.join "VERSION") + '.zip')
15
+
16
+ FileUtils.mkdir_p builds
17
+ File.delete zip_file if File.exist? zip_file
18
+
19
+ Zip::ZipFile.open(zip_file, Zip::ZipFile::CREATE) do |zipfile|
20
+ `git ls-files`.split($/).each do |filename|
21
+ next unless File.file?(filename)
22
+ next if exclude.map{|x| filename.start_with?(x)}.include?(true)
23
+
24
+ zipfile.add(filename, filename)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ task :schedule do
2
+ require 'rufus-scheduler'
3
+ scheduler = Rufus::Scheduler.start_new
4
+
5
+ logger = Logger.new(STDOUT)
6
+ logger.level = Logger::DEBUG
7
+ logger.formatter = proc do |severity, time, progname, msg|
8
+ Smartkiosk::Common::Logging.format "Scheduler", severity, time, progname, msg
9
+ end
10
+
11
+ scheduler.every '1m' do
12
+ logger.debug "Terminal ping"
13
+ Terminal.ping
14
+ end
15
+
16
+ scheduler.every '3h' do
17
+ logger.debug "Receipt Templates sync"
18
+ Sync::ReceiptTemplatesWorker.perform_async
19
+ end
20
+
21
+ logger.debug "Schedule loaded"
22
+ begin
23
+ scheduler.join
24
+ rescue Interrupt
25
+ logger.debug "Interrupting..."
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ task :console do
2
+ binding.pry
3
+ end
4
+
5
+ task :smartguard do
6
+ exec('bundle exec smartguard --development --app smartkiosk')
7
+ end
8
+
9
+ task :sidekiq do
10
+ exec('bundle exec sidekiq -q pings -q payments -q orders -q sync -q scheduled -r ./app.rb')
11
+ end
12
+
13
+ task :server do
14
+ require 'eventmachine'
15
+ require 'thin'
16
+
17
+ EventMachine.run do
18
+ Smartkiosk::Client.run! :server => 'thin', :port => 3000
19
+ end
20
+ end
data/server.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require "eventmachine"
5
+ require "thin"
6
+
7
+ require_relative "config/boot"
8
+
9
+ EventMachine.run do
10
+ Smartkiosk::Client.run! :port => 3000
11
+ end