Class: GodObject::Smuxi::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/god_object/smuxi/plugin.rb

Overview

Note:

This class is supposed to be an abstract base class and is not meant to produce instances directly.

Base class that implements basic features of a Smuxi plugin.

Constant Summary collapse

BASE_DIRECTORY_NAME =

Returns name of the base configuration directory

Returns:

  • (String)

    name of the base configuration directory

'smuxi'
HOOKS_DIRECTORY_NAME =

Returns name of the sub-directory containing the hook handlers

Returns:

  • (String)

    name of the sub-directory containing the hook handlers

'hooks'
STATE_DIRECTORY_NAME =

Returns name of the sub-directory containing plugin state

Returns:

  • (String)

    name of the sub-directory containing plugin state

'hook-state'
STATE_FILE_NAME =

Returns name of the file in which the permanent state is held

Returns:

  • (String)

    name of the file in which the permanent state is held

'state.yml'
HOOK_TABLE =

Returns maps Smuxi hook names to named of the method supposed to handle that hook

Returns:

  • ({String => Symbol})

    maps Smuxi hook names to named of the method supposed to handle that hook

{
  'engine/protocol-manager/on-connected'        => :connected,
  'engine/protocol-manager/on-disconnected'     => :disconnected,
  'engine/protocol-manager/on-message-received' => :message_received,
  'engine/protocol-manager/on-message-sent'     => :message_sent,
  'engine/protocol-manager/on-presence-status-changed' => :presence_status_changed,
  'engine/session/on-group-chat-person-added'   => :chat_person_added,
  'engine/session/on-group-chat-person-removed' => :chat_person_removed,
  'engine/session/on-group-chat-person-updated' => :chat_person_updated,
  'engine/session/on-event-message'             => :event_message 
}
VARIABLE_TABLE =

Returns maps Smuxi environment variable names to instance variables which will inhert the value supplied by Smuxi

Returns:

  • ({String => Symbol})

    maps Smuxi environment variable names to instance variables which will inhert the value supplied by Smuxi

