Merge branch 'develop' into feature/multiple-users-activation-permissions

This commit is contained in:
Maxim Filippov 2019-10-11 15:59:35 +03:00
commit c0aca32dd0
110 changed files with 831 additions and 300 deletions

View File

@ -1,3 +1,3 @@
[
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"]
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}", "priv/repo/migrations/*.exs"]
]

View File

@ -16,10 +16,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OAuth: support for hierarchical permissions / [Mastodon 2.4.3 OAuth permissions](https://docs.joinmastodon.org/api/permissions/)
- Authentication: Added rate limit for password-authorized actions / login existence checks
- Metadata Link: Atom syndication Feed
- Mix task to re-count statuses for all users (`mix pleroma.count_statuses`)
- Admin API: `/users/:nickname/toggle_activation` endpoint is now deprecated in favor of: `/users/activate`, `/users/deactivate`, both accept `nicknames` array
- Admin API: `POST /api/pleroma/admin/users/:nickname/permission_group/:permission_group` / `DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group` are deprecated in favor of: `POST /api/pleroma/admin/users/permission_group/:permission_group` / `DELETE /api/pleroma/admin/users/permission_group/:permission_group` (both accept `nicknames` array)
### Changed
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
- **Breaking:** Admin API: Return link alongside with token on password reset
@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Admin API: Return link alongside with token on password reset
- MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities
- OStatus: Extract RSS functionality
- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`)
### Fixed
- Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`)

View File

@ -0,0 +1,22 @@
defmodule Mix.Tasks.Pleroma.CountStatuses do
@shortdoc "Re-counts statuses for all users"
use Mix.Task
alias Pleroma.User
import Ecto.Query
def run([]) do
Mix.Pleroma.start_pleroma()
stream =
User
|> where(local: true)
|> Pleroma.Repo.stream()
Pleroma.Repo.transaction(fn ->
Enum.each(stream, &User.update_note_count/1)
end)
Mix.Pleroma.shell_info("Done")
end
end

View File

@ -167,7 +167,11 @@ def create(%{assigns: %{user: _user}} = conn, %{"media_ids" => _} = params) do
def show(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
true <- Visibility.visible_for_user?(activity, user) do
try_render(conn, "show.json", activity: activity, for: user)
try_render(conn, "show.json",
activity: activity,
for: user,
with_direct_conversation_id: true
)
end
end

View File

@ -3,14 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.User do
def change do
create_if_not_exists table(:users) do
add :email, :string
add :password_hash, :string
add :name, :string
add :nickname, :string
add :bio, :string
add(:email, :string)
add(:password_hash, :string)
add(:name, :string)
add(:nickname, :string)
add(:bio, :string)
timestamps()
end
end
end

View File

@ -3,12 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.Activity do
def change do
create_if_not_exists table(:activities) do
add :data, :map
add(:data, :map)
timestamps()
end
create_if_not_exists index(:activities, [:data], using: :gin)
create_if_not_exists(index(:activities, [:data], using: :gin))
end
end

View File

@ -3,10 +3,9 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.Object do
def change do
create_if_not_exists table(:objects) do
add :data, :map
add(:data, :map)
timestamps()
end
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddFollowingListToUsers do
def change do
alter table(:users) do
add :following, :map
add(:following, :map)
end
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddApIdToUsers do
def change do
alter table(:users) do
add :ap_id, :string
add(:ap_id, :string)
end
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddIndexToObjects do
use Ecto.Migration
def change do
create_if_not_exists index(:objects, [:data], using: :gin)
create_if_not_exists(index(:objects, [:data], using: :gin))
end
end

View File

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.AddUniqueIndexToEmailAndNickname do
use Ecto.Migration
def change do
create_if_not_exists unique_index(:users, [:email])
create_if_not_exists unique_index(:users, [:nickname])
create_if_not_exists(unique_index(:users, [:email]))
create_if_not_exists(unique_index(:users, [:nickname]))
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddAvatarObjectToUsers do
def change do
alter table(:users) do
add :avatar, :map
add(:avatar, :map)
end
end
end

View File

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateWebsubServerSubscription do
def change do
create_if_not_exists table(:websub_server_subscriptions) do
add :topic, :string
add :callback, :string
add :secret, :string
add :valid_until, :naive_datetime
add :state, :string
add(:topic, :string)
add(:callback, :string)
add(:secret, :string)
add(:valid_until, :naive_datetime)
add(:state, :string)
timestamps()
end

View File

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.AddFieldsToUsers do
def change do
alter table(:users) do
add :local, :boolean, default: true
add :info, :map
add(:local, :boolean, default: true)
add(:info, :map)
end
end
end

View File

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateWebsubClientSubscription do
def change do
create_if_not_exists table(:websub_client_subscriptions) do
add :topic, :string
add :secret, :string
add :valid_until, :naive_datetime_usec
add :state, :string
add :subscribers, :map
add(:topic, :string)
add(:secret, :string)
add(:valid_until, :naive_datetime_usec)
add(:state, :string)
add(:subscribers, :map)
timestamps()
end

View File

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.AddUserAndHub do
def change do
alter table(:websub_client_subscriptions) do
add :hub, :string
add :user_id, references(:users)
add(:hub, :string)
add(:user_id, references(:users))
end
end
end

View File

@ -2,10 +2,16 @@ defmodule Pleroma.Repo.Migrations.AddIdContraintsToActivitiesAndObjectsPartTwo d
use Ecto.Migration
def up do
drop_if_exists index(:objects, ["(data->>\"id\")"], name: :objects_unique_apid_index)
drop_if_exists index(:activities, ["(data->>\"id\")"], name: :activities_unique_apid_index)
create_if_not_exists unique_index(:objects, ["(data->>'id')"], name: :objects_unique_apid_index)
create_if_not_exists unique_index(:activities, ["(data->>'id')"], name: :activities_unique_apid_index)
drop_if_exists(index(:objects, ["(data->>\"id\")"], name: :objects_unique_apid_index))
drop_if_exists(index(:activities, ["(data->>\"id\")"], name: :activities_unique_apid_index))
create_if_not_exists(
unique_index(:objects, ["(data->>'id')"], name: :objects_unique_apid_index)
)
create_if_not_exists(
unique_index(:activities, ["(data->>'id')"], name: :activities_unique_apid_index)
)
end
def down, do: :ok

View File

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddLocalFieldToActivities do
def change do
alter table(:activities) do
add :local, :boolean, default: true
add(:local, :boolean, default: true)
end
create_if_not_exists index(:activities, [:local])
create_if_not_exists(index(:activities, [:local]))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddUniqueIndexToAPID do
use Ecto.Migration
def change do
create_if_not_exists unique_index(:users, [:ap_id])
create_if_not_exists(unique_index(:users, [:ap_id]))
end
end

View File

@ -3,14 +3,13 @@ defmodule Pleroma.Repo.Migrations.LongerBios do
def up do
alter table(:users) do
modify :bio, :text
modify(:bio, :text)
end
end
def down do
alter table(:users) do
modify :bio, :string
modify(:bio, :string)
end
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.RemoveActivitiesIndex do
use Ecto.Migration
def change do
drop_if_exists index(:activities, [:data])
drop_if_exists(index(:activities, [:data]))
end
end

View File

@ -2,7 +2,16 @@ defmodule Pleroma.Repo.Migrations.AddObjectActivityIndexPartTwo do
use Ecto.Migration
def change do
drop_if_exists index(:objects, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index)
create_if_not_exists index(:activities, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index)
drop_if_exists(
index(:objects, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
create_if_not_exists(
index(:activities, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
end
end

View File

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.AddActorIndexToActivity do
use Ecto.Migration
def change do
create_if_not_exists index(:activities, ["(data->>'actor')", "inserted_at desc"], name: :activities_actor_index)
create_if_not_exists(
index(:activities, ["(data->>'actor')", "inserted_at desc"], name: :activities_actor_index)
)
end
end

View File

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.AddFollowerAddressToUser do
def up do
alter table(:users) do
add :follower_address, :string, unique: true
add(:follower_address, :string, unique: true)
end
end
def down do
alter table(:users) do
remove :follower_address
remove(:follower_address)
end
end
end

View File

@ -3,12 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddMastodonApps do
def change do
create_if_not_exists table(:apps) do
add :client_name, :string
add :redirect_uris, :string
add :scopes, :string
add :website, :string
add :client_id, :string
add :client_secret, :string
add(:client_name, :string)
add(:redirect_uris, :string)
add(:scopes, :string)
add(:website, :string)
add(:client_id, :string)
add(:client_secret, :string)
timestamps()
end

View File

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateOAuthAuthorizations do
def change do
create_if_not_exists table(:oauth_authorizations) do
add :app_id, references(:apps)
add :user_id, references(:users)
add :token, :string
add :valid_until, :naive_datetime_usec
add :used, :boolean, default: false
add(:app_id, references(:apps))
add(:user_id, references(:users))
add(:token, :string)
add(:valid_until, :naive_datetime_usec)
add(:used, :boolean, default: false)
timestamps()
end

View File

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateOAuthToken do
def change do
create_if_not_exists table(:oauth_tokens) do
add :app_id, references(:apps)
add :user_id, references(:users)
add :token, :string
add :refresh_token, :string
add :valid_until, :naive_datetime_usec
add(:app_id, references(:apps))
add(:user_id, references(:users))
add(:token, :string)
add(:refresh_token, :string)
add(:valid_until, :naive_datetime_usec)
timestamps()
end

View File

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateNotifications do
def change do
create_if_not_exists table(:notifications) do
add :user_id, references(:users, on_delete: :delete_all)
add :activity_id, references(:activities, on_delete: :delete_all)
add :seen, :boolean, default: false
add(:user_id, references(:users, on_delete: :delete_all))
add(:activity_id, references(:activities, on_delete: :delete_all))
add(:seen, :boolean, default: false)
timestamps()
end
create_if_not_exists index(:notifications, [:user_id])
create_if_not_exists(index(:notifications, [:user_id]))
end
end

View File

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.AddContextIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["(data->>'type')", "(data->>'context')"], name: :activities_context_index, concurrently: true)
create(
index(:activities, ["(data->>'type')", "(data->>'context')"],
name: :activities_context_index,
concurrently: true
)
)
end
end

View File

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddFTSIndexToActivities do
@disable_ddl_transaction true
def change do
create index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"], concurrently: true, using: :gin, name: :activities_fts)
create(
index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"],
concurrently: true,
using: :gin,
name: :activities_fts
)
)
end
end

View File

@ -4,6 +4,12 @@ defmodule Pleroma.Repo.Migrations.AddTagIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["(data #> '{\"object\",\"tag\"}')"], concurrently: true, using: :gin, name: :activities_tags)
create(
index(:activities, ["(data #> '{\"object\",\"tag\"}')"],
concurrently: true,
using: :gin,
name: :activities_tags
)
)
end
end

View File

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.CreatePasswordResetTokens do
def change do
create_if_not_exists table(:password_reset_tokens) do
add :token, :string
add :user_id, references(:users)
add :used, :boolean, default: false
add(:token, :string)
add(:user_id, references(:users))
add(:used, :boolean, default: false)
timestamps()
end

View File

@ -4,7 +4,17 @@ defmodule Pleroma.Repo.Migrations.AddSecondObjectIndexToActivty do
@disable_ddl_transaction true
def change do
drop_if_exists index(:activities, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index)
create index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"], name: :activities_create_objects_index, concurrently: true)
drop_if_exists(
index(:activities, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
create(
index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"],
name: :activities_create_objects_index,
concurrently: true
)
)
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropObjectIndex do
use Ecto.Migration
def change do
drop_if_exists index(:objects, [:data], using: :gin)
drop_if_exists(index(:objects, [:data], using: :gin))
end
end

View File

@ -4,6 +4,11 @@ defmodule Pleroma.Repo.Migrations.AddObjectActorIndex do
@disable_ddl_transaction true
def change do
create index(:objects, ["(data->>'actor')", "(data->>'type')"], concurrently: true, name: :objects_actor_type)
create(
index(:objects, ["(data->>'actor')", "(data->>'type')"],
concurrently: true,
name: :objects_actor_type
)
)
end
end

View File

@ -5,16 +5,17 @@ defmodule Pleroma.Repo.Migrations.AddActorToActivity do
def up do
alter table(:activities) do
add :actor, :string
add(:actor, :string)
end
create index(:activities, [:actor, "id DESC NULLS LAST"], concurrently: true)
create(index(:activities, [:actor, "id DESC NULLS LAST"], concurrently: true))
end
def down do
drop_if_exists index(:activities, [:actor, "id DESC NULLS LAST"])
drop_if_exists(index(:activities, [:actor, "id DESC NULLS LAST"]))
alter table(:activities) do
remove :actor
remove(:actor)
end
end
end

View File

@ -5,17 +5,19 @@ defmodule Pleroma.Repo.Migrations.FillActorField do
def up do
max = Repo.aggregate(Activity, :max, :id)
if max do
IO.puts("#{max} activities")
chunks = 0..(round(max / 10_000))
chunks = 0..round(max / 10_000)
Enum.each(chunks, fn (i) ->
Enum.each(chunks, fn i ->
min = i * 10_000
max = min + 10_000
execute("""
update activities set actor = data->>'actor' where id > #{min} and id <= #{max};
""")
|> IO.inspect
|> IO.inspect()
end)
end
end
@ -23,4 +25,3 @@ def up do
def down do
end
end

View File

@ -3,6 +3,6 @@ defmodule Pleroma.Repo.Migrations.AddSortIndexToActivities do
@disable_ddl_transaction true
def change do
create index(:activities, ["id desc nulls last"], concurrently: true)
create(index(:activities, ["id desc nulls last"], concurrently: true))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddLocalIndexToUser do
use Ecto.Migration
def change do
create_if_not_exists index(:users, [:local])
create_if_not_exists(index(:users, [:local]))
end
end

View File

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddRecipientsToActivities do
def change do
alter table(:activities) do
add :recipients, {:array, :string}
add(:recipients, {:array, :string})
end
create_if_not_exists index(:activities, [:recipients], using: :gin)
create_if_not_exists(index(:activities, [:recipients], using: :gin))
end
end

View File

@ -4,17 +4,21 @@ defmodule Pleroma.Repo.Migrations.FillRecipientsInActivities do
def up do
max = Repo.aggregate(Activity, :max, :id)
if max do
IO.puts("#{max} activities")
chunks = 0..(round(max / 10_000))
chunks = 0..round(max / 10_000)
Enum.each(chunks, fn (i) ->
Enum.each(chunks, fn i ->
min = i * 10_000
max = min + 10_000
execute("""
update activities set recipients = array(select jsonb_array_elements_text(data->'to')) where id > #{min} and id <= #{max};
update activities set recipients = array(select jsonb_array_elements_text(data->'to')) where id > #{
min
} and id <= #{max};
""")
|> IO.inspect
|> IO.inspect()
end)
end
end

View File

@ -3,17 +3,18 @@ defmodule Pleroma.Repo.Migrations.MakeFollowingPostgresArray do
def up do
alter table(:users) do
add :following_temp, {:array, :string}
add(:following_temp, {:array, :string})
end
execute """
execute("""
update users set following_temp = array(select jsonb_array_elements_text(following));
"""
""")
alter table(:users) do
remove :following
remove(:following)
end
rename table(:users), :following_temp, to: :following
rename(table(:users), :following_temp, to: :following)
end
def down, do: :ok

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddFollowerAddressIndexToUsers do
@disable_ddl_transaction true
def change do
create index(:users, [:follower_address], concurrently: true)
create index(:users, [:following], concurrently: true, using: :gin)
create(index(:users, [:follower_address], concurrently: true))
create(index(:users, [:following], concurrently: true, using: :gin))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropLocalIndexOnActivities do
use Ecto.Migration
def change do
drop_if_exists index(:users, [:local])
drop_if_exists(index(:users, [:local]))
end
end

View File

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.ActuallyDropLocalIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:users, [:local])
drop_if_exists index("activities", :local)
create_if_not_exists(index(:users, [:local]))
drop_if_exists(index("activities", :local))
end
end

View File

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateLists do
def change do
create_if_not_exists table(:lists) do
add :user_id, references(:users, on_delete: :delete_all)
add :title, :string
add :following, {:array, :string}
add(:user_id, references(:users, on_delete: :delete_all))
add(:title, :string)
add(:following, {:array, :string})
timestamps()
end
create_if_not_exists index(:lists, [:user_id])
create_if_not_exists(index(:lists, [:user_id]))
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.ModifyActivityIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["id desc nulls last", "local"], concurrently: true)
drop_if_exists index(:activities, ["id desc nulls last"])
create(index(:activities, ["id desc nulls last", "local"], concurrently: true))
drop_if_exists(index(:activities, ["id desc nulls last"]))
end
end

View File

@ -4,8 +4,15 @@ defmodule Pleroma.Repo.Migrations.AddTrigramExtension do
def up do
Logger.warn("ATTENTION ATTENTION ATTENTION\n")
Logger.warn("This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n")
Logger.warn("sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n")
Logger.warn(
"This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n"
)
Logger.warn(
"sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n"
)
execute("create extension if not exists pg_trgm")
end

View File

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserTrigramIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:users, ["(nickname || name) gist_trgm_ops"], name: :users_trigram_index, using: :gist)
create_if_not_exists(
index(:users, ["(nickname || name) gist_trgm_ops"], name: :users_trigram_index, using: :gist)
)
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddListFollowIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:lists, [:following])
create_if_not_exists(index(:lists, [:following]))
end
end

View File

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateApidHostExtractionIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["(split_part(actor, '/', 3))"], concurrently: true, name: :activities_hosts)
create(
index(:activities, ["(split_part(actor, '/', 3))"],
concurrently: true,
name: :activities_hosts
)
)
end
end

View File

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserInviteTokens do
def change do
create_if_not_exists table(:user_invite_tokens) do
add :token, :string
add :used, :boolean, default: false
add(:token, :string)
add(:used, :boolean, default: false)
timestamps()
end

View File

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateActivitiesInReplyToIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["(data->'object'->>'inReplyTo')"], concurrently: true, name: :activities_in_reply_to)
create(
index(:activities, ["(data->'object'->>'inReplyTo')"],
concurrently: true,
name: :activities_in_reply_to
)
)
end
end

View File

@ -3,18 +3,21 @@ defmodule Pleroma.Repo.Migrations.CreateFilters do
def change do
create_if_not_exists table(:filters) do
add :user_id, references(:users, on_delete: :delete_all)
add :filter_id, :integer
add :hide, :boolean
add :phrase, :string
add :context, {:array, :string}
add :expires_at, :utc_datetime
add :whole_word, :boolean
add(:user_id, references(:users, on_delete: :delete_all))
add(:filter_id, :integer)
add(:hide, :boolean)
add(:phrase, :string)
add(:context, {:array, :string})
add(:expires_at, :utc_datetime)
add(:whole_word, :boolean)
timestamps()
end
create_if_not_exists index(:filters, [:user_id])
create_if_not_exists index(:filters, [:phrase], where: "hide = true", name: :hided_phrases_index)
create_if_not_exists(index(:filters, [:user_id]))
create_if_not_exists(
index(:filters, [:phrase], where: "hide = true", name: :hided_phrases_index)
)
end
end

View File

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.AddRecipientsToAndCcFieldsToActivities do
def change do
alter table(:activities) do
add :recipients_to, {:array, :string}
add :recipients_cc, {:array, :string}
add(:recipients_to, {:array, :string})
add(:recipients_cc, {:array, :string})
end
create_if_not_exists index(:activities, [:recipients_to], using: :gin)
create_if_not_exists index(:activities, [:recipients_cc], using: :gin)
create_if_not_exists(index(:activities, [:recipients_to], using: :gin))
create_if_not_exists(index(:activities, [:recipients_cc], using: :gin))
end
end

View File

@ -2,7 +2,12 @@ defmodule Pleroma.Repo.Migrations.ActivitiesAddToCcIndices do
use Ecto.Migration
def change do
create_if_not_exists index(:activities, ["(data->'to')"], name: :activities_to_index, using: :gin)
create_if_not_exists index(:activities, ["(data->'cc')"], name: :activities_cc_index, using: :gin)
create_if_not_exists(
index(:activities, ["(data->'to')"], name: :activities_to_index, using: :gin)
)
create_if_not_exists(
index(:activities, ["(data->'cc')"], name: :activities_cc_index, using: :gin)
)
end
end

View File

@ -3,15 +3,15 @@ defmodule Pleroma.Repo.Migrations.RemoveRecipientsToAndCcFieldsFromActivities do
def up do
alter table(:activities) do
remove :recipients_to
remove :recipients_cc
remove(:recipients_to)
remove(:recipients_cc)
end
end
def down do
alter table(:activities) do
add :recipients_to, {:array, :string}
add :recipients_cc, {:array, :string}
add(:recipients_to, {:array, :string})
add(:recipients_cc, {:array, :string})
end
end
end

View File

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.UsersAddIsModeratorIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:users, ["(info->'is_moderator')"], name: :users_is_moderator_index, using: :gin)
create_if_not_exists(
index(:users, ["(info->'is_moderator')"], name: :users_is_moderator_index, using: :gin)
)
end
end

View File

@ -3,16 +3,16 @@ defmodule Pleroma.Repo.Migrations.CreatePushSubscriptions do
def change do
create_if_not_exists table("push_subscriptions") do
add :user_id, references("users", on_delete: :delete_all)
add :token_id, references("oauth_tokens", on_delete: :delete_all)
add :endpoint, :string
add :key_p256dh, :string
add :key_auth, :string
add :data, :map
add(:user_id, references("users", on_delete: :delete_all))
add(:token_id, references("oauth_tokens", on_delete: :delete_all))
add(:endpoint, :string)
add(:key_p256dh, :string)
add(:key_auth, :string)
add(:data, :map)
timestamps()
end
create_if_not_exists index("push_subscriptions", [:user_id, :token_id], unique: true)
create_if_not_exists(index("push_subscriptions", [:user_id, :token_id], unique: true))
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.UsersAddLastRefreshedAt do
def change do
alter table(:users) do
add :last_refreshed_at, :naive_datetime_usec
add(:last_refreshed_at, :naive_datetime_usec)
end
end
end

View File

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddTagsToUsers do
def change do
alter table(:users) do
add :tags, {:array, :string}
add(:tags, {:array, :string})
end
create_if_not_exists index(:users, [:tags], using: :gin)
create_if_not_exists(index(:users, [:tags], using: :gin))
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddBookmarksToUsers do
def change do
alter table(:users) do
add :bookmarks, {:array, :string}, null: false, default: []
add(:bookmarks, {:array, :string}, null: false, default: [])
end
end
end

View File

@ -22,26 +22,28 @@ def up do
clippy = start_clippy_heartbeats()
# Lock both tables to avoid a running server to meddling with our transaction
execute "LOCK TABLE activities;"
execute "LOCK TABLE users;"
execute("LOCK TABLE activities;")
execute("LOCK TABLE users;")
execute """
execute("""
ALTER TABLE activities
DROP CONSTRAINT activities_pkey CASCADE,
ALTER COLUMN id DROP default,
ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid),
ADD PRIMARY KEY (id);
"""
""")
execute """
execute("""
ALTER TABLE users
DROP CONSTRAINT users_pkey CASCADE,
ALTER COLUMN id DROP default,
ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid),
ADD PRIMARY KEY (id);
"""
""")
execute "UPDATE users SET info = jsonb_set(info, '{pinned_activities}', array_to_json(ARRAY(select jsonb_array_elements_text(info->'pinned_activities')))::jsonb);"
execute(
"UPDATE users SET info = jsonb_set(info, '{pinned_activities}', array_to_json(ARRAY(select jsonb_array_elements_text(info->'pinned_activities')))::jsonb);"
)
# Fkeys:
# Activities - Referenced by:
@ -56,18 +58,19 @@ def up do
# TABLE "push_subscriptions" CONSTRAINT "push_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
# TABLE "websub_client_subscriptions" CONSTRAINT "websub_client_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
execute """
execute("""
ALTER TABLE notifications
ALTER COLUMN activity_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(activity_id), 32, '0' ) AS uuid),
ADD CONSTRAINT notifications_activity_id_fkey FOREIGN KEY (activity_id) REFERENCES activities(id) ON DELETE CASCADE;
"""
""")
for table <- ~w(notifications filters lists oauth_authorizations oauth_tokens password_reset_tokens push_subscriptions websub_client_subscriptions) do
execute """
for table <-
~w(notifications filters lists oauth_authorizations oauth_tokens password_reset_tokens push_subscriptions websub_client_subscriptions) do
execute("""
ALTER TABLE #{table}
ALTER COLUMN user_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(user_id), 32, '0' ) AS uuid),
ADD CONSTRAINT #{table}_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
"""
""")
end
flush()
@ -78,41 +81,50 @@ def up do
def down, do: :ok
defp start_clippy_heartbeats() do
count = from(a in "activities", select: count(a.id)) |> Repo.one!
count = from(a in "activities", select: count(a.id)) |> Repo.one!()
if count > 5000 do
heartbeat_interval = :timer.minutes(2) + :timer.seconds(30)
all_tips = Clippy.tips() ++ [
all_tips =
Clippy.tips() ++
[
"The migration is still running, maybe it's time for another “tea”?",
"Happy rabbits practice a cute behavior known as a\n“binky:” they jump up in the air\nand twist\nand spin around!",
"Nothing and everything.\n\nI still work.",
"Pleroma runs on a Raspberry Pi!\n\n … but this migration will take forever if you\nactually run on a raspberry pi",
"Status? Stati? Post? Note? Toot?\nRepeat? Reboost? Boost? Retweet? Retoot??\n\nI-I'm confused.",
"Status? Stati? Post? Note? Toot?\nRepeat? Reboost? Boost? Retweet? Retoot??\n\nI-I'm confused."
]
heartbeat = fn(heartbeat, runs, all_tips, tips) ->
tips = if Integer.is_even(runs) do
heartbeat = fn heartbeat, runs, all_tips, tips ->
tips =
if Integer.is_even(runs) do
tips = if tips == [], do: all_tips, else: tips
[tip | tips] = Enum.shuffle(tips)
Clippy.puts(tip)
tips
else
IO.puts "\n -- #{DateTime.to_string(DateTime.utc_now())} Migration still running, please wait…\n"
IO.puts(
"\n -- #{DateTime.to_string(DateTime.utc_now())} Migration still running, please wait…\n"
)
tips
end
:timer.sleep(heartbeat_interval)
heartbeat.(heartbeat, runs + 1, all_tips, tips)
end
Clippy.puts [
Clippy.puts([
[:red, :bright, "It looks like you are running an older instance!"],
[""],
[:bright, "This migration may take a long time", :reset, " -- so you probably should"],
["go drink a cofe, or a tea, or a beer, a whiskey, a vodka,"],
["while it runs to deal with your temporary fediverse pause!"]
]
])
:timer.sleep(heartbeat_interval)
spawn_link(fn() -> heartbeat.(heartbeat, 1, all_tips, []) end)
spawn_link(fn -> heartbeat.(heartbeat, 1, all_tips, []) end)
end
end
@ -120,8 +132,7 @@ defp stop_clippy_heartbeats(pid) do
if pid do
Process.unlink(pid)
Process.exit(pid, :kill)
Clippy.puts [[:green, :bright, "Hurray!!", "", "", "Migration completed!"]]
Clippy.puts([[:green, :bright, "Hurray!!", "", "", "Migration completed!"]])
end
end
end

View File

@ -43,6 +43,8 @@ def down do
)
)
execute("drop function if exists activity_visibility(actor varchar, recipients varchar[], data jsonb)")
execute(
"drop function if exists activity_visibility(actor varchar, recipients varchar[], data jsonb)"
)
end
end

View File

@ -2,7 +2,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserFtsIndex do
use Ecto.Migration
def change do
create_if_not_exists index(
create_if_not_exists(
index(
:users,
[
"""
@ -13,5 +14,6 @@ def change do
name: :users_fts_index,
using: :gin
)
)
end
end

View File

@ -27,10 +27,8 @@ def up do
"""
execute(definition)
end
def down do
end
end

View File

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.UsersAddIsAdminIndex do
use Ecto.Migration
def change do
create_if_not_exists(index(:users, ["(info->'is_admin')"], name: :users_is_admin_index, using: :gin))
create_if_not_exists(
index(:users, ["(info->'is_admin')"], name: :users_is_admin_index, using: :gin)
)
end
end

View File

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateInstances do
def change do
create_if_not_exists table(:instances) do
add :host, :string
add :unreachable_since, :naive_datetime_usec
add(:host, :string)
add(:unreachable_since, :naive_datetime_usec)
timestamps()
end
create_if_not_exists unique_index(:instances, [:host])
create_if_not_exists index(:instances, [:unreachable_since])
create_if_not_exists(unique_index(:instances, [:host]))
create_if_not_exists(index(:instances, [:unreachable_since]))
end
end

View File

@ -27,11 +27,8 @@ def up do
"""
execute(definition)
end
def down do
end
end

View File

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddActivitiesLikesIndex do
@disable_ddl_transaction true
def change do
create index(:activities, ["((data #> '{\"object\",\"likes\"}'))"], concurrently: true, name: :activities_likes, using: :gin)
create(
index(:activities, ["((data #> '{\"object\",\"likes\"}'))"],
concurrently: true,
name: :activities_likes,
using: :gin
)
)
end
end

View File

@ -2,9 +2,17 @@ defmodule Pleroma.Repo.Migrations.SplitHideNetwork do
use Ecto.Migration
def up do
execute("UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network') AND local")
execute("UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network') WHERE local")
execute("UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network') WHERE local")
execute(
"UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network') AND local"
)
execute(
"UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network') WHERE local"
)
execute(
"UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network') WHERE local"
)
end
def down do

View File

@ -3,10 +3,10 @@ defmodule Pleroma.Repo.Migrations.CreateThreadMutes do
def change do
create_if_not_exists table(:thread_mutes) do
add :user_id, references(:users, type: :uuid, on_delete: :delete_all)
add :context, :string
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
add(:context, :string)
end
create_if_not_exists unique_index(:thread_mutes, [:user_id, :context], name: :unique_index)
create_if_not_exists(unique_index(:thread_mutes, [:user_id, :context], name: :unique_index))
end
end

View File

@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.AddScopeSToOAuthEntities do
def change do
for t <- [:oauth_authorizations, :oauth_tokens] do
alter table(t) do
add :scopes, {:array, :string}, default: [], null: false
add(:scopes, {:array, :string}, default: [], null: false)
end
end
end

View File

@ -4,14 +4,20 @@ defmodule Pleroma.Repo.Migrations.ChangeAppsScopesToVarcharArray do
@alter_apps_scopes "ALTER TABLE apps ALTER COLUMN scopes"
def up do
execute "#{@alter_apps_scopes} TYPE varchar(255)[] USING string_to_array(scopes, ',')::varchar(255)[];"
execute "#{@alter_apps_scopes} SET DEFAULT ARRAY[]::character varying[];"
execute "#{@alter_apps_scopes} SET NOT NULL;"
execute(
"#{@alter_apps_scopes} TYPE varchar(255)[] USING string_to_array(scopes, ',')::varchar(255)[];"
)
execute("#{@alter_apps_scopes} SET DEFAULT ARRAY[]::character varying[];")
execute("#{@alter_apps_scopes} SET NOT NULL;")
end
def down do
execute "#{@alter_apps_scopes} DROP NOT NULL;"
execute "#{@alter_apps_scopes} DROP DEFAULT;"
execute "#{@alter_apps_scopes} TYPE varchar(255) USING array_to_string(scopes, ',')::varchar(255);"
execute("#{@alter_apps_scopes} DROP NOT NULL;")
execute("#{@alter_apps_scopes} DROP DEFAULT;")
execute(
"#{@alter_apps_scopes} TYPE varchar(255) USING array_to_string(scopes, ',')::varchar(255);"
)
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.DataMigrationPopulateOAuthScopes do
def up do
for t <- [:oauth_authorizations, :oauth_tokens] do
execute "UPDATE #{t} SET scopes = apps.scopes FROM apps WHERE #{t}.app_id = apps.id;"
execute("UPDATE #{t} SET scopes = apps.scopes FROM apps WHERE #{t}.app_id = apps.id;")
end
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.DataMigrationNormalizeScopes do
def up do
for t <- [:apps, :oauth_authorizations, :oauth_tokens] do
execute "UPDATE #{t} SET scopes = string_to_array(array_to_string(scopes, ' '), ' ');"
execute("UPDATE #{t} SET scopes = string_to_array(array_to_string(scopes, ' '), ' ');")
end
end

View File

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.AddDefaultTagsToUser do
use Ecto.Migration
def up do
execute "UPDATE users SET tags = array[]::varchar[] where tags IS NULL"
execute("UPDATE users SET tags = array[]::varchar[] where tags IS NULL")
end
def down, do: :noop

View File

@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.UpdateUserNoteCounters do
@public "https://www.w3.org/ns/activitystreams#Public"
def up do
execute """
execute("""
WITH public_note_count AS (
SELECT
data->>'actor' AS actor,
@ -19,11 +19,11 @@ def up do
SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true)
FROM public_note_count AS o
WHERE u.ap_id = o.actor
"""
""")
end
def down do
execute """
execute("""
WITH public_note_count AS (
SELECT
data->>'actor' AS actor,
@ -36,6 +36,6 @@ def down do
SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true)
FROM public_note_count AS o
WHERE u.ap_id = o.actor
"""
""")
end
end

View File

@ -3,16 +3,16 @@ defmodule Pleroma.Repo.Migrations.CreateRegistrations do
def change do
create_if_not_exists table(:registrations, primary_key: false) do
add :id, :uuid, primary_key: true
add :user_id, references(:users, type: :uuid, on_delete: :delete_all)
add :provider, :string
add :uid, :string
add :info, :map, default: %{}
add(:id, :uuid, primary_key: true)
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
add(:provider, :string)
add(:uid, :string)
add(:info, :map, default: %{})
timestamps()
end
create_if_not_exists unique_index(:registrations, [:provider, :uid])
create_if_not_exists unique_index(:registrations, [:user_id, :provider, :uid])
create_if_not_exists(unique_index(:registrations, [:provider, :uid]))
create_if_not_exists(unique_index(:registrations, [:user_id, :provider, :uid]))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.CreateNotificationIdIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:notifications, ["id desc nulls last"])
create_if_not_exists(index(:notifications, ["id desc nulls last"]))
end
end

View File

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddIndexOnSubscribers do
@disable_ddl_transaction true
def change do
create index(:users, ["(info->'subscribers')"], name: :users_subscribers_index, using: :gin, concurrently: true)
create(
index(:users, ["(info->'subscribers')"],
name: :users_subscribers_index,
using: :gin,
concurrently: true
)
)
end
end

View File

@ -19,8 +19,8 @@ def change do
timestamps()
end
create_if_not_exists index(:conversation_participations, [:conversation_id])
create_if_not_exists unique_index(:conversation_participations, [:user_id, :conversation_id])
create_if_not_exists unique_index(:conversations, [:ap_id])
create_if_not_exists(index(:conversation_participations, [:conversation_id]))
create_if_not_exists(unique_index(:conversation_participations, [:user_id, :conversation_id]))
create_if_not_exists(unique_index(:conversations, [:ap_id]))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddParticipationUpdatedAtIndex do
use Ecto.Migration
def change do
create_if_not_exists index(:conversation_participations, ["updated_at desc"])
create_if_not_exists(index(:conversation_participations, ["updated_at desc"]))
end
end

View File

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.AddIndexOnUserInfoDeactivated do
use Ecto.Migration
def change do
create_if_not_exists(index(:users, ["(info->'deactivated')"], name: :users_deactivated_index, using: :gin))
create_if_not_exists(
index(:users, ["(info->'deactivated')"], name: :users_deactivated_index, using: :gin)
)
end
end

View File

@ -29,7 +29,7 @@ def up do
def down do
alter table(:users) do
add :bookmarks, {:array, :string}, null: false, default: []
add(:bookmarks, {:array, :string}, null: false, default: [])
end
end
end

View File

@ -2,7 +2,18 @@ defmodule Pleroma.Repo.Migrations.AddFTSIndexToObjects do
use Ecto.Migration
def change do
drop_if_exists index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"], using: :gin, name: :activities_fts)
create_if_not_exists index(:objects, ["(to_tsvector('english', data->>'content'))"], using: :gin, name: :objects_fts)
drop_if_exists(
index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"],
using: :gin,
name: :activities_fts
)
)
create_if_not_exists(
index(:objects, ["(to_tsvector('english', data->>'content'))"],
using: :gin,
name: :objects_fts
)
)
end
end

View File

@ -2,18 +2,18 @@ defmodule Pleroma.Repo.Migrations.SetDefaultStateToReports do
use Ecto.Migration
def up do
execute """
execute("""
UPDATE activities AS a
SET data = jsonb_set(data, '{state}', '"open"', true)
WHERE data->>'type' = 'Flag'
"""
""")
end
def down do
execute """
execute("""
UPDATE activities AS a
SET data = data #- '{state}'
WHERE data->>'type' = 'Flag'
"""
""")
end
end

View File

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.ChangeHideColumnInFilterTable do
def up do
alter table(:filters) do
modify :hide, :boolean, default: false
modify(:hide, :boolean, default: false)
end
end
def down do
alter table(:filters) do
modify :hide, :boolean
modify(:hide, :boolean)
end
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddObjectInReplyToIndex do
use Ecto.Migration
def change do
create index(:objects, ["(data->>'inReplyTo')"], name: :objects_in_reply_to_index)
create(index(:objects, ["(data->>'inReplyTo')"], name: :objects_in_reply_to_index))
end
end

View File

@ -2,7 +2,10 @@ defmodule Pleroma.Repo.Migrations.AddTagIndexToObjects do
use Ecto.Migration
def change do
drop_if_exists index(:activities, ["(data #> '{\"object\",\"tag\"}')"], using: :gin, name: :activities_tags)
create_if_not_exists index(:objects, ["(data->'tag')"], using: :gin, name: :objects_tags)
drop_if_exists(
index(:activities, ["(data #> '{\"object\",\"tag\"}')"], using: :gin, name: :activities_tags)
)
create_if_not_exists(index(:objects, ["(data->'tag')"], using: :gin, name: :objects_tags))
end
end

View File

@ -3,6 +3,8 @@ defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
alias Pleroma.User
def change do
execute("update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true")
execute(
"update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
)
end
end

View File

@ -7,7 +7,7 @@ def change do
add(:participation_id, references(:conversation_participations, on_delete: :delete_all))
end
create_if_not_exists index(:conversation_participation_recipient_ships, [:user_id])
create_if_not_exists index(:conversation_participation_recipient_ships, [:participation_id])
create_if_not_exists(index(:conversation_participation_recipient_ships, [:user_id]))
create_if_not_exists(index(:conversation_participation_recipient_ships, [:participation_id]))
end
end

View File

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddLikesIndexToObjects do
use Ecto.Migration
def change do
create_if_not_exists index(:objects, ["(data->'likes')"], using: :gin, name: :objects_likes)
create_if_not_exists(index(:objects, ["(data->'likes')"], using: :gin, name: :objects_likes))
end
end

View File

@ -6,7 +6,8 @@ def change do
add(:object_id, references(:objects, type: :id), null: false)
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all), null: false)
end
create_if_not_exists index(:deliveries, :object_id, name: :deliveries_object_id)
create_if_not_exists(index(:deliveries, :object_id, name: :deliveries_object_id))
create_if_not_exists(unique_index(:deliveries, [:user_id, :object_id]))
end
end

View File

@ -2,7 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropSubscriptionIfExists do
use Ecto.Migration
def change do
end
def up do
@ -10,6 +9,7 @@ def up do
drop_if_exists(index(:subscription_notifications, ["id desc nulls last"]))
drop_if_exists(table(:subscription_notifications))
end
def down do
:ok
end

View File

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddKeysColumn do
def change do
alter table("users") do
add_if_not_exists :keys, :text
add_if_not_exists(:keys, :text)
end
end
end

View File

@ -2,6 +2,9 @@ defmodule Pleroma.Repo.Migrations.MoveKeysToSeparateColumn do
use Ecto.Migration
def change do
execute("update users set keys = info->>'keys' where local", "update users set info = jsonb_set(info, '{keys}'::text[], to_jsonb(keys)) where local")
execute(
"update users set keys = info->>'keys' where local",
"update users set info = jsonb_set(info, '{keys}'::text[], to_jsonb(keys)) where local"
)
end
end

View File

@ -45,21 +45,52 @@ detect_branch() {
}
update() {
set -e
NO_RM=false
while echo "$1" | grep "^-" >/dev/null; do
case "$1" in
--zip-url)
FULL_URI="$2"
shift 2
;;
--no-rm)
NO_RM=true
shift
;;
--flavour)
FLAVOUR="$2"
shift 2
;;
--branch)
BRANCH="$2"
shift 2
;;
--tmp-dir)
TMP_DIR="$2"
shift 2
;;
-*)
echo "invalid option: $1" 1>&2
shift
;;
esac
done
RELEASE_ROOT=$(dirname "$SCRIPTPATH")
uri="${PLEROMA_CTL_URI:-https://git.pleroma.social}"
project_id="${PLEROMA_CTL_PROJECT_ID:-2}"
project_branch="$(detect_branch)"
flavour="${PLEROMA_CTL_FLAVOUR:-$(detect_flavour)}"
echo "Detected flavour: $flavour"
tmp="${PLEROMA_CTL_TMP_DIR:-/tmp}"
uri="https://git.pleroma.social"
project_id="2"
project_branch="${BRANCH:-$(detect_branch)}"
flavour="${FLAVOUR:-$(detect_flavour)}"
tmp="${TMP_DIR:-/tmp}"
artifact="$tmp/pleroma.zip"
full_uri="${uri}/api/v4/projects/${project_id}/jobs/artifacts/${project_branch}/download?job=${flavour}"
full_uri="${FULL_URI:-${uri}/api/v4/projects/${project_id}/jobs/artifacts/${project_branch}/download?job=${flavour}}"
echo "Downloading the artifact from ${full_uri} to ${artifact}"
curl "$full_uri" -o "${artifact}"
echo "Unpacking ${artifact} to ${tmp}"
unzip -q "$artifact" -d "$tmp"
echo "Copying files over to $RELEASE_ROOT"
if [ "$1" != "--no-rm" ]; then
if [ "$NO_RM" = false ]; then
echo "Removing files from the previous release"
rm -r "${RELEASE_ROOT:-?}"/*
fi
cp -rf "$tmp/release"/* "$RELEASE_ROOT"
@ -86,36 +117,41 @@ if [ -z "$1" ] || [ "$1" = "help" ]; then
Rollback database migrations (needs to be done before downgrading)
update [OPTIONS]
Update the instance using the latest CI artifact for the current branch.
The only supported option is --no-rm, when set the script won't delete the whole directory, but
just force copy over files from the new release. This wastes more space, but may be useful if
some files are stored inside of the release directories (although you really shouldn't store them
there), or if you want to be able to quickly revert a broken update.
The script will try to detect your architecture and ABI and set a flavour automatically,
but if it is wrong, you can overwrite it by setting PLEROMA_CTL_FLAVOUR to the desired flavour.
By default the artifact will be downloaded from https://git.pleroma.social for pleroma/pleroma (project id: 2)
to /tmp/, you can overwrite these settings by setting PLEROMA_CTL_URI, PLEROMA_CTL_PROJECT_ID and PLEROMA_CTL_TMP_DIR
respectively.
Update the instance.
Options:
--branch Update to a specified branch, instead of the latest version of the current one.
--flavour Update to a specified flavour (CPU architecture+libc), instead of the current one.
--zip-url Get the release from a specified url. If set, renders the previous 2 options inactive.
--no-rm Do not erase previous release's files.
--tmp-dir Download the temporary files to a specified directory.
and any mix tasks under Pleroma namespace, for example \`mix pleroma.user COMMAND\` is
equivalent to \`$(basename "$0") user COMMAND\`
By default pleroma_ctl will try calling into a running instance to execute non migration-related commands,
if for some reason this is undesired, set PLEROMA_CTL_RPC_DISABLED environment variable
if for some reason this is undesired, set PLEROMA_CTL_RPC_DISABLED environment variable.
"
else
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT")
if [ "$1" = "update" ]; then
update "$2"
elif [ "$1" = "migrate" ] || [ "$1" = "rollback" ] || [ "$1" = "create" ] || [ "$1 $2" = "instance gen" ] || [ -n "$PLEROMA_CTL_RPC_DISABLED" ]; then
"$SCRIPTPATH"/pleroma eval 'Pleroma.ReleaseTasks.run("'"$*"'")'
FULL_ARGS="$*"
ACTION="$1"
shift
if [ "$(echo \"$1\" | grep \"^-\" >/dev/null)" = false ]; then
SUBACTION="$1"
shift
fi
if [ "$ACTION" = "update" ]; then
update "$@"
elif [ "$ACTION" = "migrate" ] || [ "$ACTION" = "rollback" ] || [ "$ACTION" = "create" ] || [ "$ACTION $SUBACTION" = "instance gen" ] || [ "$PLEROMA_CTL_RPC_DISABLED" = true ]; then
"$SCRIPTPATH"/pleroma eval 'Pleroma.ReleaseTasks.run("'"$FULL_ARGS"'")'
else
"$SCRIPTPATH"/pleroma rpc 'Pleroma.ReleaseTasks.run("'"$*"'")'
"$SCRIPTPATH"/pleroma rpc 'Pleroma.ReleaseTasks.run("'"$FULL_ARGS"'")'
fi
fi

View File

@ -126,9 +126,25 @@ test "when association is not loaded" do
}
{:ok, local_activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "find me!"})
{:ok, japanese_activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "更新情報"})
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
{:ok, remote_activity} = ObanHelpers.perform(job)
%{local_activity: local_activity, remote_activity: remote_activity, user: user}
%{
japanese_activity: japanese_activity,
local_activity: local_activity,
remote_activity: remote_activity,
user: user
}
end
test "finds utf8 text in statuses", %{
japanese_activity: japanese_activity,
user: user
} do
activities = Activity.search(user, "更新情報")
assert [^japanese_activity] = activities
end
test "find local and remote statuses for authenticated users", %{

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
<Link rel="lrdd" type="application/xrd+xml" template="https://mstdn.jp/.well-known/webfinger?resource={uri}"/>
</XRD>

Some files were not shown because too many files have changed in this diff Show More