Merge branch 'feature/releases' into 'develop'
Releases See merge request pleroma/pleroma!1261
This commit is contained in:
commit
8fd68b8039
|
@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- [MongooseIM](https://github.com/esl/MongooseIM) http authentication support.
|
- [MongooseIM](https://github.com/esl/MongooseIM) http authentication support.
|
||||||
- LDAP authentication
|
- LDAP authentication
|
||||||
- External OAuth provider authentication
|
- External OAuth provider authentication
|
||||||
|
- Support for building a release using [`mix release`](https://hexdocs.pm/mix/master/Mix.Tasks.Release.html)
|
||||||
- A [job queue](https://git.pleroma.social/pleroma/pleroma_job_queue) for federation, emails, web push, etc.
|
- A [job queue](https://git.pleroma.social/pleroma/pleroma_job_queue) for federation, emails, web push, etc.
|
||||||
- [Prometheus](https://prometheus.io/) metrics
|
- [Prometheus](https://prometheus.io/) metrics
|
||||||
- Support for Mastodon's remote interaction
|
- Support for Mastodon's remote interaction
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
http: [port: 4000],
|
http: [port: 4000],
|
||||||
protocol: "http"
|
protocol: "http"
|
||||||
|
|
||||||
|
config :phoenix, serve_endpoints: true
|
||||||
|
|
||||||
# Do not print debug messages in production
|
# Do not print debug messages in production
|
||||||
config :logger, level: :warn
|
config :logger, level: :warn
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
import Config
|
|
@ -10,19 +10,53 @@ def start_pleroma do
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_option(options, opt, prompt, defval \\ nil, defname \\ nil) do
|
def get_option(options, opt, prompt, defval \\ nil, defname \\ nil) do
|
||||||
Keyword.get(options, opt) ||
|
Keyword.get(options, opt) || shell_prompt(prompt, defval, defname)
|
||||||
case Mix.shell().prompt("#{prompt} [#{defname || defval}]") do
|
|
||||||
"\n" ->
|
|
||||||
case defval do
|
|
||||||
nil -> get_option(options, opt, prompt, defval)
|
|
||||||
defval -> defval
|
|
||||||
end
|
|
||||||
|
|
||||||
opt ->
|
|
||||||
opt |> String.trim()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def shell_prompt(prompt, defval \\ nil, defname \\ nil) do
|
||||||
|
prompt_message = "#{prompt} [#{defname || defval}]"
|
||||||
|
|
||||||
|
input =
|
||||||
|
if mix_shell?(),
|
||||||
|
do: Mix.shell().prompt(prompt_message),
|
||||||
|
else: :io.get_line(prompt_message)
|
||||||
|
|
||||||
|
case input do
|
||||||
|
"\n" ->
|
||||||
|
case defval do
|
||||||
|
nil ->
|
||||||
|
shell_prompt(prompt, defval, defname)
|
||||||
|
|
||||||
|
defval ->
|
||||||
|
defval
|
||||||
|
end
|
||||||
|
|
||||||
|
input ->
|
||||||
|
String.trim(input)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def shell_yes?(message) do
|
||||||
|
if mix_shell?(),
|
||||||
|
do: Mix.shell().yes?("Continue?"),
|
||||||
|
else: shell_prompt(message, "Continue?") in ~w(Yn Y y)
|
||||||
|
end
|
||||||
|
|
||||||
|
def shell_info(message) do
|
||||||
|
if mix_shell?(),
|
||||||
|
do: Mix.shell().info(message),
|
||||||
|
else: IO.puts(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def shell_error(message) do
|
||||||
|
if mix_shell?(),
|
||||||
|
do: Mix.shell().error(message),
|
||||||
|
else: IO.puts(:stderr, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "Performs a safe check whether `Mix.shell/0` is available (does not raise if Mix is not loaded)"
|
||||||
|
def mix_shell?, do: :erlang.function_exported(Mix, :shell, 0)
|
||||||
|
|
||||||
def escape_sh_path(path) do
|
def escape_sh_path(path) do
|
||||||
~S(') <> String.replace(path, ~S('), ~S(\')) <> ~S(')
|
~S(') <> String.replace(path, ~S('), ~S(\')) <> ~S(')
|
||||||
end
|
end
|
||||||
|
|
|
@ -155,17 +155,17 @@ def run(["gen" | rest]) do
|
||||||
dbpass: dbpass
|
dbpass: dbpass
|
||||||
)
|
)
|
||||||
|
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"Writing config to #{config_path}. You should rename it to config/prod.secret.exs or config/dev.secret.exs."
|
"Writing config to #{config_path}. You should rename it to config/prod.secret.exs or config/dev.secret.exs."
|
||||||
)
|
)
|
||||||
|
|
||||||
File.write(config_path, result_config)
|
File.write(config_path, result_config)
|
||||||
Mix.shell().info("Writing #{psql_path}.")
|
Common.shell_info("Writing #{psql_path}.")
|
||||||
File.write(psql_path, result_psql)
|
File.write(psql_path, result_psql)
|
||||||
|
|
||||||
write_robots_txt(indexable)
|
write_robots_txt(indexable)
|
||||||
|
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"\n" <>
|
"\n" <>
|
||||||
"""
|
"""
|
||||||
To get started:
|
To get started:
|
||||||
|
@ -179,7 +179,7 @@ def run(["gen" | rest]) do
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Mix.shell().error(
|
Common.shell_error(
|
||||||
"The task would have overwritten the following files:\n" <>
|
"The task would have overwritten the following files:\n" <>
|
||||||
(Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
|
(Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
|
||||||
"Rerun with `--force` to overwrite them."
|
"Rerun with `--force` to overwrite them."
|
||||||
|
@ -204,10 +204,10 @@ defp write_robots_txt(indexable) do
|
||||||
|
|
||||||
if File.exists?(robots_txt_path) do
|
if File.exists?(robots_txt_path) do
|
||||||
File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
|
File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
|
||||||
Mix.shell().info("Backing up existing robots.txt to #{robots_txt_path}.bak")
|
Common.shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
|
||||||
end
|
end
|
||||||
|
|
||||||
File.write(robots_txt_path, robots_txt)
|
File.write(robots_txt_path, robots_txt)
|
||||||
Mix.shell().info("Writing #{robots_txt_path}.")
|
Common.shell_info("Writing #{robots_txt_path}.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ def run(["follow", target]) do
|
||||||
# put this task to sleep to allow the genserver to push out the messages
|
# put this task to sleep to allow the genserver to push out the messages
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
else
|
else
|
||||||
{:error, e} -> Mix.shell().error("Error while following #{target}: #{inspect(e)}")
|
{:error, e} -> Common.shell_error("Error while following #{target}: #{inspect(e)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ def run(["unfollow", target]) do
|
||||||
# put this task to sleep to allow the genserver to push out the messages
|
# put this task to sleep to allow the genserver to push out the messages
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
else
|
else
|
||||||
{:error, e} -> Mix.shell().error("Error while following #{target}: #{inspect(e)}")
|
{:error, e} -> Common.shell_error("Error while following #{target}: #{inspect(e)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,10 +38,10 @@ def run(["migrate_local", target_uploader | args]) do
|
||||||
Pleroma.Config.put([Upload, :uploader], uploader)
|
Pleroma.Config.put([Upload, :uploader], uploader)
|
||||||
end
|
end
|
||||||
|
|
||||||
Mix.shell().info("Migrating files from local #{local_path} to #{to_string(uploader)}")
|
Common.shell_info("Migrating files from local #{local_path} to #{to_string(uploader)}")
|
||||||
|
|
||||||
if delete? do
|
if delete? do
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"Attention: uploaded files will be deleted, hope you have backups! (--delete ; cancel with ^C)"
|
"Attention: uploaded files will be deleted, hope you have backups! (--delete ; cancel with ^C)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ def run(["migrate_local", target_uploader | args]) do
|
||||||
|> Enum.filter(& &1)
|
|> Enum.filter(& &1)
|
||||||
|
|
||||||
total_count = length(uploads)
|
total_count = length(uploads)
|
||||||
Mix.shell().info("Found #{total_count} uploads")
|
Common.shell_info("Found #{total_count} uploads")
|
||||||
|
|
||||||
uploads
|
uploads
|
||||||
|> Task.async_stream(
|
|> Task.async_stream(
|
||||||
|
@ -90,7 +90,7 @@ def run(["migrate_local", target_uploader | args]) do
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
Mix.shell().error("failed to upload #{inspect(upload.path)}: #{inspect(error)}")
|
Common.shell_error("failed to upload #{inspect(upload.path)}: #{inspect(error)}")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
timeout: 150_000
|
timeout: 150_000
|
||||||
|
@ -99,10 +99,10 @@ def run(["migrate_local", target_uploader | args]) do
|
||||||
# credo:disable-for-next-line Credo.Check.Warning.UnusedEnumOperation
|
# credo:disable-for-next-line Credo.Check.Warning.UnusedEnumOperation
|
||||||
|> Enum.reduce(0, fn done, count ->
|
|> Enum.reduce(0, fn done, count ->
|
||||||
count = count + length(done)
|
count = count + length(done)
|
||||||
Mix.shell().info("Uploaded #{count}/#{total_count} files")
|
Common.shell_info("Uploaded #{count}/#{total_count} files")
|
||||||
count
|
count
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Mix.shell().info("Done!")
|
Common.shell_info("Done!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -115,7 +115,7 @@ def run(["new", nickname, email | rest]) do
|
||||||
admin? = Keyword.get(options, :admin, false)
|
admin? = Keyword.get(options, :admin, false)
|
||||||
assume_yes? = Keyword.get(options, :assume_yes, false)
|
assume_yes? = Keyword.get(options, :assume_yes, false)
|
||||||
|
|
||||||
Mix.shell().info("""
|
Common.shell_info("""
|
||||||
A user will be created with the following information:
|
A user will be created with the following information:
|
||||||
- nickname: #{nickname}
|
- nickname: #{nickname}
|
||||||
- email: #{email}
|
- email: #{email}
|
||||||
|
@ -128,7 +128,7 @@ def run(["new", nickname, email | rest]) do
|
||||||
- admin: #{if(admin?, do: "true", else: "false")}
|
- admin: #{if(admin?, do: "true", else: "false")}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
proceed? = assume_yes? or Mix.shell().yes?("Continue?")
|
proceed? = assume_yes? or Common.shell_yes?("Continue?")
|
||||||
|
|
||||||
if proceed? do
|
if proceed? do
|
||||||
Common.start_pleroma()
|
Common.start_pleroma()
|
||||||
|
@ -145,7 +145,7 @@ def run(["new", nickname, email | rest]) do
|
||||||
changeset = User.register_changeset(%User{}, params, need_confirmation: false)
|
changeset = User.register_changeset(%User{}, params, need_confirmation: false)
|
||||||
{:ok, _user} = User.register(changeset)
|
{:ok, _user} = User.register(changeset)
|
||||||
|
|
||||||
Mix.shell().info("User #{nickname} created")
|
Common.shell_info("User #{nickname} created")
|
||||||
|
|
||||||
if moderator? do
|
if moderator? do
|
||||||
run(["set", nickname, "--moderator"])
|
run(["set", nickname, "--moderator"])
|
||||||
|
@ -159,7 +159,7 @@ def run(["new", nickname, email | rest]) do
|
||||||
run(["reset_password", nickname])
|
run(["reset_password", nickname])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Mix.shell().info("User will not be created.")
|
Common.shell_info("User will not be created.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -168,10 +168,10 @@ def run(["rm", nickname]) do
|
||||||
|
|
||||||
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
User.perform(:delete, user)
|
User.perform(:delete, user)
|
||||||
Mix.shell().info("User #{nickname} deleted.")
|
Common.shell_info("User #{nickname} deleted.")
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No local user #{nickname}")
|
Common.shell_error("No local user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -181,12 +181,12 @@ def run(["toggle_activated", nickname]) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
{:ok, user} = User.deactivate(user, !user.info.deactivated)
|
{:ok, user} = User.deactivate(user, !user.info.deactivated)
|
||||||
|
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"Activation status of #{nickname}: #{if(user.info.deactivated, do: "de", else: "")}activated"
|
"Activation status of #{nickname}: #{if(user.info.deactivated, do: "de", else: "")}activated"
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No user #{nickname}")
|
Common.shell_error("No user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ def run(["reset_password", nickname]) do
|
||||||
|
|
||||||
with %User{local: true} = user <- User.get_cached_by_nickname(nickname),
|
with %User{local: true} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
|
{:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||||
Mix.shell().info("Generated password reset token for #{user.nickname}")
|
Common.shell_info("Generated password reset token for #{user.nickname}")
|
||||||
|
|
||||||
IO.puts(
|
IO.puts(
|
||||||
"URL: #{
|
"URL: #{
|
||||||
|
@ -208,7 +208,7 @@ def run(["reset_password", nickname]) do
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No local user #{nickname}")
|
Common.shell_error("No local user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ def run(["unsubscribe", nickname]) do
|
||||||
Common.start_pleroma()
|
Common.start_pleroma()
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
Mix.shell().info("Deactivating #{user.nickname}")
|
Common.shell_info("Deactivating #{user.nickname}")
|
||||||
User.deactivate(user)
|
User.deactivate(user)
|
||||||
|
|
||||||
{:ok, friends} = User.get_friends(user)
|
{:ok, friends} = User.get_friends(user)
|
||||||
|
@ -224,7 +224,7 @@ def run(["unsubscribe", nickname]) do
|
||||||
Enum.each(friends, fn friend ->
|
Enum.each(friends, fn friend ->
|
||||||
user = User.get_cached_by_id(user.id)
|
user = User.get_cached_by_id(user.id)
|
||||||
|
|
||||||
Mix.shell().info("Unsubscribing #{friend.nickname} from #{user.nickname}")
|
Common.shell_info("Unsubscribing #{friend.nickname} from #{user.nickname}")
|
||||||
User.unfollow(user, friend)
|
User.unfollow(user, friend)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -233,11 +233,11 @@ def run(["unsubscribe", nickname]) do
|
||||||
user = User.get_cached_by_id(user.id)
|
user = User.get_cached_by_id(user.id)
|
||||||
|
|
||||||
if Enum.empty?(user.following) do
|
if Enum.empty?(user.following) do
|
||||||
Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}")
|
Common.shell_info("Successfully unsubscribed all followers from #{user.nickname}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No user #{nickname}")
|
Common.shell_error("No user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ def run(["set", nickname | rest]) do
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No local user #{nickname}")
|
Common.shell_error("No local user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -284,10 +284,10 @@ def run(["tag", nickname | tags]) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
user = user |> User.tag(tags)
|
user = user |> User.tag(tags)
|
||||||
|
|
||||||
Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}")
|
Common.shell_info("Tags of #{user.nickname}: #{inspect(tags)}")
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("Could not change user tags for #{nickname}")
|
Common.shell_error("Could not change user tags for #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -297,10 +297,10 @@ def run(["untag", nickname | tags]) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
user = user |> User.untag(tags)
|
user = user |> User.untag(tags)
|
||||||
|
|
||||||
Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}")
|
Common.shell_info("Tags of #{user.nickname}: #{inspect(tags)}")
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("Could not change user tags for #{nickname}")
|
Common.shell_error("Could not change user tags for #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ def run(["invite" | rest]) do
|
||||||
with {:ok, val} <- options[:expires_at],
|
with {:ok, val} <- options[:expires_at],
|
||||||
options = Map.put(options, :expires_at, val),
|
options = Map.put(options, :expires_at, val),
|
||||||
{:ok, invite} <- UserInviteToken.create_invite(options) do
|
{:ok, invite} <- UserInviteToken.create_invite(options) do
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"Generated user invite token " <> String.replace(invite.invite_type, "_", " ")
|
"Generated user invite token " <> String.replace(invite.invite_type, "_", " ")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -340,14 +340,14 @@ def run(["invite" | rest]) do
|
||||||
IO.puts(url)
|
IO.puts(url)
|
||||||
else
|
else
|
||||||
error ->
|
error ->
|
||||||
Mix.shell().error("Could not create invite token: #{inspect(error)}")
|
Common.shell_error("Could not create invite token: #{inspect(error)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(["invites"]) do
|
def run(["invites"]) do
|
||||||
Common.start_pleroma()
|
Common.start_pleroma()
|
||||||
|
|
||||||
Mix.shell().info("Invites list:")
|
Common.shell_info("Invites list:")
|
||||||
|
|
||||||
UserInviteToken.list_invites()
|
UserInviteToken.list_invites()
|
||||||
|> Enum.each(fn invite ->
|
|> Enum.each(fn invite ->
|
||||||
|
@ -361,7 +361,7 @@ def run(["invites"]) do
|
||||||
" | Max use: #{max_use} Left use: #{max_use - invite.uses}"
|
" | Max use: #{max_use} Left use: #{max_use - invite.uses}"
|
||||||
end
|
end
|
||||||
|
|
||||||
Mix.shell().info(
|
Common.shell_info(
|
||||||
"ID: #{invite.id} | Token: #{invite.token} | Token type: #{invite.invite_type} | Used: #{
|
"ID: #{invite.id} | Token: #{invite.token} | Token type: #{invite.invite_type} | Used: #{
|
||||||
invite.used
|
invite.used
|
||||||
}#{expire_info}#{using_info}"
|
}#{expire_info}#{using_info}"
|
||||||
|
@ -374,9 +374,9 @@ def run(["revoke_invite", token]) do
|
||||||
|
|
||||||
with {:ok, invite} <- UserInviteToken.find_by_token(token),
|
with {:ok, invite} <- UserInviteToken.find_by_token(token),
|
||||||
{:ok, _} <- UserInviteToken.update_invite(invite, %{used: true}) do
|
{:ok, _} <- UserInviteToken.update_invite(invite, %{used: true}) do
|
||||||
Mix.shell().info("Invite for token #{token} was revoked.")
|
Common.shell_info("Invite for token #{token} was revoked.")
|
||||||
else
|
else
|
||||||
_ -> Mix.shell().error("No invite found with token #{token}")
|
_ -> Common.shell_error("No invite found with token #{token}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -385,10 +385,10 @@ def run(["delete_activities", nickname]) do
|
||||||
|
|
||||||
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
{:ok, _} = User.delete_user_activities(user)
|
{:ok, _} = User.delete_user_activities(user)
|
||||||
Mix.shell().info("User #{nickname} statuses deleted.")
|
Common.shell_info("User #{nickname} statuses deleted.")
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No local user #{nickname}")
|
Common.shell_error("No local user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -400,10 +400,10 @@ def run(["toggle_confirmed", nickname]) do
|
||||||
|
|
||||||
message = if user.info.confirmation_pending, do: "needs", else: "doesn't need"
|
message = if user.info.confirmation_pending, do: "needs", else: "doesn't need"
|
||||||
|
|
||||||
Mix.shell().info("#{nickname} #{message} confirmation.")
|
Common.shell_info("#{nickname} #{message} confirmation.")
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
Mix.shell().error("No local user #{nickname}")
|
Common.shell_error("No local user #{nickname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ defp set_moderator(user, value) do
|
||||||
|
|
||||||
{:ok, user} = User.update_and_set_cache(user_cng)
|
{:ok, user} = User.update_and_set_cache(user_cng)
|
||||||
|
|
||||||
Mix.shell().info("Moderator status of #{user.nickname}: #{user.info.is_moderator}")
|
Common.shell_info("Moderator status of #{user.nickname}: #{user.info.is_moderator}")
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ defp set_admin(user, value) do
|
||||||
|
|
||||||
{:ok, user} = User.update_and_set_cache(user_cng)
|
{:ok, user} = User.update_and_set_cache(user_cng)
|
||||||
|
|
||||||
Mix.shell().info("Admin status of #{user.nickname}: #{user.info.is_admin}")
|
Common.shell_info("Admin status of #{user.nickname}: #{user.info.is_admin}")
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ defp set_locked(user, value) do
|
||||||
|
|
||||||
{:ok, user} = User.update_and_set_cache(user_cng)
|
{:ok, user} = User.update_and_set_cache(user_cng)
|
||||||
|
|
||||||
Mix.shell().info("Locked status of #{user.nickname}: #{user.info.locked}")
|
Common.shell_info("Locked status of #{user.nickname}: #{user.info.locked}")
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.ReleaseTasks do
|
||||||
|
@repo Pleroma.Repo
|
||||||
|
|
||||||
|
def run(args) do
|
||||||
|
Mix.Tasks.Pleroma.Common.start_pleroma()
|
||||||
|
[task | args] = String.split(args)
|
||||||
|
|
||||||
|
case task do
|
||||||
|
"migrate" -> migrate()
|
||||||
|
"create" -> create()
|
||||||
|
"rollback" -> rollback(String.to_integer(Enum.at(args, 0)))
|
||||||
|
task -> mix_task(task, args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp mix_task(task, args) do
|
||||||
|
{:ok, modules} = :application.get_key(:pleroma, :modules)
|
||||||
|
|
||||||
|
module =
|
||||||
|
Enum.find(modules, fn module ->
|
||||||
|
module = Module.split(module)
|
||||||
|
|
||||||
|
match?(["Mix", "Tasks", "Pleroma" | _], module) and
|
||||||
|
String.downcase(List.last(module)) == task
|
||||||
|
end)
|
||||||
|
|
||||||
|
if module do
|
||||||
|
module.run(args)
|
||||||
|
else
|
||||||
|
IO.puts("The task #{task} does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrate do
|
||||||
|
{:ok, _, _} = Ecto.Migrator.with_repo(@repo, &Ecto.Migrator.run(&1, :up, all: true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def rollback(version) do
|
||||||
|
{:ok, _, _} = Ecto.Migrator.with_repo(@repo, &Ecto.Migrator.run(&1, :down, to: version))
|
||||||
|
end
|
||||||
|
|
||||||
|
def create do
|
||||||
|
case @repo.__adapter__.storage_up(@repo.config) do
|
||||||
|
:ok ->
|
||||||
|
IO.puts("The database for #{inspect(@repo)} has been created")
|
||||||
|
|
||||||
|
{:error, :already_up} ->
|
||||||
|
IO.puts("The database for #{inspect(@repo)} has already been created")
|
||||||
|
|
||||||
|
{:error, term} when is_binary(term) ->
|
||||||
|
IO.puts(:stderr, "The database for #{inspect(@repo)} couldn't be created: #{term}")
|
||||||
|
|
||||||
|
{:error, term} ->
|
||||||
|
IO.puts(
|
||||||
|
:stderr,
|
||||||
|
"The database for #{inspect(@repo)} couldn't be created: #{inspect(term)}"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
mix.exs
12
mix.exs
|
@ -32,10 +32,22 @@ def project do
|
||||||
],
|
],
|
||||||
main: "readme",
|
main: "readme",
|
||||||
output: "priv/static/doc"
|
output: "priv/static/doc"
|
||||||
|
],
|
||||||
|
releases: [
|
||||||
|
pleroma: [
|
||||||
|
include_executables_for: [:unix],
|
||||||
|
applications: [ex_syslogger: :load, syslog: :load],
|
||||||
|
steps: [:assemble, ©_pleroma_ctl/1]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def copy_pleroma_ctl(%{path: target_path} = release) do
|
||||||
|
File.cp!("./rel/pleroma_ctl", Path.join([target_path, "bin", "pleroma_ctl"]))
|
||||||
|
release
|
||||||
|
end
|
||||||
|
|
||||||
# Configuration for the OTP application.
|
# Configuration for the OTP application.
|
||||||
#
|
#
|
||||||
# Type `mix help compile.app` for more information.
|
# Type `mix help compile.app` for more information.
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Sets and enables heart (recommended only in daemon mode)
|
||||||
|
# if [ "$RELEASE_COMMAND" = "daemon" ] || [ "$RELEASE_COMMAND" = "daemon_iex" ]; then
|
||||||
|
# HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND"
|
||||||
|
# export HEART_COMMAND
|
||||||
|
# export ELIXIR_ERL_OPTIONS="-heart"
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# Set the release to work across nodes
|
||||||
|
export RELEASE_DISTRIBUTION=name
|
||||||
|
export RELEASE_NODE=<%= @release.name %>@127.0.0.1
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# XXX: This should be removed when elixir's releases get custom command support
|
||||||
|
if [ -z "$1" ] || [ "$1" == "help" ]; then
|
||||||
|
echo "Usage: $(basename "$0") COMMAND [ARGS]
|
||||||
|
|
||||||
|
The known commands are:
|
||||||
|
|
||||||
|
create Create database schema (needs to be executed only once)
|
||||||
|
migrate Execute database migrations (needs to be done after updates)
|
||||||
|
rollback [VERSION] Rollback database migrations (needs to be done before downgrading)
|
||||||
|
|
||||||
|
and any mix tasks under Pleroma namespace, for example \`mix pleroma.user COMMAND\` is
|
||||||
|
equivalent to \`$(basename "$0") user COMMAND\`
|
||||||
|
"
|
||||||
|
else
|
||||||
|
SCRIPT=$(readlink -f "$0")
|
||||||
|
SCRIPTPATH=$(dirname "$SCRIPT")
|
||||||
|
$SCRIPTPATH/pleroma eval 'Pleroma.ReleaseTasks.run("'"$*"'")'
|
||||||
|
fi
|
|
@ -0,0 +1,11 @@
|
||||||
|
## Customize flags given to the VM: http://erlang.org/doc/man/erl.html
|
||||||
|
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
|
||||||
|
|
||||||
|
## Number of dirty schedulers doing IO work (file, sockets, etc)
|
||||||
|
##+SDio 5
|
||||||
|
|
||||||
|
## Increase number of concurrent ports/sockets
|
||||||
|
##+Q 65536
|
||||||
|
|
||||||
|
## Tweak GC to run more often
|
||||||
|
##-env ERL_FULLSWEEP_AFTER 10
|
Loading…
Reference in New Issue