[MastodonAPI] Add filters

This commit is contained in:
Haelwenn (lanodan) Monnier 2018-08-14 04:27:28 +02:00
parent a5adb251ab
commit 6e030129fb
No known key found for this signature in database
GPG key ID: D5B7A8E43C997DEE
7 changed files with 372 additions and 1 deletions

62
lib/pleroma/filter.ex Normal file
View file

@ -0,0 +1,62 @@
defmodule Pleroma.Filter do
use Ecto.Schema
import Ecto.{Changeset, Query}
alias Pleroma.{User, Repo, Activity}
schema "filters" do
belongs_to(:user, Pleroma.User)
field(:filter_id, :integer)
field(:hide, :boolean, default: false)
field(:whole_word, :boolean, default: true)
field(:phrase, :string)
field(:context, {:array, :string})
field(:expires_at, :utc_datetime)
timestamps()
end
def get(id, %{id: user_id} = _user) do
query =
from(
f in Pleroma.Filter,
where: f.filter_id == ^id,
where: f.user_id == ^user_id
)
Repo.one(query)
end
def get_filters(%Pleroma.User{id: user_id} = user) do
query =
from(
f in Pleroma.Filter,
where: f.user_id == ^user_id
)
Repo.all(query)
end
def create(%Pleroma.Filter{} = filter) do
Repo.insert(filter)
end
def delete(%Pleroma.Filter{id: filter_key} = filter) when is_number(filter_key) do
Repo.delete(filter)
end
def delete(%Pleroma.Filter{id: filter_key} = filter) when is_nil(filter_key) do
%Pleroma.Filter{id: id} = get(filter.filter_id, %{id: filter.user_id})
filter
|> Map.put(:id, id)
|> Repo.delete()
end
def update(%Pleroma.Filter{} = filter) do
destination = Map.from_struct(filter)
Pleroma.Filter.get(filter.filter_id, %{id: filter.user_id})
|> cast(destination, [:phrase, :context, :hide, :expires_at, :whole_word])
|> Repo.update()
end
end

View file

@ -2,7 +2,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller
alias Pleroma.{Repo, Object, Activity, User, Notification, Stats}
alias Pleroma.Web
alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView}
alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView, FilterView}
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
@ -1089,6 +1089,65 @@ def render_notification(user, %{id: id, activity: activity, inserted_at: created
end
end
def get_filters(%{assigns: %{user: user}} = conn, params) do
filters = Pleroma.Filter.get_filters(user)
res = FilterView.render("filters.json", filters: filters)
json(conn, res)
end
def create_filter(
%{assigns: %{user: user}} = conn,
%{"phrase" => phrase, "context" => context} = params
) do
query = %Pleroma.Filter{
user_id: user.id,
phrase: phrase,
context: context,
hide: Map.get(params, "irreversible", nil),
whole_word: Map.get(params, "boolean", true)
# expires_at
}
{:ok, response} = Pleroma.Filter.create(query)
res = FilterView.render("filter.json", filter: response)
json(conn, res)
end
def get_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id} = params) do
filter = Pleroma.Filter.get(filter_id, user)
res = FilterView.render("filter.json", filter: filter)
json(conn, res)
end
def update_filter(
%{assigns: %{user: user}} = conn,
%{"phrase" => phrase, "context" => context, "id" => filter_id} = params
) do
query = %Pleroma.Filter{
user_id: user.id,
filter_id: filter_id,
phrase: phrase,
context: context,
hide: Map.get(params, "irreversible", nil),
whole_word: Map.get(params, "boolean", true)
# expires_at
}
{:ok, response} = Pleroma.Filter.update(query)
res = FilterView.render("filter.json", filter: response)
json(conn, res)
end
def delete_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id} = params) do
query = %Pleroma.Filter{
user_id: user.id,
filter_id: filter_id
}
{:ok, response} = Pleroma.Filter.delete(query)
json(conn, %{})
end
def errors(conn, _) do
conn
|> put_status(500)

View file

@ -0,0 +1,20 @@
defmodule Pleroma.Web.MastodonAPI.FilterView do
use Pleroma.Web, :view
alias Pleroma.Web.MastodonAPI.FilterView
alias Pleroma.Web.CommonAPI.Utils
def render("filters.json", %{filters: filters} = opts) do
render_many(filters, FilterView, "filter.json", opts)
end
def render("filter.json", %{filter: filter}) do
%{
id: to_string(filter.filter_id),
phrase: filter.phrase,
context: filter.context,
expires_at: Utils.to_masto_date(filter.expires_at),
irreversible: filter.hide,
whole_word: false
}
end
end

