philomena/lib/philomena/comments.ex

255 lines
5.8 KiB
Elixir
Raw Normal View History

2019-08-18 20:14:36 +02:00
defmodule Philomena.Comments do
@moduledoc """
The Comments context.
"""
import Ecto.Query, warn: false
alias Ecto.Multi
2019-08-18 20:14:36 +02:00
alias Philomena.Repo
alias Philomena.Elasticsearch
alias Philomena.Reports.Report
2019-08-18 20:14:36 +02:00
alias Philomena.Comments.Comment
alias Philomena.Comments.ElasticsearchIndex, as: CommentIndex
2020-12-06 17:42:14 +01:00
alias Philomena.IndexWorker
alias Philomena.Images.Image
2019-11-18 05:02:08 +01:00
alias Philomena.Images
alias Philomena.Notifications
2020-12-06 17:42:14 +01:00
alias Philomena.NotificationWorker
2019-12-06 15:43:01 +01:00
alias Philomena.Versions
2020-09-07 20:50:34 +02:00
alias Philomena.Reports
alias Philomena.Users.User
2019-08-18 20:14:36 +02:00
@doc """
Gets a single comment.
Raises `Ecto.NoResultsError` if the Comment does not exist.
## Examples
iex> get_comment!(123)
%Comment{}
iex> get_comment!(456)
** (Ecto.NoResultsError)
"""
def get_comment!(id), do: Repo.get!(Comment, id)
@doc """
Creates a comment.
## Examples
iex> create_comment(%{field: value})
{:ok, %Comment{}}
iex> create_comment(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
2020-02-22 16:31:30 +01:00
def create_comment(image, attribution, params \\ %{}) do
comment =
Ecto.build_assoc(image, :comments)
|> Comment.creation_changeset(params, attribution)
image_query =
Image
|> where(id: ^image.id)
2020-01-11 05:20:19 +01:00
Multi.new()
|> Multi.insert(:comment, comment)
|> Multi.update_all(:image, image_query, inc: [comments_count: 1])
|> maybe_create_subscription_on_reply(image, attribution[:user])
|> Repo.transaction()
end
defp maybe_create_subscription_on_reply(multi, image, %User{watch_on_reply: true} = user) do
multi
2019-11-18 05:02:08 +01:00
|> Multi.run(:subscribe, fn _repo, _changes ->
Images.create_subscription(image, user)
2019-11-18 05:02:08 +01:00
end)
end
defp maybe_create_subscription_on_reply(multi, _image, _user) do
multi
end
def notify_comment(comment) do
2020-12-06 17:42:14 +01:00
Exq.enqueue(Exq, "notifications", NotificationWorker, ["Comments", comment.id])
end
2020-12-06 17:42:14 +01:00
def perform_notify(comment_id) do
comment = get_comment!(comment_id)
image =
comment
|> Repo.preload(:image)
|> Map.fetch!(:image)
subscriptions =
image
|> Repo.preload(:subscriptions)
|> Map.fetch!(:subscriptions)
Notifications.notify(
comment,
subscriptions,
%{
actor_id: image.id,
actor_type: "Image",
actor_child_id: comment.id,
actor_child_type: "Comment",
action: "commented on"
}
)
2019-08-18 20:14:36 +02:00
end
@doc """
Updates a comment.
## Examples
iex> update_comment(comment, %{field: new_value})
{:ok, %Comment{}}
iex> update_comment(comment, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
2019-12-06 15:43:01 +01:00
def update_comment(%Comment{} = comment, editor, attrs) do
now = DateTime.utc_now() |> DateTime.truncate(:second)
current_body = comment.body
current_reason = comment.edit_reason
2020-01-11 05:20:19 +01:00
comment_changes = Comment.changeset(comment, attrs, now)
2019-12-06 15:43:01 +01:00
2020-01-11 05:20:19 +01:00
Multi.new()
2019-12-06 15:43:01 +01:00
|> Multi.update(:comment, comment_changes)
|> Multi.run(:version, fn _repo, _changes ->
Versions.create_version("Comment", comment.id, editor.id, %{
"body" => current_body,
"edit_reason" => current_reason
})
end)
Squashed commit of the following: commit 8ea9cff4af46e24c38020652cedeff72957354fb Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:29:24 2020 -0400 remove remaining serializable aside hiding related commit 99ccf06264db6319ece2a896a104031447447a5f Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:20:40 2020 -0400 interactions: remove serializable commit a63bef06a6962368f69cf83afbc3c44f2467618c Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:16:27 2020 -0400 users: remove serializable commit 8053229f6fab507c29a40f0e22dd9cab7971e34f Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:11:14 2020 -0400 user_links: remove serializable commit 9b058add825b0a876a91a1cf2b1b22dc34066e42 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:09:33 2020 -0400 topics: remove serializable commit cd9ea908c34f72c0120fca1c4d581540db60db98 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:05:23 2020 -0400 tags: remove serializable commit c7563fef8fc905c32a0727a4b104222227a6bafa Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:02:22 2020 -0400 static_pages: remove serializable commit 3da661bdd1aec74e4ac5b69ec21124bc1ebc6fb4 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 01:00:15 2020 -0400 posts: remove serializable commit 18a50a4e5bed1ab6e4e6c13c3051a21ae7e8fbb0 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:55:55 2020 -0400 poll_votes: remove serializable commit 7d946ef23d7b27877d4bf0fb6a4db4ae64a9ffab Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:51:49 2020 -0400 galleries: remove serializable commit d8c35a0934e5394b092b050e071abdada4bdb640 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:42:43 2020 -0400 conversations: remove serializable commit 079e6dca6c8064867f2c0f90f351ea83c0f12b75 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:38:28 2020 -0400 comments: remove serializable commit 00ae38bad566fb6badeccceac2e394e65ec9428e Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:37:15 2020 -0400 commissions: remove serializable commit b3c4a4b13671ca73c58080b090dd6165552c87d6 Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:17:12 2020 -0400 bans: remove serializable commit 8be9fe913ff1f6264b899e96ee38fa52032b8bda Author: byte[] <byteslice@airmail.cc> Date: Sun Sep 6 00:02:44 2020 -0400 badges: remove serializable commit 162adda185f705b9749774c4af8c7d8db0d89790 Author: byte[] <byteslice@airmail.cc> Date: Sat Sep 5 23:56:51 2020 -0400 adverts: remove serializable
2020-09-06 07:30:53 +02:00
|> Repo.transaction()
2019-08-18 20:14:36 +02:00
end
@doc """
Deletes a Comment.
## Examples
iex> delete_comment(comment)
{:ok, %Comment{}}
iex> delete_comment(comment)
{:error, %Ecto.Changeset{}}
"""
def delete_comment(%Comment{} = comment) do
Repo.delete(comment)
end
2019-12-10 21:29:48 +01:00
def hide_comment(%Comment{} = comment, attrs, user) do
reports =
Report
|> where(reportable_type: "Comment", reportable_id: ^comment.id)
|> select([r], r.id)
2020-09-07 20:50:34 +02:00
|> update(set: [open: false, state: "closed", admin_id: ^user.id])
comment = Comment.hide_changeset(comment, attrs, user)
Multi.new()
|> Multi.update(:comment, comment)
|> Multi.update_all(:reports, reports, [])
|> Repo.transaction()
2020-09-07 20:50:34 +02:00
|> case do
{:ok, %{comment: comment, reports: {_count, reports}}} ->
Reports.reindex_reports(reports)
reindex_comment(comment)
{:ok, comment}
error ->
error
end
2019-12-10 21:29:48 +01:00
end
def unhide_comment(%Comment{} = comment) do
comment
|> Comment.unhide_changeset()
|> Repo.update()
2020-09-07 20:50:34 +02:00
|> case do
{:ok, comment} ->
reindex_comment(comment)
{:ok, comment}
error ->
error
end
2019-12-10 21:29:48 +01:00
end
2019-12-11 23:21:14 +01:00
def destroy_comment(%Comment{} = comment) do
comment
|> Comment.destroy_changeset()
|> Repo.update()
end
2019-12-21 22:37:06 +01:00
def migrate_comments(image, duplicate_of_image) do
2019-12-22 02:31:25 +01:00
{count, nil} =
Comment
|> where(image_id: ^image.id)
|> Repo.update_all(set: [image_id: duplicate_of_image.id])
Image
|> where(id: ^duplicate_of_image.id)
|> Repo.update_all(inc: [comments_count: count])
2019-12-21 22:37:06 +01:00
reindex_comments(duplicate_of_image)
end
2019-08-18 20:14:36 +02:00
@doc """
Returns an `%Ecto.Changeset{}` for tracking comment changes.
## Examples
iex> change_comment(comment)
%Ecto.Changeset{source: %Comment{}}
"""
def change_comment(%Comment{} = comment) do
Comment.changeset(comment, %{})
end
def user_name_reindex(old_name, new_name) do
data = CommentIndex.user_name_update_by_query(old_name, new_name)
Elasticsearch.update_by_query(Comment, data.query, data.set_replacements, data.replacements)
end
def reindex_comment(%Comment{} = comment) do
2020-12-06 17:42:14 +01:00
Exq.enqueue(Exq, "indexing", IndexWorker, ["Comments", "id", [comment.id]])
comment
end
2019-12-21 22:37:06 +01:00
def reindex_comments(image) do
2020-12-06 17:42:14 +01:00
Exq.enqueue(Exq, "indexing", IndexWorker, ["Comments", "image_id", [image.id]])
2019-12-21 22:37:06 +01:00
image
end
def indexing_preloads do
[:user, image: :tags]
end
2020-12-06 17:42:14 +01:00
def perform_reindex(column, condition) do
Comment
|> preload(^indexing_preloads())
|> where([c], field(c, ^column) in ^condition)
|> Elasticsearch.reindex(Comment)
end
2019-08-18 20:14:36 +02:00
end