diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ff3308e31..10a843af2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,7 +6,7 @@ variables: &global_variables
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
DB_HOST: postgres
- DB_PORT: 5432
+ DB_PORT: "5432"
MIX_ENV: test
workflow:
diff --git a/Dockerfile b/Dockerfile
index d2a3e3573..13d8a85ac 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,7 +9,7 @@ COPY . .
ENV MIX_ENV=prod
-RUN apk add git gcc g++ musl-dev make cmake file-dev &&\
+RUN apk add git gcc g++ musl-dev make cmake file-dev rust &&\
echo "import Config" > config/prod.secret.exs &&\
mix local.hex --force &&\
mix local.rebar --force &&\
@@ -37,7 +37,7 @@ ARG HOME=/opt/pleroma
ARG DATA=/var/lib/pleroma
RUN apk update &&\
- apk add exiftool ffmpeg imagemagick libmagic ncurses postgresql-client &&\
+ apk add exiftool ffmpeg vips libmagic ncurses postgresql-client &&\
adduser --system --shell /bin/false --home ${HOME} pleroma &&\
mkdir -p ${DATA}/uploads &&\
mkdir -p ${DATA}/static &&\
diff --git a/changelog.d/anonymous-exception-else.fix b/changelog.d/anonymous-exception-else.fix
new file mode 100644
index 000000000..38d5d1be5
--- /dev/null
+++ b/changelog.d/anonymous-exception-else.fix
@@ -0,0 +1 @@
+Fix #strip_report_status_data
diff --git a/changelog.d/blurhash.change b/changelog.d/blurhash.change
new file mode 100644
index 000000000..4276eb164
--- /dev/null
+++ b/changelog.d/blurhash.change
@@ -0,0 +1 @@
+Replace eblurhash with rinpatch_blurhash. This also removes a dependency on ImageMagick.
diff --git a/changelog.d/doc-fix.skip b/changelog.d/doc-fix.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/docs-max-elixir-erlang.change b/changelog.d/docs-max-elixir-erlang.change
new file mode 100644
index 000000000..a58b7fc17
--- /dev/null
+++ b/changelog.d/docs-max-elixir-erlang.change
@@ -0,0 +1 @@
+- Document maximum supported version of Erlang & Elixir
diff --git a/changelog.d/favicon.add b/changelog.d/favicon.add
new file mode 100644
index 000000000..cf12395e7
--- /dev/null
+++ b/changelog.d/favicon.add
@@ -0,0 +1 @@
+Add support for configuring favicon, embed favicon and PWA manifest in server-generated meta
diff --git a/changelog.d/federation_status-access.change b/changelog.d/federation_status-access.change
new file mode 100644
index 000000000..952254476
--- /dev/null
+++ b/changelog.d/federation_status-access.change
@@ -0,0 +1 @@
+- Make `/api/v1/pleroma/federation_status` publicly available
diff --git a/changelog.d/frontend-management.add b/changelog.d/frontend-management.add
new file mode 100644
index 000000000..b85cddd96
--- /dev/null
+++ b/changelog.d/frontend-management.add
@@ -0,0 +1 @@
+[docs] add frontends management documentation
diff --git a/changelog.d/generate-unset-user-keys-migration.skip b/changelog.d/generate-unset-user-keys-migration.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/loading-order-test-fix.skip b/changelog.d/loading-order-test-fix.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/promex.change b/changelog.d/promex.change
new file mode 100644
index 000000000..6c1571c54
--- /dev/null
+++ b/changelog.d/promex.change
@@ -0,0 +1 @@
+Change the prometheus library to PromEx.
diff --git a/changelog.d/reachability.change b/changelog.d/reachability.change
new file mode 100644
index 000000000..06f63272b
--- /dev/null
+++ b/changelog.d/reachability.change
@@ -0,0 +1 @@
+Reduce the reachability timestamp update to a single upsert query
diff --git a/changelog.d/scrobble-url.add b/changelog.d/scrobble-url.add
new file mode 100644
index 000000000..24bdeed89
--- /dev/null
+++ b/changelog.d/scrobble-url.add
@@ -0,0 +1 @@
+Adds the capability to add a URL to a scrobble (optional field)
diff --git a/changelog.d/system-cflags.fix b/changelog.d/system-cflags.fix
new file mode 100644
index 000000000..84de5ad57
--- /dev/null
+++ b/changelog.d/system-cflags.fix
@@ -0,0 +1 @@
+- Fix eblurhash and elixir-captcha not using system cflags
diff --git a/changelog.d/vips.change b/changelog.d/vips.change
new file mode 100644
index 000000000..ee18cd34b
--- /dev/null
+++ b/changelog.d/vips.change
@@ -0,0 +1 @@
+Change mediaproxy previews to use vips to generate thumbnails instead of ImageMagick
diff --git a/config/config.exs b/config/config.exs
index f2c137872..b884b3514 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -171,6 +171,7 @@ config :pleroma, :instance,
short_description: "",
background_image: "/images/city.jpg",
instance_thumbnail: "/instance/thumbnail.jpeg",
+ favicon: "/favicon.png",
limit: 5_000,
description_limit: 5_000,
remote_limit: 100_000,
@@ -346,6 +347,8 @@ config :pleroma, :manifest,
icons: [
%{
src: "/static/logo.svg",
+ sizes: "144x144",
+ purpose: "any",
type: "image/svg+xml"
}
],
@@ -648,12 +651,26 @@ config :pleroma, Pleroma.Emails.UserEmail,
config :pleroma, Pleroma.Emails.NewUsersDigestEmail, enabled: false
-config :prometheus, Pleroma.Web.Endpoint.MetricsExporter,
- enabled: false,
- auth: false,
- ip_whitelist: [],
- path: "/api/pleroma/app_metrics",
- format: :text
+config :pleroma, Pleroma.PromEx,
+ disabled: false,
+ manual_metrics_start_delay: :no_delay,
+ drop_metrics_groups: [],
+ grafana: [
+ host: System.get_env("GRAFANA_HOST", "http://localhost:3000"),
+ auth_token: System.get_env("GRAFANA_TOKEN"),
+ upload_dashboards_on_start: false,
+ folder_name: "BEAM",
+ annotate_app_lifecycle: true
+ ],
+ metrics_server: [
+ port: 4021,
+ path: "/metrics",
+ protocol: :http,
+ pool_size: 5,
+ cowboy_opts: [],
+ auth_strategy: :none
+ ],
+ datasource: "Prometheus"
config :pleroma, Pleroma.ScheduledActivity,
daily_user_limit: 25,
diff --git a/config/description.exs b/config/description.exs
index b152981c4..27e7f7e9b 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -987,6 +987,12 @@ config :pleroma, :config_description, [
"The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance.",
suggestions: ["/instance/thumbnail.jpeg"]
},
+ %{
+ key: :favicon,
+ type: {:string, :image},
+ description: "Favicon of the instance",
+ suggestions: ["/favicon.png"]
+ },
%{
key: :show_reactions,
type: :boolean,
diff --git a/docs/administration/frontends-management.md b/docs/administration/frontends-management.md
new file mode 100644
index 000000000..f982c4bca
--- /dev/null
+++ b/docs/administration/frontends-management.md
@@ -0,0 +1,71 @@
+# Managing installed frontends
+
+Pleroma lets you install multiple frontends including multiple versions of same frontend. Right now it's only possible to switch which frontend is the default, but in the future it would be possible for user to select which frontend they prefer to use.
+
+As of 2.6.0 there are two ways of managing frontends - through PleromaFE's Admin Dashboard (preferred, easier method) or through AdminFE (clunky but also works on versions older than 2.6.0).
+
+!!! note
+ Managing frontends through UI requires [in-database configuration](../configuration/howto_database_config.md) to be enabled (default on newer instances but might be off on older ones).
+
+## How it works
+
+When installing frontends, it creates a folder in [static directory](../configuration/static_dir.md) that follows this pattern: `/frontends/${front-end name}/${front-end version}/`, puts contents of the built frontend in there. Then when accessing the server backend checks what front-end name and version are set to be default and serves index.html and assets from appropriate path.
+
+!!! warning
+
+ If you've been putting your frontend build directly into static dir as an antiquated way of serving custom frontend, this system will not work and will still serve the custom index.html you put in there. You can still serve custom frontend builds if you put your build into `/frontends/$name/$version` instead and set the "default frontend" fields appropriately.
+
+Currently, there is no backup system, i.e. when installing `master` version it _will_ overwrite installed `master` version, for now if you want to keep previous version you should back it up manually, i.e. running `cp -r ./frontends/pleroma-fe/master ./frontends/pleroma-fe/master_old` in your static dir.
+
+## Managing front-ends through Admin Dashboard
+
+Open up Admin Dashboard (gauge icon in top bar, same as where link to AdminFE was),__
+![location of Admin Dashboard icon](../assets/admin_dash_location.png)
+switch to "Front-ends" tab.
+![screenshot of Front-ends tab](../assets/frontends_tab.png)
+This page is designed to be self-explanatory and easy to use, while avoiding issues and pitfalls of AdminFE, but it's also early in development, everything is subject to change.
+
+!!! warning
+ This goes without saying, but if you set default frontend to anything except >2.6.0 version of PleromaFE you'll lose the access to Admin Dashboard and will have to use AdminFE to get it back. See below on how to use AdminFE.
+
+### Limitations
+
+Currently the list of available for install frontends is essentially hard-coded in backend's configuration, each providing only one version, with exception for PleromaFE which overrides 'pleroma-fe' to also include `develop` version. There is no way to manually install build with a URL (coming soon) nor add more available frontends to the repository (it's broken).
+
+There is also no way to tell if there is an update available or not, for now you should watch for [announcements](https://pleroma.social/announcements/) of new PleromaFE stable releases to see if there is new stable version. For `develop` version it's up to you whether you want to follow the development process or just reinstall it periodically hoping for new stuff.
+
+## Using AdminFE to manage frontends
+
+Access AdminFE either directly by going to `/pleroma/admin` of your instance or by opening Admin Dashboard and clicking the link at the bottom of the window
+![link to open old AdminFE](../assets/old_adminfe_link.png)
+
+
+Go to Settings -> Frontend.
+
+### Installing front-ends
+
+At the very top of the page there's a list of available frontends and button to install custom front-end
+
+!!! tip
+ Remember to click "Submit" in bottom right corner to save your changes!
+
+!!! bug
+ **Available Frontends** section lets you _install_ frontends but **NOT** update/reinstall them. It's only useful for installing a frontend once.
+
+Due to aforementioned bug, preferred way of installing frontends in AdminFE is by clicking the "Install another frontend"
+![screenshot of admin-fe with instructions on how to install a frontend](../assets/way_to_install_frontends.png)
+and filling in the fields. Unfortunately AdminFE does not provide the raw data necessary for you to fill those fields, so your best bet is to see what backend returns in browser's devtools or refer to the [source code](https://git.pleroma.social/pleroma/pleroma/-/blob/develop/config/config.exs?ref_type=heads#L742-791). For the most part, only **Name**, **Ref** (i.e. version) and **Build URL** fields are required, although some frontends might also require **Build Directory** to work.
+
+For pleroma-fe you can use either `master` or `develop` refs, or potentially any ref in GitLab that has artifacts for `build` job, but that's outside scope of this document.
+
+### Selecting default frontend
+
+Scroll page waaaaay down, search for "Frontends" section, subtitled "Installed frontends management", change the name and reference of the "Primary" frontend.
+![screenshot of admin-fe with instructions on how to install a frontend](../assets/primary_frontend_section.png)
+
+
+!!! danger
+ If you change "Admin" frontend name/reference you risk losing access to AdminFE as well.
+
+!!! warning
+ Don't put anything into the "Available" section as it will break the list of available frontends completely, including the "add another frontend" button. If you accidentally put something in there, click the trashbin icon next to "Available" to reset it and restore the frontends list.
diff --git a/docs/assets/admin_dash_location.png b/docs/assets/admin_dash_location.png
new file mode 100644
index 000000000..4e1d110e7
Binary files /dev/null and b/docs/assets/admin_dash_location.png differ
diff --git a/docs/assets/frontends_tab.png b/docs/assets/frontends_tab.png
new file mode 100644
index 000000000..f7c66adab
Binary files /dev/null and b/docs/assets/frontends_tab.png differ
diff --git a/docs/assets/old_adminfe_link.png b/docs/assets/old_adminfe_link.png
new file mode 100644
index 000000000..5ea6a486c
Binary files /dev/null and b/docs/assets/old_adminfe_link.png differ
diff --git a/docs/assets/primary_frontend_section.png b/docs/assets/primary_frontend_section.png
new file mode 100644
index 000000000..14c3de41b
Binary files /dev/null and b/docs/assets/primary_frontend_section.png differ
diff --git a/docs/assets/way_to_install_frontends.png b/docs/assets/way_to_install_frontends.png
new file mode 100644
index 000000000..a90ff2b5d
Binary files /dev/null and b/docs/assets/way_to_install_frontends.png differ
diff --git a/docs/installation/freebsd_en.md b/docs/installation/freebsd_en.md
index 50ed30d74..02513daf2 100644
--- a/docs/installation/freebsd_en.md
+++ b/docs/installation/freebsd_en.md
@@ -9,7 +9,7 @@ This document was written for FreeBSD 12.1, but should be work on future release
This assumes the target system has `pkg(8)`.
```
-# pkg install elixir postgresql12-server postgresql12-client postgresql12-contrib git-lite sudo nginx gmake acme.sh cmake
+# pkg install elixir postgresql12-server postgresql12-client postgresql12-contrib git-lite sudo nginx gmake acme.sh cmake vips
```
Copy the rc.d scripts to the right directory:
@@ -41,6 +41,7 @@ Create a user for Pleroma:
```
# pw add user pleroma -m
# echo 'export LC_ALL="en_US.UTF-8"' >> /home/pleroma/.profile
+# echo 'export VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS' >> /home/pleroma/.profile
# su -l pleroma
```
diff --git a/docs/installation/generic_dependencies.include b/docs/installation/generic_dependencies.include
index dcaacfdfd..3365a36a8 100644
--- a/docs/installation/generic_dependencies.include
+++ b/docs/installation/generic_dependencies.include
@@ -1,11 +1,11 @@
## Required dependencies
-* PostgreSQL 9.6+
-* Elixir 1.10+
-* Erlang OTP 22.2+
+* PostgreSQL >=9.6
+* Elixir >=1.11.0 <1.15
+* Erlang OTP >=22.2.0 <26
* git
* file / libmagic
-* gcc (clang might also work)
+* gcc or clang
* GNU make
* CMake
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 7bbc132f1..52cd6e9a9 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -54,7 +54,6 @@ defmodule Pleroma.Application do
Config.DeprecationWarnings.warn()
Pleroma.Web.Plugs.HTTPSecurityPlug.warn_if_disabled()
Pleroma.ApplicationRequirements.verify!()
- setup_instrumenters()
load_custom_modules()
Pleroma.Docs.JSON.compile()
limiters_setup()
@@ -91,6 +90,7 @@ defmodule Pleroma.Application do
# Define workers and child supervisors to be supervised
children =
[
+ Pleroma.PromEx,
Pleroma.Repo,
Config.TransferTask,
Pleroma.Emoji,
@@ -170,29 +170,6 @@ defmodule Pleroma.Application do
end
end
- defp setup_instrumenters do
- require Prometheus.Registry
-
- if Application.get_env(:prometheus, Pleroma.Repo.Instrumenter) do
- :ok =
- :telemetry.attach(
- "prometheus-ecto",
- [:pleroma, :repo, :query],
- &Pleroma.Repo.Instrumenter.handle_event/4,
- %{}
- )
-
- Pleroma.Repo.Instrumenter.setup()
- end
-
- Pleroma.Web.Endpoint.MetricsExporter.setup()
- Pleroma.Web.Endpoint.PipelineInstrumenter.setup()
-
- # Note: disabled until prometheus-phx is integrated into prometheus-phoenix:
- # Pleroma.Web.Endpoint.Instrumenter.setup()
- PrometheusPhx.setup()
- end
-
defp cachex_children do
[
build_cachex("used_captcha", ttl_interval: seconds_valid_interval()),
diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex
index 44a984019..6fd05b0e0 100644
--- a/lib/pleroma/config/transfer_task.ex
+++ b/lib/pleroma/config/transfer_task.ex
@@ -55,8 +55,7 @@ defmodule Pleroma.Config.TransferTask do
started_applications = Application.started_applications()
- # TODO: some problem with prometheus after restart!
- reject = [nil, :prometheus, :postgrex]
+ reject = [nil, :postgrex]
reject =
if restart_pleroma? do
diff --git a/lib/pleroma/docs/generator.ex b/lib/pleroma/docs/generator.ex
index 6508f1947..456a8fd54 100644
--- a/lib/pleroma/docs/generator.ex
+++ b/lib/pleroma/docs/generator.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.Docs.Generator do
# This shouldn't be needed as all modules are expected to have module_info/1,
# but in test enviroments some transient modules `:elixir_compiler_XX`
# are loaded for some reason (where XX is a random integer).
+ Code.ensure_loaded(module)
+
if function_exported?(module, :module_info, 1) do
module.module_info(:attributes)
|> Keyword.get_values(:behaviour)
diff --git a/lib/pleroma/helpers/media_helper.ex b/lib/pleroma/helpers/media_helper.ex
index 24c845fcd..07dfea55b 100644
--- a/lib/pleroma/helpers/media_helper.ex
+++ b/lib/pleroma/helpers/media_helper.ex
@@ -8,11 +8,12 @@ defmodule Pleroma.Helpers.MediaHelper do
"""
alias Pleroma.HTTP
+ alias Vix.Vips.Operation
require Logger
def missing_dependencies do
- Enum.reduce([imagemagick: "convert", ffmpeg: "ffmpeg"], [], fn {sym, executable}, acc ->
+ Enum.reduce([ffmpeg: "ffmpeg"], [], fn {sym, executable}, acc ->
if Pleroma.Utils.command_available?(executable) do
acc
else
@@ -22,54 +23,22 @@ defmodule Pleroma.Helpers.MediaHelper do
end
def image_resize(url, options) do
- with executable when is_binary(executable) <- System.find_executable("convert"),
- {:ok, args} <- prepare_image_resize_args(options),
- {:ok, env} <- HTTP.get(url, [], pool: :media),
- {:ok, fifo_path} <- mkfifo() do
- args = List.flatten([fifo_path, args])
- run_fifo(fifo_path, env, executable, args)
+ with {:ok, env} <- HTTP.get(url, [], pool: :media),
+ {:ok, resized} <-
+ Operation.thumbnail_buffer(env.body, options.max_width,
+ height: options.max_height,
+ size: :VIPS_SIZE_DOWN
+ ) do
+ if options[:format] == "png" do
+ Operation.pngsave_buffer(resized, Q: options[:quality])
+ else
+ Operation.jpegsave_buffer(resized, Q: options[:quality], interlace: true)
+ end
else
- nil -> {:error, {:convert, :command_not_found}}
{:error, _} = error -> error
end
end
- defp prepare_image_resize_args(
- %{max_width: max_width, max_height: max_height, format: "png"} = options
- ) do
- quality = options[:quality] || 85
- resize = Enum.join([max_width, "x", max_height, ">"])
-
- args = [
- "-resize",
- resize,
- "-quality",
- to_string(quality),
- "png:-"
- ]
-
- {:ok, args}
- end
-
- defp prepare_image_resize_args(%{max_width: max_width, max_height: max_height} = options) do
- quality = options[:quality] || 85
- resize = Enum.join([max_width, "x", max_height, ">"])
-
- args = [
- "-interlace",
- "Plane",
- "-resize",
- resize,
- "-quality",
- to_string(quality),
- "jpg:-"
- ]
-
- {:ok, args}
- end
-
- defp prepare_image_resize_args(_), do: {:error, :missing_options}
-
# Note: video thumbnail is intentionally not resized (always has original dimensions)
def video_framegrab(url) do
with executable when is_binary(executable) <- System.find_executable("ffmpeg"),
diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex
index 9756c66dc..101e5dc88 100644
--- a/lib/pleroma/instances/instance.ex
+++ b/lib/pleroma/instances/instance.ex
@@ -97,13 +97,9 @@ defmodule Pleroma.Instances.Instance do
def reachable?(url_or_host) when is_binary(url_or_host), do: true
def set_reachable(url_or_host) when is_binary(url_or_host) do
- with host <- host(url_or_host),
- %Instance{} = existing_record <- Repo.get_by(Instance, %{host: host}) do
- {:ok, _instance} =
- existing_record
- |> changeset(%{unreachable_since: nil})
- |> Repo.update()
- end
+ %Instance{host: host(url_or_host)}
+ |> changeset(%{unreachable_since: nil})
+ |> Repo.insert(on_conflict: {:replace, [:unreachable_since]}, conflict_target: :host)
end
def set_reachable(_), do: {:error, nil}
diff --git a/lib/pleroma/prom_ex.ex b/lib/pleroma/prom_ex.ex
new file mode 100644
index 000000000..6608708b7
--- /dev/null
+++ b/lib/pleroma/prom_ex.ex
@@ -0,0 +1,49 @@
+defmodule Pleroma.PromEx do
+ use PromEx, otp_app: :pleroma
+
+ alias PromEx.Plugins
+
+ @impl true
+ def plugins do
+ [
+ # PromEx built in plugins
+ Plugins.Application,
+ Plugins.Beam,
+ {Plugins.Phoenix, router: Pleroma.Web.Router, endpoint: Pleroma.Web.Endpoint},
+ Plugins.Ecto,
+ Plugins.Oban
+ # Plugins.PhoenixLiveView,
+ # Plugins.Absinthe,
+ # Plugins.Broadway,
+
+ # Add your own PromEx metrics plugins
+ # Pleroma.Users.PromExPlugin
+ ]
+ end
+
+ @impl true
+ def dashboard_assigns do
+ [
+ datasource_id: Pleroma.Config.get([Pleroma.PromEx, :datasource]),
+ default_selected_interval: "30s"
+ ]
+ end
+
+ @impl true
+ def dashboards do
+ [
+ # PromEx built in Grafana dashboards
+ {:prom_ex, "application.json"},
+ {:prom_ex, "beam.json"},
+ {:prom_ex, "phoenix.json"},
+ {:prom_ex, "ecto.json"},
+ {:prom_ex, "oban.json"}
+ # {:prom_ex, "phoenix_live_view.json"},
+ # {:prom_ex, "absinthe.json"},
+ # {:prom_ex, "broadway.json"},
+
+ # Add your dashboard definitions here with the format: {:otp_app, "path_in_priv"}
+ # {:pleroma, "/grafana_dashboards/user_metrics.json"}
+ ]
+ end
+end
diff --git a/lib/pleroma/repo.ex b/lib/pleroma/repo.ex
index 515b0c1ff..a50a59b3b 100644
--- a/lib/pleroma/repo.ex
+++ b/lib/pleroma/repo.ex
@@ -11,8 +11,6 @@ defmodule Pleroma.Repo do
import Ecto.Query
require Logger
- defmodule Instrumenter, do: use(Prometheus.EctoInstrumenter)
-
@doc """
Dynamically loads the repository url from the
DATABASE_URL environment variable.
diff --git a/lib/pleroma/upload/filter/analyze_metadata.ex b/lib/pleroma/upload/filter/analyze_metadata.ex
index 9a76a998b..e510ae3e6 100644
--- a/lib/pleroma/upload/filter/analyze_metadata.ex
+++ b/lib/pleroma/upload/filter/analyze_metadata.ex
@@ -8,22 +8,23 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
"""
require Logger
+ alias Vix.Vips.Image
+ alias Vix.Vips.Operation
+
@behaviour Pleroma.Upload.Filter
@spec filter(Pleroma.Upload.t()) ::
{:ok, :filtered, Pleroma.Upload.t()} | {:ok, :noop} | {:error, String.t()}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _} = upload) do
try do
- image =
- file
- |> Mogrify.open()
- |> Mogrify.verbose()
+ {:ok, image} = Image.new_from_file(file)
+ {width, height} = {Image.width(image), Image.height(image)}
upload =
upload
- |> Map.put(:width, image.width)
- |> Map.put(:height, image.height)
- |> Map.put(:blurhash, get_blurhash(file))
+ |> Map.put(:width, width)
+ |> Map.put(:height, height)
+ |> Map.put(:blurhash, get_blurhash(image))
{:ok, :filtered, upload}
rescue
@@ -53,7 +54,7 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
def filter(_), do: {:ok, :noop}
defp get_blurhash(file) do
- with {:ok, blurhash} <- :eblurhash.magick(file) do
+ with {:ok, blurhash} <- vips_blurhash(file) do
blurhash
else
_ -> nil
@@ -77,7 +78,28 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
%{width: width, height: height}
else
nil -> {:error, {:ffprobe, :command_not_found}}
- {:error, _} = error -> error
+ error -> {:error, error}
+ end
+ end
+
+ defp vips_blurhash(%Vix.Vips.Image{} = image) do
+ with {:ok, resized_image} <- Operation.thumbnail_image(image, 100),
+ {height, width} <- {Image.height(resized_image), Image.width(resized_image)},
+ max <- max(height, width),
+ {x, y} <- {max(round(width * 5 / max), 1), max(round(height * 5 / max), 1)} do
+ {:ok, rgb} =
+ if Image.has_alpha?(resized_image) do
+ # remove alpha channel
+ resized_image
+ |> Operation.extract_band!(0, n: 3)
+ |> Image.write_to_binary()
+ else
+ Image.write_to_binary(resized_image)
+ end
+
+ Blurhash.encode(rgb, width, height, x, y)
+ else
+ _ -> nil
end
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex
index ff9f84497..69054e25b 100644
--- a/lib/pleroma/web/activity_pub/mrf.ex
+++ b/lib/pleroma/web/activity_pub/mrf.ex
@@ -54,6 +54,8 @@ defmodule Pleroma.Web.ActivityPub.MRF do
@required_description_keys [:key, :related_policy]
def filter_one(policy, message) do
+ Code.ensure_loaded(policy)
+
should_plug_history? =
if function_exported?(policy, :history_awareness, 0) do
policy.history_awareness()
@@ -188,6 +190,8 @@ defmodule Pleroma.Web.ActivityPub.MRF do
def config_descriptions(policies) do
Enum.reduce(policies, @mrf_config_descriptions, fn policy, acc ->
+ Code.ensure_loaded(policy)
+
if function_exported?(policy, :config_description, 0) do
description =
@default_description
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 437220077..b32f19740 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
alias Ecto.UUID
alias Pleroma.Activity
alias Pleroma.Config
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
alias Pleroma.Maps
alias Pleroma.Notification
alias Pleroma.Object
@@ -852,9 +853,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
[actor | reported_activities] = activity.data["object"]
stripped_activities =
- Enum.map(reported_activities, fn
- act when is_map(act) -> act["id"]
- act when is_binary(act) -> act
+ Enum.reduce(reported_activities, [], fn act, acc ->
+ case ObjectID.cast(act) do
+ {:ok, act} -> [act | acc]
+ _ -> acc
+ end
end)
new_data = put_in(activity.data, ["object"], [actor | stripped_activities])
diff --git a/lib/pleroma/web/api_spec/operations/pleroma_scrobble_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_scrobble_operation.ex
index ca40da930..141b60533 100644
--- a/lib/pleroma/web/api_spec/operations/pleroma_scrobble_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/pleroma_scrobble_operation.ex
@@ -59,6 +59,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
album: %Schema{type: :string, description: "The album of the media playing"},
artist: %Schema{type: :string, description: "The artist of the media playing"},
length: %Schema{type: :integer, description: "The length of the media playing"},
+ externalLink: %Schema{type: :string, description: "A URL referencing the media playing"},
visibility: %Schema{
allOf: [VisibilityScope],
default: "public",
@@ -69,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
"title" => "Some Title",
"artist" => "Some Artist",
"album" => "Some Album",
- "length" => 180_000
+ "length" => 180_000,
+ "externalLink" => "https://www.last.fm/music/Some+Artist/_/Some+Title"
}
}
end
@@ -83,6 +85,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
title: %Schema{type: :string, description: "The title of the media playing"},
album: %Schema{type: :string, description: "The album of the media playing"},
artist: %Schema{type: :string, description: "The artist of the media playing"},
+ externalLink: %Schema{type: :string, description: "A URL referencing the media playing"},
length: %Schema{
type: :integer,
description: "The length of the media playing",
@@ -97,6 +100,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
"artist" => "Some Artist",
"album" => "Some Album",
"length" => 180_000,
+ "externalLink" => "https://www.last.fm/music/Some+Artist/_/Some+Title",
"created_at" => "2019-09-28T12:40:45.000Z"
}
}
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index ca1329284..8910ad5b8 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -83,7 +83,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp listen_object(draft) do
object =
draft.params
- |> Map.take([:album, :artist, :title, :length])
+ |> Map.take([:album, :artist, :title, :length, :externalLink])
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|> Map.put("type", "Audio")
|> Map.put("to", draft.to)
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index 65dd72c49..307fa069e 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -151,47 +151,6 @@ defmodule Pleroma.Web.Endpoint do
plug(Pleroma.Web.Plugs.RemoteIp)
- defmodule Instrumenter do
- use Prometheus.PhoenixInstrumenter
- end
-
- defmodule PipelineInstrumenter do
- use Prometheus.PlugPipelineInstrumenter
- end
-
- defmodule MetricsExporter do
- use Prometheus.PlugExporter
- end
-
- defmodule MetricsExporterCaller do
- @behaviour Plug
-
- def init(opts), do: opts
-
- def call(conn, opts) do
- prometheus_config = Application.get_env(:prometheus, MetricsExporter, [])
- ip_whitelist = List.wrap(prometheus_config[:ip_whitelist])
-
- cond do
- !prometheus_config[:enabled] ->
- conn
-
- ip_whitelist != [] and
- !Enum.find(ip_whitelist, fn ip ->
- Pleroma.Helpers.InetHelper.parse_address(ip) == {:ok, conn.remote_ip}
- end) ->
- conn
-
- true ->
- MetricsExporter.call(conn, opts)
- end
- end
- end
-
- plug(PipelineInstrumenter)
-
- plug(MetricsExporterCaller)
-
plug(Pleroma.Web.Router)
@doc """
diff --git a/lib/pleroma/web/fallback/redirect_controller.ex b/lib/pleroma/web/fallback/redirect_controller.ex
index 1a86f7a53..4a0885fab 100644
--- a/lib/pleroma/web/fallback/redirect_controller.ex
+++ b/lib/pleroma/web/fallback/redirect_controller.ex
@@ -17,10 +17,28 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|> json(%{error: "Not implemented"})
end
+ def add_generated_metadata(page_content, extra \\ "") do
+ title = "