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",
|
real: "omnibot",
|
||||||
port: 6667,
|
port: 6667,
|
||||||
ssl: false,
|
ssl: false,
|
||||||
modules: [],
|
plugins: [],
|
||||||
module_paths: []
|
plugin_paths: []
|
||||||
]
|
]
|
||||||
|
|
||||||
@doc ~S"""
|
@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
|
def all_channels(cfg) do
|
||||||
Enum.flat_map(cfg.modules, fn
|
Enum.flat_map(cfg.plugins, fn
|
||||||
{_, [channels: :all]} -> []
|
{_, [channels: :all]} -> []
|
||||||
{_, [channels: channels]} -> channels
|
{_, [channels: channels]} -> channels
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ defmodule Omnibot.Irc do
|
|||||||
def part(irc, channel), do: send_msg(irc, "PART", channel)
|
def part(irc, channel), do: send_msg(irc, "PART", channel)
|
||||||
|
|
||||||
defp route_msg(irc, msg) do
|
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(
|
Task.Supervisor.async_stream_nolink(
|
||||||
Omnibot.RouterSupervisor,
|
Omnibot.RouterSupervisor,
|
||||||
modules,
|
plugins,
|
||||||
fn {module, _mod_cfg} -> module.on_msg(irc, msg) end,
|
fn {plugin, _plug_cfg} -> plugin.on_msg(irc, msg) end,
|
||||||
timeout: 30_000,
|
timeout: 30_000,
|
||||||
on_timeout: :kill_task
|
on_timeout: :kill_task
|
||||||
) |> Stream.run()
|
) |> Stream.run()
|
||||||
|
|||||||
@@ -11,42 +11,42 @@ defmodule Omnibot.PluginSupervisor do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(cfg) do
|
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 = [
|
core = [
|
||||||
Omnibot.Core
|
Omnibot.Core
|
||||||
]
|
]
|
||||||
|
|
||||||
# Map the modules in the configuration to the children
|
# Map the plugins in the configuration to the children
|
||||||
children =
|
children =
|
||||||
for mod <- (core ++ cfg.modules) do
|
for plug <- (core ++ cfg.plugins) do
|
||||||
case mod do
|
case plug do
|
||||||
{name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name}
|
{name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name}
|
||||||
name -> {name, cfg: name.default_config(), name: name}
|
name -> {name, cfg: name.default_config(), name: name}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add each child to the "loaded modules" list in the State
|
# Add each child to the "loaded plugins" list in the State
|
||||||
Enum.each(children, fn {module, opts} -> State.add_loaded_module({module, opts[:cfg]}) end)
|
Enum.each(children, fn {plugin, opts} -> State.add_loaded_plugin({plugin, opts[:cfg]}) end)
|
||||||
|
|
||||||
Supervisor.init(children, strategy: :one_for_one)
|
Supervisor.init(children, strategy: :one_for_one)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compile_files([]), do: nil
|
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
|
case {File.exists?(path), File.dir?(path)} do
|
||||||
{_, true} -> compile_dir(path, opts[:recurse] || false)
|
{_, true} -> compile_dir(path, opts[:recurse] || false)
|
||||||
{true, false} -> Code.require_file(path)
|
{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
|
end
|
||||||
|
|
||||||
compile_files(module_paths)
|
compile_files(plugin_paths)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compile_files([path | module_paths]) do
|
defp compile_files([path | plugin_paths]) do
|
||||||
compile_files([{path, []} | module_paths])
|
compile_files([{path, []} | plugin_paths])
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compile_dir(path, recurse) do
|
defp compile_dir(path, recurse) do
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ defmodule Omnibot.Plugin.Base do
|
|||||||
|
|
||||||
@impl Plugin.Base
|
@impl Plugin.Base
|
||||||
def on_msg(irc, msg) do
|
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
|
# https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub
|
||||||
route_msg(irc, msg)
|
route_msg(irc, msg)
|
||||||
end
|
end
|
||||||
|
|||||||
40
lib/state.ex
40
lib/state.ex
@@ -2,7 +2,7 @@ defmodule Omnibot.State do
|
|||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
@enforce_keys [:cfg]
|
@enforce_keys [:cfg]
|
||||||
defstruct [:cfg, channels: MapSet.new(), module_map: %{}]
|
defstruct [:cfg, channels: MapSet.new(), plugin_map: %{}]
|
||||||
|
|
||||||
## Client API
|
## Client API
|
||||||
|
|
||||||
@@ -21,25 +21,25 @@ defmodule Omnibot.State do
|
|||||||
GenServer.call(state, :cfg)
|
GenServer.call(state, :cfg)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Adds a loaded module to the default state."
|
@doc "Adds a loaded plugin to the default state."
|
||||||
def add_loaded_module(module), do: add_loaded_module(__MODULE__, module)
|
def add_loaded_plugin(plugin), do: add_loaded_plugin(__MODULE__, plugin)
|
||||||
|
|
||||||
@doc "Adds a loaded module to the given state."
|
@doc "Adds a loaded plugin to the given state."
|
||||||
def add_loaded_module(state, {module, cfg}), do: GenServer.cast(state, {:add_loaded_module, {module, cfg}})
|
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."
|
@doc "Adds a loaded plugin to the given state."
|
||||||
def add_loaded_module(state, module), do: add_loaded_module(state, {module, []})
|
def add_loaded_plugin(state, plugin), do: add_loaded_plugin(state, {plugin, []})
|
||||||
|
|
||||||
@doc "Gets all loaded modules from the default state."
|
@doc "Gets all loaded plugins from the default state."
|
||||||
def loaded_modules(), do: loaded_modules(__MODULE__)
|
def loaded_plugins(), do: loaded_plugins(__MODULE__)
|
||||||
|
|
||||||
@doc "Gets all loaded modules from the given state."
|
@doc "Gets all loaded plugins from the given state."
|
||||||
def loaded_modules(state), do: GenServer.call(state, :loaded_modules)
|
def loaded_plugins(state), do: GenServer.call(state, :loaded_plugins)
|
||||||
|
|
||||||
def all_channels(), do: all_channels(__MODULE__)
|
def all_channels(), do: all_channels(__MODULE__)
|
||||||
|
|
||||||
def all_channels(state) do
|
def all_channels(state) do
|
||||||
loaded_modules(state) |> Enum.flat_map(
|
loaded_plugins(state) |> Enum.flat_map(
|
||||||
fn {_, cfg} ->
|
fn {_, cfg} ->
|
||||||
case cfg[:channels] do
|
case cfg[:channels] do
|
||||||
:all -> []
|
:all -> []
|
||||||
@@ -51,14 +51,14 @@ defmodule Omnibot.State do
|
|||||||
|> MapSet.to_list()
|
|> MapSet.to_list()
|
||||||
end
|
end
|
||||||
|
|
||||||
def channel_modules(channel), do: channel_modules(__MODULE__, channel)
|
def channel_plugins(channel), do: channel_plugins(__MODULE__, channel)
|
||||||
|
|
||||||
@doc ~S"""
|
@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.
|
loaded, and listening to the given channel.
|
||||||
"""
|
"""
|
||||||
def channel_modules(state, channel) do
|
def channel_plugins(state, channel) do
|
||||||
loaded_modules(state) |> Enum.filter(
|
loaded_plugins(state) |> Enum.filter(
|
||||||
fn {_, cfg} ->
|
fn {_, cfg} ->
|
||||||
cfg[:channels] == :all or Enum.member?(cfg[:channels] || [], channel)
|
cfg[:channels] == :all or Enum.member?(cfg[:channels] || [], channel)
|
||||||
end)
|
end)
|
||||||
@@ -77,13 +77,13 @@ defmodule Omnibot.State do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call(:loaded_modules, _from, state) do
|
def handle_call(:loaded_plugins, _from, state) do
|
||||||
{:reply, state.module_map, state}
|
{:reply, state.plugin_map, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_cast({:add_loaded_module, {module, cfg}}, state) do
|
def handle_cast({:add_loaded_plugin, {plugin, cfg}}, state) do
|
||||||
state = %{state | module_map: Map.put(state.module_map, module, cfg)}
|
state = %{state | plugin_map: Map.put(state.plugin_map, plugin, cfg)}
|
||||||
{:noreply, state}
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ defmodule StateTest do
|
|||||||
{:ok, state: state}
|
{:ok, state: state}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "state channel_modules works correctly", %{state: state} do
|
test "state channel_plugins works correctly", %{state: state} do
|
||||||
modules = [
|
plugins = [
|
||||||
{FooBar, channels: ["#foo", "#bar"]},
|
{FooBar, channels: ["#foo", "#bar"]},
|
||||||
{Foo, channels: ["#foo"]},
|
{Foo, channels: ["#foo"]},
|
||||||
{Bar, channels: ["#bar"]},
|
{Bar, channels: ["#bar"]},
|
||||||
@@ -17,36 +17,36 @@ defmodule StateTest do
|
|||||||
{All, channels: :all},
|
{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")
|
plugins = State.channel_plugins(state, "#foo")
|
||||||
|> Enum.map(fn {module, _} -> module end)
|
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||||
assert length(modules) == 3
|
assert length(plugins) == 3
|
||||||
assert Enum.member?(modules, FooBar)
|
assert Enum.member?(plugins, FooBar)
|
||||||
assert Enum.member?(modules, Foo)
|
assert Enum.member?(plugins, Foo)
|
||||||
assert Enum.member?(modules, All)
|
assert Enum.member?(plugins, All)
|
||||||
|
|
||||||
modules = State.channel_modules(state, "#bar")
|
plugins = State.channel_plugins(state, "#bar")
|
||||||
|> Enum.map(fn {module, _} -> module end)
|
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||||
assert length(modules) == 3
|
assert length(plugins) == 3
|
||||||
assert Enum.member?(modules, FooBar)
|
assert Enum.member?(plugins, FooBar)
|
||||||
assert Enum.member?(modules, Bar)
|
assert Enum.member?(plugins, Bar)
|
||||||
assert Enum.member?(modules, All)
|
assert Enum.member?(plugins, All)
|
||||||
|
|
||||||
modules = State.channel_modules(state, "#baz")
|
plugins = State.channel_plugins(state, "#baz")
|
||||||
|> Enum.map(fn {module, _} -> module end)
|
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||||
assert length(modules) == 2
|
assert length(plugins) == 2
|
||||||
assert Enum.member?(modules, Baz)
|
assert Enum.member?(plugins, Baz)
|
||||||
assert Enum.member?(modules, All)
|
assert Enum.member?(plugins, All)
|
||||||
|
|
||||||
modules = State.channel_modules(state, nil)
|
plugins = State.channel_plugins(state, nil)
|
||||||
|> Enum.map(fn {module, _} -> module end)
|
|> Enum.map(fn {plugin, _} -> plugin end)
|
||||||
assert length(modules) == 1
|
assert length(plugins) == 1
|
||||||
assert Enum.member?(modules, All)
|
assert Enum.member?(plugins, All)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "state all_channels works correctly", %{state: state} do
|
test "state all_channels works correctly", %{state: state} do
|
||||||
modules = [
|
plugins = [
|
||||||
{FooBar, channels: ["#foo", "#bar"]},
|
{FooBar, channels: ["#foo", "#bar"]},
|
||||||
{Foo, channels: ["#foo"]},
|
{Foo, channels: ["#foo"]},
|
||||||
{Bar, channels: ["#bar"]},
|
{Bar, channels: ["#bar"]},
|
||||||
@@ -54,7 +54,7 @@ defmodule StateTest do
|
|||||||
{All, channels: :all},
|
{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)
|
channels = State.all_channels(state)
|
||||||
|
|
||||||
assert length(channels) == 3
|
assert length(channels) == 3
|
||||||
|
|||||||
Reference in New Issue
Block a user