revert 4a94c9a31e
revert Add ability to follow hashtags (#336) Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/336translations
parent
4c3971aebd
commit
ec6bf8c3f7
@ -1,49 +0,0 @@
|
|||||||
defmodule Pleroma.User.HashtagFollow do
|
|
||||||
use Ecto.Schema
|
|
||||||
import Ecto.Query
|
|
||||||
import Ecto.Changeset
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Hashtag
|
|
||||||
alias Pleroma.Repo
|
|
||||||
|
|
||||||
schema "user_follows_hashtag" do
|
|
||||||
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
|
||||||
belongs_to(:hashtag, Hashtag)
|
|
||||||
end
|
|
||||||
|
|
||||||
def changeset(%__MODULE__{} = user_hashtag_follow, attrs) do
|
|
||||||
user_hashtag_follow
|
|
||||||
|> cast(attrs, [:user_id, :hashtag_id])
|
|
||||||
|> unique_constraint(:hashtag_id,
|
|
||||||
name: :user_hashtag_follows_user_id_hashtag_id_index,
|
|
||||||
message: "already following"
|
|
||||||
)
|
|
||||||
|> validate_required([:user_id, :hashtag_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def new(%User{} = user, %Hashtag{} = hashtag) do
|
|
||||||
%__MODULE__{}
|
|
||||||
|> changeset(%{user_id: user.id, hashtag_id: hashtag.id})
|
|
||||||
|> Repo.insert(on_conflict: :nothing)
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete(%User{} = user, %Hashtag{} = hashtag) do
|
|
||||||
with %__MODULE__{} = user_hashtag_follow <- get(user, hashtag) do
|
|
||||||
Repo.delete(user_hashtag_follow)
|
|
||||||
else
|
|
||||||
_ -> {:ok, nil}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(%User{} = user, %Hashtag{} = hashtag) do
|
|
||||||
from(hf in __MODULE__)
|
|
||||||
|> where([hf], hf.user_id == ^user.id and hf.hashtag_id == ^hashtag.id)
|
|
||||||
|> Repo.one()
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_by_user(%User{} = user) do
|
|
||||||
Ecto.assoc(user, :followed_hashtags)
|
|
||||||
|> Repo.all()
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,65 +0,0 @@
|
|||||||
defmodule Pleroma.Web.ApiSpec.TagOperation do
|
|
||||||
alias OpenApiSpex.Operation
|
|
||||||
alias OpenApiSpex.Schema
|
|
||||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
|
||||||
alias Pleroma.Web.ApiSpec.Schemas.Tag
|
|
||||||
|
|
||||||
def open_api_operation(action) do
|
|
||||||
operation = String.to_existing_atom("#{action}_operation")
|
|
||||||
apply(__MODULE__, operation, [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_operation do
|
|
||||||
%Operation{
|
|
||||||
tags: ["Tags"],
|
|
||||||
summary: "Hashtag",
|
|
||||||
description: "View a hashtag",
|
|
||||||
security: [%{"oAuth" => ["read"]}],
|
|
||||||
parameters: [id_param()],
|
|
||||||
operationId: "TagController.show",
|
|
||||||
responses: %{
|
|
||||||
200 => Operation.response("Hashtag", "application/json", Tag),
|
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def follow_operation do
|
|
||||||
%Operation{
|
|
||||||
tags: ["Tags"],
|
|
||||||
summary: "Follow a hashtag",
|
|
||||||
description: "Follow a hashtag",
|
|
||||||
security: [%{"oAuth" => ["write:follows"]}],
|
|
||||||
parameters: [id_param()],
|
|
||||||
operationId: "TagController.follow",
|
|
||||||
responses: %{
|
|
||||||
200 => Operation.response("Hashtag", "application/json", Tag),
|
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def unfollow_operation do
|
|
||||||
%Operation{
|
|
||||||
tags: ["Tags"],
|
|
||||||
summary: "Unfollow a hashtag",
|
|
||||||
description: "Unfollow a hashtag",
|
|
||||||
security: [%{"oAuth" => ["write:follow"]}],
|
|
||||||
parameters: [id_param()],
|
|
||||||
operationId: "TagController.unfollow",
|
|
||||||
responses: %{
|
|
||||||
200 => Operation.response("Hashtag", "application/json", Tag),
|
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp id_param do
|
|
||||||
Operation.parameter(
|
|
||||||
:id,
|
|
||||||
:path,
|
|
||||||
%Schema{type: :string},
|
|
||||||
"Name of the hashtag"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,47 +0,0 @@
|
|||||||
defmodule Pleroma.Web.MastodonAPI.TagController do
|
|
||||||
@moduledoc "Hashtag routes for mastodon API"
|
|
||||||
use Pleroma.Web, :controller
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Hashtag
|
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
|
||||||
plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read"]} when action in [:show])
|
|
||||||
|
|
||||||
plug(
|
|
||||||
Pleroma.Web.Plugs.OAuthScopesPlug,
|
|
||||||
%{scopes: ["write:follows"]} when action in [:follow, :unfollow]
|
|
||||||
)
|
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TagOperation
|
|
||||||
|
|
||||||
def show(conn, %{id: id}) do
|
|
||||||
with %Hashtag{} = hashtag <- Hashtag.get_by_name(id) do
|
|
||||||
render(conn, "show.json", tag: hashtag, for_user: conn.assigns.user)
|
|
||||||
else
|
|
||||||
_ -> conn |> render_error(:not_found, "Hashtag not found")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def follow(conn, %{id: id}) do
|
|
||||||
with %Hashtag{} = hashtag <- Hashtag.get_by_name(id),
|
|
||||||
%User{} = user <- conn.assigns.user,
|
|
||||||
{:ok, _} <-
|
|
||||||
User.follow_hashtag(user, hashtag) do
|
|
||||||
render(conn, "show.json", tag: hashtag, for_user: user)
|
|
||||||
else
|
|
||||||
_ -> render_error(conn, :not_found, "Hashtag not found")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def unfollow(conn, %{id: id}) do
|
|
||||||
with %Hashtag{} = hashtag <- Hashtag.get_by_name(id),
|
|
||||||
%User{} = user <- conn.assigns.user,
|
|
||||||
{:ok, _} <-
|
|
||||||
User.unfollow_hashtag(user, hashtag) do
|
|
||||||
render(conn, "show.json", tag: hashtag, for_user: user)
|
|
||||||
else
|
|
||||||
_ -> render_error(conn, :not_found, "Hashtag not found")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,21 +0,0 @@
|
|||||||
defmodule Pleroma.Web.MastodonAPI.TagView do
|
|
||||||
use Pleroma.Web, :view
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web.Router.Helpers
|
|
||||||
|
|
||||||
def render("show.json", %{tag: tag, for_user: user}) do
|
|
||||||
following =
|
|
||||||
with %User{} <- user do
|
|
||||||
User.following_hashtag?(user, tag)
|
|
||||||
else
|
|
||||||
_ -> false
|
|
||||||
end
|
|
||||||
|
|
||||||
%{
|
|
||||||
name: tag.name,
|
|
||||||
url: Helpers.tag_feed_url(Pleroma.Web.Endpoint, :feed, tag.name),
|
|
||||||
history: [],
|
|
||||||
following: following
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,12 +0,0 @@
|
|||||||
defmodule Pleroma.Repo.Migrations.AddUserFollowsHashtag do
|
|
||||||
use Ecto.Migration
|
|
||||||
|
|
||||||
def change do
|
|
||||||
create table(:user_follows_hashtag) do
|
|
||||||
add(:hashtag_id, references(:hashtags))
|
|
||||||
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
|
|
||||||
end
|
|
||||||
|
|
||||||
create(unique_index(:user_follows_hashtag, [:user_id, :hashtag_id]))
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,97 +0,0 @@
|
|||||||
defmodule Pleroma.Web.MastodonAPI.TagControllerTest do
|
|
||||||
use Pleroma.Web.ConnCase
|
|
||||||
|
|
||||||
import Pleroma.Factory
|
|
||||||
import Tesla.Mock
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
|
|
||||||
setup do
|
|
||||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
|
||||||
:ok
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /api/v1/tags/:id" do
|
|
||||||
test "returns 200 with tag" do
|
|
||||||
%{user: user, conn: conn} = oauth_access(["read"])
|
|
||||||
|
|
||||||
tag = insert(:hashtag, name: "jubjub")
|
|
||||||
{:ok, _user} = User.follow_hashtag(user, tag)
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/tags/jubjub")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert %{
|
|
||||||
"name" => "jubjub",
|
|
||||||
"url" => "http://localhost:4001/tags/jubjub",
|
|
||||||
"history" => [],
|
|
||||||
"following" => true
|
|
||||||
} = response
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 404 with unknown tag" do
|
|
||||||
%{conn: conn} = oauth_access(["read"])
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/tags/jubjub")
|
|
||||||
|> json_response_and_validate_schema(404)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "POST /api/v1/tags/:id/follow" do
|
|
||||||
test "should follow a hashtag" do
|
|
||||||
%{user: user, conn: conn} = oauth_access(["write:follows"])
|
|
||||||
hashtag = insert(:hashtag, name: "jubjub")
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> post("/api/v1/tags/jubjub/follow")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert response["following"] == true
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
|
||||||
assert User.following_hashtag?(user, hashtag)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "should 404 if hashtag doesn't exist" do
|
|
||||||
%{conn: conn} = oauth_access(["write:follows"])
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> post("/api/v1/tags/rubrub/follow")
|
|
||||||
|> json_response_and_validate_schema(404)
|
|
||||||
|
|
||||||
assert response["error"] == "Hashtag not found"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "POST /api/v1/tags/:id/unfollow" do
|
|
||||||
test "should unfollow a hashtag" do
|
|
||||||
%{user: user, conn: conn} = oauth_access(["write:follows"])
|
|
||||||
hashtag = insert(:hashtag, name: "jubjub")
|
|
||||||
{:ok, user} = User.follow_hashtag(user, hashtag)
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> post("/api/v1/tags/jubjub/unfollow")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert response["following"] == false
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
|
||||||
refute User.following_hashtag?(user, hashtag)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "should 404 if hashtag doesn't exist" do
|
|
||||||
%{conn: conn} = oauth_access(["write:follows"])
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> post("/api/v1/tags/rubrub/unfollow")
|
|
||||||
|> json_response_and_validate_schema(404)
|
|
||||||
|
|
||||||
assert response["error"] == "Hashtag not found"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in new issue