end
def subscribe(subscriber, %{ap_id: ap_id}) do
- info_cng =
- subscriber.info
- |> User.Info.add_to_subscriptions(ap_id)
+ with %User{} = user <- get_or_fetch_by_ap_id(ap_id) do
+ info_cng =
+ user.info
+ |> User.Info.add_to_subscribers(subscriber.ap_id)
- change(subscriber)
- |> put_embed(:info, info_cng)
- |> update_and_set_cache()
+ change(user)
+ |> put_embed(:info, info_cng)
+ |> update_and_set_cache()
+ end
end
def unsubscribe(unsubscriber, %{ap_id: ap_id}) do
- info_cng =
- unsubscriber.info
- |> User.Info.remove_from_subscriptions(ap_id)
+ with %User{} = user <- get_or_fetch_by_ap_id(ap_id) do
+ info_cng =
+ user.info
+ |> User.Info.remove_from_subscribers(unsubscriber.ap_id)
- change(unsubscriber)
- |> put_embed(:info, info_cng)
- |> update_and_set_cache()
+ change(user)
+ |> put_embed(:info, info_cng)
+ |> update_and_set_cache()
+ end
end
def block(blocker, %User{ap_id: ap_id} = blocked) do
end
def subscribed_to?(user, %{ap_id: ap_id}) do
- subs = user.info.subscriptions
- Enum.member?(subs, ap_id)
+ with %User{} = target <- User.get_by_ap_id(ap_id) do
+ Enum.member?(target.info.subscribers, user.ap_id)
+ end
end
def muted_users(user),
def blocked_users(user),
do: Repo.all(from(u in User, where: u.ap_id in ^user.info.blocks))
- def subscribed_users(user),
- do:
- Repo.all(
- from(u in User,
- where: fragment("?->'subscriptions' @> ?", u.info, ^user.ap_id)
- )
- )
+ def subscribers(user),
+ do: Repo.all(from(u in User, where: u.ap_id in ^user.info.subscribers))
def block_domain(user, domain) do
info_cng =
field(:domain_blocks, {:array, :string}, default: [])
field(:mutes, {:array, :string}, default: [])
field(:muted_reblogs, {:array, :string}, default: [])
- field(:subscriptions, {:array, :string}, default: [])
+ field(:subscribers, {:array, :string}, default: [])
field(:deactivated, :boolean, default: false)
field(:no_rich_text, :boolean, default: false)
field(:ap_enabled, :boolean, default: false)
|> validate_required([:blocks])
end
- def set_subscriptions(info, subscriptions) do
- params = %{subscriptions: subscriptions}
+ def set_subscribers(info, subscribers) do
+ params = %{subscribers: subscribers}
info
- |> cast(params, [:subscriptions])
- |> validate_required([:subscriptions])
+ |> cast(params, [:subscribers])
+ |> validate_required([:subscribers])
end
def add_to_mutes(info, muted) do
set_blocks(info, List.delete(info.blocks, blocked))
end
- def add_to_subscriptions(info, subscribed) do
- set_subscriptions(info, Enum.uniq([subscribed | info.subscriptions]))
+ def add_to_subscribers(info, subscribed) do
+ set_subscribers(info, Enum.uniq([subscribed | info.subscribers]))
end
- def remove_from_subscriptions(info, subscribed) do
- set_subscriptions(info, List.delete(info.subscriptions, subscribed))
+ def remove_from_subscribers(info, subscribed) do
+ set_subscribers(info, List.delete(info.subscribers, subscribed))
end
def set_domain_blocks(info, domain_blocks) do
with %User{} = user <- User.get_by_ap_id(actor) do
subscriber_ids =
user
- |> User.subscribed_users()
+ |> User.subscribers()
|> Enum.map(& &1.ap_id)
recipients ++ subscriber_ids
json(conn, %{})
end
+ def subscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+ with %User{} = subscription_target <- User.get_by_id(id) do
+ {:ok, subscription_target} = User.subscribe(user, subscription_target)
+
+ conn
+ |> put_view(AccountView)
+ |> render("relationship.json", %{user: user, target: subscription_target})
+ end
+ end
+
+ def unsubscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+ with %User{} = subscription_target <- User.get_by_id(id) do
+ {:ok, subscription_target} = User.unsubscribe(user, subscription_target)
+
+ conn
+ |> put_view(AccountView)
+ |> render("relationship.json", %{user: user, target: subscription_target})
+ end
+ end
+
def status_search(user, query) do
fetched =
if Regex.match?(~r/https?:/, query) do
blocking: User.blocks?(user, target),
muting: User.mutes?(user, target),
muting_notifications: false,
+ subscribing: User.subscribed_to?(user, target),
requested: requested,
domain_blocking: false,
showing_reblogs: User.showing_reblogs?(user, target),
post("/domain_blocks", MastodonAPIController, :block_domain)
delete("/domain_blocks", MastodonAPIController, :unblock_domain)
+
+ post("/pleroma/accounts/:id/subscribe", MastodonAPIController, :subscribe)
+ post("/pleroma/accounts/:id/unsubscribe", MastodonAPIController, :unsubscribe)
end
scope [] do
post("/pleroma/friendships/approve", TwitterAPI.Controller, :approve_friend_request)
post("/pleroma/friendships/deny", TwitterAPI.Controller, :deny_friend_request)
- post("/pleroma/subscriptions/create", TwitterAPI.Controller, :subscribe)
- post("/pleroma/subscriptions/destroy", TwitterAPI.Controller, :unsubscribe)
-
post("/friendships/create", TwitterAPI.Controller, :follow)
post("/friendships/destroy", TwitterAPI.Controller, :unfollow)
end
end
- def subscribe(%User{} = subscriber, params) do
- with {:ok, %User{} = subscribed} <- get_user(params),
- {:ok, subscriber} <- User.subscribe(subscriber, subscribed) do
- {:ok, subscriber, subscribed}
- end
- end
-
- def unsubscribe(%User{} = unsubscriber, params) do
- with {:ok, %User{} = unsubscribed} <- get_user(params),
- {:ok, unsubscriber} <- User.unsubscribe(unsubscriber, unsubscribed) do
- {:ok, unsubscriber, unsubscribed}
- end
- end
-
def repeat(%User{} = user, ap_id_or_id) do
with {:ok, _announce, %{data: %{"id" => id}}} <- CommonAPI.repeat(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
end
end
- def subscribe(%{assigns: %{user: user}} = conn, params) do
- case TwitterAPI.subscribe(user, params) do
- {:ok, user, subscribed} ->
- conn
- |> put_view(UserView)
- |> render("show.json", %{user: subscribed, for: user})
-
- {:error, msg} ->
- forbidden_json_reply(conn, msg)
- end
- end
-
- def unsubscribe(%{assigns: %{user: user}} = conn, params) do
- case TwitterAPI.unsubscribe(user, params) do
- {:ok, user, unsubscribed} ->
- conn
- |> put_view(UserView)
- |> render("show.json", %{user: unsubscribed, for: user})
-
- {:error, msg} ->
- forbidden_json_reply(conn, msg)
- end
- end
-
def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Activity.get_by_id(id),
true <- Visibility.visible_for_user?(activity, user) do
for_user = assigns[:for]
image = User.avatar_url(user) |> MediaProxy.url()
- {following, follows_you, statusnet_blocking, subscribed} =
+ {following, follows_you, statusnet_blocking} =
if for_user do
{
User.following?(for_user, user),
User.following?(user, for_user),
- User.blocks?(for_user, user),
- User.subscribed_to?(for_user, user)
+ User.blocks?(for_user, user)
}
else
- {false, false, false, false}
+ {false, false, false}
end
user_info = User.get_cached_user_info(user)
"pleroma" =>
%{
"confirmation_pending" => user_info.confirmation_pending,
- "tags" => user.tags,
- "subscribed" => subscribed
+ "tags" => user.tags
}
|> maybe_with_activation_status(user, for_user)
}
blocking: true,
muting: false,
muting_notifications: false,
+ subscribing: false,
requested: false,
domain_blocking: false,
showing_reblogs: true,
following: false,
followed_by: false,
blocking: true,
+ subscribing: false,
muting: false,
muting_notifications: false,
requested: false,
assert %{"id" => _id, "muting" => false} = json_response(conn, 200)
end
+ test "subscribing / unsubscribing to a user", %{conn: conn} do
+ user = insert(:user)
+ subscription_target = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
+
+ assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
+
+ assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200)
+ end
+
test "getting a list of mutes", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
- "tags" => [],
- "subscribed" => false
+ "tags" => []
}
}
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
- "tags" => [],
- "subscribed" => false
+ "tags" => []
}
}
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
- "tags" => [],
- "subscribed" => false
+ "tags" => []
}
}
assert represented == UserView.render("show.json", %{user: follower, for: user})
end
- test "a user that you are subscribed to" do
- user = insert(:user)
- subscriber = insert(:user)
- {:ok, subscriber} = User.subscribe(subscriber, user)
- represented = UserView.render("show.json", %{user: user, for: subscriber})
- assert represented["pleroma"]["subscribed"] == true
- end
-
test "a user that is a moderator" do
user = insert(:user, %{info: %{is_moderator: true}})
represented = UserView.render("show.json", %{user: user, for: user})
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
- "tags" => [],
- "subscribed" => false
+ "tags" => []
}
}