Fixes #415. Properly handle nil and empty string by User.parse_bio
[akkoma] / lib / pleroma / user.ex
index 74ae5ef0d7e30c9905fc32e1ddb21fc78e7d9aeb..5d05dddfa2bc2de120879c6c81fac2e4c7901d0b 100644 (file)
@@ -2,6 +2,7 @@ defmodule Pleroma.User do
   use Ecto.Schema
 
   import Ecto.{Changeset, Query}
+  alias Ecto.Multi
   alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
   alias Comeonin.Pbkdf2
   alias Pleroma.Formatter
@@ -23,6 +24,7 @@ defmodule Pleroma.User do
     field(:local, :boolean, default: true)
     field(:follower_address, :string)
     field(:search_distance, :float, virtual: true)
+    field(:tags, {:array, :string}, default: [])
     field(:last_refreshed_at, :naive_datetime)
     has_many(:notifications, Notification)
     embeds_one(:info, Pleroma.User.Info)
@@ -62,10 +64,6 @@ defmodule Pleroma.User do
     |> validate_required([:following])
   end
 
-  def info_changeset(struct, params \\ %{}) do
-    raise "NOT VALID ANYMORE"
-  end
-
   def user_info(%User{} = user) do
     oneself = if user.local, do: 1, else: 0
 
@@ -806,7 +804,11 @@ defmodule Pleroma.User do
     end
   end
 
-  def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) do
+  def parse_bio(bio, user \\ %User{info: %{source_data: %{}}})
+  def parse_bio(nil, user), do: ""
+  def parse_bio(bio, user) when bio == "", do: bio
+
+  def parse_bio(bio, user) do
     mentions = Formatter.parse_mentions(bio)
     tags = Formatter.parse_tags(bio)
 
@@ -819,4 +821,41 @@ defmodule Pleroma.User do
 
     CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji)
   end
+
+  def tag(user_identifiers, tags) when is_list(user_identifiers) do
+    Repo.transaction(fn ->
+      for user_identifier <- user_identifiers, do: tag(user_identifier, tags)
+    end)
+  end
+
+  def untag(user_identifiers, tags) when is_list(user_identifiers) do
+    Repo.transaction(fn ->
+      for user_identifier <- user_identifiers, do: untag(user_identifier, tags)
+    end)
+  end
+
+  def tag(nickname, tags) when is_binary(nickname), do: tag(User.get_by_nickname(nickname), tags)
+
+  def untag(nickname, tags) when is_binary(nickname),
+    do: untag(User.get_by_nickname(nickname), tags)
+
+  def tag(%User{} = user, tags),
+    do: update_tags(user, Enum.uniq(user.tags ++ normalize_tags(tags)))
+
+  def untag(%User{} = user, tags), do: update_tags(user, user.tags -- normalize_tags(tags))
+
+  defp update_tags(%User{} = user, new_tags) do
+    {:ok, updated_user} =
+      user
+      |> change(%{tags: new_tags})
+      |> Repo.update()
+
+    updated_user
+  end
+
+  defp normalize_tags(tags) do
+    [tags]
+    |> List.flatten()
+    |> Enum.map(&String.downcase(&1))
+  end
 end