X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fhashtag.ex;h=9030ee4e92c0f1537476459f0eda21eb2b49c756;hb=a079ec3a3cdfd42d2cbd51c7698c2c87828e5778;hp=de52c4dae66b5a98e744ea7d4db259e98ec5921f;hpb=5992382cf86d89879b7a8e2dcbf26e910634a73a;p=akkoma diff --git a/lib/pleroma/hashtag.ex b/lib/pleroma/hashtag.ex index de52c4dae..9030ee4e9 100644 --- a/lib/pleroma/hashtag.ex +++ b/lib/pleroma/hashtag.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Hashtag do alias Ecto.Multi alias Pleroma.Hashtag + alias Pleroma.User.HashtagFollow alias Pleroma.Object alias Pleroma.Repo @@ -21,22 +22,33 @@ defmodule Pleroma.Hashtag do timestamps() end + def normalize_name(name) do + name + |> String.downcase() + |> String.trim() + end + + def get_by_id(id) do + Repo.get(Hashtag, id) + end + def get_by_name(name) do - Repo.get_by(Hashtag, name: name) + Repo.get_by(Hashtag, name: normalize_name(name)) end - def get_or_create_by_name(name) when is_bitstring(name) do - with %Hashtag{} = hashtag <- get_by_name(name) do - {:ok, hashtag} - else - _ -> - %Hashtag{} - |> changeset(%{name: name}) - |> Repo.insert() - end + def get_or_create_by_name(name) do + changeset = changeset(%Hashtag{}, %{name: name}) + + Repo.insert( + changeset, + on_conflict: [set: [name: get_field(changeset, :name)]], + conflict_target: :name, + returning: true + ) end def get_or_create_by_names(names) when is_list(names) do + names = Enum.map(names, &normalize_name/1) timestamp = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) structs = @@ -47,23 +59,30 @@ defmodule Pleroma.Hashtag do |> Map.merge(%{inserted_at: timestamp, updated_at: timestamp}) end) - with {:ok, %{query_op: hashtags}} <- - Multi.new() - |> Multi.insert_all(:insert_all_op, Hashtag, structs, on_conflict: :nothing) - |> Multi.run(:query_op, fn _repo, _changes -> - {:ok, Repo.all(from(ht in Hashtag, where: ht.name in ^names))} - end) - |> Repo.transaction() do - {:ok, hashtags} - else - {:error, _name, value, _changes_so_far} -> {:error, value} + try do + with {:ok, %{query_op: hashtags}} <- + Multi.new() + |> Multi.insert_all(:insert_all_op, Hashtag, structs, + on_conflict: :nothing, + conflict_target: :name + ) + |> Multi.run(:query_op, fn _repo, _changes -> + {:ok, Repo.all(from(ht in Hashtag, where: ht.name in ^names))} + end) + |> Repo.transaction() do + {:ok, hashtags} + else + {:error, _name, value, _changes_so_far} -> {:error, value} + end + rescue + e -> {:error, e} end end def changeset(%Hashtag{} = struct, params) do struct |> cast(params, [:name]) - |> update_change(:name, &String.downcase/1) + |> update_change(:name, &normalize_name/1) |> validate_required([:name]) |> unique_constraint(:name) end @@ -74,8 +93,9 @@ defmodule Pleroma.Hashtag do where: hto.object_id == ^object_id, select: hto.hashtag_id ) - |> Repo.delete_all() do - delete_unreferenced(hashtag_ids) + |> Repo.delete_all(), + {:ok, unreferenced_count} <- delete_unreferenced(hashtag_ids) do + {:ok, length(hashtag_ids), unreferenced_count} end end @@ -92,4 +112,22 @@ defmodule Pleroma.Hashtag do {:ok, deleted_count} end end + + def get_followers(%Hashtag{id: hashtag_id}) do + from(hf in HashtagFollow) + |> where([hf], hf.hashtag_id == ^hashtag_id) + |> join(:inner, [hf], u in assoc(hf, :user)) + |> select([hf, u], u.id) + |> Repo.all() + end + + def get_recipients_for_activity(%Pleroma.Activity{object: %{hashtags: tags}}) + when is_list(tags) do + tags + |> Enum.map(&get_followers/1) + |> List.flatten() + |> Enum.uniq() + end + + def get_recipients_for_activity(_activity), do: [] end