da_funk 0.5.4 → 0.6.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.
@@ -16,46 +16,45 @@ module DaFunk
16
16
 
17
17
  def attach
18
18
  Device::Display.clear
19
- puts "Connecting..."
19
+ I18n.pt(:attach_connecting)
20
20
  if Device::Network.connected? < 0
21
21
  if (ret = Device::Network.attach) == 0
22
- puts "Successfully Connected"
22
+ I18n.pt(:attach_connected)
23
23
  else
24
- puts "Attach fail #{ret}"
24
+ I18n.pt(:attach_fail, :args => [ret.to_s])
25
25
  sleep 4
26
26
  return false
27
27
  end
28
28
  else
29
- puts "Already connected"
29
+ I18n.pt(:attach_already_connected)
30
30
  end
31
31
  true
32
32
  end
33
33
 
34
- # TODO Add i18n or something
35
34
  def check_download_error(ret)
36
35
  value = true
37
36
  case ret
38
37
  when Device::Transaction::Download::SERIAL_NUMBER_NOT_FOUND
39
- puts "Serial number not found."
38
+ I18n.pt(:download_serial_number_not_found, :args => [ret])
40
39
  value = false
41
40
  when Device::Transaction::Download::FILE_NOT_FOUND
42
- puts "File not found."
41
+ I18n.pt(:download_file_not_found, :args => [ret])
43
42
  value = false
44
43
  when Device::Transaction::Download::FILE_NOT_CHANGE
45
- puts "File is the same."
44
+ I18n.pt(:download_file_is_the_same, :args => [ret])
46
45
  when Device::Transaction::Download::SUCCESS
47
- puts "Success."
46
+ I18n.pt(:download_success, :args => [ret])
48
47
  when Device::Transaction::Download::COMMUNICATION_ERROR
49
- puts "Communication failure."
48
+ I18n.pt(:download_communication_failure, :args => [ret])
50
49
  value = false
51
50
  when Device::Transaction::Download::MAPREDUCE_RESPONSE_ERROR
52
- puts "Encoding error."
51
+ I18n.pt(:download_encoding_error, :args => [ret])
53
52
  value = false
54
53
  when Device::Transaction::Download::IO_ERROR
55
- puts "IO Error."
54
+ I18n.pt(:download_io_error, :args => [ret])
56
55
  value = false
57
56
  else
58
- puts "Communication fail."
57
+ I18n.pt(:download_communication_failure, :args => [ret])
59
58
  value = false
60
59
  end
61
60
 
@@ -72,6 +71,17 @@ module DaFunk
72
71
  ret
73
72
  end
74
73
 
74
+ def try_key(keys, timeout = Device::IO.timeout)
75
+ key = nil
76
+ keys = [keys].flatten
77
+ time = Time.now + timeout / 1000 if (timeout != 0)
78
+ while (! keys.include?(key)) do
79
+ return Device::IO::KEY_TIMEOUT if (timeout != 0 && time < Time.now)
80
+ key = getc(timeout)
81
+ end
82
+ key
83
+ end
84
+
75
85
  # Create a form menu.
76
86
  #
77
87
  # @param title [String] Text to display on line 0. If nil title won't be
@@ -98,26 +108,86 @@ module DaFunk
98
108
  # menu("Option menu", selection, options)
99
109
  #
100
110
  def menu(title, selection, options = {})
101
- options[:number] = true if options[:number].nil?
111
+ return nil if selection.empty?
112
+ options[:number] = true if options[:number].nil?
113
+ options[:timeout] ||= Device::IO.timeout
114
+ key, selected = pagination(title, options, selection) do |collection, line_zero|
115
+ collection.each_with_index do |value,i|
116
+ display = value.is_a?(Array) ? value[0] : value
117
+ if options[:number]
118
+ Device::Display.print("#{i+1} #{display}", i+line_zero, 0)
119
+ else
120
+ Device::Display.print("#{display}", i+line_zero, 0)
121
+ end
122
+ end
123
+ end
102
124
 
103
- if title
104
- Device::Display.clear
105
- print_title(title, options[:default])
125
+ if key == Device::IO::ENTER || key == Device::IO::CANCEL
126
+ options[:default]
127
+ else
128
+ selected
106
129
  end
107
- values = Hash.new
108
- selection.each_with_index do |value,i|
109
- values[i.to_i] = value[1]
110
- if options[:number]
111
- Device::Display.print("#{i+1} - #{value[0]}", i+2, 0)
112
- else
113
- Device::Display.print(value[0], i+2, 0)
130
+ end
131
+
132
+ # TODO Scalone: Refactor.
133
+ def pagination(title, options, collection, &block)
134
+ if title.nil?
135
+ start_line = 0
136
+ options[:limit] ||= STDOUT.max_y
137
+ else
138
+ start_line = 1
139
+ options[:limit] ||= STDOUT.max_y - 1
140
+ end
141
+ if collection.size > options[:limit] # minus header
142
+ key = Device::IO::F1
143
+ pages = pagination_page(collection, options[:limit] - 1)
144
+ page = 1
145
+ while(key == Device::IO::F1 || key == Device::IO::F2)
146
+ Device::Display.clear
147
+ print_title(title, options[:default]) if title
148
+ Device::Display.print("< F1 ____ #{page}/#{pages.size} ____ F2 >", start_line, 0)
149
+ values = pages[page].to_a
150
+ block.call(values, start_line+1)
151
+ key = try_key(pagination_keys(values.size))
152
+ page = pagination_key_page(page, key, pages.size)
114
153
  end
154
+ else
155
+ Device::Display.clear
156
+ print_title(title, options[:default]) if title
157
+ values = collection.to_a
158
+ block.call(values, start_line)
159
+ key = try_key(pagination_keys(collection.size))
160
+ end
161
+ result = values[key.to_i-1] if key.integer?
162
+ if result.is_a? Array
163
+ [key, result[1]]
164
+ else
165
+ [key, result]
115
166
  end
167
+ end
116
168
 
117
- key = getc(options[:timeout] || Device::IO.timeout)
169
+ def pagination_key_page(page, key, size)
170
+ if key == Device::IO::F1
171
+ page == 1 ? page : page -= 1
172
+ elsif key == Device::IO::F2
173
+ page >= size ? size : page += 1
174
+ end
175
+ end
118
176
 
119
- return options[:default] if key == Device::IO::ENTER || key == Device::IO::CANCEL
120
- [values[key.to_i - 1]].flatten.first
177
+ def pagination_page(values, size)
178
+ page = 1
179
+ i = 0
180
+ values.group_by do |value|
181
+ if size < (i+=1)
182
+ page+=1; i=0
183
+ end
184
+ page
185
+ end
186
+ end
187
+
188
+ def pagination_keys(size)
189
+ (1..size.to_i).to_a.map(&:to_s) + [Device::IO::ENTER, Device::IO::CLEAR,
190
+ Device::IO::CANCEL, Device::IO::F1, Device::IO::F2]
121
191
  end
122
192
 
123
193
  def number_to_currency(value, options = {})
@@ -146,12 +216,7 @@ module DaFunk
146
216
  text << ch
147
217
  text << options[:delimiter] if (i % 3 == 0) && (len - unit.size) != i
148
218
  end
149
- currency = [rjust(text.reverse, 1, "0"),rjust(unit, options[:precision], "0")].join options[:separator]
150
- if options[:label]
151
- options[:label] + currency
152
- else
153
- currency
154
- end
219
+ [rjust(text.reverse, 1, "0"),rjust(unit, options[:precision], "0")].join options[:separator]
155
220
  end
156
221
 
157
222
  def ljust(string, size, new_string)
@@ -183,9 +248,9 @@ module DaFunk
183
248
 
184
249
  def print_title(string, default)
185
250
  if default
186
- puts("#{string} (#{default}):")
251
+ puts("#{string} (#{default})")
187
252
  else
188
- puts("#{string}:")
253
+ puts("#{string}")
189
254
  end
190
255
  end
191
256
  end
