Update the instance of "module" with "plugin" and "mod" with "plug" where appropriate
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -9,15 +9,15 @@ defmodule Omnibot.Config do
|
||||
real: "omnibot",
|
||||
port: 6667,
|
||||
ssl: false,
|
||||
modules: [],
|
||||
module_paths: []
|
||||
plugins: [],
|
||||
plugin_paths: []
|
||||
]
|
||||
|
||||
@doc ~S"""
|
||||
Gets all channels that the bot should join via its modules.
|
||||
Gets all channels that the bot should join via its plugins.
|
||||
"""
|
||||
def all_channels(cfg) do
|
||||
Enum.flat_map(cfg.modules, fn
|
||||
Enum.flat_map(cfg.plugins, fn
|
||||
{_, [channels: :all]} -> []
|
||||
{_, [channels: channels]} -> channels
|
||||
end)
|
||||
|
||||
@@ -28,12 +28,12 @@ defmodule Omnibot.Irc do
|
||||
def part(irc, channel), do: send_msg(irc, "PART", channel)
|
||||
|
||||
defp route_msg(irc, msg) do
|
||||
modules = Msg.channel(msg) |> State.channel_modules()
|
||||
plugins = Msg.channel(msg) |> State.channel_plugins()
|
||||
|
||||
Task.Supervisor.async_stream_nolink(
|
||||
Omnibot.RouterSupervisor,
|
||||
modules,
|
||||
fn {module, _mod_cfg} -> module.on_msg(irc, msg) end,
|
||||
plugins,
|
||||
fn {plugin, _plug_cfg} -> plugin.on_msg(irc, msg) end,
|
||||
timeout: 30_000,
|
||||
on_timeout: :kill_task
|
||||
) |> Stream.run()
|
||||
|
||||
@@ -11,42 +11,42 @@ defmodule Omnibot.PluginSupervisor do
|
||||
|
||||
@impl true
|
||||
def init(cfg) do
|
||||
compile_files(cfg.module_paths || [])
|
||||
compile_files(cfg.plugin_paths || [])
|
||||
|
||||
# These are modules that need to be loaded for core functionality of the bot
|
||||
# These are plugins that need to be loaded for core functionality of the bot
|
||||
core = [
|
||||
Omnibot.Core
|
||||
]
|
||||
|
||||
# Map the modules in the configuration to the children
|
||||
# Map the plugins in the configuration to the children
|
||||
children =
|
||||
for mod <- (core ++ cfg.modules) do
|
||||
case mod do
|
||||
for plug <- (core ++ cfg.plugins) do
|
||||
case plug do
|
||||
{name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name}
|
||||
name -> {name, cfg: name.default_config(), name: name}
|
||||
end
|
||||
end
|
||||
|
||||
# Add each child to the "loaded modules" list in the State
|
||||
Enum.each(children, fn {module, opts} -> State.add_loaded_module({module, opts[:cfg]}) end)
|
||||
# Add each child to the "loaded plugins" list in the State
|
||||
Enum.each(children, fn {plugin, opts} -> State.add_loaded_plugin({plugin, opts[:cfg]}) end)
|
||||
|
||||
Supervisor.init(children, strategy: :one_for_one)
|
||||
end
|
||||
|
||||
defp compile_files([]), do: nil
|
||||
|
||||
defp compile_files([{path, opts} | module_paths]) do
|
||||
defp compile_files([{path, opts} | plugin_paths]) do
|
||||
case {File.exists?(path), File.dir?(path)} do
|
||||
{_, true} -> compile_dir(path, opts[:recurse] || false)
|
||||
{true, false} -> Code.require_file(path)
|
||||
{_, _} -> Logger.error("module path '#{path}' does not exist, it will not be loaded")
|
||||
{_, _} -> Logger.error("plugin path '#{path}' does not exist, it will not be loaded")
|
||||
end
|
||||
|
||||
compile_files(module_paths)
|
||||
compile_files(plugin_paths)
|
||||
end
|
||||
|
||||
defp compile_files([path | module_paths]) do
|
||||
compile_files([{path, []} | module_paths])
|
||||
defp compile_files([path | plugin_paths]) do
|
||||
compile_files([{path, []} | plugin_paths])
|
||||
end
|
||||
|
||||
defp compile_dir(path, recurse) do
|
||||
|
||||
@@ -37,7 +37,7 @@ defmodule Omnibot.Plugin.Base do
|
||||
|
||||
@impl Plugin.Base
|
||||
def on_msg(irc, msg) do
|
||||
# TODO - instead of using a router for modules, consider using a PubSub with a Registry:
|
||||
# TODO - instead of using a router for plugins, consider using a PubSub with a Registry:
|
||||
# https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub
|
||||
route_msg(irc, msg)
|
||||
end
|
||||
|
||||
40
lib/state.ex
40
lib/state.ex
@@ -2,7 +2,7 @@ defmodule Omnibot.State do
|
||||
use GenServer
|
||||
|
||||
@enforce_keys [:cfg]
|
||||
defstruct [:cfg, channels: MapSet.new(), module_map: %{}]
|
||||
defstruct [:cfg, channels: MapSet.new(), plugin_map: %{}]
|
||||
|
||||
## Client API
|
||||
|
||||
@@ -21,25 +21,25 @@ defmodule Omnibot.State do
|
||||
GenServer.call(state, :cfg)
|
||||
end
|
||||
|
||||
@doc "Adds a loaded module to the default state."
|
||||
def add_loaded_module(module), do: add_loaded_module(__MODULE__, module)
|
||||
@doc "Adds a loaded plugin to the default state."
|
||||
def add_loaded_plugin(plugin), do: add_loaded_plugin(__MODULE__, plugin)
|
||||
|
||||
@doc "Adds a loaded module to the given state."
|
||||
def add_loaded_module(state, {module, cfg}), do: GenServer.cast(state, {:add_loaded_module, {module, cfg}})
|
||||
@doc "Adds a loaded plugin to the given state."
|
||||
def add_loaded_plugin(state, {plugin, cfg}), do: GenServer.cast(state, {:add_loaded_plugin, {plugin, cfg}})
|
||||
|
||||
@doc "Adds a loaded module to the given state."
|
||||
def add_loaded_module(state, module), do: add_loaded_module(state, {module, []})
|
||||
@doc "Adds a loaded plugin to the given state."
|
||||
def add_loaded_plugin(state, plugin), do: add_loaded_plugin(state, {plugin, []})
|
||||
|
||||
@doc "Gets all loaded modules from the default state."
|
||||
def loaded_modules(), do: loaded_modules(__MODULE__)
|
||||
@doc "Gets all loaded plugins from the default state."
|
||||
def loaded_plugins(), do: loaded_plugins(__MODULE__)
|
||||
|
||||
@doc "Gets all loaded modules from the given state."
|
||||
def loaded_modules(state), do: GenServer.call(state, :loaded_modules)
|
||||
@doc "Gets all loaded plugins from the given state."
|
||||
def loaded_plugins(state), do: GenServer.call(state, :loaded_plugins)
|
||||
|
||||
def all_channels(), do: all_channels(__MODULE__)
|
||||
|
||||
def all_channels(state) do
|
||||
loaded_modules(state) |> Enum.flat_map(
|
||||
loaded_plugins(state) |> Enum.flat_map(
|
||||
fn {_, cfg} ->
|
||||
case cfg[:channels] do
|
||||
:all -> []
|
||||
@@ -51,14 +51,14 @@ defmodule Omnibot.State do
|
||||
|> MapSet.to_list()
|
||||
end
|
||||
|
||||
def channel_modules(channel), do: channel_modules(__MODULE__, channel)
|
||||
def channel_plugins(channel), do: channel_plugins(__MODULE__, channel)
|
||||
|
||||
@doc ~S"""
|
||||
Gets a list of all `{module, mod_cfg}` from the given State that are both
|
||||
Gets a list of all `{plugin, plug_cfg}` from the given State that are both
|
||||
loaded, and listening to the given channel.
|
||||
"""
|
||||
def channel_modules(state, channel) do
|
||||
loaded_modules(state) |> Enum.filter(
|
||||
def channel_plugins(state, channel) do
|
||||
loaded_plugins(state) |> Enum.filter(
|
||||
fn {_, cfg} ->
|
||||
cfg[:channels] == :all or Enum.member?(cfg[:channels] || [], channel)
|
||||
end)
|
||||
@@ -77,13 +77,13 @@ defmodule Omnibot.State do
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call(:loaded_modules, _from, state) do
|
||||
{:reply, state.module_map, state}
|
||||
def handle_call(:loaded_plugins, _from, state) do
|
||||
{:reply, state.plugin_map, state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_cast({:add_loaded_module, {module, cfg}}, state) do
|
||||
state = %{state | module_map: Map.put(state.module_map, module, cfg)}
|
||||
def handle_cast({:add_loaded_plugin, {plugin, cfg}}, state) do
|
||||
state = %{state | plugin_map: Map.put(state.plugin_map, plugin, cfg)}
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,8 +8,8 @@ defmodule StateTest do
|
||||
{:ok, state: state}
|
||||
end
|
||||
|
||||
test "state channel_modules works correctly", %{state: state} do
|
||||
modules = [
|
||||
test "state channel_plugins works correctly", %{state: state} do
|
||||
plugins = [
|
||||
{FooBar, channels: ["#foo", "#bar"]},
|
||||
{Foo, channels: ["#foo"]},
|
||||
{Bar, channels: ["#bar"]},
|
||||
@@ -17,36 +17,36 @@ defmodule StateTest do
|
||||
{All, channels: :all},
|
||||
]
|
||||
|
||||
modules |> Enum.each(fn module -> State.add_loaded_module(state, module) end)
|
||||
plugins |> Enum.each(fn plugin -> State.add_loaded_plugin(state, plugin) end)
|
||||
|
||||
modules = State.channel_modules(state, "#foo")
|
||||
|> Enum.map(fn {module, _} -> module end)
|
||||
assert length(modules) == 3
|
||||
assert Enum.member?(modules, FooBar)
|
||||
assert Enum.member?(modules, Foo)
|
||||
assert Enum.member?(modules, All)
|
||||
plugins = State.channel_plugins(state, "#foo")
|
||||
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||
assert length(plugins) == 3
|
||||
assert Enum.member?(plugins, FooBar)
|
||||
assert Enum.member?(plugins, Foo)
|
||||
assert Enum.member?(plugins, All)
|
||||
|
||||
modules = State.channel_modules(state, "#bar")
|
||||
|> Enum.map(fn {module, _} -> module end)
|
||||
assert length(modules) == 3
|
||||
assert Enum.member?(modules, FooBar)
|
||||
assert Enum.member?(modules, Bar)
|
||||
assert Enum.member?(modules, All)
|
||||
plugins = State.channel_plugins(state, "#bar")
|
||||
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||
assert length(plugins) == 3
|
||||
assert Enum.member?(plugins, FooBar)
|
||||
assert Enum.member?(plugins, Bar)
|
||||
assert Enum.member?(plugins, All)
|
||||
|
||||
modules = State.channel_modules(state, "#baz")
|
||||
|> Enum.map(fn {module, _} -> module end)
|
||||
assert length(modules) == 2
|
||||
assert Enum.member?(modules, Baz)
|
||||
assert Enum.member?(modules, All)
|
||||
plugins = State.channel_plugins(state, "#baz")
|
||||
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||
assert length(plugins) == 2
|
||||
assert Enum.member?(plugins, Baz)
|
||||
assert Enum.member?(plugins, All)
|
||||
|
||||
modules = State.channel_modules(state, nil)
|
||||
|> Enum.map(fn {module, _} -> module end)
|
||||
assert length(modules) == 1
|
||||
assert Enum.member?(modules, All)
|
||||
plugins = State.channel_plugins(state, nil)
|
||||
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||
assert length(plugins) == 1
|
||||
assert Enum.member?(plugins, All)
|
||||
end
|
||||
|
||||
test "state all_channels works correctly", %{state: state} do
|
||||
modules = [
|
||||
plugins = [
|
||||
{FooBar, channels: ["#foo", "#bar"]},
|
||||
{Foo, channels: ["#foo"]},
|
||||
{Bar, channels: ["#bar"]},
|
||||
@@ -54,7 +54,7 @@ defmodule StateTest do
|
||||
{All, channels: :all},
|
||||
]
|
||||
|
||||
modules |> Enum.each(fn module -> State.add_loaded_module(state, module) end)
|
||||
plugins |> Enum.each(fn plugin -> State.add_loaded_plugin(state, plugin) end)
|
||||
channels = State.all_channels(state)
|
||||
|
||||
assert length(channels) == 3
|
||||
|
||||
Reference in New Issue
Block a user