Merge branch 'cycles-phase-1' into 'develop'
Recompilation speedup: Phase 1 See merge request soapbox-pub/soapbox!29
This commit is contained in:
commit
eda02cfe00
52 changed files with 246 additions and 162 deletions
|
@ -54,6 +54,10 @@
|
||||||
|
|
||||||
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true
|
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true
|
||||||
|
|
||||||
|
# Reduce recompilation time
|
||||||
|
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
|
||||||
|
config :phoenix, :plug_init_mode, :runtime
|
||||||
|
|
||||||
if File.exists?("./config/dev.secret.exs") do
|
if File.exists?("./config/dev.secret.exs") do
|
||||||
import_config "dev.secret.exs"
|
import_config "dev.secret.exs"
|
||||||
else
|
else
|
||||||
|
|
|
@ -133,6 +133,10 @@
|
||||||
ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock,
|
ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock,
|
||||||
logger: Pleroma.LoggerMock
|
logger: Pleroma.LoggerMock
|
||||||
|
|
||||||
|
# Reduce recompilation time
|
||||||
|
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
|
||||||
|
config :phoenix, :plug_init_mode, :runtime
|
||||||
|
|
||||||
if File.exists?("./config/test.secret.exs") do
|
if File.exists?("./config/test.secret.exs") do
|
||||||
import_config "test.secret.exs"
|
import_config "test.secret.exs"
|
||||||
else
|
else
|
||||||
|
|
45
lib/pleroma/activity/html.ex
Normal file
45
lib/pleroma/activity/html.ex
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Activity.HTML do
|
||||||
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.Object
|
||||||
|
|
||||||
|
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||||
|
|
||||||
|
def get_cached_scrubbed_html_for_activity(
|
||||||
|
content,
|
||||||
|
scrubbers,
|
||||||
|
activity,
|
||||||
|
key \\ "",
|
||||||
|
callback \\ fn x -> x end
|
||||||
|
) do
|
||||||
|
key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"
|
||||||
|
|
||||||
|
@cachex.fetch!(:scrubber_cache, key, fn _key ->
|
||||||
|
object = Object.normalize(activity, fetch: false)
|
||||||
|
HTML.ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_cached_stripped_html_for_activity(content, activity, key) do
|
||||||
|
get_cached_scrubbed_html_for_activity(
|
||||||
|
content,
|
||||||
|
FastSanitize.Sanitizer.StripTags,
|
||||||
|
activity,
|
||||||
|
key,
|
||||||
|
&HtmlEntities.decode/1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_scrubber_signature(scrubber) when is_atom(scrubber) do
|
||||||
|
generate_scrubber_signature([scrubber])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_scrubber_signature(scrubbers) do
|
||||||
|
Enum.reduce(scrubbers, "", fn scrubber, signature ->
|
||||||
|
"#{signature}#{to_string(scrubber)}"
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,19 +3,21 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Config.Loader do
|
defmodule Pleroma.Config.Loader do
|
||||||
@reject_keys [
|
defp reject_keys,
|
||||||
Pleroma.Repo,
|
do: [
|
||||||
Pleroma.Web.Endpoint,
|
Pleroma.Repo,
|
||||||
:env,
|
Pleroma.Web.Endpoint,
|
||||||
:configurable_from_database,
|
:env,
|
||||||
:database,
|
:configurable_from_database,
|
||||||
:swarm
|
:database,
|
||||||
]
|
:swarm
|
||||||
|
]
|
||||||
|
|
||||||
@reject_groups [
|
defp reject_groups,
|
||||||
:postgrex,
|
do: [
|
||||||
:tesla
|
:postgrex,
|
||||||
]
|
:tesla
|
||||||
|
]
|
||||||
|
|
||||||
if Code.ensure_loaded?(Config.Reader) do
|
if Code.ensure_loaded?(Config.Reader) do
|
||||||
@reader Config.Reader
|
@reader Config.Reader
|
||||||
|
@ -52,7 +54,7 @@ defp filter(configs) do
|
||||||
@spec filter_group(atom(), keyword()) :: keyword()
|
@spec filter_group(atom(), keyword()) :: keyword()
|
||||||
def filter_group(group, configs) do
|
def filter_group(group, configs) do
|
||||||
Enum.reject(configs[group], fn {key, _v} ->
|
Enum.reject(configs[group], fn {key, _v} ->
|
||||||
key in @reject_keys or group in @reject_groups or
|
key in reject_keys() or group in reject_groups() or
|
||||||
(group == :phoenix and key == :serve_endpoints)
|
(group == :phoenix and key == :serve_endpoints)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,23 +13,25 @@ defmodule Pleroma.Config.TransferTask do
|
||||||
|
|
||||||
@type env() :: :test | :benchmark | :dev | :prod
|
@type env() :: :test | :benchmark | :dev | :prod
|
||||||
|
|
||||||
@reboot_time_keys [
|
defp reboot_time_keys,
|
||||||
{:pleroma, :hackney_pools},
|
do: [
|
||||||
{:pleroma, :chat},
|
{:pleroma, :hackney_pools},
|
||||||
{:pleroma, Oban},
|
{:pleroma, :chat},
|
||||||
{:pleroma, :rate_limit},
|
{:pleroma, Oban},
|
||||||
{:pleroma, :markup},
|
{:pleroma, :rate_limit},
|
||||||
{:pleroma, :streamer},
|
{:pleroma, :markup},
|
||||||
{:pleroma, :pools},
|
{:pleroma, :streamer},
|
||||||
{:pleroma, :connections_pool}
|
{:pleroma, :pools},
|
||||||
]
|
{:pleroma, :connections_pool}
|
||||||
|
]
|
||||||
|
|
||||||
@reboot_time_subkeys [
|
defp reboot_time_subkeys,
|
||||||
{:pleroma, Pleroma.Captcha, [:seconds_valid]},
|
do: [
|
||||||
{:pleroma, Pleroma.Upload, [:proxy_remote]},
|
{:pleroma, Pleroma.Captcha, [:seconds_valid]},
|
||||||
{:pleroma, :instance, [:upload_limit]},
|
{:pleroma, Pleroma.Upload, [:proxy_remote]},
|
||||||
{:pleroma, :gopher, [:enabled]}
|
{:pleroma, :instance, [:upload_limit]},
|
||||||
]
|
{:pleroma, :gopher, [:enabled]}
|
||||||
|
]
|
||||||
|
|
||||||
def start_link(restart_pleroma? \\ true) do
|
def start_link(restart_pleroma? \\ true) do
|
||||||
load_and_update_env([], restart_pleroma?)
|
load_and_update_env([], restart_pleroma?)
|
||||||
|
@ -165,12 +167,12 @@ def pleroma_need_restart?(group, key, value) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp group_and_key_need_reboot?(group, key) do
|
defp group_and_key_need_reboot?(group, key) do
|
||||||
Enum.any?(@reboot_time_keys, fn {g, k} -> g == group and k == key end)
|
Enum.any?(reboot_time_keys(), fn {g, k} -> g == group and k == key end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp group_and_subkey_need_reboot?(group, key, value) do
|
defp group_and_subkey_need_reboot?(group, key, value) do
|
||||||
Keyword.keyword?(value) and
|
Keyword.keyword?(value) and
|
||||||
Enum.any?(@reboot_time_subkeys, fn {g, k, subkeys} ->
|
Enum.any?(reboot_time_subkeys(), fn {g, k, subkeys} ->
|
||||||
g == group and k == key and
|
g == group and k == key and
|
||||||
Enum.any?(Keyword.keys(value), &(&1 in subkeys))
|
Enum.any?(Keyword.keys(value), &(&1 in subkeys))
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -11,9 +11,7 @@ defmodule Pleroma.Gun do
|
||||||
@callback await(pid(), reference()) :: {:response, :fin, 200, []}
|
@callback await(pid(), reference()) :: {:response, :fin, 200, []}
|
||||||
@callback set_owner(pid(), pid()) :: :ok
|
@callback set_owner(pid(), pid()) :: :ok
|
||||||
|
|
||||||
@api Pleroma.Config.get([Pleroma.Gun], Pleroma.Gun.API)
|
defp api, do: Pleroma.Config.get([Pleroma.Gun], Pleroma.Gun.API)
|
||||||
|
|
||||||
defp api, do: @api
|
|
||||||
|
|
||||||
def open(host, port, opts), do: api().open(host, port, opts)
|
def open(host, port, opts), do: api().open(host, port, opts)
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
|
defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
|
||||||
use GenServer, restart: :temporary
|
use GenServer, restart: :temporary
|
||||||
|
|
||||||
@registry Pleroma.Gun.ConnectionPool
|
defp registry, do: Pleroma.Gun.ConnectionPool
|
||||||
|
|
||||||
def start_monitor do
|
def start_monitor do
|
||||||
pid =
|
pid =
|
||||||
case :gen_server.start(__MODULE__, [], name: {:via, Registry, {@registry, "reclaimer"}}) do
|
case :gen_server.start(__MODULE__, [], name: {:via, Registry, {registry(), "reclaimer"}}) do
|
||||||
{:ok, pid} ->
|
{:ok, pid} ->
|
||||||
pid
|
pid
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ def handle_continue(:reclaim, _) do
|
||||||
# {worker_pid, crf, last_reference} end)
|
# {worker_pid, crf, last_reference} end)
|
||||||
unused_conns =
|
unused_conns =
|
||||||
Registry.select(
|
Registry.select(
|
||||||
@registry,
|
registry(),
|
||||||
[
|
[
|
||||||
{{:_, :"$1", {:_, :"$2", :"$3", :"$4"}}, [{:==, :"$2", []}], [{{:"$1", :"$3", :"$4"}}]}
|
{{:_, :"$1", {:_, :"$2", :"$3", :"$4"}}, [{:==, :"$2", []}], [{{:"$1", :"$3", :"$4"}}]}
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,10 +6,10 @@ defmodule Pleroma.Gun.ConnectionPool.Worker do
|
||||||
alias Pleroma.Gun
|
alias Pleroma.Gun
|
||||||
use GenServer, restart: :temporary
|
use GenServer, restart: :temporary
|
||||||
|
|
||||||
@registry Pleroma.Gun.ConnectionPool
|
defp registry, do: Pleroma.Gun.ConnectionPool
|
||||||
|
|
||||||
def start_link([key | _] = opts) do
|
def start_link([key | _] = opts) do
|
||||||
GenServer.start_link(__MODULE__, opts, name: {:via, Registry, {@registry, key}})
|
GenServer.start_link(__MODULE__, opts, name: {:via, Registry, {registry(), key}})
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -24,7 +24,7 @@ def handle_continue({:connect, [key, uri, opts, client_pid]}, _) do
|
||||||
time = :erlang.monotonic_time(:millisecond)
|
time = :erlang.monotonic_time(:millisecond)
|
||||||
|
|
||||||
{_, _} =
|
{_, _} =
|
||||||
Registry.update_value(@registry, key, fn _ ->
|
Registry.update_value(registry(), key, fn _ ->
|
||||||
{conn_pid, [client_pid], 1, time}
|
{conn_pid, [client_pid], 1, time}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ def handle_call(:add_client, {client_pid, _}, %{key: key, protocol: protocol} =
|
||||||
time = :erlang.monotonic_time(:millisecond)
|
time = :erlang.monotonic_time(:millisecond)
|
||||||
|
|
||||||
{{conn_pid, used_by, _, _}, _} =
|
{{conn_pid, used_by, _, _}, _} =
|
||||||
Registry.update_value(@registry, key, fn {conn_pid, used_by, crf, last_reference} ->
|
Registry.update_value(registry(), key, fn {conn_pid, used_by, crf, last_reference} ->
|
||||||
{conn_pid, [client_pid | used_by], crf(time - last_reference, crf), time}
|
{conn_pid, [client_pid | used_by], crf(time - last_reference, crf), time}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ def handle_call(:add_client, {client_pid, _}, %{key: key, protocol: protocol} =
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call(:remove_client, {client_pid, _}, %{key: key} = state) do
|
def handle_call(:remove_client, {client_pid, _}, %{key: key} = state) do
|
||||||
{{_conn_pid, used_by, _crf, _last_reference}, _} =
|
{{_conn_pid, used_by, _crf, _last_reference}, _} =
|
||||||
Registry.update_value(@registry, key, fn {conn_pid, used_by, crf, last_reference} ->
|
Registry.update_value(registry(), key, fn {conn_pid, used_by, crf, last_reference} ->
|
||||||
{conn_pid, List.delete(used_by, client_pid), crf, last_reference}
|
{conn_pid, List.delete(used_by, client_pid), crf, last_reference}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -49,31 +49,6 @@ def filter_tags(html, scrubber) do
|
||||||
def filter_tags(html), do: filter_tags(html, nil)
|
def filter_tags(html), do: filter_tags(html, nil)
|
||||||
def strip_tags(html), do: filter_tags(html, FastSanitize.Sanitizer.StripTags)
|
def strip_tags(html), do: filter_tags(html, FastSanitize.Sanitizer.StripTags)
|
||||||
|
|
||||||
def get_cached_scrubbed_html_for_activity(
|
|
||||||
content,
|
|
||||||
scrubbers,
|
|
||||||
activity,
|
|
||||||
key \\ "",
|
|
||||||
callback \\ fn x -> x end
|
|
||||||
) do
|
|
||||||
key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"
|
|
||||||
|
|
||||||
@cachex.fetch!(:scrubber_cache, key, fn _key ->
|
|
||||||
object = Pleroma.Object.normalize(activity, fetch: false)
|
|
||||||
ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_cached_stripped_html_for_activity(content, activity, key) do
|
|
||||||
get_cached_scrubbed_html_for_activity(
|
|
||||||
content,
|
|
||||||
FastSanitize.Sanitizer.StripTags,
|
|
||||||
activity,
|
|
||||||
key,
|
|
||||||
&HtmlEntities.decode/1
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_scrubbed_html(
|
def ensure_scrubbed_html(
|
||||||
content,
|
content,
|
||||||
scrubbers,
|
scrubbers,
|
||||||
|
@ -92,16 +67,6 @@ def ensure_scrubbed_html(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp generate_scrubber_signature(scrubber) when is_atom(scrubber) do
|
|
||||||
generate_scrubber_signature([scrubber])
|
|
||||||
end
|
|
||||||
|
|
||||||
defp generate_scrubber_signature(scrubbers) do
|
|
||||||
Enum.reduce(scrubbers, "", fn scrubber, signature ->
|
|
||||||
"#{signature}#{to_string(scrubber)}"
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
def extract_first_external_url_from_object(%{data: %{"content" => content}} = object)
|
def extract_first_external_url_from_object(%{data: %{"content" => content}} = object)
|
||||||
when is_binary(content) do
|
when is_binary(content) do
|
||||||
unless object.data["fake"] do
|
unless object.data["fake"] do
|
||||||
|
|
|
@ -54,8 +54,8 @@ def pool_timeout(pool) do
|
||||||
Config.get([:pools, pool, :recv_timeout], default)
|
Config.get([:pools, pool, :recv_timeout], default)
|
||||||
end
|
end
|
||||||
|
|
||||||
@prefix Pleroma.Gun.ConnectionPool
|
|
||||||
def limiter_setup do
|
def limiter_setup do
|
||||||
|
prefix = Pleroma.Gun.ConnectionPool
|
||||||
wait = Config.get([:connections_pool, :connection_acquisition_wait])
|
wait = Config.get([:connections_pool, :connection_acquisition_wait])
|
||||||
retries = Config.get([:connections_pool, :connection_acquisition_retries])
|
retries = Config.get([:connections_pool, :connection_acquisition_retries])
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def limiter_setup do
|
||||||
max_waiting = Keyword.get(opts, :max_waiting, 10)
|
max_waiting = Keyword.get(opts, :max_waiting, 10)
|
||||||
|
|
||||||
result =
|
result =
|
||||||
ConcurrentLimiter.new(:"#{@prefix}.#{name}", max_running, max_waiting,
|
ConcurrentLimiter.new(:"#{prefix}.#{name}", max_running, max_waiting,
|
||||||
wait: wait,
|
wait: wait,
|
||||||
max_retries: retries
|
max_retries: retries
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,9 +35,10 @@ def controller do
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
import Pleroma.Web.Gettext
|
import Pleroma.Web.Gettext
|
||||||
import Pleroma.Web.Router.Helpers
|
|
||||||
import Pleroma.Web.TranslationHelpers
|
import Pleroma.Web.TranslationHelpers
|
||||||
|
|
||||||
|
alias Pleroma.Web.Router.Helpers, as: Routes
|
||||||
|
|
||||||
plug(:set_put_layout)
|
plug(:set_put_layout)
|
||||||
|
|
||||||
defp set_put_layout(conn, _) do
|
defp set_put_layout(conn, _) do
|
||||||
|
@ -131,7 +132,8 @@ def view do
|
||||||
|
|
||||||
import Pleroma.Web.ErrorHelpers
|
import Pleroma.Web.ErrorHelpers
|
||||||
import Pleroma.Web.Gettext
|
import Pleroma.Web.Gettext
|
||||||
import Pleroma.Web.Router.Helpers
|
|
||||||
|
alias Pleroma.Web.Router.Helpers, as: Routes
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -233,16 +235,4 @@ defmacro __using__(which) when is_atom(which) do
|
||||||
def base_url do
|
def base_url do
|
||||||
Pleroma.Web.Endpoint.url()
|
Pleroma.Web.Endpoint.url()
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Change to Phoenix.Router.routes/1 for Phoenix 1.6.0+
|
|
||||||
def get_api_routes do
|
|
||||||
Pleroma.Web.Router.__routes__()
|
|
||||||
|> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end)
|
|
||||||
|> Enum.map(fn r ->
|
|
||||||
r.path
|
|
||||||
|> String.split("/", trim: true)
|
|
||||||
|> List.first()
|
|
||||||
end)
|
|
||||||
|> Enum.uniq()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,26 +7,23 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.MRF
|
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
|
||||||
alias Pleroma.Web.ActivityPub.SideEffects
|
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.Federator
|
||||||
|
|
||||||
@side_effects Config.get([:pipeline, :side_effects], SideEffects)
|
defp side_effects, do: Config.get([:pipeline, :side_effects], SideEffects)
|
||||||
@federator Config.get([:pipeline, :federator], Federator)
|
defp federator, do: Config.get([:pipeline, :federator], Federator)
|
||||||
@object_validator Config.get([:pipeline, :object_validator], ObjectValidator)
|
defp object_validator, do: Config.get([:pipeline, :object_validator], ObjectValidator)
|
||||||
@mrf Config.get([:pipeline, :mrf], MRF)
|
defp mrf, do: Config.get([:pipeline, :mrf], MRF)
|
||||||
@activity_pub Config.get([:pipeline, :activity_pub], ActivityPub)
|
defp activity_pub, do: Config.get([:pipeline, :activity_pub], ActivityPub)
|
||||||
@config Config.get([:pipeline, :config], Config)
|
defp config, do: Config.get([:pipeline, :config], Config)
|
||||||
|
|
||||||
@spec common_pipeline(map(), keyword()) ::
|
@spec common_pipeline(map(), keyword()) ::
|
||||||
{:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
|
{:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
|
||||||
def common_pipeline(object, meta) do
|
def common_pipeline(object, meta) do
|
||||||
case Repo.transaction(fn -> do_common_pipeline(object, meta) end) do
|
case Repo.transaction(fn -> do_common_pipeline(object, meta) end) do
|
||||||
{:ok, {:ok, activity, meta}} ->
|
{:ok, {:ok, activity, meta}} ->
|
||||||
@side_effects.handle_after_transaction(meta)
|
side_effects().handle_after_transaction(meta)
|
||||||
{:ok, activity, meta}
|
{:ok, activity, meta}
|
||||||
|
|
||||||
{:ok, value} ->
|
{:ok, value} ->
|
||||||
|
@ -42,13 +39,13 @@ def common_pipeline(object, meta) do
|
||||||
|
|
||||||
def do_common_pipeline(object, meta) do
|
def do_common_pipeline(object, meta) do
|
||||||
with {_, {:ok, validated_object, meta}} <-
|
with {_, {:ok, validated_object, meta}} <-
|
||||||
{:validate_object, @object_validator.validate(object, meta)},
|
{:validate_object, object_validator().validate(object, meta)},
|
||||||
{_, {:ok, mrfd_object, meta}} <-
|
{_, {:ok, mrfd_object, meta}} <-
|
||||||
{:mrf_object, @mrf.pipeline_filter(validated_object, meta)},
|
{:mrf_object, mrf().pipeline_filter(validated_object, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
{:persist_object, @activity_pub.persist(mrfd_object, meta)},
|
{:persist_object, activity_pub().persist(mrfd_object, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, activity, meta}} <-
|
||||||
{:execute_side_effects, @side_effects.handle(activity, meta)},
|
{:execute_side_effects, side_effects().handle(activity, meta)},
|
||||||
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
||||||
{:ok, activity, meta}
|
{:ok, activity, meta}
|
||||||
else
|
else
|
||||||
|
@ -61,7 +58,7 @@ defp maybe_federate(%Object{}, _), do: {:ok, :not_federated}
|
||||||
|
|
||||||
defp maybe_federate(%Activity{} = activity, meta) do
|
defp maybe_federate(%Activity{} = activity, meta) do
|
||||||
with {:ok, local} <- Keyword.fetch(meta, :local) do
|
with {:ok, local} <- Keyword.fetch(meta, :local) do
|
||||||
do_not_federate = meta[:do_not_federate] || !@config.get([:instance, :federating])
|
do_not_federate = meta[:do_not_federate] || !config().get([:instance, :federating])
|
||||||
|
|
||||||
if !do_not_federate and local and not Visibility.is_local_public?(activity) do
|
if !do_not_federate and local and not Visibility.is_local_public?(activity) do
|
||||||
activity =
|
activity =
|
||||||
|
@ -71,7 +68,7 @@ defp maybe_federate(%Activity{} = activity, meta) do
|
||||||
activity
|
activity
|
||||||
end
|
end
|
||||||
|
|
||||||
@federator.publish(activity)
|
federator().publish(activity)
|
||||||
{:ok, :federated}
|
{:ok, :federated}
|
||||||
else
|
else
|
||||||
{:ok, :not_federated}
|
{:ok, :not_federated}
|
||||||
|
|
|
@ -13,7 +13,6 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppController do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.AppView)
|
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
|
|
10
lib/pleroma/web/admin_api/views/o_auth_app_view.ex
Normal file
10
lib/pleroma/web/admin_api/views/o_auth_app_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.OAuthAppView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.AppView.render(view, opts)
|
||||||
|
end
|
|
@ -28,7 +28,7 @@ def feed_redirect(%{assigns: %{format: format}} = conn, _params)
|
||||||
|
|
||||||
def feed_redirect(conn, %{"nickname" => nickname}) do
|
def feed_redirect(conn, %{"nickname" => nickname}) do
|
||||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
||||||
redirect(conn, external: "#{user_feed_url(conn, :feed, user.nickname)}.atom")
|
redirect(conn, external: "#{Routes.user_feed_url(conn, :feed, user.nickname)}.atom")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ def login(conn, params) do
|
||||||
defp redirect_to_oauth_form(conn, _params) do
|
defp redirect_to_oauth_form(conn, _params) do
|
||||||
with {:ok, app} <- local_mastofe_app() do
|
with {:ok, app} <- local_mastofe_app() do
|
||||||
path =
|
path =
|
||||||
o_auth_path(conn, :authorize,
|
Routes.o_auth_path(conn, :authorize,
|
||||||
response_type: "code",
|
response_type: "code",
|
||||||
client_id: app.client_id,
|
client_id: app.client_id,
|
||||||
redirect_uri: ".",
|
redirect_uri: ".",
|
||||||
|
@ -90,7 +90,7 @@ def password_reset(conn, params) do
|
||||||
defp local_mastodon_post_login_path(conn) do
|
defp local_mastodon_post_login_path(conn) do
|
||||||
case get_session(conn, :return_to) do
|
case get_session(conn, :return_to) do
|
||||||
nil ->
|
nil ->
|
||||||
masto_fe_path(conn, :index, ["getting-started"])
|
Routes.masto_fe_path(conn, :index, ["getting-started"])
|
||||||
|
|
||||||
return_to ->
|
return_to ->
|
||||||
delete_session(conn, :return_to)
|
delete_session(conn, :return_to)
|
||||||
|
|
|
@ -9,7 +9,6 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestController do
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
|
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(:assign_follower when action != :index)
|
plug(:assign_follower when action != :index)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
|
||||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||||
plug(Majic.Plug, [pool: Pleroma.MajicPool] when action in [:create, :create2])
|
plug(Majic.Plug, [pool: Pleroma.MajicPool] when action in [:create, :create2])
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:media"]} when action == :show)
|
plug(OAuthScopesPlug, %{scopes: ["read:media"]} when action == :show)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write:media"]} when action != :show)
|
plug(OAuthScopesPlug, %{scopes: ["write:media"]} when action != :show)
|
||||||
|
|
|
@ -37,8 +37,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
when action in [:public, :hashtag]
|
when action in [:public, :hashtag]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation
|
||||||
|
|
||||||
# GET /api/v1/timelines/home
|
# GET /api/v1/timelines/home
|
||||||
|
|
10
lib/pleroma/web/mastodon_api/views/follow_request_view.ex
Normal file
10
lib/pleroma/web/mastodon_api/views/follow_request_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.MastodonAPI.FollowRequestView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.AccountView.render(view, opts)
|
||||||
|
end
|
10
lib/pleroma/web/mastodon_api/views/media_view.ex
Normal file
10
lib/pleroma/web/mastodon_api/views/media_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.MastodonAPI.MediaView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.StatusView.render(view, opts)
|
||||||
|
end
|
|
@ -257,7 +257,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
|
|
||||||
content_html =
|
content_html =
|
||||||
content
|
content
|
||||||
|> HTML.get_cached_scrubbed_html_for_activity(
|
|> Activity.HTML.get_cached_scrubbed_html_for_activity(
|
||||||
User.html_filter_policy(opts[:for]),
|
User.html_filter_policy(opts[:for]),
|
||||||
activity,
|
activity,
|
||||||
"mastoapi:content"
|
"mastoapi:content"
|
||||||
|
@ -265,7 +265,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
|
|
||||||
content_plaintext =
|
content_plaintext =
|
||||||
content
|
content
|
||||||
|> HTML.get_cached_stripped_html_for_activity(
|
|> Activity.HTML.get_cached_stripped_html_for_activity(
|
||||||
activity,
|
activity,
|
||||||
"mastoapi:content"
|
"mastoapi:content"
|
||||||
)
|
)
|
||||||
|
|
10
lib/pleroma/web/mastodon_api/views/timeline_view.ex
Normal file
10
lib/pleroma/web/mastodon_api/views/timeline_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.MastodonAPI.TimelineView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.StatusView.render(view, opts)
|
||||||
|
end
|
|
@ -3,6 +3,7 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Metadata.Utils do
|
defmodule Pleroma.Web.Metadata.Utils do
|
||||||
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Emoji
|
alias Pleroma.Emoji
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
@ -13,7 +14,7 @@ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
|
||||||
# html content comes from DB already encoded, decode first and scrub after
|
# html content comes from DB already encoded, decode first and scrub after
|
||||||
|> HtmlEntities.decode()
|
|> HtmlEntities.decode()
|
||||||
|> String.replace(~r/<br\s?\/?>/, " ")
|
|> String.replace(~r/<br\s?\/?>/, " ")
|
||||||
|> HTML.get_cached_stripped_html_for_activity(object, "metadata")
|
|> Activity.HTML.get_cached_stripped_html_for_activity(object, "metadata")
|
||||||
|> Emoji.Formatter.demojify()
|
|> Emoji.Formatter.demojify()
|
||||||
|> HtmlEntities.decode()
|
|> HtmlEntities.decode()
|
||||||
|> Formatter.truncate()
|
|> Formatter.truncate()
|
||||||
|
|
|
@ -427,7 +427,7 @@ def prepare_request(%Plug.Conn{} = conn, %{
|
||||||
|> Map.put("state", state)
|
|> Map.put("state", state)
|
||||||
|
|
||||||
# Handing the request to Ueberauth
|
# Handing the request to Ueberauth
|
||||||
redirect(conn, to: o_auth_path(conn, :request, provider, params))
|
redirect(conn, to: Routes.o_auth_path(conn, :request, provider, params))
|
||||||
end
|
end
|
||||||
|
|
||||||
def request(%Plug.Conn{} = conn, params) do
|
def request(%Plug.Conn{} = conn, params) do
|
||||||
|
@ -601,7 +601,7 @@ def login(%User{} = user, %App{} = app, requested_scopes) when is_list(requested
|
||||||
end
|
end
|
||||||
|
|
||||||
# Special case: Local MastodonFE
|
# Special case: Local MastodonFE
|
||||||
defp redirect_uri(%Plug.Conn{} = conn, "."), do: auth_url(conn, :login)
|
defp redirect_uri(%Plug.Conn{} = conn, "."), do: Routes.auth_url(conn, :login)
|
||||||
|
|
||||||
defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri
|
defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
||||||
plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend)
|
plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend)
|
||||||
|
|
||||||
plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
|
plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
|
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ defmodule Pleroma.Web.PleromaAPI.ConversationController do
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.ConversationView)
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:show, :statuses])
|
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:show, :statuses])
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
|
|
|
@ -14,8 +14,6 @@ defmodule Pleroma.Web.PleromaAPI.NotificationController do
|
||||||
%{scopes: ["write:notifications"]} when action == :mark_as_read
|
%{scopes: ["write:notifications"]} when action == :mark_as_read
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.NotificationView)
|
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaNotificationOperation
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaNotificationOperation
|
||||||
|
|
||||||
def mark_as_read(%{assigns: %{user: user}, body_params: %{id: notification_id}} = conn, _) do
|
def mark_as_read(%{assigns: %{user: user}, body_params: %{id: notification_id}} = conn, _) do
|
||||||
|
|
10
lib/pleroma/web/pleroma_api/views/account_view.ex
Normal file
10
lib/pleroma/web/pleroma_api/views/account_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.AccountView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.AccountView.render(view, opts)
|
||||||
|
end
|
10
lib/pleroma/web/pleroma_api/views/conversation_view.ex
Normal file
10
lib/pleroma/web/pleroma_api/views/conversation_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.ConversationView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.ConversationView.render(view, opts)
|
||||||
|
end
|
10
lib/pleroma/web/pleroma_api/views/notification_view.ex
Normal file
10
lib/pleroma/web/pleroma_api/views/notification_view.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.NotificationView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Web.MastodonAPI
|
||||||
|
|
||||||
|
def render(view, opts), do: MastodonAPI.NotificationView.render(view, opts)
|
||||||
|
end
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
|
||||||
"""
|
"""
|
||||||
@behaviour Plug
|
@behaviour Plug
|
||||||
|
|
||||||
@api_routes Pleroma.Web.get_api_routes()
|
@api_routes Pleroma.Web.Router.get_api_routes()
|
||||||
|
|
||||||
def file_path(path, frontend_type \\ :primary) do
|
def file_path(path, frontend_type \\ :primary) do
|
||||||
if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
|
if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
|
||||||
|
|
|
@ -140,6 +140,10 @@ defmodule Pleroma.Web.Router do
|
||||||
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
|
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pipeline :static_fe do
|
||||||
|
plug(Pleroma.Web.Plugs.StaticFEPlug)
|
||||||
|
end
|
||||||
|
|
||||||
scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do
|
scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do
|
||||||
pipe_through(:pleroma_api)
|
pipe_through(:pleroma_api)
|
||||||
|
|
||||||
|
@ -631,7 +635,7 @@ defmodule Pleroma.Web.Router do
|
||||||
scope "/", Pleroma.Web do
|
scope "/", Pleroma.Web do
|
||||||
# Note: html format is supported only if static FE is enabled
|
# Note: html format is supported only if static FE is enabled
|
||||||
# Note: http signature is only considered for json requests (no auth for non-json requests)
|
# Note: http signature is only considered for json requests (no auth for non-json requests)
|
||||||
pipe_through([:accepts_html_json, :http_signature, Pleroma.Web.Plugs.StaticFEPlug])
|
pipe_through([:accepts_html_json, :http_signature, :static_fe])
|
||||||
|
|
||||||
get("/objects/:uuid", OStatus.OStatusController, :object)
|
get("/objects/:uuid", OStatus.OStatusController, :object)
|
||||||
get("/activities/:uuid", OStatus.OStatusController, :activity)
|
get("/activities/:uuid", OStatus.OStatusController, :activity)
|
||||||
|
@ -650,7 +654,7 @@ defmodule Pleroma.Web.Router do
|
||||||
scope "/", Pleroma.Web do
|
scope "/", Pleroma.Web do
|
||||||
# Note: html format is supported only if static FE is enabled
|
# Note: html format is supported only if static FE is enabled
|
||||||
# Note: http signature is only considered for json requests (no auth for non-json requests)
|
# Note: http signature is only considered for json requests (no auth for non-json requests)
|
||||||
pipe_through([:accepts_html_xml_json, :http_signature, Pleroma.Web.Plugs.StaticFEPlug])
|
pipe_through([:accepts_html_xml_json, :http_signature, :static_fe])
|
||||||
|
|
||||||
# Note: returns user _profile_ for json requests, redirects to user _feed_ for non-json ones
|
# Note: returns user _profile_ for json requests, redirects to user _feed_ for non-json ones
|
||||||
get("/users/:nickname", Feed.UserController, :feed_redirect, as: :user_feed)
|
get("/users/:nickname", Feed.UserController, :feed_redirect, as: :user_feed)
|
||||||
|
@ -658,7 +662,7 @@ defmodule Pleroma.Web.Router do
|
||||||
|
|
||||||
scope "/", Pleroma.Web do
|
scope "/", Pleroma.Web do
|
||||||
# Note: html format is supported only if static FE is enabled
|
# Note: html format is supported only if static FE is enabled
|
||||||
pipe_through([:accepts_html_xml, Pleroma.Web.Plugs.StaticFEPlug])
|
pipe_through([:accepts_html_xml, :static_fe])
|
||||||
|
|
||||||
get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed)
|
get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed)
|
||||||
end
|
end
|
||||||
|
@ -769,11 +773,11 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/embed/:id", EmbedController, :show)
|
get("/embed/:id", EmbedController, :show)
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/proxy/", Pleroma.Web.MediaProxy do
|
scope "/proxy/", Pleroma.Web do
|
||||||
get("/preview/:sig/:url", MediaProxyController, :preview)
|
get("/preview/:sig/:url", MediaProxy.MediaProxyController, :preview)
|
||||||
get("/preview/:sig/:url/:filename", MediaProxyController, :preview)
|
get("/preview/:sig/:url/:filename", MediaProxy.MediaProxyController, :preview)
|
||||||
get("/:sig/:url", MediaProxyController, :remote)
|
get("/:sig/:url", MediaProxy.MediaProxyController, :remote)
|
||||||
get("/:sig/:url/:filename", MediaProxyController, :remote)
|
get("/:sig/:url/:filename", MediaProxy.MediaProxyController, :remote)
|
||||||
end
|
end
|
||||||
|
|
||||||
if Pleroma.Config.get(:env) == :dev do
|
if Pleroma.Config.get(:env) == :dev do
|
||||||
|
@ -826,4 +830,16 @@ defmodule Pleroma.Web.Router do
|
||||||
|
|
||||||
options("/*path", RedirectController, :empty)
|
options("/*path", RedirectController, :empty)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Change to Phoenix.Router.routes/1 for Phoenix 1.6.0+
|
||||||
|
def get_api_routes do
|
||||||
|
__MODULE__.__routes__()
|
||||||
|
|> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end)
|
||||||
|
|> Enum.map(fn r ->
|
||||||
|
r.path
|
||||||
|
|> String.split("/", trim: true)
|
||||||
|
|> List.first()
|
||||||
|
end)
|
||||||
|
|> Enum.uniq()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,6 @@ defmodule Pleroma.Web.StaticFE.StaticFEController do
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
|
|
||||||
plug(:put_layout, :static_fe)
|
plug(:put_layout, :static_fe)
|
||||||
plug(:put_view, Pleroma.Web.StaticFE.StaticFEView)
|
|
||||||
plug(:assign_id)
|
plug(:assign_id)
|
||||||
|
|
||||||
@page_keys ["max_id", "min_id", "limit", "since_id", "order"]
|
@page_keys ["max_id", "min_id", "limit", "since_id", "order"]
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
||||||
xmlns:statusnet="http://status.net/schema/api/1/">
|
xmlns:statusnet="http://status.net/schema/api/1/">
|
||||||
|
|
||||||
<id><%= '#{tag_feed_url(@conn, :feed, @tag)}.rss' %></id>
|
<id><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></id>
|
||||||
<title>#<%= @tag %></title>
|
<title>#<%= @tag %></title>
|
||||||
|
|
||||||
<subtitle>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</subtitle>
|
<subtitle>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</subtitle>
|
||||||
<logo><%= feed_logo() %></logo>
|
<logo><%= feed_logo() %></logo>
|
||||||
<updated><%= most_recent_update(@activities) %></updated>
|
<updated><%= most_recent_update(@activities) %></updated>
|
||||||
<link rel="self" href="<%= '#{tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
<%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
|
<%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<title>#<%= @tag %></title>
|
<title>#<%= @tag %></title>
|
||||||
<description>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</description>
|
<description>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</description>
|
||||||
<link><%= '#{tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
|
<link><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
|
||||||
<webfeeds:logo><%= feed_logo() %></webfeeds:logo>
|
<webfeeds:logo><%= feed_logo() %></webfeeds:logo>
|
||||||
<webfeeds:accentColor>2b90d9</webfeeds:accentColor>
|
<webfeeds:accentColor>2b90d9</webfeeds:accentColor>
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
|
|
|
@ -6,16 +6,16 @@
|
||||||
xmlns:poco="http://portablecontacts.net/spec/1.0"
|
xmlns:poco="http://portablecontacts.net/spec/1.0"
|
||||||
xmlns:ostatus="http://ostatus.org/schema/1.0">
|
xmlns:ostatus="http://ostatus.org/schema/1.0">
|
||||||
|
|
||||||
<id><%= user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
|
<id><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
|
||||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
<updated><%= most_recent_update(@activities, @user) %></updated>
|
<updated><%= most_recent_update(@activities, @user) %></updated>
|
||||||
<logo><%= logo(@user) %></logo>
|
<logo><%= logo(@user) %></logo>
|
||||||
<link rel="self" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
||||||
|
|
||||||
<%= render @view_module, "_author.atom", assigns %>
|
<%= render @view_module, "_author.atom", assigns %>
|
||||||
|
|
||||||
<%= if last_activity(@activities) do %>
|
<%= if last_activity(@activities) do %>
|
||||||
<link rel="next" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
|
<link rel="next" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<rss version="2.0">
|
<rss version="2.0">
|
||||||
<channel>
|
<channel>
|
||||||
<guid><%= user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %></guid>
|
<guid><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %></guid>
|
||||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
<updated><%= most_recent_update(@activities, @user) %></updated>
|
<updated><%= most_recent_update(@activities, @user) %></updated>
|
||||||
<image><%= logo(@user) %></image>
|
<image><%= logo(@user) %></image>
|
||||||
<link><%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
<link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
||||||
|
|
||||||
<%= render @view_module, "_author.rss", assigns %>
|
<%= render @view_module, "_author.rss", assigns %>
|
||||||
|
|
||||||
<%= if last_activity(@activities) do %>
|
<%= if last_activity(@activities) do %>
|
||||||
<link rel="next"><%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %></link>
|
<link rel="next"><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %></link>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<%= Config.get([:instance, :name]) %>
|
<%= Config.get([:instance, :name]) %>
|
||||||
</title>
|
</title>
|
||||||
<link rel="icon" type="image/png" href="/favicon.png"/>
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
<link rel="manifest" type="applicaton/manifest+json" href="<%= masto_fe_path(Pleroma.Web.Endpoint, :manifest) %>" />
|
<link rel="manifest" type="applicaton/manifest+json" href="<%= Routes.masto_fe_path(Pleroma.Web.Endpoint, :manifest) %>" />
|
||||||
|
|
||||||
<meta name="theme-color" content="<%= Config.get([:manifest, :theme_color]) %>" />
|
<meta name="theme-color" content="<%= Config.get([:manifest, :theme_color]) %>" />
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<h2>Two-factor recovery</h2>
|
<h2>Two-factor recovery</h2>
|
||||||
|
|
||||||
<%= form_for @conn, mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
|
<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<%= label f, :code, "Recovery code" %>
|
<%= label f, :code, "Recovery code" %>
|
||||||
<%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, spellcheck: false] %>
|
<%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, spellcheck: false] %>
|
||||||
|
@ -19,6 +19,6 @@
|
||||||
|
|
||||||
<%= submit "Verify" %>
|
<%= submit "Verify" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<a href="<%= mfa_path(@conn, :show, %{challenge_type: "totp", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
|
<a href="<%= Routes.mfa_path(@conn, :show, %{challenge_type: "totp", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
|
||||||
Enter a two-factor code
|
Enter a two-factor code
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<h2>Two-factor authentication</h2>
|
<h2>Two-factor authentication</h2>
|
||||||
|
|
||||||
<%= form_for @conn, mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
|
<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<%= label f, :code, "Authentication code" %>
|
<%= label f, :code, "Authentication code" %>
|
||||||
<%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %>
|
<%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %>
|
||||||
|
@ -19,6 +19,6 @@
|
||||||
|
|
||||||
<%= submit "Verify" %>
|
<%= submit "Verify" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<a href="<%= mfa_path(@conn, :show, %{challenge_type: "recovery", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
|
<a href="<%= Routes.mfa_path(@conn, :show, %{challenge_type: "recovery", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
|
||||||
Enter a two-factor recovery code
|
Enter a two-factor recovery code
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<h2>Sign in with external provider</h2>
|
<h2>Sign in with external provider</h2>
|
||||||
|
|
||||||
<%= form_for @conn, o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
|
<%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
|
||||||
<div style="display: none">
|
<div style="display: none">
|
||||||
<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %>
|
<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<h2>Registration Details</h2>
|
<h2>Registration Details</h2>
|
||||||
|
|
||||||
<p>If you'd like to register a new account, please provide the details below.</p>
|
<p>If you'd like to register a new account, please provide the details below.</p>
|
||||||
<%= form_for @conn, o_auth_path(@conn, :register), [as: "authorization"], fn f -> %>
|
<%= form_for @conn, Routes.o_auth_path(@conn, :register), [as: "authorization"], fn f -> %>
|
||||||
|
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<%= label f, :nickname, "Nickname" %>
|
<%= label f, :nickname, "Nickname" %>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %>
|
<%= form_for @conn, Routes.o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %>
|
||||||
|
|
||||||
<%= if @user do %>
|
<%= if @user do %>
|
||||||
<div class="account-header">
|
<div class="account-header">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<h2>Password Reset for <%= @user.nickname %></h2>
|
<h2>Password Reset for <%= @user.nickname %></h2>
|
||||||
<%= form_for @conn, reset_password_path(@conn, :do_reset), [as: "data"], fn f -> %>
|
<%= form_for @conn, Routes.reset_password_path(@conn, :do_reset), [as: "data"], fn f -> %>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<%= label f, :password, "Password" %>
|
<%= label f, :password, "Password" %>
|
||||||
<%= password_input f, :password %>
|
<%= password_input f, :password %>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<h2>Remote follow</h2>
|
<h2>Remote follow</h2>
|
||||||
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
||||||
<p><%= @followee.nickname %></p>
|
<p><%= @followee.nickname %></p>
|
||||||
<%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %>
|
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %>
|
||||||
<%= hidden_input f, :id, value: @followee.id %>
|
<%= hidden_input f, :id, value: @followee.id %>
|
||||||
<%= submit "Authorize" %>
|
<%= submit "Authorize" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<h2>Log in to follow</h2>
|
<h2>Log in to follow</h2>
|
||||||
<p><%= @followee.nickname %></p>
|
<p><%= @followee.nickname %></p>
|
||||||
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
||||||
<%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
|
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
|
||||||
<%= text_input f, :name, placeholder: "Username", required: true %>
|
<%= text_input f, :name, placeholder: "Username", required: true %>
|
||||||
<br>
|
<br>
|
||||||
<%= password_input f, :password, placeholder: "Password", required: true %>
|
<%= password_input f, :password, placeholder: "Password", required: true %>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<h2>Two-factor authentication</h2>
|
<h2>Two-factor authentication</h2>
|
||||||
<p><%= @followee.nickname %></p>
|
<p><%= @followee.nickname %></p>
|
||||||
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
||||||
<%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "mfa"], fn f -> %>
|
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "mfa"], fn f -> %>
|
||||||
<%= text_input f, :code, placeholder: "Authentication code", required: true %>
|
<%= text_input f, :code, placeholder: "Authentication code", required: true %>
|
||||||
<br>
|
<br>
|
||||||
<%= hidden_input f, :id, value: @followee.id %>
|
<%= hidden_input f, :id, value: @followee.id %>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<h2>Error: <%= @error %></h2>
|
<h2>Error: <%= @error %></h2>
|
||||||
<% else %>
|
<% else %>
|
||||||
<h2>Remotely follow <%= @nickname %></h2>
|
<h2>Remotely follow <%= @nickname %></h2>
|
||||||
<%= form_for @conn, util_path(@conn, :remote_subscribe), [as: "user"], fn f -> %>
|
<%= form_for @conn, Routes.util_path(@conn, :remote_subscribe), [as: "user"], fn f -> %>
|
||||||
<%= hidden_input f, :nickname, value: @nickname %>
|
<%= hidden_input f, :nickname, value: @nickname %>
|
||||||
<%= text_input f, :profile, placeholder: "Your account ID, e.g. lain@quitter.se" %>
|
<%= text_input f, :profile, placeholder: "Your account ID, e.g. lain@quitter.se" %>
|
||||||
<%= submit "Follow" %>
|
<%= submit "Follow" %>
|
||||||
|
|
|
@ -38,7 +38,7 @@ def follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
|
||||||
defp follow_status(conn, _user, acct) do
|
defp follow_status(conn, _user, acct) do
|
||||||
with {:ok, object} <- Fetcher.fetch_object_from_id(acct),
|
with {:ok, object} <- Fetcher.fetch_object_from_id(acct),
|
||||||
%Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object.data["id"]) do
|
%Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object.data["id"]) do
|
||||||
redirect(conn, to: o_status_path(conn, :notice, activity_id))
|
redirect(conn, to: Routes.o_status_path(conn, :notice, activity_id))
|
||||||
else
|
else
|
||||||
error ->
|
error ->
|
||||||
handle_follow_error(conn, error)
|
handle_follow_error(conn, error)
|
||||||
|
|
|
@ -79,7 +79,7 @@ def render("manifest.json", _params) do
|
||||||
background_color: Config.get([:manifest, :background_color]),
|
background_color: Config.get([:manifest, :background_color]),
|
||||||
display: "standalone",
|
display: "standalone",
|
||||||
scope: Pleroma.Web.base_url(),
|
scope: Pleroma.Web.base_url(),
|
||||||
start_url: masto_fe_path(Pleroma.Web.Endpoint, :index, ["getting-started"]),
|
start_url: Routes.masto_fe_path(Pleroma.Web.Endpoint, :index, ["getting-started"]),
|
||||||
categories: [
|
categories: [
|
||||||
"social"
|
"social"
|
||||||
],
|
],
|
||||||
|
|
|
@ -105,6 +105,6 @@ test "api routes are detected correctly" do
|
||||||
"check_password"
|
"check_password"
|
||||||
]
|
]
|
||||||
|
|
||||||
assert expected_routes == Pleroma.Web.get_api_routes()
|
assert expected_routes == Pleroma.Web.Router.get_api_routes()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue