Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.2KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Mix.Tasks.Pleroma.Database do
  5. alias Pleroma.Conversation
  6. alias Pleroma.Object
  7. alias Pleroma.Repo
  8. alias Pleroma.User
  9. require Logger
  10. require Pleroma.Constants
  11. import Mix.Pleroma
  12. use Mix.Task
  13. @shortdoc "A collection of database related tasks"
  14. @moduledoc File.read!("docs/administration/CLI_tasks/database.md")
  15. def run(["remove_embedded_objects" | args]) do
  16. {options, [], []} =
  17. OptionParser.parse(
  18. args,
  19. strict: [
  20. vacuum: :boolean
  21. ]
  22. )
  23. start_pleroma()
  24. Logger.info("Removing embedded objects")
  25. Repo.query!(
  26. "update activities set data = safe_jsonb_set(data, '{object}'::text[], data->'object'->'id') where data->'object'->>'id' is not null;",
  27. [],
  28. timeout: :infinity
  29. )
  30. if Keyword.get(options, :vacuum) do
  31. Logger.info("Runnning VACUUM FULL")
  32. Repo.query!(
  33. "vacuum full;",
  34. [],
  35. timeout: :infinity
  36. )
  37. end
  38. end
  39. def run(["bump_all_conversations"]) do
  40. start_pleroma()
  41. Conversation.bump_for_all_activities()
  42. end
  43. def run(["update_users_following_followers_counts"]) do
  44. start_pleroma()
  45. User
  46. |> Repo.all()
  47. |> Enum.each(&User.update_follower_count/1)
  48. end
  49. def run(["prune_objects" | args]) do
  50. import Ecto.Query
  51. {options, [], []} =
  52. OptionParser.parse(
  53. args,
  54. strict: [
  55. vacuum: :boolean
  56. ]
  57. )
  58. start_pleroma()
  59. deadline = Pleroma.Config.get([:instance, :remote_post_retention_days])
  60. Logger.info("Pruning objects older than #{deadline} days")
  61. time_deadline =
  62. NaiveDateTime.utc_now()
  63. |> NaiveDateTime.add(-(deadline * 86_400))
  64. from(o in Object,
  65. where:
  66. fragment(
  67. "?->'to' \\? ? OR ?->'cc' \\? ?",
  68. o.data,
  69. ^Pleroma.Constants.as_public(),
  70. o.data,
  71. ^Pleroma.Constants.as_public()
  72. ),
  73. where: o.inserted_at < ^time_deadline,
  74. where:
  75. fragment("split_part(?->>'actor', '/', 3) != ?", o.data, ^Pleroma.Web.Endpoint.host())
  76. )
  77. |> Repo.delete_all(timeout: :infinity)
  78. if Keyword.get(options, :vacuum) do
  79. Logger.info("Runnning VACUUM FULL")
  80. Repo.query!(
  81. "vacuum full;",
  82. [],
  83. timeout: :infinity
  84. )
  85. end
  86. end
  87. def run(["fix_likes_collections"]) do
  88. import Ecto.Query
  89. start_pleroma()
  90. from(object in Object,
  91. where: fragment("(?)->>'likes' is not null", object.data),
  92. select: %{id: object.id, likes: fragment("(?)->>'likes'", object.data)}
  93. )
  94. |> Pleroma.RepoStreamer.chunk_stream(100)
  95. |> Stream.each(fn objects ->
  96. ids =
  97. objects
  98. |> Enum.filter(fn object -> object.likes |> Jason.decode!() |> is_map() end)
  99. |> Enum.map(& &1.id)
  100. Object
  101. |> where([object], object.id in ^ids)
  102. |> update([object],
  103. set: [
  104. data:
  105. fragment(
  106. "safe_jsonb_set(?, '{likes}', '[]'::jsonb, true)",
  107. object.data
  108. )
  109. ]
  110. )
  111. |> Repo.update_all([], timeout: :infinity)
  112. end)
  113. |> Stream.run()
  114. end
  115. end