X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Ffilter.ex;h=5d6df95306ef768256b10f3585bfe3074199f745;hb=9433311923d4b41b057ce6cb1632ff27d46919b4;hp=fe904df3aae085fd8cd053acdb76c766fd41c107;hpb=1c9e539b47ff594d75c9548a04e64cb0c61cff8c;p=akkoma diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex index fe904df3a..5d6df9530 100644 --- a/lib/pleroma/filter.ex +++ b/lib/pleroma/filter.ex @@ -1,10 +1,18 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Filter do use Ecto.Schema - import Ecto.{Changeset, Query} - alias Pleroma.{User, Repo, Activity} + + import Ecto.Changeset + import Ecto.Query + + alias Pleroma.Repo + alias Pleroma.User schema "filters" do - belongs_to(:user, Pleroma.User) + belongs_to(:user, User, type: FlakeId.Ecto.CompatType) field(:filter_id, :integer) field(:hide, :boolean, default: false) field(:whole_word, :boolean, default: true) @@ -26,16 +34,53 @@ defmodule Pleroma.Filter do Repo.one(query) end - def get_filters(%Pleroma.User{id: user_id} = user) do + def get_active(query) do + from(f in query, where: is_nil(f.expires_at) or f.expires_at > ^NaiveDateTime.utc_now()) + end + + def get_irreversible(query) do + from(f in query, where: f.hide) + end + + def get_filters(query \\ __MODULE__, %User{id: user_id}) do query = from( - f in Pleroma.Filter, - where: f.user_id == ^user_id + f in query, + where: f.user_id == ^user_id, + order_by: [desc: :id] ) Repo.all(query) end + def create(%Pleroma.Filter{user_id: user_id, filter_id: nil} = filter) do + # If filter_id wasn't given, use the max filter_id for this user plus 1. + # XXX This could result in a race condition if a user tries to add two + # different filters for their account from two different clients at the + # same time, but that should be unlikely. + + max_id_query = + from( + f in Pleroma.Filter, + where: f.user_id == ^user_id, + select: max(f.filter_id) + ) + + filter_id = + case Repo.one(max_id_query) do + # Start allocating from 1 + nil -> + 1 + + max_id -> + max_id + 1 + end + + filter + |> Map.put(:filter_id, filter_id) + |> Repo.insert() + end + def create(%Pleroma.Filter{} = filter) do Repo.insert(filter) end @@ -52,11 +97,40 @@ defmodule Pleroma.Filter do |> 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]) + def update(%Pleroma.Filter{} = filter, params) do + filter + |> cast(params, [:phrase, :context, :hide, :expires_at, :whole_word]) + |> validate_required([:phrase, :context]) |> Repo.update() end + + def compose_regex(user_or_filters, format \\ :postgres) + + def compose_regex(%User{} = user, format) do + __MODULE__ + |> get_active() + |> get_irreversible() + |> get_filters(user) + |> compose_regex(format) + end + + def compose_regex([_ | _] = filters, format) do + phrases = + filters + |> Enum.map(& &1.phrase) + |> Enum.join("|") + + case format do + :postgres -> + "\\y(#{phrases})\\y" + + :re -> + ~r/\b#{phrases}\b/i + + _ -> + nil + end + end + + def compose_regex(_, _), do: nil end