diff --git a/lib/contrib/fortune.ex b/lib/contrib/fortune.ex index c66118b..bc17c70 100644 --- a/lib/contrib/fortune.ex +++ b/lib/contrib/fortune.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Fortune do - use Omnibot.Module + use Omnibot.Plugin @fortunes [ "Reply hazy, try again", diff --git a/lib/contrib/linkbot.ex b/lib/contrib/linkbot.ex index 728c39f..de6af26 100644 --- a/lib/contrib/linkbot.ex +++ b/lib/contrib/linkbot.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Linkbot do - use Omnibot.Module + use Omnibot.Plugin require Logger @default_config timeout: 30_000 @@ -19,9 +19,6 @@ defmodule Omnibot.Contrib.Linkbot do plug Tesla.Middleware.FollowRedirects, max_redirects: 10 plug Tesla.Middleware.Compression, format: "gzip" - - @title_regex ~r"(?<title>.+)"i - def get_title(url) do # 1. check for "meta" tag (in the header) with a "property" attribute of "og:title", and fetch the "content" attribute of that tag # 2. check for meta tag with attribute "name" == "title", and fetch "content" attribute diff --git a/lib/contrib/wordbot.ex b/lib/contrib/wordbot.ex index 94dcd1a..015c683 100644 --- a/lib/contrib/wordbot.ex +++ b/lib/contrib/wordbot.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Wordbot do - use Omnibot.Module.Base + use Omnibot.Plugin.Base use Supervisor require Logger diff --git a/lib/contrib/wordbot/bot.ex b/lib/contrib/wordbot/bot.ex index 10b8761..e6002bd 100644 --- a/lib/contrib/wordbot/bot.ex +++ b/lib/contrib/wordbot/bot.ex @@ -1,6 +1,6 @@ defmodule Omnibot.Contrib.Wordbot.Bot do - use Omnibot.Module.Base - use Omnibot.Module.GenServer + use Omnibot.Plugin.Base + use Omnibot.Plugin.GenServer alias Omnibot.{Contrib.Wordbot, Irc, State, Util} require Logger @@ -128,7 +128,7 @@ defmodule Omnibot.Contrib.Wordbot.Bot do start_round(irc, channel) end - ## Module callbacks + ## Plugin callbacks @impl true def on_init(cfg) do diff --git a/lib/core.ex b/lib/core.ex index 6fb2314..db05f60 100644 --- a/lib/core.ex +++ b/lib/core.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Core do - use Omnibot.Module + use Omnibot.Plugin alias Omnibot.State @default_config [channels: :all] diff --git a/lib/module/agent.ex b/lib/module/agent.ex deleted file mode 100644 index 3c53cf4..0000000 --- a/lib/module/agent.ex +++ /dev/null @@ -1,40 +0,0 @@ -defmodule Omnibot.Module.Agent do - defmacro __using__([]) do - quote do - alias Omnibot.Module - use Agent - - def start_link(opts) do - cfg = opts[:cfg] - state = opts[:state] || on_init(cfg) - Module.Agent.start_link(cfg, state, opts) - end - - def cfg, do: Module.Agent.cfg(__MODULE__) - def state, do: Module.Agent.state(__MODULE__) - - def update_state(update, timeout \\ 5000), - do: Module.Agent.update_state(__MODULE__, update, timeout) - end - end - - def start_link(cfg, state, opts) do - Agent.start_link(fn -> {cfg, state} end, opts) - end - - def cfg(agent) do - Agent.get(agent, fn {cfg, _} -> cfg end) - end - - def state(agent) do - Agent.get(agent, fn {_, state} -> state end) - end - - def update_state(agent, update, timeout \\ 5000) do - Agent.update( - agent, - fn {cfg, state} -> {cfg, apply(update, [state])} end, - timeout - ) - end -end diff --git a/lib/module/base.ex b/lib/module/base.ex deleted file mode 100644 index 0bafd3c..0000000 --- a/lib/module/base.ex +++ /dev/null @@ -1,129 +0,0 @@ -defmodule Omnibot.Module.Base do - defmodule Hooks do - defmacro __before_compile__(_env) do - quote generated: true do - @impl true - def on_channel_msg(_irc, _channel, _nick, _line), do: nil - - @impl true - def on_channel_msg(_irc, _channel, _nick, _cmd, _params), do: nil - - @impl true - def on_join(_irc, _channel, _nick), do: nil - - @impl true - def on_part(_irc, _channel, _nick), do: nil - - @impl true - def on_kick(_irc, _channel, _nick, _target), do: nil - - @impl true - def on_init(_cfg), do: nil - - @impl true - def default_config(), do: @default_config - - def commands(), do: MapSet.to_list(@commands) - end - end - end - - defmacro __using__([]) do - quote do - alias Omnibot.{Irc, Module} - import Omnibot.Module.Base - - @behaviour Module.Base - - @impl Module.Base - def on_msg(irc, msg) do - # TODO - instead of using a router for modules, consider using a PubSub with a Registry: - # https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub - route_msg(irc, msg) - end - - defp route_msg(irc, msg) do - nick = msg.prefix.nick - case String.upcase(msg.command) do - "PRIVMSG" -> - [channel | params] = msg.params - line = Enum.join(params, " ") - - case String.split(line, " ") do - [cmd | params] -> if Enum.member?(commands(), cmd), - do: on_channel_msg(irc, channel, nick, cmd, params), - else: on_channel_msg(irc, channel, nick, line) - _ -> on_channel_msg(irc, channel, nick, line) - end - - "JOIN" -> - [channel | _] = msg.params - on_join(irc, channel, nick) - - "PART" -> - [channel | _] = msg.params - on_part(irc, channel, nick) - - "KICK" -> - [channel, target | _] = msg.params - on_kick(irc, channel, nick, target) - - _ -> - nil - end - end - - defoverridable Module.Base - - @commands MapSet.new() - @default_config [] - @before_compile Omnibot.Module.Base.Hooks - end - end - - @callback on_msg(irc :: pid(), msg :: %Omnibot.Irc.Msg{}) :: any - @callback on_channel_msg(irc :: pid(), channel :: String.t(), nick :: String.t(), line :: String.t()) :: any - @callback on_channel_msg( - irc :: pid(), - channel :: String.t(), - nick :: String.t(), - cmd :: String.t(), - params :: [String.t()] - ) :: any - @callback on_join(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any - @callback on_part(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any - @callback on_kick(irc :: pid(), channel :: String.t(), nick :: String.t(), target :: String.t()) :: any - @callback on_init(cfg :: any) :: any - @callback default_config() :: any - - defmacro command(cmd, opts) do - quote generated: true do - @commands MapSet.put(@commands, unquote(cmd)) - @impl Omnibot.Module.Base - def on_channel_msg(var!(irc), var!(channel), var!(nick), unquote(cmd), var!(params)) do - unquote(opts[:do]) - end - end - end - - defmacro command(cmd, params, opts) do - params = - Enum.map( - params, - fn param -> - case param do - {_, _, _} -> quote(do: var!(unquote(param))) - lit -> Macro.escape(lit) - end - end - ) - - quote generated: true do - @commands MapSet.put(@commands, unquote(cmd)) - @impl Omnibot.Module.Base - def on_channel_msg(var!(irc), var!(channel), var!(nick), unquote(cmd), unquote(params)) do - unquote(opts[:do]) - end - end - end -end diff --git a/lib/module/gen_server.ex b/lib/module/gen_server.ex deleted file mode 100644 index 0ae03cc..0000000 --- a/lib/module/gen_server.ex +++ /dev/null @@ -1,50 +0,0 @@ -defmodule Omnibot.Module.GenServer do - defmacro __using__([]) do - quote do - alias Omnibot.Module - use GenServer - - def start_link(opts) do - cfg = opts[:cfg] - state = opts[:state] - GenServer.start_link(__MODULE__, {cfg, state}, opts) - end - - def cfg() do - GenServer.call(__MODULE__, :cfg) - end - - def state() do - GenServer.call(__MODULE__, :state) - end - - def update_state(update) do - GenServer.cast(__MODULE__, {:state, update}) - end - - ## Server callbacks - - @impl GenServer - def init({cfg, state}) do - state = state || on_init(cfg) - {:ok, {cfg, state}} - end - - @impl GenServer - def handle_call(:cfg, _from, {cfg, state}) do - {:reply, cfg, {cfg, state}} - end - - @impl GenServer - def handle_call(:state, _from, {cfg, state}) do - {:reply, state, {cfg, state}} - end - - @impl GenServer - def handle_cast({:state, update}, {cfg, state}) do - {:noreply, {cfg, apply(update, [state])}} - end - end - end -end - diff --git a/lib/module/module.ex b/lib/module/module.ex deleted file mode 100644 index 151170d..0000000 --- a/lib/module/module.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule Omnibot.Module do - defmacro __using__([]) do - quote do - use Omnibot.Module.Base - use Omnibot.Module.Agent - end - end -end diff --git a/lib/module_supervisor.ex b/lib/module_supervisor.ex index 2f8abb2..2018754 100644 --- a/lib/module_supervisor.ex +++ b/lib/module_supervisor.ex @@ -1,4 +1,4 @@ -defmodule Omnibot.ModuleSupervisor do +defmodule Omnibot.PluginSupervisor do @moduledoc false use Supervisor diff --git a/lib/supervisor.ex b/lib/supervisor.ex index d18d649..1031815 100644 --- a/lib/supervisor.ex +++ b/lib/supervisor.ex @@ -16,7 +16,7 @@ defmodule Omnibot.Supervisor do children = [ {Task.Supervisor, name: Omnibot.RouterSupervisor, strategy: :one_for_one}, {Omnibot.State, cfg: cfg, name: Omnibot.State}, - {Omnibot.ModuleSupervisor, cfg: cfg, name: Omnibot.ModuleSupervisor}, + {Omnibot.PluginSupervisor, cfg: cfg, name: Omnibot.PluginSupervisor}, ] ++ unless IEx.started?(), do: [{Omnibot.Irc, name: Omnibot.Irc}], else: []