smartkiosk-client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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