View file

@ -154,6 +154,12 @@ def user_fetcher(username_or_email) do
post("/domain_blocks", MastodonAPIController, :block_domain)
delete("/domain_blocks", MastodonAPIController, :unblock_domain)
get("/filters", MastodonAPIController, :get_filters)
post("/filters", MastodonAPIController, :create_filter)
get("/filters/:id", MastodonAPIController, :get_filter)
put("/filters/:id", MastodonAPIController, :update_filter)
delete("/filters/:id", MastodonAPIController, :delete_filter)
get("/suggestions", MastodonAPIController, :suggestions)
end

View file

@ -0,0 +1,20 @@
defmodule Pleroma.Repo.Migrations.CreateFilters do
use Ecto.Migration
def change do
create table(:filters) do
add :user_id, references(:users, on_delete: :delete_all)
add :filter_id, :integer
add :hide, :boolean
add :phrase, :string
add :context, {:array, :string}
add :expires_at, :datetime
add :whole_word, :boolean
timestamps()
end
create index(:filters, [:user_id])
create index(:filters, [:phrase], where: "hide = true", name: :hided_phrases_index)
end
end

85
test/filter_test.exs Normal file
View file

@ -0,0 +1,85 @@
defmodule Pleroma.FilterTest do
alias Pleroma.{User, Repo}
use Pleroma.DataCase
import Pleroma.Factory
import Ecto.Query
test "creating a filter" do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 42,
phrase: "knights",
context: ["home"]
}
{:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query)
result = Pleroma.Filter.get(filter.filter_id, user)
assert query.phrase == result.phrase
end
test "deleting a filter" do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 0,
phrase: "knights",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
{:ok, filter} = Pleroma.Filter.delete(query)
assert is_nil(Repo.get(Pleroma.Filter, filter.filter_id))
end
test "getting all filters by an user" do
user = insert(:user)
query_one = %Pleroma.Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
context: ["home"]
}
query_two = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "who",
context: ["home"]
}
{:ok, filter_one} = Pleroma.Filter.create(query_one)
{:ok, filter_two} = Pleroma.Filter.create(query_two)
filters = Pleroma.Filter.get_filters(user)
assert filter_one in filters
assert filter_two in filters
end
test "updating a filter" do
user = insert(:user)
query_one = %Pleroma.Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
context: ["home"]
}
query_two = %Pleroma.Filter{
user_id: user.id,
filter_id: 1,
phrase: "who",
context: ["home", "timeline"]
}
{:ok, filter_one} = Pleroma.Filter.create(query_one)
{:ok, filter_two} = Pleroma.Filter.update(query_two)
assert filter_one != filter_two
assert filter_two.phrase == query_two.phrase
assert filter_two.context == query_two.context
end
end

View file

@ -251,6 +251,125 @@ test "when you didn't create it", %{conn: conn} do
end
end
describe "filters" do
test "creating a filter", %{conn: conn} do
user = insert(:user)
filter = %Pleroma.Filter{
phrase: "knights",
context: ["home"]
}
conn =
conn
|> assign(:user, user)
|> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})
assert response = json_response(conn, 200)
assert response["phrase"] == filter.phrase
assert response["context"] == filter.context
end
test "fetching a list of filters", %{conn: conn} do
user = insert(:user)
query_one = %Pleroma.Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
context: ["home"]
}
query_two = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "who",
context: ["home"]
}
{:ok, filter_one} = Pleroma.Filter.create(query_one)
{:ok, filter_two} = Pleroma.Filter.create(query_two)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/filters")
assert response = json_response(conn, 200)
end
test "get a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/filters/#{filter.filter_id}")
assert response = json_response(conn, 200)
end
test "update a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
new = %Pleroma.Filter{
phrase: "nii",
context: ["home"]
}
conn =
conn
|> assign(:user, user)
|> put("/api/v1/filters/#{query.filter_id}", %{
phrase: new.phrase,
context: new.context
})
assert response = json_response(conn, 200)
assert response["phrase"] == new.phrase
assert response["context"] == new.context
end
test "delete a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
conn =
conn
|> assign(:user, user)
|> delete("/api/v1/filters/#{filter.filter_id}")
assert response = json_response(conn, 200)
assert response == %{}
end
end
describe "lists" do
test "creating a list", %{conn: conn} do
user = insert(:user)