{
  'SMUXI_CHAT_ID'   => :@chat_id,
  'SMUXI_CHAT_NAME' => :@chat_name,
  'SMUXI_CHAT_TYPE' => :@chat_type,
  'SMUXI_MSG'                     => :@message,
  'SMUXI_MSG_TYPE'                => :@message_type,
  'SMUXI_MSG_TIMESTAMP_UNIX'      => :@message_timestamp_unix,
  'SMUXI_MSG_TIMESTAMP_ISO_UTC'   => :@message_timestamp_iso_utc,
  'SMUXI_MSG_TIMESTAMP_ISO_LOCAL' => :@message_timestamp_iso_local,
  'SMUXI_SENDER'   => :@sender,
  'SMUXI_RECEIVER' => :@receiver,
  'SMUXI_PROTOCOL_MANAGER_TYPE'            => :@protocol_manager_type,
  'SMUXI_PROTOCOL_MANAGER_PROTOCOL'        => :@protocol_manager_protocol,
  'SMUXI_PROTOCOL_MANAGER_NETWORK'         => :@protocol_manager_network,
  'SMUXI_PROTOCOL_MANAGER_HOST'            => :@protocol_manager_host,
  'SMUXI_PROTOCOL_MANAGER_PORT'            => :@protocol_manager_port,
  'SMUXI_PROTOCOL_MANAGER_ME_ID'           => :@protocol_manager_me_id,
  'SMUXI_PROTOCOL_MANAGER_PRESENCE_STATUS' => :@protocol_manager_presence_status,
  'SMUXI_PRESENCE_STATUS_CHANGED_OLD_STATUS'  => :@presence_status_old,
  'SMUXI_PRESENCE_STATUS_CHANGED_NEW_STATUS'  => :@presence_status_new,
  'SMUXI_PRESENCE_STATUS_CHANGED_NEW_MESSAGE' => :@presence_status_new_message,
  'SMUXI_CMD'              => :@command,
  'SMUXI_CMD_PARAMETER'    => :@command_parameter,
  'SMUXI_CMD_CHARACTER'    => :@command_character,
  'SMUXI_FRONTEND_VERSION' => :@frontend_version,
  'SMUXI_ENGINE_VERSION'   => :@engine_version 
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Plugin

Initializes the plugin.

Known variables' values from the supplied environment will be transferred to the respective instance variables.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • environment ({String => String})

    environment variables for the plugin execution

  • base_directory (Pathname)

    the configuration directory for Smuxi. The hooks and hook-state sub-directories are expected to reside here

  • state_directory (Pathname)

    the directory that Smuxi reserved for this plugin to store its state.

  • hook_name (String)

    name of the Smuxi hook that is executed

  • script_name (String)

    name of plugin hook executable, without path

See Also:



304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/god_object/smuxi/plugin.rb', line 304

def initialize(options = {})
  @environment     = options[:environment]
  @base_directory  = options[:base_directory]
  @state_directory = options[:state_directory]
  @state           = options[:state]
  @hook_name       = options[:hook_name]
  @script_name     = options[:script_name]

  VARIABLE_TABLE.each do |environment_variable, instance_variable|
    instance_variable_set(instance_variable,
                          @environment[environment_variable])
  end
end

Instance Attribute Details

#stateObject (readonly)

Returns the value of attribute state



286
287
288
# File 'lib/god_object/smuxi/plugin.rb', line 286

def state
  @state
end

Class Method Details

.base_directory_guessPathname

Returns path to the base directory

Returns:

  • (Pathname)

    path to the base directory



214
215
216
# File 'lib/god_object/smuxi/plugin.rb', line 214

def base_directory_guess
  Pathname.new('~/.local/share').expand_path + BASE_DIRECTORY_NAME
end

.cli_install(executable_path) ⇒ void

Note:

This method outputs to STDOUT and exits the program after it finishes.

This method returns an undefined value.

Installs the plugin by placing symlinks to the plugin executable into Smuxi's hook handler paths.

Parameters:

  • executable_path (String)

    path of the plugin executable file



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/god_object/smuxi/plugin.rb', line 177

def cli_install(executable_path)
  puts "Creating symlinks at the Smuxi plugin hook locations…"
  puts

  install(executable_path) do |hook_executable_file|
    puts "Creating `#{hook_executable_file}`"
  end

  puts
  puts "Plugin `#{name}` installed."

  exit
end

.cli_uninstall(executable_path) ⇒ void

Note:

This method outputs to STDOUT and exits the program after it finishes.

This method returns an undefined value.

Uninstalls the plugin by removing symlinks to the plugin executable from Smuxi's hook handler paths.

Parameters:

  • executable_path (String)

    path of the plugin executable file



199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/god_object/smuxi/plugin.rb', line 199

def cli_uninstall(executable_path)
  puts "Trying to remove hook symlinks…"
  puts
  
  uninstall(executable_path) do |hook_executable_file|
    puts "Removing `#{hook_executable_file}`"
  end

  puts
  puts "Plugin `#{name}` uninstalled."

  exit
end

.execute(executable_path, environment = ENV, arguments = ARGV) ⇒ void

This method returns an undefined value.

Decides whether to execute a plugin hook handler or plugin maintenance features.

In case the first command line argument is install or uninstall, the plugin installation or uninstallation maintenance methods are executed.

Otherwise, the plugin expects to be called as a hook handler by Smuxi.

Parameters:

  • executable_path (String)

    path of the plugin executable file

  • environment ({String => String}) (defaults to: ENV)

    the environment variables available to the plugin, defaults to the actual system environment

  • arguments (Array<String>) (defaults to: ARGV)

    list of command line arguments given to the plugin, defaults to the actual command line arguments



107
108
109
110
111
112
113
114
115
116
# File 'lib/god_object/smuxi/plugin.rb', line 107

def execute(executable_path, environment = ENV, arguments = ARGV)
  case arguments.first
  when 'install'
    cli_install(executable_path)
  when 'uninstall'
    cli_uninstall(executable_path)
  else
    execute_hook(executable_path, environment)
  end
end

.execute_hook(executable_path, environment = ENV) ⇒ void

This method returns an undefined value.

The name of the hook executed is detected through the name of the executable called. A plugin instance will be created and the hook name is then used to decide which instance method is called on that.

Parameters:

  • executable_path (String)

    path of the plugin executable file

  • environment ({String => String}) (defaults to: ENV)

    the environment variables available to the plugin, defaults to the actual system environment



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/god_object/smuxi/plugin.rb', line 126

def execute_hook(executable_path, environment = ENV)
  split_pattern = /\/#{BASE_DIRECTORY_NAME}\/#{HOOKS_DIRECTORY_NAME}\//
  config_directory, relative_executable = executable_path.
                                          split(split_pattern)

  base_directory      = Pathname.new(config_directory) +
                        BASE_DIRECTORY_NAME
  relative_executable = Pathname.new(relative_executable)
  script_name         = relative_executable.basename.to_s
  hook_name           = relative_executable.dirname.to_s
  state_directory     = base_directory +
                        STATE_DIRECTORY_NAME +
                        hook_name +
                        script_name

  state_file = state_directory + STATE_FILE_NAME

  if state_file.exist?
    state = YAML.load(state_file.read)
  else
    state = {}
  end

  instance = new(
    environment:     environment,
    base_directory:  base_directory,
    script_name:     script_name,
    hook_name:       hook_name,
    state_directory: state_directory,
    state:           state
  )

  if method_name = HOOK_TABLE[hook_name]
    instance.public_send(method_name)

    state_file.open('w') do |io|
      io.write(YAML.dump(instance.state))
    end
  else
    raise "Hook `#{hook_name}` unsupported"
  end
end

.install(executable_path, base_directory = base_directory_guess, &block) ⇒ void

This method returns an undefined value.

Installs the plugin by placing symlinks to the plugin executable into Smuxi's hook handler paths.

Parameters:

  • executable_path (String)

    path of the plugin executable file

  • base_directory (Pathname) (defaults to: base_directory_guess)

    the configuration directory for Smuxi. The hooks sub-directory is expected to reside here



253
254
255
256
257
258
259
260
261
262
263
# File 'lib/god_object/smuxi/plugin.rb', line 253

def install(executable_path, base_directory = base_directory_guess, &block)
  executable_file = Pathname.new(executable_path).expand_path
  executable_name = executable_file.basename.to_s

  used_hook_paths(base_directory).each do |hook_path|
    hook_executable_file = hook_path + executable_name 
    block.call(hook_executable_file) if block
    hook_executable_file.unlink if hook_executable_file.symlink?
    hook_executable_file.make_symlink(executable_file)
  end
end

.uninstall(executable_path, base_directory = base_directory_guess) {|hook_executable| ... } ⇒ void

This method returns an undefined value.

Uninstalls the plugin by removing symlinks to the plugin executable from Smuxi's hook handler paths.

Parameters:

  • executable_path (String)

    path of the plugin executable file

  • base_directory (Pathname) (defaults to: base_directory_guess)

    the configuration directory for Smuxi. The hooks sub-directory is expected to reside here

Yields:

  • (hook_executable)

    hook_executable



273
274
275
276
277
278
279
280
281
282
# File 'lib/god_object/smuxi/plugin.rb', line 273

def uninstall(executable_path, base_directory = base_directory_guess, &block)
  executable_file = Pathname.new(executable_path).expand_path
  executable_name = executable_file.basename.to_s

  used_hook_paths(base_directory).each do |hook_path|
    hook_executable_file = hook_path + executable_name
    block.call(hook_executable_file) if block
    hook_executable_file.unlink if hook_executable_file.symlink?
  end
end

.used_hook_methodsArray<Symbol>

Returns a list of the names of all hook handler instance methods implemented by this class

Returns:

  • (Array<Symbol>)

    a list of the names of all hook handler instance methods implemented by this class



220
221
222
# File 'lib/god_object/smuxi/plugin.rb', line 220

def used_hook_methods
  instance_methods.to_set.intersection(HOOK_TABLE.values.to_set)
end

.used_hook_namesArray<String>

Returns a list of the names of all hooks supported by this class

Returns:

  • (Array<String>)

    a list of the names of all hooks supported by this class



226
227
228
229
230
231
232
# File 'lib/god_object/smuxi/plugin.rb', line 226

def used_hook_names
  inverted_hook_table = HOOK_TABLE.invert

  used_hook_methods.map do |method_name|
    inverted_hook_table[method_name]
  end
end

.used_hook_paths(base_directory = base_directory_guess) ⇒ Array<String>

Returns a list of the Smuxi hook paths this plugin needs to be linked in

Parameters:

  • base_directory (Pathname) (defaults to: base_directory_guess)

    the Smuxi configuration directory. The hooks directory is expected to reside here

Returns:

  • (Array<String>)

    a list of the Smuxi hook paths this plugin needs to be linked in



238
239
240
241
242
243
244
# File 'lib/god_object/smuxi/plugin.rb', line 238

def used_hook_paths(base_directory = base_directory_guess)
  hooks_directory = base_directory + HOOKS_DIRECTORY_NAME
  
  used_hook_names.map do |hook_name|
    hooks_directory + hook_name
  end
end

Instance Method Details

#command(type, name, data = nil) ⇒ void

This method returns an undefined value.

Calls a command in Smuxi

Parameters:

  • type (String)

    the command type

  • name (Symbol, String)

    the command name

  • data (String) (defaults to: nil)

    the argument data added to the command



324
325
326
327
328
329
# File 'lib/god_object/smuxi/plugin.rb', line 324

def command(type, name, data = nil)
  command = "#{type} /#{name}"
  command += " #{data}" if data
  
  STDOUT.puts(command)
end

#protocol_manager_command(name, data = nil) ⇒ void

This method returns an undefined value.

Calls a protocol manager command in Smuxi

Parameters:

  • name (Symbol, String)

    the command name

  • data (String) (defaults to: nil)

    the argument data added to the command



345
346
347
# File 'lib/god_object/smuxi/plugin.rb', line 345

def protocol_manager_command(name, data = nil)
  command('ProtocolManager.Command', name, data)
end

#puts(message) ⇒ Object

Outputs a message to the Smuxi user

Parameters:

  • message (String)

    the text message sent to the Smuxi user



352
353
354
# File 'lib/god_object/smuxi/plugin.rb', line 352

def puts(message)
  session_command(:echo, message)
end

#session_command(name, data = nil) ⇒ void

This method returns an undefined value.

Calls a session command in Smuxi

Parameters:

  • name (Symbol, String)

    the command name

  • data (String) (defaults to: nil)

    the argument data added to the command



336
337
338
# File 'lib/god_object/smuxi/plugin.rb', line 336

def session_command(name, data = nil)
  command('Session.Command', name, data)
end