WIP: post editing #103
5 changed files with 102 additions and 7 deletions
|
@ -198,7 +198,7 @@ def make_new_object_data_from_update_object(original_data, new_data) do
|
|||
}
|
||||
end
|
||||
|
||||
defp for_each_history_item(%{"orderedItems" => items} = history, _object, fun) do
|
||||
def for_each_history_item(%{"orderedItems" => items} = history, _object, fun) do
|
||||
new_items =
|
||||
Enum.map(items, fun)
|
||||
|> Enum.reduce_while(
|
||||
|
@ -215,7 +215,7 @@ defp for_each_history_item(%{"orderedItems" => items} = history, _object, fun) d
|
|||
end
|
||||
end
|
||||
|
||||
defp for_each_history_item(history, _, _) do
|
||||
def for_each_history_item(history, _, _) do
|
||||
{:ok, history}
|
||||
end
|
||||
|
||||
|
|
|
@ -53,10 +53,53 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
|
||||
@required_description_keys [:key, :related_policy]
|
||||
|
||||
def filter_one(policy, message) do
|
||||
should_plug_history? =
|
||||
if function_exported?(policy, :history_awareness, 0) do
|
||||
policy.history_awareness()
|
||||
else
|
||||
:manual
|
||||
end
|
||||
|> Kernel.==(:auto)
|
||||
|
||||
if not should_plug_history? do
|
||||
policy.filter(message)
|
||||
else
|
||||
main_result = policy.filter(message)
|
||||
|
||||
with {_, {:ok, main_message}} <- {:main, main_result},
|
||||
{_,
|
||||
%{
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [_ | _]
|
||||
}
|
||||
}} = {_, object} <- {:object, message["object"]},
|
||||
{_, {:ok, new_history}} <-
|
||||
{:history,
|
||||
Pleroma.Object.Updater.for_each_history_item(
|
||||
object["formerRepresentations"],
|
||||
object,
|
||||
fn item ->
|
||||
with {:ok, filtered} <- policy.filter(Map.put(message, "object", item)) do
|
||||
{:ok, filtered["object"]}
|
||||
else
|
||||
e -> e
|
||||
end
|
||||
end
|
||||
)} do
|
||||
{:ok, put_in(main_message, ["object", "formerRepresentations"], new_history)}
|
||||
else
|
||||
{:main, _} -> main_result
|
||||
{:object, _} -> main_result
|
||||
{:history, e} -> e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def filter(policies, %{} = message) do
|
||||
policies
|
||||
|> Enum.reduce({:ok, message}, fn
|
||||
policy, {:ok, message} -> policy.filter(message)
|
||||
policy, {:ok, message} -> filter_one(policy, message)
|
||||
_, error -> error
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do
|
|||
|
||||
@reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless])
|
||||
|
||||
def history_awareness, do: :auto
|
||||
|
||||
def filter_by_summary(
|
||||
%{data: %{"summary" => parent_summary}} = _in_reply_to,
|
||||
%{"summary" => child_summary} = child
|
||||
|
@ -27,8 +29,8 @@ def filter_by_summary(
|
|||
|
||||
def filter_by_summary(_in_reply_to, child), do: child
|
||||
|
||||
def filter(%{"type" => "Create", "object" => child_object} = object)
|
||||
when is_map(child_object) do
|
||||
def filter(%{"type" => type, "object" => child_object} = object)
|
||||
when type in ["Create", "Update"] and is_map(child_object) do
|
||||
child =
|
||||
child_object["inReplyTo"]
|
||||
|> Object.normalize(fetch: false)
|
||||
|
|
|
@ -12,5 +12,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.Policy do
|
|||
label: String.t(),
|
||||
description: String.t()
|
||||
}
|
||||
@optional_callbacks config_description: 0
|
||||
@callback history_awareness() :: :auto | :manual
|
||||
@optional_callbacks config_description: 0, history_awareness: 0
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
|
||||
|
||||
describe "rewrites summary" do
|
||||
|
@ -35,10 +36,58 @@ test "it adds `re:` to summary object when child summary containts re-subject of
|
|||
assert {:ok, res} = EnsureRePrepended.filter(message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
end
|
||||
|
||||
test "it adds `re:` to history" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
|
||||
test "it accepts Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
end
|
||||
|
||||
describe "skip filter" do
|
||||
test "it skip if type isn't 'Create'" do
|
||||
test "it skip if type isn't 'Create' or 'Update'" do
|
||||
message = %{
|
||||
"type" => "Annotation",
|
||||
"object" => %{"summary" => "object-summary"}
|
||||
|
|
Loading…
Reference in a new issue