More tests

This commit is contained in:
Thomas Citharel
2018-08-24 11:34:00 +02:00
parent a3852f26c1
commit 686cf04787
29 changed files with 945 additions and 241 deletions

View File

@@ -6,7 +6,7 @@ defmodule Eventos.Service.ActivityPub do
"""
alias Eventos.Events
alias Eventos.Events.{Event, Category}
alias Eventos.Events.{Event, Category, Comment}
alias Eventos.Service.ActivityPub.Transmogrifier
alias Eventos.Service.WebFinger
alias Eventos.Activity
@@ -44,36 +44,65 @@ defmodule Eventos.Service.ActivityPub do
end
end
def fetch_event_from_url(url) do
if object = Events.get_event_by_url!(url) do
{:ok, object}
def fetch_object_from_url(url, :event), do: fetch_event_from_url(url)
def fetch_object_from_url(url, :note), do: fetch_note_from_url(url)
@spec fetch_object_from_url(String.t()) :: tuple()
def fetch_object_from_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/activity+json"],
follow_redirect: true,
timeout: 10_000,
recv_timeout: 20_000
),
{:ok, data} <- Jason.decode(body),
nil <- Events.get_event_by_url(data["id"]),
nil <- Events.get_comment_from_url(data["id"]),
params <- %{
"type" => "Create",
"to" => data["to"],
"cc" => data["cc"],
"actor" => data["attributedTo"],
"object" => data
},
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
case data["type"] do
"Event" ->
{:ok, Events.get_event_by_url!(activity.data["object"]["id"])}
"Note" ->
{:ok, Events.get_comment_from_url!(activity.data["object"]["id"])}
end
else
object = %Event{} -> {:ok, object}
object = %Comment{} -> {:ok, object}
e -> {:error, e}
end
end
@spec fetch_object_from_url(String.t()) :: tuple()
def fetch_event_from_url(url) do
with nil <- Events.get_event_by_url(url) do
Logger.info("Fetching #{url} via AP")
fetch_object_from_url(url)
else
%Event{} = comment ->
{:ok, comment}
end
end
@spec fetch_object_from_url(String.t()) :: tuple()
def fetch_note_from_url(url) do
with nil <- Events.get_comment_from_url(url) do
Logger.info("Fetching #{url} via AP")
with true <- String.starts_with?(url, "http"),
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
HTTPoison.get(
url,
[Accept: "application/activity+json"],
follow_redirect: true,
timeout: 10_000,
recv_timeout: 20_000
),
{:ok, data} <- Jason.decode(body),
nil <- Events.get_event_by_url!(data["id"]),
params <- %{
"type" => "Create",
"to" => data["to"],
"cc" => data["cc"],
"actor" => data["attributedTo"],
"object" => data
},
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
{:ok, Events.get_event_by_url!(activity.data["object"]["id"])}
else
object = %Event{} -> {:ok, object}
e -> e
end
fetch_object_from_url(url)
else
%Comment{} = comment ->
{:ok, comment}
end
end
@@ -127,7 +156,7 @@ defmodule Eventos.Service.ActivityPub do
end
end
def follow(follower, followed, activity_id \\ nil, local \\ true) do
def follow(%Actor{} = follower, %Actor{} = followed, activity_id \\ nil, local \\ true) do
with data <- make_follow_data(follower, followed, activity_id),
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity) do
@@ -135,7 +164,9 @@ defmodule Eventos.Service.ActivityPub do
end
end
def delete(%Event{url: url, organizer_actor: actor} = event, local \\ true) do
def delete(object, local \\ true)
def delete(%Event{url: url, organizer_actor: actor} = event, local) do
data = %{
"type" => "Delete",
"actor" => actor.url,
@@ -150,6 +181,21 @@ defmodule Eventos.Service.ActivityPub do
end
end
def delete(%Comment{url: url, actor: actor} = comment, local) do
data = %{
"type" => "Delete",
"actor" => actor.url,
"object" => url,
"to" => [actor.url <> "/followers", "https://www.w3.org/ns/activitystreams#Public"]
}
with Events.delete_comment(comment),
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
def create_public_activities(%Actor{} = actor) do
end
@@ -285,13 +331,22 @@ defmodule Eventos.Service.ActivityPub do
case actor.type do
:Person ->
{:ok, events, total} = Events.get_events_for_actor(actor, page, limit)
{:ok, comments, total} = Events.get_comments_for_actor(actor, page, limit)
activities =
event_activities =
Enum.map(events, fn event ->
{:ok, activity} = event_to_activity(event)
activity
end)
comment_activities =
Enum.map(comments, fn comment ->
{:ok, activity} = comment_to_activity(comment)
activity
end)
activities = event_activities ++ comment_activities
{activities, total}
:Service ->
@@ -322,6 +377,7 @@ defmodule Eventos.Service.ActivityPub do
defp event_to_activity(%Event{} = event, local \\ true) do
activity = %Activity{
type: :Event,
data: event,
local: local,
actor: event.organizer_actor.url,
@@ -333,6 +389,20 @@ defmodule Eventos.Service.ActivityPub do
{:ok, activity}
end
defp comment_to_activity(%Comment{} = comment, local \\ true) do
activity = %Activity{
type: :Comment,
data: comment,
local: local,
actor: comment.actor.url,
recipients: ["https://www.w3.org/ns/activitystreams#Public"]
}
# Notification.create_notifications(activity)
# stream_out(activity)
{:ok, activity}
end
defp ical_event_to_activity(%ExIcal.Event{} = ical_event, %Actor{} = actor, source) do
# Logger.debug(inspect ical_event)
# TODO : refactor me !

View File

@@ -4,7 +4,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
"""
alias Eventos.Actors.Actor
alias Eventos.Actors
alias Eventos.Events.Event
alias Eventos.Events.{Event, Comment}
alias Eventos.Service.ActivityPub
import Ecto.Query
@@ -77,9 +77,9 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
# - tags
# - emoji
def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do
Logger.debug("Handle incoming to create notes")
Logger.info("Handle incoming to create notes")
with %Actor{} = actor <- Actor.get_or_fetch_by_url(data["actor"]) do
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(data["actor"]) do
Logger.debug("found actor")
object = fix_object(data["object"])
@@ -104,8 +104,8 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data
) do
with %Actor{} = followed <- Actors.get_actor_by_url(followed),
%Actor{} = follower <- Actors.get_or_fetch_by_url(follower),
with {:ok, %Actor{} = followed} <- Actors.get_or_fetch_by_url(followed),
{:ok, %Actor{} = follower} <- Actors.get_or_fetch_by_url(follower),
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
ActivityPub.accept(%{to: [follower.url], actor: followed.url, object: data, local: true})
@@ -133,7 +133,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
def handle_incoming(
%{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data
) do
with %Actor{} = actor <- Actors.get_or_fetch_by_url(actor),
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(actor),
{:ok, object} <-
get_obj_helper(object_id) || ActivityPub.fetch_event_from_url(object_id),
{:ok, activity, object} <- ActivityPub.announce(actor, object, id, false) do
@@ -268,6 +268,17 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
{:ok, event}
end
def prepare_outgoing(%Comment{} = comment) do
comment =
comment
|> Map.from_struct()
|> Map.drop([:__meta__])
|> Map.put(:"@context", "https://www.w3.org/ns/activitystreams")
|> prepare_object
{:ok, comment}
end
#
# def maybe_fix_object_url(data) do
# if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do

View File

@@ -132,20 +132,23 @@ defmodule Eventos.Service.ActivityPub.Utils do
"""
def insert_full_object(%{"object" => %{"type" => type} = object_data})
when is_map(object_data) and type == "Note" do
import Logger
Logger.debug("insert full object")
Logger.debug(inspect(object_data))
actor = Actors.get_actor_by_url(object_data["actor"])
with {:ok, %Actor{id: actor_id}} <- Actors.get_or_fetch_by_url(object_data["actor"]) do
data = %{
"text" => object_data["content"],
"url" => object_data["id"],
"actor_id" => actor_id,
"in_reply_to_comment_id" => object_data["inReplyTo"]
}
data = %{
"text" => object_data["content"],
"url" => object_data["id"],
"actor_id" => actor.id,
"in_reply_to_comment_id" => object_data["inReplyTo"]
}
require Logger
Logger.info("comment data ready to be inserted")
Logger.info(inspect(data))
with {:ok, _} <- Events.create_comment(data) do
:ok
with {:ok, comm} <- Events.create_comment(data) do
Logger.info("comment inserted")
Logger.info(inspect(comm))
:ok
end
end
end