@@ -0,0 +1,77 @@
1
+ class I18n
2
+ include DaFunk::Helper
3
+ class << self
4
+ attr_accessor :locale, :hash, :block_parse, :klasses
5
+ end
6
+
7
+ self.block_parse = Proc.new do |hash_,values_|
8
+ if values_[1].is_a?(Hash)
9
+ hash_[values_[0]] = values_[1].inject({}, &block_parse)
10
+ else
11
+ hash_[values_[0].to_sym] = values_[1]
12
+ end
13
+ hash_
14
+ end
15
+
16
+ def self.filepath(klass)
17
+ "./#{klass}/i18n.json"
18
+ end
19
+
20
+ def self.configure(klass, locale)
21
+ raise I18nError.new("File not found") if (! File.exists?(filepath(klass)))
22
+ self.parse(klass)
23
+ @locale = locale
24
+ raise I18nError.new("Locale not found") unless language
25
+ end
26
+
27
+ def self.parse(klass)
28
+ @klasses ||= []
29
+ if @hash
30
+ self.merge(JSON.parse(File.read(filepath(klass))).inject({}, &block_parse))
31
+ else
32
+ @hash = JSON.parse(File.read(filepath(klass))).inject({}, &block_parse)
33
+ end
34
+ @klasses << klass
35
+ end
36
+
37
+ def self.merge(hash2)
38
+ @hash ||= {}
39
+ hash2.keys.each do |key|
40
+ @hash[key] ||= {}
41
+ @hash[key].merge!(hash2[key] || {})
42
+ end
43
+ end
44
+
45
+ def self.language
46
+ @hash[@locale]
47
+ end
48
+
49
+ def self.t(symbol, options = {})
50
+ if ! options[:time].nil?
51
+ parse_time(get(symbol), options[:time])
52
+ elsif options[:args]
53
+ get(symbol) % options[:args]
54
+ else
55
+ get(symbol)
56
+ end
57
+ end
58
+
59
+ def self.get(symbol)
60
+ language[symbol] || "No Translation"
61
+ end
62
+
63
+ def self.pt(symbol, options = {})
64
+ puts(t(symbol, options))
65
+ end
66
+
67
+ def self.parse_time(value, time)
68
+ value.sub("yy", time.year.to_s).
69
+ sub("y", time.year.to_s[2..3]).
70
+ sub("M", rjust(time.month.to_s, 2, "0")).
71
+ sub("d", rjust(time.day.to_s, 2, "0")).
72
+ sub("h", rjust(time.hour.to_s, 2, "0")).
73
+ sub("m", rjust(time.min.to_s, 2, "0")).
74
+ sub("s", rjust(time.sec.to_s, 2, "0"))
75
+ end
76
+ end
77
+
@@ -0,0 +1,3 @@
1
+ class I18nError < StandardError
2
+ end
3
+
@@ -9,4 +9,5 @@ file_path = File.join(File.dirname(File.realpath(__FILE__)), "..")
9
9
  require file_path + "/iso8583/message.rb"
10
10
  require file_path + "/iso8583/util.rb"
11
11
  require file_path + "/iso8583/version.rb"
12
+ require file_path + "/iso8583/file_parser.rb"
12
13
  end
@@ -10,7 +10,8 @@ module DaFunk
10
10
  include ::Rake::DSL if defined?(::Rake::DSL)
11
11
 
12
12
  attr_accessor :name, :libs, :tests, :tests_unit, :tests_integration, :root_path, :main_out,
13
- :test_out, :resources, :mrbc, :mruby, :out_path, :resources_out, :debug
13
+ :test_out, :resources, :mrbc, :mruby, :out_path, :resources_out, :debug,
14
+ :tests_resources, :tests_res_out
14
15
 
15
16
  def initialize
16
17
  yield self if block_given?
@@ -20,6 +21,7 @@ module DaFunk
20
21
  @tests ||= FileList['test/**/*test.rb']
21
22
  @tests_integration ||= FileList['test/integration/**/*test.rb']
22
23
  @tests_unit ||= FileList['test/unit/**/*test.rb']
24
+ @tests_resources ||= FileList['test/resources/**/*']
23
25
  @root_path ||= "./"
24
26
  @name ||= File.basename(File.expand_path(@root_path))
25
27
  @out_path ||= File.join(root_path, "out", @name)
@@ -27,6 +29,7 @@ module DaFunk
27
29
  @test_out ||= File.join(out_path, "test.mrb")
28
30
  @resources ||= FileList['resources/**/*']
29
31
  @resources_out ||= @resources.pathmap("%{resources,#{out_path}}p")
32
+ @tests_res_out ||= @tests_resources.pathmap("%{test/resources,out}p")
30
33
  @mruby ||= "cloudwalk run"
31
34
  @mrbc = get_mrbc_bin(@mrbc)
32
35
 
@@ -117,6 +120,9 @@ module DaFunk
117
120
  namespace :test do
118
121
  task :setup => :resources do
119
122
  ENV["RUBY_PLATFORM"] = "mruby"
123
+ tests_resources.each_with_index do |file,dest_i|
124
+ FileUtils.cp(file, tests_res_out[dest_i]) if File.file?(file)
125
+ end
120
126
  end
121
127
 
122
128
  desc "Run unit test on mruby"
