Module: MovingImages::Smig

Defined in:
lib/moving_images/smig.rb

Overview

The Smig module is used for sending commands using "smig" to MovingImages.
The perform_commands method will raise an exception and set the module properties @@exitvalue, and @@exitstring if smig returns an error. The no throw version of the perform_command method ignores the return value and are useful within the rescue and ensure sections of a begin - end block.
To create a smig command see CommandModule and its classes. To create a list of smig commands and configure how they are run see CommandModule::SmigCommands

Constant Summary

Smig =

The command line tool used to communicate with MovingImages.

"smig"
@@exitvalue =

The return value. Non zero values indicate an error occurred.

0
@@exitstring =

If @@exitvalue is non zero @@exitstring will hold a short error message

""

Class Method Summary (collapse)

Class Method Details

+ (void) close_object(object_id)

This method returns an undefined value.

Close the object with object id.

Parameters:

  • object_id (Hash)

    The object identifier.



269
270
271
272
# File 'lib/moving_images/smig.rb', line 269

def self.close_object(object_id)
  close_command = CommandModule.make_close(object_id)
  self.perform_command(close_command)
end

+ (void) close_object_nothrow(object_id)

This method returns an undefined value.

Close without raising an exception the object with object id.

Parameters:

  • object_id (Hash)

    The object identifier.



278
279
280
281
# File 'lib/moving_images/smig.rb', line 278

def self.close_object_nothrow(object_id)
  close_command = CommandModule.make_close(object_id)
  self.perform_command_nothrow(close_command)
end

+ (String) closeall_nothrow(objectType: nil)

Close all MovingImages objects.
This is a bit dangerous, if moving images is responding to more than one scripts concurrently then this command will close all the objects, not just the ones related to the script running this command. If objectType is not nil, then only objects of type objectType will be closed.

Parameters:

  • objectType (String, Symbol)

    Optional object type.

Returns:

  • (String)

    The result of running command. Empty string is no error.



291
292
293
294
295
# File 'lib/moving_images/smig.rb', line 291

def self.closeall_nothrow(objectType: nil)
  commandHash = { :command => "closeall" }
  commandHash[:objecttype] = objectType unless objectType.nil?
  return self.perform_commands_nothrow( { :commands => [ commandHash ] } )
end

+ (String) exitstring

Get the string returned from the smig command if an error occurred

Returns:

  • (String)

    The error message.



48
49
50
# File 'lib/moving_images/smig.rb', line 48

def self.exitstring
  return @@exitstring
end

+ (Fixnum) exitvalue

Get exit value from the last perform_commands method run.

Returns:

  • (Fixnum)

    The error code. A value of 0 indicates no error.



42
43
44
# File 'lib/moving_images/smig.rb', line 42

def self.exitvalue
  return @@exitvalue
end

+ (String) get_classtypeproperty(objecttype: "bitmapcontext", property: "numberofobjects")

Get a class type property

Parameters:

  • objecttype (String, Symbol)

    The class type to get the property from

  • property (String)

    The property to be requested of the class.

Returns:

  • (String)

    The property value



242
243
244
245
246
247
248
# File 'lib/moving_images/smig.rb', line 242

def self.get_classtypeproperty(objecttype: "bitmapcontext",
                                property: "numberofobjects")
  commandHash = { :command => "getproperty",
                   :objecttype => objecttype.to_s,
                   :propertykey => property }
  return self.perform_commands( { :commands => [ commandHash ] } )
end

+ (Fixnum) get_numberofobjects(objecttype: nil)

Get the number of MovingImages base objects.
If objecttype is nil, then get the count of all the base objects, otherwise objecttype is the base object class type which we want to the how many objects of that type there are.

Parameters:

  • objecttype (String, Symbol, nil)

Returns:

  • (Fixnum)

    The number of base objects



231
232
233
234
235
236
# File 'lib/moving_images/smig.rb', line 231

def self.get_numberofobjects(objecttype: nil)
  commandHash = { :command => "getproperty",
                  :propertykey => "numberofobjects" }
  commandHash[:objecttype] = objecttype unless objecttype.nil?
  return self.perform_command(commandHash).to_i
end

+ (String) get_objectproperty(object, property: :numberofimages, imageindex: nil)

