X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fconfig%2Fconfig_db.ex;h=85a049f8a00d8907d20f1ffe3d00eae2a9f0b534;hb=efb8ef5abee1a8defa2bfba40ad1065db4c09ddf;hp=e433ce442ebce8f88721c7678d88a1bbde6dd70b;hpb=29155137fdae15fccfaa68fb9c954e98078ce0c4;p=akkoma diff --git a/lib/pleroma/config/config_db.ex b/lib/pleroma/config/config_db.ex index e433ce442..85a049f8a 100644 --- a/lib/pleroma/config/config_db.ex +++ b/lib/pleroma/config/config_db.ex @@ -5,6 +5,7 @@ defmodule Pleroma.ConfigDB do use Ecto.Schema import Ecto.Changeset + import Ecto.Query import Pleroma.Web.Gettext alias __MODULE__ alias Pleroma.Repo @@ -15,10 +16,25 @@ defmodule Pleroma.ConfigDB do field(:key, :string) field(:group, :string) field(:value, :binary) + field(:db, {:array, :string}, virtual: true, default: []) timestamps() end + @spec get_all_as_keyword() :: keyword() + def get_all_as_keyword do + ConfigDB + |> select([c], {c.group, c.key, c.value}) + |> Repo.all() + |> Enum.reduce([], fn {group, key, value}, acc -> + group = ConfigDB.from_string(group) + key = ConfigDB.from_string(key) + value = from_binary(value) + + Keyword.update(acc, group, [{key, value}], &Keyword.merge(&1, [{key, value}])) + end) + end + @spec get_by_params(map()) :: ConfigDB.t() | nil def get_by_params(params), do: Repo.get_by(ConfigDB, params) @@ -46,9 +62,73 @@ defmodule Pleroma.ConfigDB do |> Repo.update() end + @spec get_db_keys(ConfigDB.t()) :: [String.t()] + def get_db_keys(%ConfigDB{} = config) do + config.value + |> ConfigDB.from_binary() + |> get_db_keys(config.key) + end + + @spec get_db_keys(keyword(), any()) :: [String.t()] + def get_db_keys(value, key) do + if Keyword.keyword?(value) do + value |> Keyword.keys() |> Enum.map(&convert(&1)) + else + [convert(key)] + end + end + + @full_subkey_update [ + {:pleroma, :assets, :mascots}, + {:pleroma, :emoji, :groups}, + {:pleroma, :workers, :retries}, + {:pleroma, :mrf_subchain, :match_actor}, + {:pleroma, :mrf_keyword, :replace} + ] + + @spec deep_merge(atom(), atom(), keyword(), keyword()) :: keyword() + def deep_merge(group, key, old_value, new_value) do + old_keys = + old_value + |> Keyword.keys() + |> MapSet.new() + + new_keys = + new_value + |> Keyword.keys() + |> MapSet.new() + + intersect_keys = old_keys |> MapSet.intersection(new_keys) |> MapSet.to_list() + + subkeys = sub_key_full_update(group, key, intersect_keys) + + merged_value = DeepMerge.deep_merge(old_value, new_value) + + Enum.reduce(subkeys, merged_value, fn subkey, acc -> + Keyword.put(acc, subkey, new_value[subkey]) + end) + end + + @spec sub_key_full_update?(atom(), atom(), [Keyword.key()]) :: boolean() + def sub_key_full_update?(group, key, subkeys) do + Enum.any?(@full_subkey_update, fn {g, k, subkey} -> + g == group and k == key and subkey in subkeys + end) + end + + defp sub_key_full_update(group, key, subkeys) do + Enum.map(@full_subkey_update, fn + {g, k, subkey} when g == group and k == key -> + if subkey in subkeys, do: subkey, else: [] + + _ -> + [] + end) + |> List.flatten() + end + @full_key_update [ {:pleroma, :ecto_repos}, - {:pleroma, :assets}, {:quack, :meta}, {:mime, :types}, {:cors_plug, [:max_age, :methods, :expose, :headers]}, @@ -82,8 +162,14 @@ defmodule Pleroma.ConfigDB do old_value <- from_binary(config.value), transformed_value <- do_transform(params[:value]), {:can_be_merged, true, config} <- {:can_be_merged, is_list(transformed_value), config}, - new_value <- DeepMerge.deep_merge(old_value, transformed_value) do - ConfigDB.update(config, %{value: new_value, transformed?: true}) + new_value <- + deep_merge( + ConfigDB.from_string(config.group), + ConfigDB.from_string(config.key), + old_value, + transformed_value + ) do + ConfigDB.update(config, %{value: new_value}) else {reason, false, config} when reason in [:partial_update, :can_be_merged] -> ConfigDB.update(config, params) @@ -137,6 +223,9 @@ defmodule Pleroma.ConfigDB do end end + @spec convert(any()) :: any() + def convert(entity), do: do_convert(entity) + defp do_convert(entity) when is_list(entity) do for v <- entity, into: [], do: do_convert(v) end @@ -174,7 +263,6 @@ defmodule Pleroma.ConfigDB do } end - defp do_convert({:dispatch, [entity]}), do: %{"tuple" => [":dispatch", [inspect(entity)]]} # TODO: will become useless after removing hackney defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]} @@ -202,6 +290,9 @@ defmodule Pleroma.ConfigDB do def transform(entity), do: to_binary(entity) + @spec transform_with_out_binary(any()) :: any() + def transform_with_out_binary(entity), do: do_transform(entity) + @spec to_binary(any()) :: binary() def to_binary(entity), do: :erlang.term_to_binary(entity) @@ -211,14 +302,13 @@ defmodule Pleroma.ConfigDB do {:proxy_url, {do_transform_string(type), parse_host(host), port}} end - defp do_transform(%{"tuple" => [":dispatch", [entity]]}) do - {dispatch_settings, []} = do_eval(entity) - {:dispatch, [dispatch_settings]} - end - # TODO: will become useless after removing hackney defp do_transform(%{"tuple" => [":partial_chain", entity]}) do - {partial_chain, []} = do_eval(entity) + {partial_chain, []} = + entity + |> String.replace(~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "") + |> Code.eval_string() + {:partial_chain, partial_chain} end @@ -301,12 +391,7 @@ defmodule Pleroma.ConfigDB do @spec is_module_name?(String.t()) :: boolean() def is_module_name?(string) do - Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Quack)\./, string) or + Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Quack|Ueberauth)\./, string) or string in ["Oban", "Ueberauth", "ExSyslogger"] end - - defp do_eval(entity) do - cleaned_string = String.replace(entity, ~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "") - Code.eval_string(cleaned_string) - end end