forked from AkkomaGang/akkoma
Encapsulation of tags / hashtags fetching from objects.
This commit is contained in:
parent
8e1f32e715
commit
ee221277b0
12 changed files with 78 additions and 39 deletions
|
@ -48,14 +48,12 @@ defp item_creation_tags(tags, _, _) do
|
||||||
tags
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
defp hashtags_to_topics(%{data: %{"tag" => tags}}) do
|
defp hashtags_to_topics(object) do
|
||||||
tags
|
object
|
||||||
|> Enum.filter(&is_bitstring(&1))
|
|> Object.hashtags()
|
||||||
|> Enum.map(fn tag -> "hashtag:" <> tag end)
|
|> Enum.map(fn hashtag -> "hashtag:" <> hashtag end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp hashtags_to_topics(_), do: []
|
|
||||||
|
|
||||||
defp remote_topics(%{local: true}), do: []
|
defp remote_topics(%{local: true}), do: []
|
||||||
|
|
||||||
defp remote_topics(%{actor: actor}) when is_binary(actor),
|
defp remote_topics(%{actor: actor}) when is_binary(actor),
|
||||||
|
|
|
@ -47,17 +47,33 @@ def with_joined_activity(query, activity_type \\ "Create", join_type \\ :inner)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(data) do
|
def create(data) do
|
||||||
Object.change(%Object{}, %{data: data})
|
%Object{}
|
||||||
|
|> Object.change(%{data: data})
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
def change(struct, params \\ %{}) do
|
def change(struct, params \\ %{}) do
|
||||||
struct
|
changeset =
|
||||||
|> cast(params, [:data])
|
struct
|
||||||
|> validate_required([:data])
|
|> cast(params, [:data])
|
||||||
|> unique_constraint(:ap_id, name: :objects_unique_apid_index)
|
|> validate_required([:data])
|
||||||
|
|> unique_constraint(:ap_id, name: :objects_unique_apid_index)
|
||||||
|
|
||||||
|
if hashtags_changed?(struct, get_change(changeset, :data)) do
|
||||||
|
# TODO: modify assoc once it's introduced
|
||||||
|
changeset
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp hashtags_changed?(%Object{} = struct, %{"tag" => _} = data) do
|
||||||
|
Enum.sort(embedded_hashtags(struct)) !=
|
||||||
|
Enum.sort(object_data_hashtags(data))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp hashtags_changed?(_, _), do: false
|
||||||
|
|
||||||
def get_by_id(nil), do: nil
|
def get_by_id(nil), do: nil
|
||||||
def get_by_id(id), do: Repo.get(Object, id)
|
def get_by_id(id), do: Repo.get(Object, id)
|
||||||
|
|
||||||
|
@ -344,4 +360,23 @@ def replies(object, opts \\ []) do
|
||||||
|
|
||||||
def self_replies(object, opts \\ []),
|
def self_replies(object, opts \\ []),
|
||||||
do: replies(object, Keyword.put(opts, :self_only, true))
|
do: replies(object, Keyword.put(opts, :self_only, true))
|
||||||
|
|
||||||
|
def tags(%Object{data: %{"tag" => tags}}) when is_list(tags), do: tags
|
||||||
|
|
||||||
|
def tags(_), do: []
|
||||||
|
|
||||||
|
def hashtags(object), do: embedded_hashtags(object)
|
||||||
|
|
||||||
|
defp embedded_hashtags(%Object{data: data}) do
|
||||||
|
object_data_hashtags(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp embedded_hashtags(_), do: []
|
||||||
|
|
||||||
|
defp object_data_hashtags(%{"tag" => tags}) when is_list(tags) do
|
||||||
|
# Note: AS2 map-type elements are ignored
|
||||||
|
Enum.filter(tags, &is_bitstring(&1))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp object_data_hashtags(_), do: []
|
||||||
end
|
end
|
||||||
|
|
|
@ -74,9 +74,11 @@ defp check_media_nsfw(
|
||||||
|
|
||||||
object =
|
object =
|
||||||
if MRF.subdomain_match?(media_nsfw, actor_host) do
|
if MRF.subdomain_match?(media_nsfw, actor_host) do
|
||||||
tags = (child_object["tag"] || []) ++ ["nsfw"]
|
child_object =
|
||||||
child_object = Map.put(child_object, "tag", tags)
|
child_object
|
||||||
child_object = Map.put(child_object, "sensitive", true)
|
|> Map.put("tag", (child_object["tag"] || []) ++ ["nsfw"])
|
||||||
|
|> Map.put("sensitive", true)
|
||||||
|
|
||||||
Map.put(object, "object", child_object)
|
Map.put(object, "object", child_object)
|
||||||
else
|
else
|
||||||
object
|
object
|
||||||
|
|
|
@ -32,18 +32,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
"""
|
"""
|
||||||
def fix_object(object, options \\ []) do
|
def fix_object(object, options \\ []) do
|
||||||
object
|
object
|
||||||
|> strip_internal_fields
|
|> strip_internal_fields()
|
||||||
|> fix_actor
|
|> fix_actor()
|
||||||
|> fix_url
|
|> fix_url()
|
||||||
|> fix_attachments
|
|> fix_attachments()
|
||||||
|> fix_context
|
|> fix_context()
|
||||||
|> fix_in_reply_to(options)
|
|> fix_in_reply_to(options)
|
||||||
|> fix_emoji
|
|> fix_emoji()
|
||||||
|> fix_tag
|
|> fix_tag()
|
||||||
|> set_sensitive
|
|> set_sensitive()
|
||||||
|> fix_content_map
|
|> fix_content_map()
|
||||||
|> fix_addressing
|
|> fix_addressing()
|
||||||
|> fix_summary
|
|> fix_summary()
|
||||||
|> fix_type(options)
|
|> fix_type(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -315,10 +315,9 @@ def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
|
||||||
tags =
|
tags =
|
||||||
tag
|
tag
|
||||||
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|
||||||
|> Enum.map(fn %{"name" => name} ->
|
|> Enum.map(fn
|
||||||
name
|
%{"name" => "#" <> hashtag} -> String.downcase(hashtag)
|
||||||
|> String.slice(1..-1)
|
%{"name" => hashtag} -> String.downcase(hashtag)
|
||||||
|> String.downcase()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Map.put(object, "tag", tag ++ tags)
|
Map.put(object, "tag", tag ++ tags)
|
||||||
|
|
|
@ -32,6 +32,7 @@ def prepare_activity(activity, opts \\ []) do
|
||||||
|
|
||||||
%{
|
%{
|
||||||
activity: activity,
|
activity: activity,
|
||||||
|
object: object,
|
||||||
data: Map.get(object, :data),
|
data: Map.get(object, :data),
|
||||||
actor: actor
|
actor: actor
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,8 +201,10 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
like_count = object.data["like_count"] || 0
|
like_count = object.data["like_count"] || 0
|
||||||
announcement_count = object.data["announcement_count"] || 0
|
announcement_count = object.data["announcement_count"] || 0
|
||||||
|
|
||||||
tags = object.data["tag"] || []
|
hashtags = Object.hashtags(object)
|
||||||
sensitive = object.data["sensitive"] || Enum.member?(tags, "nsfw")
|
sensitive = object.data["sensitive"] || Enum.member?(hashtags, "nsfw")
|
||||||
|
|
||||||
|
tags = Object.tags(object)
|
||||||
|
|
||||||
tag_mentions =
|
tag_mentions =
|
||||||
tags
|
tags
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for tag <- @data["tag"] || [] do %>
|
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||||
<category term="<%= tag %>"></category>
|
<category term="<%= tag %>"></category>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<link><%= @data["external_url"] %></link>
|
<link><%= @data["external_url"] %></link>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for tag <- @data["tag"] || [] do %>
|
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||||
<category term="<%= tag %>"></category>
|
<category term="<%= tag %>"></category>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for tag <- @data["tag"] || [] do %>
|
<%= for tag <- Pleroma.Object.hashtags(@object) do %>
|
||||||
<category term="<%= tag %>"></category>
|
<category term="<%= tag %>"></category>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ test "it works for incoming notices with tag not being an array (kroeg)" do
|
||||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||||
object = Object.normalize(data["object"])
|
object = Object.normalize(data["object"])
|
||||||
|
|
||||||
assert "test" in object.data["tag"]
|
assert "test" in Object.tags(object)
|
||||||
|
assert Object.hashtags(object) == ["test"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it cleans up incoming notices which are not really DMs" do
|
test "it cleans up incoming notices which are not really DMs" do
|
||||||
|
@ -220,7 +221,8 @@ test "it works for incoming notices with hashtags" do
|
||||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||||
object = Object.normalize(data["object"])
|
object = Object.normalize(data["object"])
|
||||||
|
|
||||||
assert Enum.at(object.data["tag"], 2) == "moo"
|
assert Enum.at(Object.tags(object), 2) == "moo"
|
||||||
|
assert Object.hashtags(object) == ["moo"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works for incoming notices with contentMap" do
|
test "it works for incoming notices with contentMap" do
|
||||||
|
|
|
@ -493,7 +493,7 @@ test "it de-duplicates tags" do
|
||||||
|
|
||||||
object = Object.normalize(activity)
|
object = Object.normalize(activity)
|
||||||
|
|
||||||
assert object.data["tag"] == ["2hu"]
|
assert Object.tags(object) == ["2hu"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it adds emoji in the object" do
|
test "it adds emoji in the object" do
|
||||||
|
|
|
@ -262,8 +262,8 @@ test "a note activity" do
|
||||||
mentions: [],
|
mentions: [],
|
||||||
tags: [
|
tags: [
|
||||||
%{
|
%{
|
||||||
name: "#{object_data["tag"]}",
|
name: "#{hd(object_data["tag"])}",
|
||||||
url: "/tag/#{object_data["tag"]}"
|
url: "/tag/#{hd(object_data["tag"])}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
application: %{
|
application: %{
|
||||||
|
|
Loading…
Reference in a new issue