2020-06-10 14:28:27 +02:00
|
|
|
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
|
|
|
|
""")
|
|
|
|
|
2020-06-11 19:13:21 +02:00
|
|
|
query = from(a in Actor, where: not is_nil(a.domain) and not a.suspended)
|
2020-06-10 14:28:27 +02:00
|
|
|
|
|
|
|
{: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
|