butler-mainframe 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +43 -22
- data/lib/butler-mainframe.rb +3 -1
- data/lib/config/config.rb +3 -5
- data/lib/config/config_EXAMPLE_x3270.rb +6 -0
- data/lib/mainframe/{passport.rb → emulators/passport.rb} +1 -1
- data/lib/mainframe/{pcomm.rb → emulators/pcomm.rb} +0 -0
- data/lib/mainframe/emulators/x3270.rb +135 -0
- data/lib/mainframe/host_base.rb +41 -37
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 622cd36fbabc8ca579e69b36ef0d3ce535995854
|
4
|
+
data.tar.gz: bb98f4819d07e639c8cb88e092cc3a3a443fa648
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98f255d73ae417b65735be57cea9571d8d9f181ff794e4459a07e494ee8d1866af234d681a1f3af8301233d2b66ca166985677bbd94c14f23f33ae7c5a6565b7
|
7
|
+
data.tar.gz: 0f7ae6b50f6f8d5bdd0f0ede9fae786f3927f88ef707531f4c8fa871a8f3ddd0885331d98176b9a1fcdb6d4a82c9eeb0a30ac3ecfe6719b394505b6124e6c391
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.2.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.1.0...v0.2.0) October 20th, 2015
|
2
|
+
------------------------------
|
3
|
+
* Added support for the free and open source x3270 terminal emulator, use :x3270 as host gateway in butler configuration
|
4
|
+
* Added x3270 sections to documentation
|
5
|
+
* Passport sub class now remove spaces from command input
|
6
|
+
* Added :erase_field_first param to write method in the host base class in addition to :clean_first_chars to clear a given number of chars
|
7
|
+
|
1
8
|
0.1.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.0.6...v0.1.0) October 14th, 2015
|
2
9
|
------------------------------
|
3
10
|
* Added IBM personal communication support (tested on 6.0.16), use :pcomm as host gateway in butler configuration
|
data/README.md
CHANGED
@@ -18,17 +18,15 @@ Instal the gem from rubygems
|
|
18
18
|
gem install butler-mainframe
|
19
19
|
|
20
20
|
Then you have to install your favorite emulator.
|
21
|
-
At the moment is supported only [Passport web to host by rocket software](http://www.rocketsoftware.com/products/rocket-passport-web-to-host)
|
22
21
|
|
23
|
-
## Emulator
|
24
|
-
|
25
|
-
At the moment are managed two emulators both are commercial which must be purchased and installed on the machine.
|
26
|
-
Both have x days free trial.
|
27
22
|
|
28
|
-
|
29
|
-
* [Personal communication by IBM](http://www-03.ibm.com/software/products/en/pcomm)
|
23
|
+
## Emulator
|
30
24
|
|
25
|
+
At the moment are managed the below emulators. First two are commercial which must be purchased and installed on the machine (both have x days free trial). The last is free and open source.
|
31
26
|
|
27
|
+
* [Passport web to host by Rocket Software](http://www.rocketsoftware.com/resource/rocket-passport-web-host-overview)
|
28
|
+
* [Personal communication by IBM](http://www-03.ibm.com/software/products/en/pcomm)
|
29
|
+
* [x3270 maintained by Paul Mates](http://x3270.bgp.nu/)
|
32
30
|
|
33
31
|
|
34
32
|
## Configuration
|
@@ -43,29 +41,37 @@ In the config folder there are two files:
|
|
43
41
|
config.rb can be used for the configuration of the gem and the emulator
|
44
42
|
|
45
43
|
```ruby
|
46
|
-
# Example to
|
44
|
+
# Example to configure Passport web to host
|
47
45
|
|
48
46
|
ButlerMainframe.configure do |config|
|
49
|
-
config.host_gateway = :
|
50
|
-
config.browser_path =
|
51
|
-
config.session_path =
|
52
|
-
config.session_tag =
|
47
|
+
config.host_gateway = :passport
|
48
|
+
config.browser_path = 'c:/Program Files (x86)/Internet Explorer/iexplore.exe'
|
49
|
+
config.session_path = 'https://localhost/zephyr/Ecomes.zwh?sessionprofile=3270dsp/Sessions/host3270'
|
50
|
+
config.session_tag = 1
|
53
51
|
config.timeout = 3000
|
54
52
|
end
|
55
53
|
```
|
56
54
|
|
57
55
|
```ruby
|
58
|
-
# Example to
|
56
|
+
# Example to configure Personal communication
|
59
57
|
|
60
58
|
ButlerMainframe.configure do |config|
|
61
|
-
config.host_gateway = :
|
62
|
-
config.
|
63
|
-
config.
|
64
|
-
config.session_tag = 1
|
59
|
+
config.host_gateway = :pcomm
|
60
|
+
config.session_path = '"C:/Program Files (x86)/IBM/Personal Communications/pcsws.exe" "C:/Users/Marco/AppData/Roaming/IBM/Personal Communications/host3270.ws"'
|
61
|
+
config.session_tag = 'A'
|
65
62
|
config.timeout = 3000
|
66
63
|
end
|
67
64
|
```
|
68
65
|
|
66
|
+
```ruby
|
67
|
+
# Example to configure X3270
|
68
|
+
ButlerMainframe.configure do |config|
|
69
|
+
config.host_gateway = :x3270
|
70
|
+
config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" 127.0.0.1 -model 2 --'
|
71
|
+
config.timeout = 5 # In seconds
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
69
75
|
### Use configuration
|
70
76
|
|
71
77
|
settings.yml for the variables necessary to use the emulator like user, password, cics selection and everything else. It has one section for every environment in rails style.
|
@@ -89,7 +95,7 @@ In this example, I dont start the session and immediately create a new instance:
|
|
89
95
|
Session not found, starting new...
|
90
96
|
Starting session with process id 8560, wait please...
|
91
97
|
** Connection established with host3270 **
|
92
|
-
=> #<ButlerMainframe::Host:0x29f3358 @debug=true, @wait=0.01, @wait_debug=2, @session=1, @close_session=:evaluate, @pid=8560, @action=#<WIN32OLE:0x29ebe10
|
98
|
+
=> #<ButlerMainframe::Host:0x29f3358 @debug=true, @wait=0.01, @wait_debug=2, @session=1, @close_session=:evaluate, @pid=8560, @action=#<WIN32OLE:0x29ebe10>>
|
93
99
|
|
94
100
|
now session is ready to use:
|
95
101
|
|
@@ -128,8 +134,7 @@ host.write 'ruby on rails', :y => 6, :x => 15, hook: 'SYSTEM='
|
|
128
134
|
|
129
135
|
The aim is to speed up browsing through static screens.
|
130
136
|
The butler detects the current screen and It moves towards the target.
|
131
|
-
For example, if the current screen is the login_session and you want to go to the next,
|
132
|
-
In this case it identifies the first map the session login to the mainframe and it does the login to go to the next screen.
|
137
|
+
For example, if the current screen is the login_session and you want to go to the next, Butler log in for you.
|
133
138
|
|
134
139
|
```ruby
|
135
140
|
# Go to the login session screen
|
@@ -153,7 +158,6 @@ My advice is to use navigate method for generic navigation and use a specific mo
|
|
153
158
|
|
154
159
|
## With Rails
|
155
160
|
|
156
|
-
__In development...__
|
157
161
|
This module can be use on rails project.
|
158
162
|
Add in your gemfile
|
159
163
|
|
@@ -195,10 +199,14 @@ end
|
|
195
199
|
```
|
196
200
|
|
197
201
|
Create a polimorphic model:
|
198
|
-
|
202
|
+
|
203
|
+
rails generate screen hook_id:integer 'hook_type:string{30}' 'screen_type:integer{1}' video:text 'message:string{160}' 'cursor_x:integer{1}' 'cursor_y:integer{1}'
|
199
204
|
|
200
205
|
In the model to be related to screen we insert:
|
206
|
+
|
207
|
+
```ruby
|
201
208
|
has_many :screens, :as => :hook, :dependent => :destroy
|
209
|
+
```
|
202
210
|
|
203
211
|
|
204
212
|
## Test with rake
|
@@ -325,11 +333,24 @@ session.autECLOIA.ole_methods (screen):
|
|
325
333
|
# CancelWaits # RegisterCommEvent # UnregisterCommEvent # RegisterOIAEvent
|
326
334
|
# UnregisterOIAEvent # GetTypeInfoCount # GetTypeInfo # GetIDsOfNames
|
327
335
|
|
336
|
+
### x3270
|
337
|
+
|
338
|
+
Documentation can be found [here](http://x3270.bgp.nu/documentation-manpages.html)
|
339
|
+
__At the moment it doesn't support check on protect area__
|
340
|
+
__x3270 module works only on ruby 1.9+__
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
require 'open3'
|
344
|
+
stdin, stdout, thread = Open3.popen2e('"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --')
|
345
|
+
```
|
346
|
+
|
347
|
+
Read the methods list documentation: [windows](http://x3270.bgp.nu/Windows/wc3270-script.html) or [unix](http://x3270.bgp.nu/Unix/x3270-script.html)
|
328
348
|
|
329
349
|
## ToDo
|
330
350
|
|
331
351
|
* Improve unit test
|
332
352
|
* Improve static navigation
|
353
|
+
* Add meta class to choose your host method name and multi language support as well
|
333
354
|
|
334
355
|
## License
|
335
356
|
|
data/lib/butler-mainframe.rb
CHANGED
@@ -25,7 +25,9 @@ env = Rails.env if defined?(Rails)
|
|
25
25
|
env ||= $ARGV[0] if $ARGV
|
26
26
|
env ||= "development"
|
27
27
|
debug = env == "development" ? true : false
|
28
|
-
|
28
|
+
|
29
|
+
# require the emulator sub class specified in the config.rb
|
30
|
+
require "mainframe/emulators/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
|
29
31
|
|
30
32
|
|
31
33
|
ButlerMainframe::Settings.load!(File.join(ButlerMainframe.root,'lib','config','settings.yml'), :env => env)
|
data/lib/config/config.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
ButlerMainframe.configure do |config|
|
2
|
-
config.host_gateway =
|
3
|
-
config.
|
4
|
-
config.
|
5
|
-
config.session_tag = 1
|
6
|
-
config.timeout = 3000
|
2
|
+
config.host_gateway = :x3270
|
3
|
+
config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
|
4
|
+
config.timeout = 5 # In seconds
|
7
5
|
end
|
8
6
|
|
@@ -48,7 +48,7 @@ module ButlerMainframe
|
|
48
48
|
#Execute keyboard command like PF1 or PA2 or ENTER ...
|
49
49
|
def sub_exec_command cmd, options={}
|
50
50
|
# Cast cmd to_s cause it could be passed as label
|
51
|
-
@screen.SendKeys "<#{cmd}>"
|
51
|
+
@screen.SendKeys "<#{cmd.gsub /\s/, ''}>"
|
52
52
|
@screen.WaitHostQuiet
|
53
53
|
end
|
54
54
|
|
File without changes
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'mainframe/host_base'
|
3
|
+
|
4
|
+
# This class use X3270, an interesting project open source
|
5
|
+
# http://x3270.bgp.nu/Windows/wc3270-script.html
|
6
|
+
# http://x3270.bgp.nu/Windows/ws3270-man.html
|
7
|
+
module ButlerMainframe
|
8
|
+
class Host < HostBase
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def sub_create_object options={}
|
13
|
+
str_obj = "#{options[:session_path]}"
|
14
|
+
puts "#{Time.now.strftime "%H:%M:%S"} Creating object #{str_obj}..." if @debug == :full
|
15
|
+
@action = {}
|
16
|
+
@action[:in], @action[:out], @action[:thr] = Open3.popen2e(str_obj)
|
17
|
+
@pid = @action[:thr].pid
|
18
|
+
end
|
19
|
+
|
20
|
+
# Check is session is started
|
21
|
+
def sub_object_created?
|
22
|
+
res = @action[:in] && @action[:out] && @action[:thr]
|
23
|
+
puts "#{Time.now.strftime "%H:%M:%S"} Terminal successfully detected" if @debug == :full && res
|
24
|
+
res
|
25
|
+
end
|
26
|
+
|
27
|
+
# Check is session is operative
|
28
|
+
def sub_object_ready?
|
29
|
+
res = !x_cmd("Query(ConnectionState)").strip.empty?
|
30
|
+
puts "#{Time.now.strftime "%H:%M:%S"} Session ready" if @debug == :full && res
|
31
|
+
res
|
32
|
+
end
|
33
|
+
|
34
|
+
def sub_name
|
35
|
+
"X3270 #{x_cmd "Query(Host)"}".strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def sub_fullname
|
39
|
+
"#{sub_name} #{x_cmd "Query(LuName)"}".strip
|
40
|
+
end
|
41
|
+
|
42
|
+
#Ends the connection and closes the session
|
43
|
+
def sub_close_session
|
44
|
+
@action[:in].close
|
45
|
+
@action[:out].close
|
46
|
+
end
|
47
|
+
|
48
|
+
#Execute keyboard command like PF1 or PA2 or ENTER ...
|
49
|
+
def sub_exec_command cmd, options={}
|
50
|
+
cmd = cmd.split.map(&:capitalize).join
|
51
|
+
if m=/^(Pf|Pa)(\d+)$/.match(cmd)
|
52
|
+
cmd = "#{m[1]}(#{m[2]})"
|
53
|
+
end
|
54
|
+
x_cmd cmd
|
55
|
+
|
56
|
+
command_skip_wait = %w(^erase ^delete)
|
57
|
+
x_cmd "Wait(#{@timeout}, Output)" unless /(#{command_skip_wait.join('|')})/i === cmd
|
58
|
+
end
|
59
|
+
|
60
|
+
#It reads one line part of the screen
|
61
|
+
def sub_scan_row y, x, len
|
62
|
+
x_cmd "Ascii(#{y-1},#{x-1},#{len})"
|
63
|
+
end
|
64
|
+
|
65
|
+
#It reads a rectangle on the screen
|
66
|
+
def sub_scan_area y1, x1, y2, x2
|
67
|
+
x_cmd "Ascii(#{y1-1},#{x1-1},#{y2-y1+1},#{x2-x1+1})"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get cursor coordinates
|
71
|
+
def sub_get_cursor_axes
|
72
|
+
res = x_cmd "Query(Cursor)"
|
73
|
+
res.split.map{|c| c.to_i + 1}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Move cursor to given coordinates
|
77
|
+
def sub_set_cursor_axes y, x, options={}
|
78
|
+
options = {
|
79
|
+
:wait => true
|
80
|
+
}.merge(options)
|
81
|
+
x_cmd "MoveCursor(#{y-1},#{x-1})"
|
82
|
+
if options[:wait]
|
83
|
+
x_cmd "Wait(#{@timeout},InputField)"
|
84
|
+
raise "Positioning the cursor at the coordinates (#{y}, #{x}) failed!" unless sub_get_cursor_axes == [y, x]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Write text on the screen at given coordinates
|
89
|
+
# :check_protect => true add sensitivity to protected areas
|
90
|
+
def sub_write_text text, y, x, options={}
|
91
|
+
options = {
|
92
|
+
:check_protect => true
|
93
|
+
}.merge(options)
|
94
|
+
sub_set_cursor_axes y, x
|
95
|
+
x_cmd "String(#{text})"
|
96
|
+
# TODO
|
97
|
+
# if options[:check_protect]
|
98
|
+
# end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Wait text at given coordinates and wait the session is available again
|
102
|
+
def sub_wait_for_string text, y, x
|
103
|
+
x_cmd "Wait(#{@timeout},InputField)"
|
104
|
+
total_time = 0.0
|
105
|
+
sleep_time = 0.5
|
106
|
+
while sub_scan_row(y, x, text.size) != text do
|
107
|
+
sleep sleep_time
|
108
|
+
total_time = total_time + sleep_time
|
109
|
+
# @timeout should be in milliseconds but everything is possible
|
110
|
+
break if total_time >= @timeout
|
111
|
+
end
|
112
|
+
raise "sub_wait_for_string: string #{text} not found at (#{y}, #{x})" unless sub_scan_row(y, x, text.size) == text
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
116
|
+
def x_cmd cmd
|
117
|
+
puts "x_cmd in: #{cmd}" if @debug
|
118
|
+
@action[:in].print "#{cmd}\n"
|
119
|
+
@action[:in].flush
|
120
|
+
|
121
|
+
str_res_ok = 'ok'
|
122
|
+
ar_res = [str_res_ok, 'error']
|
123
|
+
|
124
|
+
line, str_out = '', ''
|
125
|
+
while line = @action[:out].gets.chomp do
|
126
|
+
puts "x_cmd out: '#{line}'" if @debug
|
127
|
+
break if ar_res.include? line
|
128
|
+
str_out << "#{line[6..-1]}" if /^data:\s/ === line
|
129
|
+
end
|
130
|
+
line == str_res_ok ? str_out : raise(str_out)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
data/lib/mainframe/host_base.rb
CHANGED
@@ -31,7 +31,7 @@ module ButlerMainframe
|
|
31
31
|
@session_tag = options[:session_tag]
|
32
32
|
@close_session = options[:close_session]
|
33
33
|
@timeout = options[:timeout]
|
34
|
-
@pid
|
34
|
+
@pid = nil
|
35
35
|
|
36
36
|
create_object options
|
37
37
|
end
|
@@ -45,9 +45,9 @@ module ButlerMainframe
|
|
45
45
|
puts "Session closed" if @debug
|
46
46
|
wait_session 0.1
|
47
47
|
when :evaluate
|
48
|
-
if @
|
48
|
+
if @pid
|
49
49
|
sub_close_session
|
50
|
-
puts "Session closed
|
50
|
+
puts "Session closed because started by this process with id #{@pid}" if @debug
|
51
51
|
wait_session 0.1
|
52
52
|
else
|
53
53
|
puts "Session not closed because it was already existing" if @debug
|
@@ -95,7 +95,7 @@ module ButlerMainframe
|
|
95
95
|
:check => true,
|
96
96
|
:raise_error_on_check => true,
|
97
97
|
:sensible_data => nil,
|
98
|
-
:clean_first_chars => nil
|
98
|
+
:clean_first_chars => nil # clean x chars before writing a value
|
99
99
|
}.merge(options)
|
100
100
|
|
101
101
|
y = options[:y]
|
@@ -104,18 +104,19 @@ module ButlerMainframe
|
|
104
104
|
raise "Missing coordinates! y(row)=#{y} x(column)=#{x} " unless x && y
|
105
105
|
raise "Sorry, cannot write null values" unless text
|
106
106
|
|
107
|
-
bol_written =
|
107
|
+
bol_written = false
|
108
108
|
if options[:hook]
|
109
109
|
(y-hooked_rows..y+hooked_rows).each do |row_number|
|
110
110
|
if /#{options[:hook]}/ === scan_row(row_number, 1, MAX_TERMINAL_COLUMNS)
|
111
111
|
puts "Change y from #{y} to #{row_number} cause hook to:#{options[:hook]}" if row_number != y && @debug
|
112
|
-
bol_written =
|
112
|
+
bol_written = write_text_on_map text, row_number, x, options
|
113
113
|
break
|
114
114
|
end
|
115
115
|
end
|
116
|
+
else
|
117
|
+
#If no control is required or was not found the label reference
|
118
|
+
bol_written = write_text_on_map(text, y, x, options) unless bol_written
|
116
119
|
end
|
117
|
-
#If no control is required or was not found the label reference
|
118
|
-
bol_written = write_clean_text_on_map(text, y, x, options) unless bol_written
|
119
120
|
bol_written
|
120
121
|
end
|
121
122
|
|
@@ -144,8 +145,10 @@ module ButlerMainframe
|
|
144
145
|
|
145
146
|
sub_create_object options
|
146
147
|
|
147
|
-
|
148
|
-
|
148
|
+
if sub_object_created?
|
149
|
+
puts "Using the terminal with process id #{@pid}" if @pid && @debug
|
150
|
+
else
|
151
|
+
# if the terminal is not found then we start it
|
149
152
|
puts "Session #{@session_tag} not found, starting new..." if @debug
|
150
153
|
|
151
154
|
executable, args = if options[:browser_path] && !options[:browser_path].empty?
|
@@ -172,7 +175,6 @@ module ButlerMainframe
|
|
172
175
|
sub_create_object
|
173
176
|
sub_object_created? ? break : sleep(seconds_between_attempts)
|
174
177
|
end
|
175
|
-
@session_started_by_me = true
|
176
178
|
end
|
177
179
|
|
178
180
|
raise "Session #{@session_tag} not started. Check the session #{options[:browser_path]} #{options[:session_path]}" unless sub_object_created?
|
@@ -210,47 +212,49 @@ module ButlerMainframe
|
|
210
212
|
str
|
211
213
|
end
|
212
214
|
|
213
|
-
# It has an additional option to clean the line before writing a value
|
214
|
-
def write_clean_text_on_map text, y, x, options={}
|
215
|
-
if options[:clean_first_chars] && options[:clean_first_chars].to_i > 0
|
216
|
-
puts "Clean #{options[:clean_first_chars]} char#{options[:clean_first_chars] == 1 ? '' : 's'} y:#{y} x:#{x}" if @debug
|
217
|
-
bol_cleaned = write_text_on_map(" " * options[:clean_first_chars], y, x, options)
|
218
|
-
unless bol_cleaned
|
219
|
-
puts "EHI! Impossible to clean the area specified" if @debug
|
220
|
-
return false
|
221
|
-
end
|
222
|
-
end
|
223
|
-
puts "Clean: #{options[:sensible_data] ? ('*' * text.size) : text} y:#{y} x:#{x}" if @debug
|
224
|
-
write_text_on_map(text, y, x, options)
|
225
|
-
end
|
226
|
-
|
227
215
|
# Write a text on the screen
|
228
216
|
# It also contains the logic to control the successful writing
|
229
217
|
def write_text_on_map text, y, x, options={}
|
230
218
|
options = {
|
231
219
|
:check => true,
|
232
220
|
:raise_error_on_check => true,
|
233
|
-
:sensible_data => nil
|
221
|
+
:sensible_data => nil,
|
222
|
+
:clean_first_chars => nil,
|
223
|
+
:erase_field_first => nil
|
234
224
|
}.merge(options)
|
235
|
-
raise "Impossible to write beyond row #{MAX_TERMINAL_ROWS}"
|
225
|
+
raise "Impossible to write beyond row #{MAX_TERMINAL_ROWS}" if y > MAX_TERMINAL_ROWS
|
236
226
|
raise "Impossible to write beyond column #{MAX_TERMINAL_COLUMNS}" if x > MAX_TERMINAL_COLUMNS
|
237
|
-
raise "Impossible to write a null value"
|
227
|
+
raise "Impossible to write a null value" unless text
|
228
|
+
|
229
|
+
if options[:clean_first_chars] && options[:clean_first_chars].to_i > 0
|
230
|
+
puts "write_text_on_map: Clean #{options[:clean_first_chars]} char#{options[:clean_first_chars] == 1 ? '' : 's'} y:#{y} x:#{x}" if @debug
|
231
|
+
bol_cleaned = write_text_on_map(" " * options[:clean_first_chars], y, x, options)
|
232
|
+
unless bol_cleaned
|
233
|
+
puts "write_text_on_map: EHI! Impossible to clean the area specified" if @debug
|
234
|
+
return false
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
if options[:erase_field_first]
|
239
|
+
set_cursor_axes y, x
|
240
|
+
do_erase
|
241
|
+
end
|
242
|
+
|
238
243
|
sub_write_text text, y, x, :check_protect => options[:check]
|
239
|
-
|
240
|
-
|
244
|
+
res = true
|
245
|
+
# If check is required it verify text is on the screen at given coordinates
|
246
|
+
# Sensible data option disable the check because it could be on hidden fields
|
247
|
+
if options[:check] && !options[:sensible_data]
|
241
248
|
# It expects the string is present on the session at the specified coordinates
|
242
|
-
|
243
|
-
return true
|
244
|
-
else
|
249
|
+
unless sub_wait_for_string text, y, x
|
245
250
|
if options[:raise_error_on_check]
|
246
|
-
raise "Impossible to write #{options[:sensible_data] ? ('*' * text.size) : text} at row #{y} column #{x}"
|
251
|
+
raise "write_text_on_map: Impossible to write #{options[:sensible_data] ? ('*' * text.size) : text} at row #{y} column #{x}"
|
247
252
|
else
|
248
|
-
|
253
|
+
res = false
|
249
254
|
end
|
250
255
|
end
|
251
|
-
else
|
252
|
-
return true
|
253
256
|
end
|
257
|
+
res
|
254
258
|
end
|
255
259
|
|
256
260
|
# If is called a not existing method there is the chance that an optional module may not have been added
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: butler-mainframe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Mastrodonato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This gem provides a virtual butler which can perform your custom tasks
|
14
14
|
on a 3270 emulator. You just have to choose your emulator (atm only one choice)
|
@@ -27,6 +27,7 @@ files:
|
|
27
27
|
- lib/config/config.rb
|
28
28
|
- lib/config/config_EXAMPLE_passport.rb
|
29
29
|
- lib/config/config_EXAMPLE_pcomm.rb
|
30
|
+
- lib/config/config_EXAMPLE_x3270.rb
|
30
31
|
- lib/config/settings.yml
|
31
32
|
- lib/config/settings_EXAMPLE.yml
|
32
33
|
- lib/core/configuration.rb
|
@@ -37,9 +38,10 @@ files:
|
|
37
38
|
- lib/generators/butler_mainframe.rb
|
38
39
|
- lib/mainframe/customization/active_record.rb
|
39
40
|
- lib/mainframe/customization/generic_functions.rb
|
41
|
+
- lib/mainframe/emulators/passport.rb
|
42
|
+
- lib/mainframe/emulators/pcomm.rb
|
43
|
+
- lib/mainframe/emulators/x3270.rb
|
40
44
|
- lib/mainframe/host_base.rb
|
41
|
-
- lib/mainframe/passport.rb
|
42
|
-
- lib/mainframe/pcomm.rb
|
43
45
|
- lib/vendor/deep_symbolize.rb
|
44
46
|
- rakefile
|
45
47
|
- test/test.rake
|
@@ -62,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
64
|
- !ruby/object:Gem::Version
|
63
65
|
version: '0'
|
64
66
|
requirements:
|
65
|
-
-
|
67
|
+
- A bit of awesomeness
|
66
68
|
rubyforge_project:
|
67
69
|
rubygems_version: 2.2.5
|
68
70
|
signing_key:
|