Format the code.
This commit is contained in:
parent
480932c8e5
commit
4afbef39f4
111 changed files with 4912 additions and 2769 deletions
|
|
@ -5,7 +5,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
require Logger
|
||||
|
||||
defp get_href(id) do
|
||||
with %Object{data: %{ "external_url" => external_url } }<- Object.get_cached_by_ap_id(id) do
|
||||
with %Object{data: %{"external_url" => external_url}} <- Object.get_cached_by_ap_id(id) do
|
||||
external_url
|
||||
else
|
||||
_e -> id
|
||||
|
|
@ -13,42 +13,60 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
end
|
||||
|
||||
defp get_in_reply_to(%{"object" => %{"inReplyTo" => in_reply_to}}) do
|
||||
[{:"thr:in-reply-to", [ref: to_charlist(in_reply_to), href: to_charlist(get_href(in_reply_to))], []}]
|
||||
[
|
||||
{:"thr:in-reply-to",
|
||||
[ref: to_charlist(in_reply_to), href: to_charlist(get_href(in_reply_to))], []}
|
||||
]
|
||||
end
|
||||
|
||||
defp get_in_reply_to(_), do: []
|
||||
|
||||
defp get_mentions(to) do
|
||||
Enum.map(to, fn (id) ->
|
||||
Enum.map(to, fn id ->
|
||||
cond do
|
||||
# Special handling for the AP/Ostatus public collections
|
||||
"https://www.w3.org/ns/activitystreams#Public" == id ->
|
||||
{:link, [rel: "mentioned", "ostatus:object-type": "http://activitystrea.ms/schema/1.0/collection", href: "http://activityschema.org/collection/public"], []}
|
||||
{:link,
|
||||
[
|
||||
rel: "mentioned",
|
||||
"ostatus:object-type": "http://activitystrea.ms/schema/1.0/collection",
|
||||
href: "http://activityschema.org/collection/public"
|
||||
], []}
|
||||
|
||||
# Ostatus doesn't handle follower collections, ignore these.
|
||||
Regex.match?(~r/^#{Pleroma.Web.base_url}.+followers$/, id) ->
|
||||
Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) ->
|
||||
[]
|
||||
|
||||
true ->
|
||||
{:link, [rel: "mentioned", "ostatus:object-type": "http://activitystrea.ms/schema/1.0/person", href: id], []}
|
||||
{:link,
|
||||
[
|
||||
rel: "mentioned",
|
||||
"ostatus:object-type": "http://activitystrea.ms/schema/1.0/person",
|
||||
href: id
|
||||
], []}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_links(%{local: true, data: data}) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
[
|
||||
{:link, [type: ['application/atom+xml'], href: h.(data["object"]["id"]), rel: 'self'], []},
|
||||
{:link, [type: ['text/html'], href: h.(data["object"]["id"]), rel: 'alternate'], []}
|
||||
]
|
||||
end
|
||||
|
||||
defp get_links(%{local: false,
|
||||
data: %{
|
||||
"object" => %{
|
||||
"external_url" => external_url
|
||||
}
|
||||
}}) do
|
||||
defp get_links(%{
|
||||
local: false,
|
||||
data: %{
|
||||
"object" => %{
|
||||
"external_url" => external_url
|
||||
}
|
||||
}
|
||||
}) do
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
[
|
||||
{:link, [type: ['text/html'], href: h.(external_url), rel: 'alternate'], []}
|
||||
]
|
||||
|
|
@ -57,60 +75,72 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
defp get_links(_activity), do: []
|
||||
|
||||
defp get_emoji_links(emojis) do
|
||||
Enum.map(emojis, fn({emoji, file}) ->
|
||||
Enum.map(emojis, fn {emoji, file} ->
|
||||
{:link, [name: to_charlist(emoji), rel: 'emoji', href: to_charlist(file)], []}
|
||||
end)
|
||||
end
|
||||
|
||||
def to_simple_form(activity, user, with_author \\ false)
|
||||
|
||||
def to_simple_form(%{data: %{"object" => %{"type" => "Note"}}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["object"]["published"]
|
||||
inserted_at = activity.data["object"]["published"]
|
||||
|
||||
attachments = Enum.map(activity.data["object"]["attachment"] || [], fn(attachment) ->
|
||||
url = hd(attachment["url"])
|
||||
{:link, [rel: 'enclosure', href: to_charlist(url["href"]), type: to_charlist(url["mediaType"])], []}
|
||||
end)
|
||||
attachments =
|
||||
Enum.map(activity.data["object"]["attachment"] || [], fn attachment ->
|
||||
url = hd(attachment["url"])
|
||||
|
||||
{:link,
|
||||
[rel: 'enclosure', href: to_charlist(url["href"]), type: to_charlist(url["mediaType"])],
|
||||
[]}
|
||||
end)
|
||||
|
||||
in_reply_to = get_in_reply_to(activity.data)
|
||||
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
|
||||
mentions = activity.recipients |> get_mentions
|
||||
|
||||
categories = (activity.data["object"]["tag"] || [])
|
||||
|> Enum.map(fn (tag) ->
|
||||
if is_binary(tag) do
|
||||
{:category, [term: to_charlist(tag)], []}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(&(&1))
|
||||
categories =
|
||||
(activity.data["object"]["tag"] || [])
|
||||
|> Enum.map(fn tag ->
|
||||
if is_binary(tag) do
|
||||
{:category, [term: to_charlist(tag)], []}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
emoji_links = get_emoji_links(activity.data["object"]["emoji"] || %{})
|
||||
|
||||
summary = if activity.data["object"]["summary"] do
|
||||
[{:summary, [], h.(activity.data["object"]["summary"])}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
summary =
|
||||
if activity.data["object"]["summary"] do
|
||||
[{:summary, [], h.(activity.data["object"]["summary"])}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
|
||||
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/post']},
|
||||
{:id, h.(activity.data["object"]["id"])}, # For notes, federate the object id.
|
||||
# For notes, federate the object id.
|
||||
{:id, h.(activity.data["object"]["id"])},
|
||||
{:title, ['New note by #{user.nickname}']},
|
||||
{:content, [type: 'html'], h.(activity.data["object"]["content"] |> String.replace(~r/[\n\r]/, ""))},
|
||||
{:content, [type: 'html'],
|
||||
h.(activity.data["object"]["content"] |> String.replace(~r/[\n\r]/, ""))},
|
||||
{:published, h.(inserted_at)},
|
||||
{:updated, h.(updated_at)},
|
||||
{:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])},
|
||||
{:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
|
||||
] ++ summary ++ get_links(activity) ++ categories ++ attachments ++ in_reply_to ++ author ++ mentions ++ emoji_links
|
||||
{:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []}
|
||||
] ++
|
||||
summary ++
|
||||
get_links(activity) ++
|
||||
categories ++ attachments ++ in_reply_to ++ author ++ mentions ++ emoji_links
|
||||
end
|
||||
|
||||
def to_simple_form(%{data: %{"type" => "Like"}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["published"]
|
||||
inserted_at = activity.data["published"]
|
||||
|
|
@ -126,10 +156,12 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
{:content, [type: 'html'], ['#{user.nickname} favorited something']},
|
||||
{:published, h.(inserted_at)},
|
||||
{:updated, h.(updated_at)},
|
||||
{:"activity:object", [
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
|
||||
{:id, h.(activity.data["object"])}, # For notes, federate the object id.
|
||||
]},
|
||||
{:"activity:object",
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
|
||||
# For notes, federate the object id.
|
||||
{:id, h.(activity.data["object"])}
|
||||
]},
|
||||
{:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])},
|
||||
{:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
|
||||
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
|
||||
|
|
@ -138,7 +170,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
end
|
||||
|
||||
def to_simple_form(%{data: %{"type" => "Announce"}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["published"]
|
||||
inserted_at = activity.data["published"]
|
||||
|
|
@ -152,6 +184,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
retweeted_xml = to_simple_form(retweeted_activity, retweeted_user, true)
|
||||
|
||||
mentions = activity.recipients |> get_mentions
|
||||
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
|
||||
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/share']},
|
||||
|
|
@ -168,7 +201,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
end
|
||||
|
||||
def to_simple_form(%{data: %{"type" => "Follow"}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["published"]
|
||||
inserted_at = activity.data["published"]
|
||||
|
|
@ -176,26 +209,29 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
|
||||
|
||||
mentions = (activity.recipients || []) |> get_mentions
|
||||
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
|
||||
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/follow']},
|
||||
{:id, h.(activity.data["id"])},
|
||||
{:title, ['#{user.nickname} started following #{activity.data["object"]}']},
|
||||
{:content, [type: 'html'], ['#{user.nickname} started following #{activity.data["object"]}']},
|
||||
{:content, [type: 'html'],
|
||||
['#{user.nickname} started following #{activity.data["object"]}']},
|
||||
{:published, h.(inserted_at)},
|
||||
{:updated, h.(updated_at)},
|
||||
{:"activity:object", [
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
|
||||
{:id, h.(activity.data["object"])},
|
||||
{:uri, h.(activity.data["object"])},
|
||||
]},
|
||||
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
|
||||
{:"activity:object",
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
|
||||
{:id, h.(activity.data["object"])},
|
||||
{:uri, h.(activity.data["object"])}
|
||||
]},
|
||||
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}
|
||||
] ++ mentions ++ author
|
||||
end
|
||||
|
||||
# Only undos of follow for now. Will need to get redone once there are more
|
||||
def to_simple_form(%{data: %{"type" => "Undo"}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["published"]
|
||||
inserted_at = activity.data["published"]
|
||||
|
|
@ -204,25 +240,28 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
follow_activity = Activity.get_by_ap_id(activity.data["object"])
|
||||
|
||||
mentions = (activity.recipients || []) |> get_mentions
|
||||
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
|
||||
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/unfollow']},
|
||||
{:id, h.(activity.data["id"])},
|
||||
{:title, ['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
|
||||
{:content, [type: 'html'], ['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
|
||||
{:content, [type: 'html'],
|
||||
['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
|
||||
{:published, h.(inserted_at)},
|
||||
{:updated, h.(updated_at)},
|
||||
{:"activity:object", [
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
|
||||
{:id, h.(follow_activity.data["object"])},
|
||||
{:uri, h.(follow_activity.data["object"])},
|
||||
]},
|
||||
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
|
||||
{:"activity:object",
|
||||
[
|
||||
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
|
||||
{:id, h.(follow_activity.data["object"])},
|
||||
{:uri, h.(follow_activity.data["object"])}
|
||||
]},
|
||||
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}
|
||||
] ++ mentions ++ author
|
||||
end
|
||||
|
||||
def to_simple_form(%{data: %{"type" => "Delete"}} = activity, user, with_author) do
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
updated_at = activity.data["published"]
|
||||
inserted_at = activity.data["published"]
|
||||
|
|
@ -237,20 +276,24 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
|||
{:content, [type: 'html'], ['An object was deleted']},
|
||||
{:published, h.(inserted_at)},
|
||||
{:updated, h.(updated_at)}
|
||||
] ++ author
|
||||
] ++ author
|
||||
end
|
||||
|
||||
def to_simple_form(_, _, _), do: nil
|
||||
|
||||
def wrap_with_entry(simple_form) do
|
||||
[{
|
||||
:entry, [
|
||||
xmlns: 'http://www.w3.org/2005/Atom',
|
||||
"xmlns:thr": 'http://purl.org/syndication/thread/1.0',
|
||||
"xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
|
||||
"xmlns:poco": 'http://portablecontacts.net/spec/1.0',
|
||||
"xmlns:ostatus": 'http://ostatus.org/schema/1.0'
|
||||
], simple_form
|
||||
}]
|
||||
[
|
||||
{
|
||||
:entry,
|
||||
[
|
||||
xmlns: 'http://www.w3.org/2005/Atom',
|
||||
"xmlns:thr": 'http://purl.org/syndication/thread/1.0',
|
||||
"xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
|
||||
"xmlns:poco": 'http://portablecontacts.net/spec/1.0',
|
||||
"xmlns:ostatus": 'http://ostatus.org/schema/1.0'
|
||||
],
|
||||
simple_form
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,44 +5,57 @@ defmodule Pleroma.Web.OStatus.FeedRepresenter do
|
|||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
def to_simple_form(user, activities, _users) do
|
||||
most_recent_update = (List.first(activities) || user).updated_at
|
||||
|> NaiveDateTime.to_iso8601
|
||||
most_recent_update =
|
||||
(List.first(activities) || user).updated_at
|
||||
|> NaiveDateTime.to_iso8601()
|
||||
|
||||
h = fn(str) -> [to_charlist(str)] end
|
||||
h = fn str -> [to_charlist(str)] end
|
||||
|
||||
last_activity = List.last(activities)
|
||||
|
||||
entries = activities
|
||||
|> Enum.map(fn(activity) ->
|
||||
{:entry, ActivityRepresenter.to_simple_form(activity, user)}
|
||||
end)
|
||||
|> Enum.filter(fn ({_, form}) -> form end)
|
||||
entries =
|
||||
activities
|
||||
|> Enum.map(fn activity ->
|
||||
{:entry, ActivityRepresenter.to_simple_form(activity, user)}
|
||||
end)
|
||||
|> Enum.filter(fn {_, form} -> form end)
|
||||
|
||||
[{
|
||||
:feed, [
|
||||
xmlns: 'http://www.w3.org/2005/Atom',
|
||||
"xmlns:thr": 'http://purl.org/syndication/thread/1.0',
|
||||
"xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
|
||||
"xmlns:poco": 'http://portablecontacts.net/spec/1.0',
|
||||
"xmlns:ostatus": 'http://ostatus.org/schema/1.0'
|
||||
], [
|
||||
{:id, h.(OStatus.feed_path(user))},
|
||||
{:title, ['#{user.nickname}\'s timeline']},
|
||||
{:updated, h.(most_recent_update)},
|
||||
{:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]},
|
||||
{:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []},
|
||||
{:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []},
|
||||
{:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'], []},
|
||||
{:author, UserRepresenter.to_simple_form(user)},
|
||||
] ++
|
||||
if last_activity do
|
||||
[{:link, [rel: 'next',
|
||||
href: to_charlist(OStatus.feed_path(user)) ++ '?max_id=' ++ to_charlist(last_activity.id),
|
||||
type: 'application/atom+xml'], []}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
++ entries
|
||||
}]
|
||||
[
|
||||
{
|
||||
:feed,
|
||||
[
|
||||
xmlns: 'http://www.w3.org/2005/Atom',
|
||||
"xmlns:thr": 'http://purl.org/syndication/thread/1.0',
|
||||
"xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
|
||||
"xmlns:poco": 'http://portablecontacts.net/spec/1.0',
|
||||
"xmlns:ostatus": 'http://ostatus.org/schema/1.0'
|
||||
],
|
||||
[
|
||||
{:id, h.(OStatus.feed_path(user))},
|
||||
{:title, ['#{user.nickname}\'s timeline']},
|
||||
{:updated, h.(most_recent_update)},
|
||||
{:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]},
|
||||
{:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []},
|
||||
{:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []},
|
||||
{:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'],
|
||||
[]},
|
||||
{:author, UserRepresenter.to_simple_form(user)}
|
||||
] ++
|
||||
if last_activity do
|
||||
[
|
||||
{:link,
|
||||
[
|
||||
rel: 'next',
|
||||
href:
|
||||
to_charlist(OStatus.feed_path(user)) ++
|
||||
'?max_id=' ++ to_charlist(last_activity.id),
|
||||
type: 'application/atom+xml'
|
||||
], []}
|
||||
]
|
||||
else
|
||||
[]
|
||||
end ++ entries
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ defmodule Pleroma.Web.OStatus.FollowHandler do
|
|||
def handle(entry, doc) do
|
||||
with {:ok, actor} <- OStatus.find_make_or_update_user(doc),
|
||||
id when not is_nil(id) <- XML.string_from_xpath("/entry/id", entry),
|
||||
followed_uri when not is_nil(followed_uri) <- XML.string_from_xpath("/entry/activity:object/id", entry),
|
||||
followed_uri when not is_nil(followed_uri) <-
|
||||
XML.string_from_xpath("/entry/activity:object/id", entry),
|
||||
{:ok, followed} <- OStatus.find_or_make_user(followed_uri),
|
||||
{:ok, activity} <- ActivityPub.follow(actor, followed, id, false) do
|
||||
User.follow(actor, followed)
|
||||
|
|
|
|||
|
|
@ -13,49 +13,56 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
|
|||
3. A newly generated context id.
|
||||
"""
|
||||
def get_context(entry, inReplyTo) do
|
||||
context = (
|
||||
XML.string_from_xpath("//ostatus:conversation[1]", entry)
|
||||
|| XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry)
|
||||
|| "") |> String.trim
|
||||
context =
|
||||
(XML.string_from_xpath("//ostatus:conversation[1]", entry) ||
|
||||
XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry) || "")
|
||||
|> String.trim()
|
||||
|
||||
with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(inReplyTo) do
|
||||
context
|
||||
else _e ->
|
||||
if String.length(context) > 0 do
|
||||
context
|
||||
else
|
||||
Utils.generate_context_id
|
||||
end
|
||||
else
|
||||
_e ->
|
||||
if String.length(context) > 0 do
|
||||
context
|
||||
else
|
||||
Utils.generate_context_id()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_people_mentions(entry) do
|
||||
:xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry)
|
||||
|> Enum.map(fn(person) -> XML.string_from_xpath("@href", person) end)
|
||||
:xmerl_xpath.string(
|
||||
'//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]',
|
||||
entry
|
||||
)
|
||||
|> Enum.map(fn person -> XML.string_from_xpath("@href", person) end)
|
||||
end
|
||||
|
||||
def get_collection_mentions(entry) do
|
||||
transmogrify = fn
|
||||
("http://activityschema.org/collection/public") ->
|
||||
"http://activityschema.org/collection/public" ->
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
(group) ->
|
||||
|
||||
group ->
|
||||
group
|
||||
end
|
||||
|
||||
:xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"]', entry)
|
||||
|> Enum.map(fn(collection) -> XML.string_from_xpath("@href", collection) |> transmogrify.() end)
|
||||
:xmerl_xpath.string(
|
||||
'//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"]',
|
||||
entry
|
||||
)
|
||||
|> Enum.map(fn collection -> XML.string_from_xpath("@href", collection) |> transmogrify.() end)
|
||||
end
|
||||
|
||||
def get_mentions(entry) do
|
||||
(get_people_mentions(entry)
|
||||
++ get_collection_mentions(entry))
|
||||
|> Enum.filter(&(&1))
|
||||
(get_people_mentions(entry) ++ get_collection_mentions(entry))
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
|
||||
def get_emoji(entry) do
|
||||
try do
|
||||
:xmerl_xpath.string('//link[@rel="emoji"]', entry)
|
||||
|> Enum.reduce(%{}, fn(emoji, acc) ->
|
||||
|> Enum.reduce(%{}, fn emoji, acc ->
|
||||
Map.put(acc, XML.string_from_xpath("@name", emoji), XML.string_from_xpath("@href", emoji))
|
||||
end)
|
||||
rescue
|
||||
|
|
@ -79,7 +86,8 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
|
|||
activity
|
||||
else
|
||||
_e ->
|
||||
with inReplyToHref when not is_nil(inReplyToHref) <- XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry),
|
||||
with inReplyToHref when not is_nil(inReplyToHref) <-
|
||||
XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry),
|
||||
{:ok, [activity | _]} <- OStatus.fetch_activity_from_url(inReplyToHref) do
|
||||
activity
|
||||
else
|
||||
|
|
@ -107,16 +115,40 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
|
|||
date <- XML.string_from_xpath("//published", entry),
|
||||
unlisted <- XML.string_from_xpath("//mastodon:scope", entry) == "unlisted",
|
||||
cc <- if(unlisted, do: ["https://www.w3.org/ns/activitystreams#Public"], else: []),
|
||||
note <- CommonAPI.Utils.make_note_data(actor.ap_id, to, context, content_html, attachments, inReplyToActivity, [], cw),
|
||||
note <-
|
||||
CommonAPI.Utils.make_note_data(
|
||||
actor.ap_id,
|
||||
to,
|
||||
context,
|
||||
content_html,
|
||||
attachments,
|
||||
inReplyToActivity,
|
||||
[],
|
||||
cw
|
||||
),
|
||||
note <- note |> Map.put("id", id) |> Map.put("tag", tags),
|
||||
note <- note |> Map.put("published", date),
|
||||
note <- note |> Map.put("emoji", get_emoji(entry)),
|
||||
note <- add_external_url(note, entry),
|
||||
note <- note |> Map.put("cc", cc),
|
||||
# TODO: Handle this case in make_note_data
|
||||
note <- (if inReplyTo && !inReplyToActivity, do: note |> Map.put("inReplyTo", inReplyTo), else: note)
|
||||
do
|
||||
res = ActivityPub.create(%{to: to, actor: actor, context: context, object: note, published: date, local: false, additional: %{"cc" => cc}})
|
||||
note <-
|
||||
if(
|
||||
inReplyTo && !inReplyToActivity,
|
||||
do: note |> Map.put("inReplyTo", inReplyTo),
|
||||
else: note
|
||||
) do
|
||||
res =
|
||||
ActivityPub.create(%{
|
||||
to: to,
|
||||
actor: actor,
|
||||
context: context,
|
||||
object: note,
|
||||
published: date,
|
||||
local: false,
|
||||
additional: %{"cc" => cc}
|
||||
})
|
||||
|
||||
User.increase_note_count(actor)
|
||||
res
|
||||
else
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ defmodule Pleroma.Web.OStatus do
|
|||
end
|
||||
|
||||
def pubsub_path(user) do
|
||||
"#{Web.base_url}/push/hub/#{user.nickname}"
|
||||
"#{Web.base_url()}/push/hub/#{user.nickname}"
|
||||
end
|
||||
|
||||
def salmon_path(user) do
|
||||
|
|
@ -24,48 +24,59 @@ defmodule Pleroma.Web.OStatus do
|
|||
end
|
||||
|
||||
def remote_follow_path do
|
||||
"#{Web.base_url}/ostatus_subscribe?acct={uri}"
|
||||
"#{Web.base_url()}/ostatus_subscribe?acct={uri}"
|
||||
end
|
||||
|
||||
def handle_incoming(xml_string) do
|
||||
with doc when doc != :error <- parse_document(xml_string) do
|
||||
entries = :xmerl_xpath.string('//entry', doc)
|
||||
|
||||
activities = Enum.map(entries, fn (entry) ->
|
||||
{:xmlObj, :string, object_type} = :xmerl_xpath.string('string(/entry/activity:object-type[1])', entry)
|
||||
{:xmlObj, :string, verb} = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry)
|
||||
Logger.debug("Handling #{verb}")
|
||||
activities =
|
||||
Enum.map(entries, fn entry ->
|
||||
{:xmlObj, :string, object_type} =
|
||||
:xmerl_xpath.string('string(/entry/activity:object-type[1])', entry)
|
||||
|
||||
try do
|
||||
case verb do
|
||||
'http://activitystrea.ms/schema/1.0/delete' ->
|
||||
with {:ok, activity} <- DeleteHandler.handle_delete(entry, doc), do: activity
|
||||
'http://activitystrea.ms/schema/1.0/follow' ->
|
||||
with {:ok, activity} <- FollowHandler.handle(entry, doc), do: activity
|
||||
'http://activitystrea.ms/schema/1.0/share' ->
|
||||
with {:ok, activity, retweeted_activity} <- handle_share(entry, doc), do: [activity, retweeted_activity]
|
||||
'http://activitystrea.ms/schema/1.0/favorite' ->
|
||||
with {:ok, activity, favorited_activity} <- handle_favorite(entry, doc), do: [activity, favorited_activity]
|
||||
_ ->
|
||||
case object_type do
|
||||
'http://activitystrea.ms/schema/1.0/note' ->
|
||||
with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
|
||||
'http://activitystrea.ms/schema/1.0/comment' ->
|
||||
with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
|
||||
_ ->
|
||||
Logger.error("Couldn't parse incoming document")
|
||||
nil
|
||||
end
|
||||
{:xmlObj, :string, verb} = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry)
|
||||
Logger.debug("Handling #{verb}")
|
||||
|
||||
try do
|
||||
case verb do
|
||||
'http://activitystrea.ms/schema/1.0/delete' ->
|
||||
with {:ok, activity} <- DeleteHandler.handle_delete(entry, doc), do: activity
|
||||
|
||||
'http://activitystrea.ms/schema/1.0/follow' ->
|
||||
with {:ok, activity} <- FollowHandler.handle(entry, doc), do: activity
|
||||
|
||||
'http://activitystrea.ms/schema/1.0/share' ->
|
||||
with {:ok, activity, retweeted_activity} <- handle_share(entry, doc),
|
||||
do: [activity, retweeted_activity]
|
||||
|
||||
'http://activitystrea.ms/schema/1.0/favorite' ->
|
||||
with {:ok, activity, favorited_activity} <- handle_favorite(entry, doc),
|
||||
do: [activity, favorited_activity]
|
||||
|
||||
_ ->
|
||||
case object_type do
|
||||
'http://activitystrea.ms/schema/1.0/note' ->
|
||||
with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
|
||||
|
||||
'http://activitystrea.ms/schema/1.0/comment' ->
|
||||
with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
|
||||
|
||||
_ ->
|
||||
Logger.error("Couldn't parse incoming document")
|
||||
nil
|
||||
end
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("Error occured while handling activity")
|
||||
Logger.error(xml_string)
|
||||
Logger.error(inspect(e))
|
||||
nil
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("Error occured while handling activity")
|
||||
Logger.error(xml_string)
|
||||
Logger.error(inspect(e))
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(&(&1))
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
{:ok, activities}
|
||||
else
|
||||
|
|
@ -113,15 +124,20 @@ defmodule Pleroma.Web.OStatus do
|
|||
|
||||
def get_or_try_fetching(entry) do
|
||||
Logger.debug("Trying to get entry from db")
|
||||
|
||||
with id when not is_nil(id) <- string_from_xpath("//activity:object[1]/id", entry),
|
||||
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
|
||||
{:ok, activity}
|
||||
else _ ->
|
||||
else
|
||||
_ ->
|
||||
Logger.debug("Couldn't get, will try to fetch")
|
||||
with href when not is_nil(href) <- string_from_xpath("//activity:object[1]/link[@type=\"text/html\"]/@href", entry),
|
||||
|
||||
with href when not is_nil(href) <-
|
||||
string_from_xpath("//activity:object[1]/link[@type=\"text/html\"]/@href", entry),
|
||||
{:ok, [favorited_activity]} <- fetch_activity_from_url(href) do
|
||||
{:ok, favorited_activity}
|
||||
else e -> Logger.debug("Couldn't find href: #{inspect(e)}")
|
||||
else
|
||||
e -> Logger.debug("Couldn't find href: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -137,20 +153,22 @@ defmodule Pleroma.Web.OStatus do
|
|||
|
||||
def get_attachments(entry) do
|
||||
:xmerl_xpath.string('/entry/link[@rel="enclosure"]', entry)
|
||||
|> Enum.map(fn (enclosure) ->
|
||||
|> Enum.map(fn enclosure ->
|
||||
with href when not is_nil(href) <- string_from_xpath("/link/@href", enclosure),
|
||||
type when not is_nil(type) <- string_from_xpath("/link/@type", enclosure) do
|
||||
%{
|
||||
"type" => "Attachment",
|
||||
"url" => [%{
|
||||
"type" => "Link",
|
||||
"mediaType" => type,
|
||||
"href" => href
|
||||
}]
|
||||
"url" => [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"mediaType" => type,
|
||||
"href" => href
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(&(&1))
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
@ -166,14 +184,15 @@ defmodule Pleroma.Web.OStatus do
|
|||
def get_cw(entry) do
|
||||
with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do
|
||||
cw
|
||||
else _e -> nil
|
||||
else
|
||||
_e -> nil
|
||||
end
|
||||
end
|
||||
|
||||
def get_tags(entry) do
|
||||
:xmerl_xpath.string('//category', entry)
|
||||
|> Enum.map(fn (category) -> string_from_xpath("/category/@term", category) end)
|
||||
|> Enum.filter(&(&1))
|
||||
|> Enum.map(fn category -> string_from_xpath("/category/@term", category) end)
|
||||
|> Enum.filter(& &1)
|
||||
|> Enum.map(&String.downcase/1)
|
||||
end
|
||||
|
||||
|
|
@ -184,6 +203,7 @@ defmodule Pleroma.Web.OStatus do
|
|||
maybe_update_ostatus(doc, user)
|
||||
end
|
||||
end
|
||||
|
||||
def maybe_update_ostatus(doc, user) do
|
||||
old_data = %{
|
||||
avatar: user.avatar,
|
||||
|
|
@ -196,26 +216,33 @@ defmodule Pleroma.Web.OStatus do
|
|||
avatar <- make_avatar_object(doc),
|
||||
bio <- string_from_xpath("//author[1]/summary", doc),
|
||||
name <- string_from_xpath("//author[1]/poco:displayName", doc),
|
||||
info <- Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
|
||||
new_data <- %{avatar: avatar || old_data.avatar, name: name || old_data.name, bio: bio || old_data.bio, info: info || old_data.info},
|
||||
info <-
|
||||
Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
|
||||
new_data <- %{
|
||||
avatar: avatar || old_data.avatar,
|
||||
name: name || old_data.name,
|
||||
bio: bio || old_data.bio,
|
||||
info: info || old_data.info
|
||||
},
|
||||
false <- new_data == old_data do
|
||||
change = Ecto.Changeset.change(user, new_data)
|
||||
Repo.update(change)
|
||||
else _ ->
|
||||
{:ok, user}
|
||||
else
|
||||
_ ->
|
||||
{:ok, user}
|
||||
end
|
||||
end
|
||||
|
||||
def find_make_or_update_user(doc) do
|
||||
uri = string_from_xpath("//author/uri[1]", doc)
|
||||
|
||||
with {:ok, user} <- find_or_make_user(uri) do
|
||||
maybe_update(doc, user)
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_make_user(uri) do
|
||||
query = from user in User,
|
||||
where: user.ap_id == ^uri
|
||||
query = from(user in User, where: user.ap_id == ^uri)
|
||||
|
||||
user = Repo.one(query)
|
||||
|
||||
|
|
@ -236,10 +263,12 @@ defmodule Pleroma.Web.OStatus do
|
|||
avatar: info["avatar"],
|
||||
bio: info["bio"]
|
||||
}
|
||||
|
||||
with false <- update,
|
||||
%User{} = user <- User.get_by_ap_id(data.ap_id) do
|
||||
{:ok, user}
|
||||
else _e -> User.insert_or_update_user(data)
|
||||
else
|
||||
_e -> User.insert_or_update_user(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -252,12 +281,13 @@ defmodule Pleroma.Web.OStatus do
|
|||
if href do
|
||||
%{
|
||||
"type" => "Image",
|
||||
"url" =>
|
||||
[%{
|
||||
"type" => "Link",
|
||||
"mediaType" => type,
|
||||
"href" => href
|
||||
}]
|
||||
"url" => [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"mediaType" => type,
|
||||
"href" => href
|
||||
}
|
||||
]
|
||||
}
|
||||
else
|
||||
nil
|
||||
|
|
@ -268,9 +298,10 @@ defmodule Pleroma.Web.OStatus do
|
|||
with {:ok, webfinger_data} <- WebFinger.finger(username),
|
||||
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do
|
||||
{:ok, Map.merge(webfinger_data, feed_data) |> Map.put("fqn", username)}
|
||||
else e ->
|
||||
Logger.debug(fn -> "Couldn't gather info for #{username}" end)
|
||||
{:error, e}
|
||||
else
|
||||
e ->
|
||||
Logger.debug(fn -> "Couldn't gather info for #{username}" end)
|
||||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -284,12 +315,15 @@ defmodule Pleroma.Web.OStatus do
|
|||
Regex.match?(@mastodon_regex, body) ->
|
||||
[[_, match]] = Regex.scan(@mastodon_regex, body)
|
||||
{:ok, match}
|
||||
|
||||
Regex.match?(@gs_regex, body) ->
|
||||
[[_, match]] = Regex.scan(@gs_regex, body)
|
||||
{:ok, match}
|
||||
|
||||
Regex.match?(@gs_classic_regex, body) ->
|
||||
[[_, match]] = Regex.scan(@gs_classic_regex, body)
|
||||
{:ok, match}
|
||||
|
||||
true ->
|
||||
Logger.debug(fn -> "Couldn't find Atom link in #{inspect(body)}" end)
|
||||
{:error, "Couldn't find the Atom link"}
|
||||
|
|
@ -298,7 +332,14 @@ defmodule Pleroma.Web.OStatus do
|
|||
|
||||
def fetch_activity_from_atom_url(url) do
|
||||
with true <- String.starts_with?(url, "http"),
|
||||
{:ok, %{body: body, status_code: code}} when code in 200..299 <- @httpoison.get(url, [Accept: "application/atom+xml"], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
|
||||
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
|
||||
@httpoison.get(
|
||||
url,
|
||||
[Accept: "application/atom+xml"],
|
||||
follow_redirect: true,
|
||||
timeout: 10000,
|
||||
recv_timeout: 20000
|
||||
) do
|
||||
Logger.debug("Got document from #{url}, handling...")
|
||||
handle_incoming(body)
|
||||
else
|
||||
|
|
@ -310,10 +351,12 @@ defmodule Pleroma.Web.OStatus do
|
|||
|
||||
def fetch_activity_from_html_url(url) do
|
||||
Logger.debug("Trying to fetch #{url}")
|
||||
|
||||
with true <- String.starts_with?(url, "http"),
|
||||
{:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
|
||||
{:ok, %{body: body}} <-
|
||||
@httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
|
||||
{:ok, atom_url} <- get_atom_url(body) do
|
||||
fetch_activity_from_atom_url(atom_url)
|
||||
fetch_activity_from_atom_url(atom_url)
|
||||
else
|
||||
e ->
|
||||
Logger.debug("Couldn't get #{url}: #{inspect(e)}")
|
||||
|
|
@ -326,9 +369,10 @@ defmodule Pleroma.Web.OStatus do
|
|||
with {:ok, activities} when length(activities) > 0 <- fetch_activity_from_atom_url(url) do
|
||||
{:ok, activities}
|
||||
else
|
||||
_e -> with {:ok, activities} <- fetch_activity_from_html_url(url) do
|
||||
{:ok, activities}
|
||||
end
|
||||
_e ->
|
||||
with {:ok, activities} <- fetch_activity_from_html_url(url) do
|
||||
{:ok, activities}
|
||||
end
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
|
|
|
|||
|
|
@ -16,23 +16,26 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|
|||
case get_format(conn) do
|
||||
"html" -> Fallback.RedirectController.redirector(conn, nil)
|
||||
"activity+json" -> ActivityPubController.user(conn, params)
|
||||
_ -> redirect conn, external: OStatus.feed_path(user)
|
||||
_ -> redirect(conn, external: OStatus.feed_path(user))
|
||||
end
|
||||
end
|
||||
|
||||
def feed(conn, %{"nickname" => nickname} = params) do
|
||||
user = User.get_cached_by_nickname(nickname)
|
||||
|
||||
query_params = Map.take(params, ["max_id"])
|
||||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
|
||||
query_params =
|
||||
Map.take(params, ["max_id"])
|
||||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
|
||||
|
||||
activities = ActivityPub.fetch_public_activities(query_params)
|
||||
|> Enum.reverse
|
||||
activities =
|
||||
ActivityPub.fetch_public_activities(query_params)
|
||||
|> Enum.reverse()
|
||||
|
||||
response = user
|
||||
|> FeedRepresenter.to_simple_form(activities, [user])
|
||||
|> :xmerl.export_simple(:xmerl_xml)
|
||||
|> to_string
|
||||
response =
|
||||
user
|
||||
|> FeedRepresenter.to_simple_form(activities, [user])
|
||||
|> :xmerl.export_simple(:xmerl_xml)
|
||||
|> to_string
|
||||
|
||||
conn
|
||||
|> put_resp_content_type("application/atom+xml")
|
||||
|
|
@ -73,7 +76,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|
|||
else
|
||||
with id <- o_status_url(conn, :object, uuid),
|
||||
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id),
|
||||
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
||||
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
||||
case get_format(conn) do
|
||||
"html" -> redirect(conn, to: "/notice/#{activity.id}")
|
||||
_ -> represent_activity(conn, activity, user)
|
||||
|
|
@ -96,24 +99,27 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|
|||
|
||||
# TODO: Data leak
|
||||
def notice(conn, %{"id" => id}) do
|
||||
with %Activity{} = activity <- Repo.get(Activity, id),
|
||||
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
||||
with %Activity{} = activity <- Repo.get(Activity, id),
|
||||
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
||||
case get_format(conn) do
|
||||
"html" ->
|
||||
conn
|
||||
|> put_resp_content_type("text/html")
|
||||
|> send_file(200, "priv/static/index.html")
|
||||
_ -> represent_activity(conn, activity, user)
|
||||
|
||||
_ ->
|
||||
represent_activity(conn, activity, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp represent_activity(conn, activity, user) do
|
||||
response = activity
|
||||
|> ActivityRepresenter.to_simple_form(user, true)
|
||||
|> ActivityRepresenter.wrap_with_entry
|
||||
|> :xmerl.export_simple(:xmerl_xml)
|
||||
|> to_string
|
||||
response =
|
||||
activity
|
||||
|> ActivityRepresenter.to_simple_form(user, true)
|
||||
|> ActivityRepresenter.wrap_with_entry()
|
||||
|> :xmerl.export_simple(:xmerl_xml)
|
||||
|> to_string
|
||||
|
||||
conn
|
||||
|> put_resp_content_type("application/atom+xml")
|
||||
|
|
|
|||
|
|
@ -1,22 +1,26 @@
|
|||
defmodule Pleroma.Web.OStatus.UserRepresenter do
|
||||
alias Pleroma.User
|
||||
|
||||
def to_simple_form(user) do
|
||||
ap_id = to_charlist(user.ap_id)
|
||||
nickname = to_charlist(user.nickname)
|
||||
name = to_charlist(user.name)
|
||||
bio = to_charlist(user.bio)
|
||||
avatar_url = to_charlist(User.avatar_url(user))
|
||||
banner = if banner_url = User.banner_url(user) do
|
||||
[{:link, [rel: 'header', href: banner_url], []}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
ap_enabled = if user.local do
|
||||
[{:ap_enabled, ['true']}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
banner =
|
||||
if banner_url = User.banner_url(user) do
|
||||
[{:link, [rel: 'header', href: banner_url], []}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
ap_enabled =
|
||||
if user.local do
|
||||
[{:ap_enabled, ['true']}]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
[
|
||||
{:id, [ap_id]},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue