Class: Blur::Client

Inherits:
Object
  • Object
show all
Includes:
Callbacks, Handling
Defined in:
library/blur/client.rb,
library/blur/handling.rb

Overview

The Client class is the controller of the low-level access.

It stores networks, scripts and callbacks, and is also encharge of distributing the incoming commands to the right networks and scripts.

Defined Under Namespace

Modules: Handling

Constant Summary collapse

ENVIRONMENT =

The default environment.

ENV['BLUR_ENV'] || 'development'
DEFAULT_CONFIG =

The default configuration.

{
  'blur' => {
    'cache_dir' => 'cache/',
    'scripts_dir' => 'scripts/',
    'networks' => []
  },
  'scripts' => {}
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Handling

#got_001, #got_005, #got_900, #got_904, #got_authenticate, #got_cap, #got_channel_topic, #got_end_of_motd, #got_join, #got_kick, #got_mode, #got_name_reply, #got_nick, #got_nickname_in_use, #got_part, #got_ping, #got_pong, #got_privmsg, #got_quit, #got_topic

Methods included from Callbacks

#callbacks, #emit, #notify_scripts, #on

Constructor Details

#initialize(options = {}) ⇒ Client

Instantiates the client, stores the options, instantiates the networks and then loads available scripts.

Parameters:

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

    the options for the client.

Options Hash (options):

  • :config_path (String)

    path to a configuration file.

  • :environment (String)

    the client environment.

Raises:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'library/blur/client.rb', line 44

def initialize options = {}
  @scripts = {}
  @networks = []
  @config_path = options[:config_path]
  @environment = options[:environment] || ENVIRONMENT
  @verbose = options[:verbose] == true

  raise ConfigError, 'missing config file path in :config_path option' unless @config_path

  load_config!

  networks = @config['blur']['networks']

  if networks&.any?
    networks.each do |network_options|
      @networks.<< Network.new network_options, self
    end
  end

  trap 2, &method(:quit)
end

Instance Attribute Details

#configHash

Returns client configuration.

Returns:

  • (Hash)

    client configuration.



30
31
32
# File 'library/blur/client.rb', line 30

def config
  @config
end

#config_pathString

Returns the path to the currently used config file.

Returns:

  • (String)

    the path to the currently used config file.



36
37
38
# File 'library/blur/client.rb', line 36

def config_path
  @config_path
end

#networksArray

Returns a list of instantiated networks.

Returns:

  • (Array)

    a list of instantiated networks.



28
29
30
# File 'library/blur/client.rb', line 28

def networks
  @networks
end

#scriptsHash

Returns initialized scripts.

Returns:

  • (Hash)

    initialized scripts.



32
33
34
# File 'library/blur/client.rb', line 32

def scripts
  @scripts
end

#verboseBoolean

Returns whether verbose logging is enabled.

Returns:

  • (Boolean)

    whether verbose logging is enabled.



34
35
36
# File 'library/blur/client.rb', line 34

def verbose
  @verbose
end

Instance Method Details

#connectObject

Connect to each network available that is not already connected, then proceed to start the run-loop.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'library/blur/client.rb', line 68

def connect
  networks = @networks.reject &:connected?

  load_scripts!
  networks.each &:connect

  EventMachine.error_handler do |exception|
    message_pattern = /^.*?:(\d+):/
    backtrace = exception.backtrace.first
    error_line = backtrace.match(message_pattern)[1].to_i + 1

    puts "#{exception.message} on line #{error_line.to_s}"
    puts exception.backtrace.join "\n"
  end
end

#got_message(network, message) ⇒ Object

Is called when a command have been received and parsed, this distributes the command to the loader, which then further distributes it to events and scripts.

Parameters:

  • network (Network)

    the network that received the command.

  • command (Network::Command)

    the received command.



90
91
92
93
94
95
96
# File 'library/blur/client.rb', line 90

def got_message network, message
  puts "#{message.command.to_s.ljust(8, ' ')} #{message.parameters.map(&:inspect).join ' '}" if @verbose

  name = :"got_#{message.command.downcase}"

  __send__ name, network, message if respond_to? name
end

#initialize_superscriptsObject

Instantiates each SuperScript in the Blur.scripts list by manually allocating an instance and calling #initialize on it, then the instance is stored in Client#scripts.

Raises:

  • (Exception)

    any exception that might occur in any scripts’ #initialize method.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'library/blur/client.rb', line 170

def initialize_superscripts
  scripts_config = @config['scripts']
  scripts_cache_dir = File.expand_path @config['blur']['cache_dir']

  Blur.scripts.each do |name, superscript|
    script = superscript.allocate
    script.cache = ScriptCache.load name, scripts_cache_dir
    script.config = scripts_config.fetch name, {}
    script._client_ref = self
    script.send :initialize

    @scripts[name] = script
  end
end

#load_script_file(file_path) ⇒ Object

Loads the given file_path as a Ruby script, wrapping it in an anonymous module to protect our global namespace.

Parameters:

  • file_path (String)

    the path to the ruby script.

Raises:

  • (Exception)

    if there was any problems loading the file



155
156
157
158
159
160
161
162
# File 'library/blur/client.rb', line 155

def load_script_file file_path
  load file_path, true
rescue Exception => e
  warn "The script `#{file_path}' failed to load"
  warn "#{e.class}: #{e.message}"
  warn ''
  warn 'Backtrace:', '---', e.backtrace
end

#load_scripts!Object

Loads all scripts in the script directory.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'library/blur/client.rb', line 128

def load_scripts!
  scripts_dir = File.expand_path @config['blur']['scripts_dir']
  script_file_paths = Dir.glob File.join scripts_dir, '*.rb'

  # Sort the script file paths by file name so they load by alphabetical
  # order.
  #
  # This will make it possible to create a script called '10_database.rb'
  # which will be loaded before '20_settings.rb' and non-numeric prefixes
  # will be loaded after that.
  script_file_paths = script_file_paths.sort do |a, b|
    File.basename(a) <=> File.basename(b)
  end

  script_file_paths.each { |script_path| load_script_file script_path }

  initialize_superscripts

  emit :scripts_loaded
end

#network_connection_closed(network) ⇒ Object

Called when a network connection is either closed, or terminated.



99
100
101
# File 'library/blur/client.rb', line 99

def network_connection_closed network
  emit :connection_close, network
end

#quit(_signal = :SIGINT) ⇒ Object

Try to gracefully disconnect from each network, unload all scripts and exit properly.

Parameters:

  • signal (optional, Symbol)

    The signal received by the system, if any.



107
108
109
110
111
112
113
114
# File 'library/blur/client.rb', line 107

def quit _signal = :SIGINT
  @networks.each do |network|
    network.transmit :QUIT, 'Got SIGINT?'
    network.disconnect
  end

  EventMachine.stop
end

#reload!Object

Reloads configuration file and scripts.



117
118
119
120
121
122
123
124
125
# File 'library/blur/client.rb', line 117

def reload!
  EM.schedule do
    unload_scripts!
    load_config!
    load_scripts!

    yield if block_given?
  end
end

#unload_scripts!Object

Unloads initialized scripts and superscripts.

This method will call #unloaded on the instance of each loaded script to give it a chance to clean up any resources.



189
190
191
192
193
194
195
# File 'library/blur/client.rb', line 189

def unload_scripts!
  @scripts.each do |_name, script|
    script.__send__ :unloaded if script.respond_to? :unloaded
  end.clear

  Blur.reset_scripts!
end