@@ -0,0 +1,30 @@
1
+ module DaFunk
2
+ class ScreenFlow
3
+ attr_accessor :list
4
+
5
+ def self.add(method, &block)
6
+ define_method method do
7
+ @list << CallbackFlow.new(self, @list.last, &block)
8
+ self
9
+ end
10
+ end
11
+
12
+ def initialize
13
+ self.list = []
14
+ order
15
+ end
16
+
17
+ def order
18
+ end
19
+
20
+ def start
21
+ first = self.list.first
22
+ first.dispatch(true) if first
23
+ end
24
+
25
+ def confirm(text)
26
+ puts text.chomp
27
+ getc(0)
28
+ end
29
+ end
30
+ end
data/lib/device.rb CHANGED
@@ -20,7 +20,7 @@ class Device
20
20
 
21
21
  def self.app_loop(&block)
22
22
  Device::Display.clear
23
- puts "Checking Notifications..."
23
+ puts "SETUP NOTIFICATIONS..."
24
24
  Notification.setup
25
25
  loop do
26
26
  Notification.check
@@ -1,40 +1,98 @@
1
+ # Scenario
2
+ # 1. Load from scratch
3
+ # - No file downloaded
4
+ # - with file downloaded
5
+ # 2. Second load
6
+ # - No crc update
7
+ # - With crc update
8
+
1
9
  class Device
2
10
  class Application
3
- attr_reader :label, :file_path, :type, :crc, :order, :name
11
+ attr_accessor :crc
12
+ attr_reader :label, :file, :type, :order, :name, :remote, :original, :crc_local
13
+
14
+ def self.delete(collection)
15
+ collection.each do |app|
16
+ begin
17
+ app.delete
18
+ rescue RuntimeError
19
+ end
20
+ end
21
+ end
4
22
 
5
- def initialize(label, file_path, type, crc)
6
- @name = label
23
+ def initialize(label, remote, type, crc)
24
+ @type = type
25
+ @crc = crc
26
+ @original = remote
7
27
  @order, @label = split_label(label)
8
- @file_path = file_path
9
- @type = type
10
- @crc = crc
28
+ @remote = remote.sub("#{Device::Setting.company_name}_", "")
29
+ @name = remote.sub("#{Device::Setting.company_name}_", "").split(".")[0]
30
+ @file = check_path(@remote)
31
+ @crc_local = @crc if File.exists?(@file)
11
32
  end
12
33
 
13
- def file
14
- @file ||= file_path.gsub("#{Device::Setting.company_name}_", "")
34
+ def download(force = false)
35
+ if force || outdated?
36
+ ret = Device::Transaction::Download.request_file(remote, file, crc_local)
37
+ else
38
+ ret = Device::Transaction::Download::FILE_NOT_CHANGE
39
+ end
40
+ @crc_local = @crc if ret == Device::Transaction::Download::SUCCESS
41
+ ret
15
42
  end
16
43
 
17
- def file_no_ext
18
- @file_no_ext ||= file.split(".")[0]
44
+ def dir
45
+ @name
19
46
  end
20
47
 
21
- def zip
22
- @zip ||= "#{file_no_ext}.zip"
48
+ def exists?
49
+ File.exists? file
50
+ end
51
+
52
+ def delete
53
+ File.delete(self.file) if exists?
54
+ if self.ruby? && Dir.exist?(self.dir) && self.dir != "main"
55
+ Dir.delete(self.dir)
56
+ end
23
57
  end
24
58
 
25
59
  def outdated?
26
- return false unless File.exists?(@file_path)
27
- file = File.open(@file_path)
28
- Device::Crypto.crc16_hex(file.read) == @crc
60
+ return true unless File.exists?(file)
61
+ unless @crc_local
62
+ handle = File.open(file)
63
+ @crc_local = Device::Crypto.crc16_hex(handle.read)
64
+ end
65
+ @crc_local != @crc
29
66
  ensure
30
- file.close if file
67
+ handle.close if handle
31
68
  end
32
69
 
33
70
  def execute(json = "")
34
- Device::Runtime.execute(file_no_ext, json)
71
+ if posxml?
72
+ Device::Runtime.execute(remote, json)
73
+ else
74
+ Device::Runtime.execute(name, json)
75
+ end
76
+ end
77
+
78
+ def posxml?
79
+ @type == "posxml" || remote.include?(".posxml")
80
+ end
81
+
82
+ def ruby?
83
+ @type == "ruby" || (! remote.include? ".posxml")
35
84
  end
36
85
 
37
86
  private
87
+
88
+ def check_path(path)
89
+ if posxml?
90
+ "./shared/#{path}"
91
+ else
92
+ "#{path.gsub("#{Device::Setting.company_name}_", "")}.zip"
93
+ end
94
+ end
95
+
38
96
  def split_label(text)
39
97
  if text == "X"
40
98
  number, text = 0, "X"