From 70b9bba56f5319361ce5a7df5c489b9c0d6905ce Mon Sep 17 00:00:00 2001 From: Jordan Bracco Date: Tue, 20 Dec 2022 02:13:47 +0000 Subject: Rename to Nola Summary: Nola rename cont. pt. 2. Refs T77. `find lib -name "*.ex" -type f | xargs sed -i '' 's/LSG/Nola/g'` Nola rename, cont. pt. 3. Refs T77. `s/:lsg/:nola/g` Nola rename, cont. pt. 4. Refs T77. Nola rename, cont. pt. 5. Refs T77. Configs. find config -type f | xargs sed -i '' 's/LSG/Nola/g' find config -type f | xargs sed -i '' 's/lsg/nola/g' BREAKING CHANGE: Config keys switch from `:lsg` to `:nola` Nola rename, the end. pt 6. Refs T77. Nola rename: The Big Move, Refs T77 Update repo URL, refs T77. Nola rename: Nola.Plugins, refs T77 Maniphest Tasks: T77 Differential Revision: https://phab.random.sh/D3 --- lib/nola_plugins/helpers/temp_ref.ex | 95 ++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 lib/nola_plugins/helpers/temp_ref.ex (limited to 'lib/nola_plugins/helpers') diff --git a/lib/nola_plugins/helpers/temp_ref.ex b/lib/nola_plugins/helpers/temp_ref.ex new file mode 100644 index 0000000..160169d --- /dev/null +++ b/lib/nola_plugins/helpers/temp_ref.ex @@ -0,0 +1,95 @@ +defmodule Nola.Plugins.TempRefHelper do + @moduledoc """ + This module allows to easily implement local temporary simple references for easy access from IRC. + + For example, your plugin output could be acted on, and instead of giving the burden for the user to + write or copy that uuid, you could give them a small alphanumeric reference to use instead. + + You can configure how many and for how long the references are kept. + + ## Usage + + `import Irc.Plugin.TempRef` + + ```elixir + defmodule Irc.MyPlugin do + defstruct [:temprefs] + + def init(_) do + # … + {:ok, %__MODULE__{temprefs: new_temp_refs()} + end + end + ``` + """ + + defstruct [:refs, :max, :expire, :build_fun, :build_increase_fun, :build_options] + + defmodule SimpleAlphaNumericBuilder do + def build(options) do + length = Keyword.get(options, :length, 3) + for _ <- 1..length, into: "", do: <> + end + + def increase(options) do + Keyword.put(options, :length, Keyword.get(options, :length, 3) + 1) + end + end + + def new_temp_refs(options \\ []) do + %__MODULE__{ + refs: Keyword.get(options, :init_refs, []), + max: Keyword.get(options, :max, []), + expire: Keyword.get(options, :expire, :infinity), + build_fun: Keyword.get(options, :build_fun, &__MODULE__.SimpleAlphaNumericBuilder.build/1), + build_increase_fun: Keyword.get(options, :build_increase_fun, &__MODULE__.SimpleAlphaNumericBuilder.increase/1), + build_options: Keyword.get(options, :build_options, [length: 3]) + } + end + + def janitor_refs(state = %__MODULE__{}) do + if length(state.refs) > state.max do + %__MODULE__{refs: state.refs |> Enum.reverse() |> tl() |> Enum.reverse()} + else + state + end + end + + def put_temp_ref(data, state = %__MODULE__{}) do + state = janitor_refs(state) + key = new_nonexisting_key(state) + if key do + ref = {key, DateTime.utc_now(), data} + {key, %__MODULE__{state | refs: [ref | state.refs]}} + else + {nil, state} + end + end + + def lookup_temp_ref(key, state, default \\ nil) do + case List.keyfind(state.refs, key, 0) do + {_, _, data} -> data + _ -> default + end + end + + defp new_nonexisting_key(state, i) when i > 50 do + nil + end + + defp new_nonexisting_key(state = %__MODULE__{refs: refs}, i \\ 1) do + build_options = if rem(i, 5) == 0 do + state.build_increase_fun.(state.build_options) + else + state.build_options + end + + key = state.build_fun.(state.build_options) + if !List.keymember?(refs, key, 0) do + key + else + new_nonexisting_key(state, i + 1) + end + end + +end -- cgit v1.2.3