+ query = if opts["local_only"] do
+ from activity in query, where: activity.local == true
+ else
+ query
+ end
+
+ query = if opts["max_id"] do
+ from activity in query, where: activity.id < ^opts["max_id"]
+ else
+ query
+ end
+
+ query = if opts["actor_id"] do
+ from activity in query,
+ where: fragment("? @> ?", activity.data, ^%{actor: opts["actor_id"]})
+ else
+ query
+ end
+
+ Enum.reverse(Repo.all(query))
+ end
+
+ def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, activity_id \\ nil, local \\ true) do
+ data = %{
+ "type" => "Announce",
+ "actor" => ap_id,
+ "object" => id,
+ "to" => [User.ap_followers(user), object.data["actor"]],
+ "context" => object.data["context"]
+ }
+
+ data = if activity_id, do: Map.put(data, "id", activity_id), else: data
+
+ {:ok, activity} = insert(data, local)
+
+ announcements = [ap_id | (object.data["announcements"] || [])] |> Enum.uniq
+
+ new_data = object.data
+ |> Map.put("announcement_count", length(announcements))
+ |> Map.put("announcements", announcements)
+
+ changeset = Changeset.change(object, data: new_data)
+ {:ok, object} = Repo.update(changeset)
+
+ update_object_in_activities(object)
+
+ if user.local do
+ Pleroma.Web.Federator.enqueue(:publish, activity)
+ end
+
+ {:ok, activity, object}
+ end
+
+ def follow(%User{ap_id: follower_id, local: actor_local}, %User{ap_id: followed_id}, local \\ true) do
+ data = %{
+ "type" => "Follow",
+ "actor" => follower_id,
+ "to" => [followed_id],
+ "object" => followed_id,
+ "published" => make_date()
+ }
+
+ with {:ok, activity} <- insert(data, local) do
+ if actor_local do
+ Pleroma.Web.Federator.enqueue(:publish, activity)
+ end
+
+ {:ok, activity}
+ end
+ end
+
+ def unfollow(follower, followed, local \\ true) do
+ with follow_activity when not is_nil(follow_activity) <- fetch_latest_follow(follower, followed) do
+ data = %{
+ "type" => "Undo",
+ "actor" => follower.ap_id,
+ "to" => [followed.ap_id],
+ "object" => follow_activity.data["id"],
+ "published" => make_date()
+ }
+
+ with {:ok, activity} <- insert(data, local) do
+ if follower.local do
+ Pleroma.Web.Federator.enqueue(:publish, activity)
+ end
+
+ {:ok, activity}
+ end
+ end