Add a command to refresh a single actor or all actors
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
98
lib/mix/tasks/mobilizon/actors/refresh.ex
Normal file
98
lib/mix/tasks/mobilizon/actors/refresh.ex
Normal file
@@ -0,0 +1,98 @@
|
||||
defmodule Mix.Tasks.Mobilizon.Actors.Refresh do
|
||||
@moduledoc """
|
||||
Task to display an actor details
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Storage.Repo
|
||||
import Ecto.Query
|
||||
require Logger
|
||||
|
||||
@shortdoc "Refresh an actor or all actors"
|
||||
|
||||
@impl Mix.Task
|
||||
def run(["--all" | options]) do
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
options,
|
||||
strict: [
|
||||
verbose: :boolean
|
||||
],
|
||||
aliases: [
|
||||
v: :verbose
|
||||
]
|
||||
)
|
||||
|
||||
verbose = Keyword.get(options, :verbose, false)
|
||||
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
total = count_actors()
|
||||
|
||||
Mix.shell().info("""
|
||||
#{total} actors to process
|
||||
""")
|
||||
|
||||
query = from(a in Actor, where: not is_nil(a.domain))
|
||||
|
||||
{:ok, _res} =
|
||||
Repo.transaction(
|
||||
fn ->
|
||||
query
|
||||
|> Repo.stream(timeout: :infinity)
|
||||
|> Stream.map(&"#{&1.preferred_username}@#{&1.domain}")
|
||||
|> Stream.each(
|
||||
if verbose,
|
||||
do: &Logger.info("Processing #{inspect(&1)}"),
|
||||
else: &Logger.debug("Processing #{inspect(&1)}")
|
||||
)
|
||||
|> Stream.map(fn username -> make_actor(username, verbose) end)
|
||||
|> Stream.scan(0, fn _, acc -> acc + 1 end)
|
||||
|> Stream.each(fn index ->
|
||||
if verbose,
|
||||
do: Logger.info("#{index}/#{total}"),
|
||||
else: ProgressBar.render(index, total)
|
||||
end)
|
||||
|> Stream.run()
|
||||
end,
|
||||
timeout: :infinity
|
||||
)
|
||||
end
|
||||
|
||||
@impl Mix.Task
|
||||
def run([preferred_username]) do
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
case ActivityPub.make_actor_from_nickname(preferred_username) do
|
||||
{:ok, %Actor{}} ->
|
||||
Mix.shell().info("""
|
||||
Actor #{preferred_username} refreshed
|
||||
""")
|
||||
|
||||
{:actor, nil} ->
|
||||
Mix.raise("Error: No such actor")
|
||||
end
|
||||
end
|
||||
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.actors.refresh requires an username as argument or --all as an option")
|
||||
end
|
||||
|
||||
@spec make_actor(String.t(), boolean()) :: any()
|
||||
defp make_actor(username, verbose) do
|
||||
ActivityPub.make_actor_from_nickname(username)
|
||||
rescue
|
||||
_ ->
|
||||
if verbose do
|
||||
Logger.warn("Failed to refresh #{username}")
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
defp count_actors do
|
||||
Repo.aggregate(from(a in Actor, where: not is_nil(a.domain)), :count)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user