Get a property of an object.
The optional imageindex parameter provides an option to get the property of an image at a particular image index, in for example an image importer object.

Parameters:

  • object (Hash)

    An object identifier.

  • property (String, Symbol)

    The property to be requested.

  • imageindex (Fixnum)

    The image index.

Returns:

  • (String)

    The property value



258
259
260
261
262
263
264
# File 'lib/moving_images/smig.rb', line 258

def self.get_objectproperty(object, property: :numberofimages,
                            imageindex: nil)
  commandHash = { :command => "getproperty", :receiverobject => object,
                      :propertykey => property }
  commandHash[:imageindex] = imageindex unless imageindex.nil?
  return self.perform_commands( { :commands => [ commandHash ] } )
end

+ (String) perform_command(theCommand)

Perform a single MovingImages command.

Parameters:

  • theCommand (Hash, #commandhash)

    The command to be performed

Returns:

  • (String)

    The output from running the command



191
192
193
194
195
196
197
198
# File 'lib/moving_images/smig.rb', line 191

def self.perform_command(theCommand)
  if theCommand.respond_to? "commandhash"
    theCommand = theCommand.commandhash
  end
  fail "theCommand is not a hash" unless theCommand.is_a?(Hash)
  commandWrapper = { :commands => [ theCommand ] }
  self.perform_commands(commandWrapper)
end

+ (String) perform_command_nothrow(theCommand)

Perform a single MovingImages command and don't throw if an error occurs.

Parameters:

  • theCommand (Hash, #commandhash)

    The command to be performed

Returns:

  • (String)

    The output from running the command



203
204
205
206
207
208
209
210
211
# File 'lib/moving_images/smig.rb', line 203

def self.perform_command_nothrow(theCommand)
  if theCommand.respond_to? "commandhash"
    theCommand = theCommand.commandhash
  end
  commandWrapper = { :commands => [ theCommand ] }
  result, _ = Open3.capture2(Smig, "performcommand",
                                  "-jsonstring", commandWrapper.to_json)
  return result
end

+ (String) perform_commands(commands, debug: false)

Perform MovingImages commands.
If an error occurs then an exception is raised

Parameters:

  • commands (Hash)

    A ruby hash containing the list of commands to run

  • debug (bool)

    Run the commands through self.perform_debugcommands.

Returns:

  • (String)

    The result from running the commands



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/moving_images/smig.rb', line 148

def self.perform_commands(commands, debug: false)
  commands = commands.commandshash if commands.respond_to? "commandshash"
  fail "commands not a commandshash" unless commands.is_a?(Hash)

  return self.perform_debugcommands(commands) if debug
  jsonstring = commands.to_json
  # Command strings longer than 240000 are too long to be passed.
  # If the command string is longer than that save the command string
  # as a file and then pass the command file to be processed to smig.
  if jsonstring.length > 200000
    tempDir = Dir.tmpdir()
    fileName = SecureRandom.uuid + ".json"
    fullPath = File.join(tempDir, fileName)
    begin
      open(fullPath, 'w') { |f| f.puts jsonstring }
      result, exitVal = Open3.capture2(Smig, "performcommand",
                                    "-jsonfile", fullPath)
    ensure
      FileUtils.rm_f(fullPath)
    end
  else
    # puts "JSON string length: " + jsonstring.length.to_s
    result, exitVal = Open3.capture2(Smig, "performcommand",
                                    "-jsonstring", jsonstring)
  end
  self.raiseexception_unlesstatuszero(method: "Smig.perform_commands",
                                      status: exitVal, result: result)
  return result
end

+ (String) perform_commands_nothrow(commands)

Perform MovingImages commands without raising an exception.

Parameters:

  • commands (Hash, #commandshash)

    The commands to run

Returns:

  • (String)

    The result from running the commands



216
217
218
219
220
221
222
223
# File 'lib/moving_images/smig.rb', line 216

def self.perform_commands_nothrow(commands)
  if commands.respond_to? "commandshash"
    commands = commands.commandshash
  end
  result, _ = Open3.capture2(Smig, "performcommand",
                                  "-jsonstring", commands.to_json)
  return result
end

+ (String) perform_debugcommands(commands)

Perform MovingImages commands one at a time.
This method unwraps the commands and performs each command individually. Also performs the cleanup commands after the command list.

Parameters:

  • commands (Hash)

    A ruby hash contain the list of commands to run.

Returns:

  • (String)

    The result from running the commands.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/moving_images/smig.rb', line 57

def self.perform_debugcommands(commands)
  # puts "Debug commands"
  commands = commands.commandshash if commands.respond_to? "commandshash"
  begin
    theCommands = commands[:commands]
    theCommands.each do |command|
      newCommandList = CommandModule::SmigCommands.new
      newCommandList.commands = [ command ]
      # newCommandList.set_saveresultstype("lastcommandresult")
      newCommandList.informationreturned = :lastcommandresult
      jsonString = newCommandList.commandshash.to_json
      # Command strings longer than 240000 are too long to be passed.
      # If the command string is longer than that save the command string
      # as a file and then pass the command file to be processed to smig.
      if jsonString.length > 200000
        tempDir = Dir.tmpdir()
        fileName = SecureRandom.uuid + ".json"
        fullPath = File.join(tempDir, fileName)
        begin
          open(fullPath, 'w') { |f| f.puts jsonString }
          result, exitVal = Open3.capture2(Smig, "performcommand",
                                        "-jsonfile", fullPath)
        ensure
          FileUtils.rm_f(fullPath)
        end
      else
        result, exitVal = Open3.capture2(Smig, "performcommand",
                                        "-jsonstring", jsonString)
      end
      self.raiseexception_unlesstatuszero(
                      method: "Smig.perform_debugcommands",
                      status: exitVal, result: result)
    end
    ""
  rescue RuntimeError => e
    puts e.message
    puts "With error code #{@@exitvalue} and output : #{@@exitstring} "
  ensure
    # now perform the cleanup commands.
    cleanupCommands = commands[:cleanupcommands]
    unless cleanupCommands.nil? || cleanupCommands.length.zero?
      self.perform_debugcommands({ :commands => cleanupCommands })
    end
  end
end

+ (String) perform_jsoncommands(jsonstring: nil, jsonfile: nil)

Perform MovingImages commands already converted to json either a string or a file. If an error occurs then then an exception is raised. One of jsonstring or jsonfile needs to be defined.

Parameters:

  • jsonstring (String, nil)

    A json representation of the commands.

  • jsonfile (String, nil)

    A path to a file with a json representation of the commands.

Returns:

  • (String)

    The result from running the commands



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/moving_images/smig.rb', line 110

def self.perform_jsoncommands(jsonstring: nil, jsonfile: nil)
  result = ""
  exit_val = nil
  unless jsonstring.nil?
    # Command strings longer than 240000 are too long to be passed.
    # If the command string is longer than that save the command string
    # as a file and then pass the command file to be processed to smig.
    if jsonstring.length > 200000
      temp_dir = Dir.tmpdir()
      file_name = SecureRadom.uuid + ".json"
      full_path = File.join(temp_dir, file_name)
      begin
        open(full_path, 'w') { |f| f.puts jsonstring }
        result, exit_val = Open3.capture2(Smig, 'performcommand',
                                          '-jsonfile', full_path)
      ensure
        FileUtils.rm_f(full_path)
      end
    else
      result, exit_val = Open3.capture2(Smig, 'performcommand',
                                    '-jsonstring', jsonstring)
    end
  end
  
  unless jsonfile.nil?
    result, exit_val = Open3.capture2(Smig, 'performcommand',
                                      '-jsonfile', jsonfile)
  end
  self.raiseexception_unlesstatuszero(method: "Smig.perform_jsoncommands",
                                      status: exit_val, result: result)
  return result
end

+ (Float) perform_timed_commands(commands, debug: false)

Perform MovingImages commands and return how long they took to run.

Parameters:

  • commands (Hash, #commandshash)

    The commands to be run

  • debug (bool)

    Should the commands be run one after the other.

Returns:

  • (Float)

    The time in seconds the commands took to run.



182
183
184
185
186
# File 'lib/moving_images/smig.rb', line 182

def self.perform_timed_commands(commands, debug: false)
  oldTime = Time.now
  self.perform_commands(commands, debug: debug)
  Time.now - oldTime
end