X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fadmin_api%2Fconfig.ex;h=1917a55805b9a728f0048ccf5150f54b498746be;hb=3c0abfca53751624ebd6ea7174ee880d9e7b29e7;hp=8b9b658a9a0c8efbdd32d26a8e81888a9e39f12d;hpb=657277ffc0d3d25be4376ed629057a2d2cefb2e1;p=akkoma diff --git a/lib/pleroma/web/admin_api/config.ex b/lib/pleroma/web/admin_api/config.ex index 8b9b658a9..1917a5580 100644 --- a/lib/pleroma/web/admin_api/config.ex +++ b/lib/pleroma/web/admin_api/config.ex @@ -5,6 +5,7 @@ defmodule Pleroma.Web.AdminAPI.Config do use Ecto.Schema import Ecto.Changeset + import Pleroma.Web.Gettext alias __MODULE__ alias Pleroma.Repo @@ -54,107 +55,128 @@ defmodule Pleroma.Web.AdminAPI.Config do @spec delete(map()) :: {:ok, Config.t()} | {:error, Changeset.t()} def delete(params) do - with %Config{} = config <- Config.get_by_params(params) do - Repo.delete(config) + with %Config{} = config <- Config.get_by_params(Map.delete(params, :subkeys)) do + if params[:subkeys] do + updated_value = + Keyword.drop( + :erlang.binary_to_term(config.value), + Enum.map(params[:subkeys], &do_transform_string(&1)) + ) + + Config.update(config, %{value: updated_value}) + else + Repo.delete(config) + {:ok, nil} + end else - nil -> {:error, "Config with params #{inspect(params)} not found"} + nil -> + err = + dgettext("errors", "Config with params %{params} not found", params: inspect(params)) + + {:error, err} end end @spec from_binary(binary()) :: term() - def from_binary(value), do: :erlang.binary_to_term(value) + def from_binary(binary), do: :erlang.binary_to_term(binary) - @spec from_binary_to_map(binary()) :: any() - def from_binary_to_map(binary) do + @spec from_binary_with_convert(binary()) :: any() + def from_binary_with_convert(binary) do from_binary(binary) |> do_convert() end - defp do_convert([{k, v}] = value) when is_list(value) and length(value) == 1, - do: %{k => do_convert(v)} + defp do_convert(entity) when is_list(entity) do + for v <- entity, into: [], do: do_convert(v) + end - defp do_convert(values) when is_list(values), do: for(val <- values, do: do_convert(val)) + defp do_convert(%Regex{} = entity), do: inspect(entity) - defp do_convert({k, v} = value) when is_tuple(value), - do: %{k => do_convert(v)} + defp do_convert(entity) when is_map(entity) do + for {k, v} <- entity, into: %{}, do: {do_convert(k), do_convert(v)} + end - defp do_convert(value) when is_tuple(value), do: %{"tuple" => do_convert(Tuple.to_list(value))} + defp do_convert({:dispatch, [entity]}), do: %{"tuple" => [":dispatch", [inspect(entity)]]} + defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]} - defp do_convert(value) when is_binary(value) or is_map(value) or is_number(value), do: value + defp do_convert(entity) when is_tuple(entity), + do: %{"tuple" => do_convert(Tuple.to_list(entity))} - defp do_convert(value) when is_atom(value) do - string = to_string(value) + defp do_convert(entity) when is_boolean(entity) or is_number(entity) or is_nil(entity), + do: entity + + defp do_convert(entity) when is_atom(entity) do + string = to_string(entity) if String.starts_with?(string, "Elixir."), - do: String.trim_leading(string, "Elixir."), - else: value + do: do_convert(string), + else: ":" <> string end - @spec transform(any()) :: binary() - def transform(%{"tuple" => _} = entity), do: :erlang.term_to_binary(do_transform(entity)) - - def transform(entity) when is_map(entity) do - tuples = - for {k, v} <- entity, - into: [], - do: {if(is_atom(k), do: k, else: String.to_atom(k)), do_transform(v)} + defp do_convert("Elixir." <> module_name), do: module_name - Enum.reject(tuples, fn {_k, v} -> is_nil(v) end) - |> Enum.sort() - |> :erlang.term_to_binary() - end + defp do_convert(entity) when is_binary(entity), do: entity - def transform(entity) when is_list(entity) do - list = Enum.map(entity, &do_transform(&1)) - :erlang.term_to_binary(list) + @spec transform(any()) :: binary() + def transform(entity) when is_binary(entity) or is_map(entity) or is_list(entity) do + :erlang.term_to_binary(do_transform(entity)) end def transform(entity), do: :erlang.term_to_binary(entity) - defp do_transform(%Regex{} = value) when is_map(value), do: value + defp do_transform(%Regex{} = entity), do: entity - defp do_transform(%{"tuple" => [k, values] = entity}) when length(entity) == 2 do - {do_transform(k), do_transform(values)} + defp do_transform(%{"tuple" => [":dispatch", [entity]]}) do + {dispatch_settings, []} = do_eval(entity) + {:dispatch, [dispatch_settings]} end - defp do_transform(%{"tuple" => values}) do - Enum.reduce(values, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end) + defp do_transform(%{"tuple" => [":partial_chain", entity]}) do + {partial_chain, []} = do_eval(entity) + {:partial_chain, partial_chain} end - defp do_transform(value) when is_map(value) do - values = for {key, val} <- value, into: [], do: {String.to_atom(key), do_transform(val)} - - Enum.sort(values) + defp do_transform(%{"tuple" => entity}) do + Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end) end - defp do_transform(value) when is_list(value) do - Enum.map(value, &do_transform(&1)) + defp do_transform(entity) when is_map(entity) do + for {k, v} <- entity, into: %{}, do: {do_transform(k), do_transform(v)} end - defp do_transform(entity) when is_list(entity) and length(entity) == 1, do: hd(entity) + defp do_transform(entity) when is_list(entity) do + for v <- entity, into: [], do: do_transform(v) + end - defp do_transform(value) when is_binary(value) do - String.trim(value) + defp do_transform(entity) when is_binary(entity) do + String.trim(entity) |> do_transform_string() end - defp do_transform(value), do: value + defp do_transform(entity), do: entity - defp do_transform_string(value) when byte_size(value) == 0, do: nil + defp do_transform_string("~r/" <> pattern) do + modificator = String.split(pattern, "/") |> List.last() + pattern = String.trim_trailing(pattern, "/" <> modificator) - defp do_transform_string(value) do - cond do - String.starts_with?(value, "Pleroma") or String.starts_with?(value, "Phoenix") -> - String.to_existing_atom("Elixir." <> value) + case modificator do + "" -> ~r/#{pattern}/ + "i" -> ~r/#{pattern}/i + "u" -> ~r/#{pattern}/u + "s" -> ~r/#{pattern}/s + end + end - String.starts_with?(value, ":") -> - String.replace(value, ":", "") |> String.to_existing_atom() + defp do_transform_string(":" <> atom), do: String.to_atom(atom) - String.starts_with?(value, "i:") -> - String.replace(value, "i:", "") |> String.to_integer() + defp do_transform_string(value) do + if String.starts_with?(value, "Pleroma") or String.starts_with?(value, "Phoenix"), + do: String.to_existing_atom("Elixir." <> value), + else: value + end - true -> - value - end + defp do_eval(entity) do + cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "") + Code.eval_string(cleaned_string, [], requires: [], macros: []) end end