diff options
Diffstat (limited to 'lib/mix')
-rw-r--r-- | lib/mix/tasks/migrate_local_uploads.ex | 97 | ||||
-rw-r--r-- | lib/mix/tasks/pleroma/sample_config.eex | 41 | ||||
-rw-r--r-- | lib/mix/tasks/reactivate_user.ex | 19 | ||||
-rw-r--r-- | lib/mix/tasks/relay_follow.ex | 24 | ||||
-rw-r--r-- | lib/mix/tasks/relay_unfollow.ex | 23 | ||||
-rw-r--r-- | lib/mix/tasks/set_admin.ex | 32 | ||||
-rw-r--r-- | lib/mix/tasks/unsubscribe_user.ex | 38 |
7 files changed, 274 insertions, 0 deletions
diff --git a/lib/mix/tasks/migrate_local_uploads.ex b/lib/mix/tasks/migrate_local_uploads.ex new file mode 100644 index 000000000..8f9e210c0 --- /dev/null +++ b/lib/mix/tasks/migrate_local_uploads.ex @@ -0,0 +1,97 @@ +defmodule Mix.Tasks.MigrateLocalUploads do + use Mix.Task + import Mix.Ecto + alias Pleroma.{Upload, Uploaders.Local, Uploaders.S3} + require Logger + + @log_every 50 + @shortdoc "Migrate uploads from local to remote storage" + + def run([target_uploader | args]) do + delete? = Enum.member?(args, "--delete") + Application.ensure_all_started(:pleroma) + + local_path = Pleroma.Config.get!([Local, :uploads]) + uploader = Module.concat(Pleroma.Uploaders, target_uploader) + + unless Code.ensure_loaded?(uploader) do + raise("The uploader #{inspect(uploader)} is not an existing/loaded module.") + end + + target_enabled? = Pleroma.Config.get([Upload, :uploader]) == uploader + + unless target_enabled? do + Pleroma.Config.put([Upload, :uploader], uploader) + end + + Logger.info("Migrating files from local #{local_path} to #{to_string(uploader)}") + + if delete? do + Logger.warn( + "Attention: uploaded files will be deleted, hope you have backups! (--delete ; cancel with ^C)" + ) + + :timer.sleep(:timer.seconds(5)) + end + + uploads = + File.ls!(local_path) + |> Enum.map(fn id -> + root_path = Path.join(local_path, id) + + cond do + File.dir?(root_path) -> + files = for file <- File.ls!(root_path), do: {id, file, Path.join([root_path, file])} + + case List.first(files) do + {id, file, path} -> + {%Pleroma.Upload{id: id, name: file, path: id <> "/" <> file, tempfile: path}, + root_path} + + _ -> + nil + end + + File.exists?(root_path) -> + file = Path.basename(id) + [hash, ext] = String.split(id, ".") + {%Pleroma.Upload{id: hash, name: file, path: file, tempfile: root_path}, root_path} + + true -> + nil + end + end) + |> Enum.filter(& &1) + + total_count = length(uploads) + Logger.info("Found #{total_count} uploads") + + uploads + |> Task.async_stream( + fn {upload, root_path} -> + case Upload.store(upload, uploader: uploader, filters: [], size_limit: nil) do + {:ok, _} -> + if delete?, do: File.rm_rf!(root_path) + Logger.debug("uploaded: #{inspect(upload.path)} #{inspect(upload)}") + :ok + + error -> + Logger.error("failed to upload #{inspect(upload.path)}: #{inspect(error)}") + end + end, + timeout: 150_000 + ) + |> Stream.chunk_every(@log_every) + |> Enum.reduce(0, fn done, count -> + count = count + length(done) + Logger.info("Uploaded #{count}/#{total_count} files") + count + end) + + Logger.info("Done!") + end + + def run(_) do + Logger.error("Usage: migrate_local_uploads S3|Swift [--delete]") + end +end diff --git a/lib/mix/tasks/pleroma/sample_config.eex b/lib/mix/tasks/pleroma/sample_config.eex index 066939981..df9d1ad65 100644 --- a/lib/mix/tasks/pleroma/sample_config.eex +++ b/lib/mix/tasks/pleroma/sample_config.eex @@ -28,3 +28,44 @@ config :pleroma, Pleroma.Repo, database: "<%= dbname %>", hostname: "<%= dbhost %>", pool_size: 10 + +# Enable Strict-Transport-Security once SSL is working: +# config :pleroma, :http_security, +# sts: true + +# Configure S3 support if desired. +# The public S3 endpoint is different depending on region and provider, +# consult your S3 provider's documentation for details on what to use. +# +# config :pleroma, Pleroma.Uploaders.S3, +# bucket: "some-bucket", +# public_endpoint: "https://s3.amazonaws.com" +# +# Configure S3 credentials: +# config :ex_aws, :s3, +# access_key_id: "xxxxxxxxxxxxx", +# secret_access_key: "yyyyyyyyyyyy", +# region: "us-east-1", +# scheme: "https://" +# +# For using third-party S3 clones like wasabi, also do: +# config :ex_aws, :s3, +# host: "s3.wasabisys.com" + + +# Configure Openstack Swift support if desired. +# +# Many openstack deployments are different, so config is left very open with +# no assumptions made on which provider you're using. This should allow very +# wide support without needing separate handlers for OVH, Rackspace, etc. +# +# config :pleroma, Pleroma.Uploaders.Swift, +# container: "some-container", +# username: "api-username-yyyy", +# password: "api-key-xxxx", +# tenant_id: "<openstack-project/tenant-id>", +# auth_url: "https://keystone-endpoint.provider.com", +# storage_url: "https://swift-endpoint.prodider.com/v1/AUTH_<tenant>/<container>", +# object_url: "https://cdn-endpoint.provider.com/<container>" +# + diff --git a/lib/mix/tasks/reactivate_user.ex b/lib/mix/tasks/reactivate_user.ex new file mode 100644 index 000000000..a30d3ac8b --- /dev/null +++ b/lib/mix/tasks/reactivate_user.ex @@ -0,0 +1,19 @@ +defmodule Mix.Tasks.ReactivateUser do + use Mix.Task + alias Pleroma.User + + @moduledoc """ + Reactivate a user + + Usage: ``mix reactivate_user <nickname>`` + + Example: ``mix reactivate_user lain`` + """ + def run([nickname]) do + Mix.Task.run("app.start") + + with user <- User.get_by_nickname(nickname) do + User.deactivate(user, false) + end + end +end diff --git a/lib/mix/tasks/relay_follow.ex b/lib/mix/tasks/relay_follow.ex new file mode 100644 index 000000000..85b1c024d --- /dev/null +++ b/lib/mix/tasks/relay_follow.ex @@ -0,0 +1,24 @@ +defmodule Mix.Tasks.RelayFollow do + use Mix.Task + require Logger + alias Pleroma.Web.ActivityPub.Relay + + @shortdoc "Follows a remote relay" + @moduledoc """ + Follows a remote relay + + Usage: ``mix relay_follow <relay_url>`` + + Example: ``mix relay_follow https://example.org/relay`` + """ + def run([target]) do + Mix.Task.run("app.start") + + with {:ok, activity} <- Relay.follow(target) do + # put this task to sleep to allow the genserver to push out the messages + :timer.sleep(500) + else + {:error, e} -> Mix.shell().error("Error while following #{target}: #{inspect(e)}") + end + end +end diff --git a/lib/mix/tasks/relay_unfollow.ex b/lib/mix/tasks/relay_unfollow.ex new file mode 100644 index 000000000..237fb771c --- /dev/null +++ b/lib/mix/tasks/relay_unfollow.ex @@ -0,0 +1,23 @@ +defmodule Mix.Tasks.RelayUnfollow do + use Mix.Task + require Logger + alias Pleroma.Web.ActivityPub.Relay + + @moduledoc """ + Unfollows a remote relay + + Usage: ``mix relay_follow <relay_url>`` + + Example: ``mix relay_follow https://example.org/relay`` + """ + def run([target]) do + Mix.Task.run("app.start") + + with {:ok, activity} <- Relay.follow(target) do + # put this task to sleep to allow the genserver to push out the messages + :timer.sleep(500) + else + {:error, e} -> Mix.shell().error("Error while following #{target}: #{inspect(e)}") + end + end +end diff --git a/lib/mix/tasks/set_admin.ex b/lib/mix/tasks/set_admin.ex new file mode 100644 index 000000000..d5ccf261b --- /dev/null +++ b/lib/mix/tasks/set_admin.ex @@ -0,0 +1,32 @@ +defmodule Mix.Tasks.SetAdmin do + use Mix.Task + alias Pleroma.User + + @doc """ + Sets admin status + Usage: set_admin nickname [true|false] + """ + def run([nickname | rest]) do + Application.ensure_all_started(:pleroma) + + status = + case rest do + [status] -> status == "true" + _ -> true + end + + with %User{local: true} = user <- User.get_by_nickname(nickname) do + info = + user.info + |> Map.put("is_admin", !!status) + + cng = User.info_changeset(user, %{info: info}) + {:ok, user} = User.update_and_set_cache(cng) + + IO.puts("Admin status of #{nickname}: #{user.info["is_admin"]}") + else + _ -> + IO.puts("No local user #{nickname}") + end + end +end diff --git a/lib/mix/tasks/unsubscribe_user.ex b/lib/mix/tasks/unsubscribe_user.ex new file mode 100644 index 000000000..62ea61a5c --- /dev/null +++ b/lib/mix/tasks/unsubscribe_user.ex @@ -0,0 +1,38 @@ +defmodule Mix.Tasks.UnsubscribeUser do + use Mix.Task + alias Pleroma.{User, Repo} + require Logger + + @moduledoc """ + Deactivate and Unsubscribe local users from a user + + Usage: ``mix unsubscribe_user <nickname>`` + + Example: ``mix unsubscribe_user lain`` + """ + def run([nickname]) do + Mix.Task.run("app.start") + + with %User{} = user <- User.get_by_nickname(nickname) do + Logger.info("Deactivating #{user.nickname}") + User.deactivate(user) + + {:ok, friends} = User.get_friends(user) + + Enum.each(friends, fn friend -> + user = Repo.get(User, user.id) + + Logger.info("Unsubscribing #{friend.nickname} from #{user.nickname}") + User.unfollow(user, friend) + end) + + :timer.sleep(500) + + user = Repo.get(User, user.id) + + if length(user.following) == 0 do + Logger.info("Successfully unsubscribed all followers from #{user.nickname}") + end + end + end +end |