Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into emoji-pack-upload
This commit is contained in:
commit
36b3aa0a97
25 changed files with 501 additions and 215 deletions
1
changelog.d/db-restore-docs.change
Normal file
1
changelog.d/db-restore-docs.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Docs: Restore DB schema before data to avoid long restore times
|
||||||
1
changelog.d/deactivated-404-inbox.change
Normal file
1
changelog.d/deactivated-404-inbox.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Return 404 with a better error message instead of 400 when receiving an activity for a deactivated user
|
||||||
1
changelog.d/gun.change
Normal file
1
changelog.d/gun.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Update Cowboy, Gun, and Plug family of dependencies
|
||||||
1
changelog.d/hashtag-search.change
Normal file
1
changelog.d/hashtag-search.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Hashtag searches return real results based on words in your query
|
||||||
1
changelog.d/smtp-docs.change
Normal file
1
changelog.d/smtp-docs.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Change SMTP example to use the Mua adapter that works with OTP>25
|
||||||
1
changelog.d/tesla.change
Normal file
1
changelog.d/tesla.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Updated Tesla to 1.15.3
|
||||||
|
|
@ -2,28 +2,60 @@
|
||||||
|
|
||||||
## Backup
|
## Backup
|
||||||
|
|
||||||
1. Stop the Pleroma service.
|
1. Stop the Pleroma service:
|
||||||
2. Go to the working directory of Pleroma (default is `/opt/pleroma`)
|
```
|
||||||
3. Run `sudo -Hu postgres pg_dump -d <pleroma_db> --format=custom -f </path/to/backup_location/pleroma.pgdump>` (make sure the postgres user has write access to the destination file)
|
# sudo systemctl stop pleroma
|
||||||
|
```
|
||||||
|
2. Go to the working directory of Pleroma (default is `/opt/pleroma`).
|
||||||
|
3. Run (make sure the postgres user has write access to the destination file):
|
||||||
|
```
|
||||||
|
# sudo -Hu postgres pg_dump -d <pleroma_db> -v --format=custom --compress=9 -f </path/to/backup_location/pleroma.pgdump>
|
||||||
|
```
|
||||||
4. Copy `pleroma.pgdump`, `config/prod.secret.exs`, `config/setup_db.psql` (if still available) and the `uploads` folder to your backup destination. If you have other modifications, copy those changes too.
|
4. Copy `pleroma.pgdump`, `config/prod.secret.exs`, `config/setup_db.psql` (if still available) and the `uploads` folder to your backup destination. If you have other modifications, copy those changes too.
|
||||||
5. Restart the Pleroma service.
|
5. Restart the Pleroma service:
|
||||||
|
```
|
||||||
|
# sudo systemctl start pleroma
|
||||||
|
```
|
||||||
|
|
||||||
## Restore/Move
|
## Restore/Move
|
||||||
|
|
||||||
1. Optionally reinstall Pleroma (either on the same server or on another server if you want to move servers).
|
1. Optionally reinstall Pleroma (either on the same server or on another server if you want to move servers).
|
||||||
2. Stop the Pleroma service.
|
2. Stop the Pleroma service:
|
||||||
3. Go to the working directory of Pleroma (default is `/opt/pleroma`)
|
```
|
||||||
|
# sudo systemctl stop pleroma
|
||||||
|
```
|
||||||
|
3. Go to the working directory of Pleroma (default is `/opt/pleroma`).
|
||||||
4. Copy the above mentioned files back to their original position.
|
4. Copy the above mentioned files back to their original position.
|
||||||
5. Drop the existing database and user if restoring in-place. `sudo -Hu postgres psql -c 'DROP DATABASE <pleroma_db>;';` `sudo -Hu postgres psql -c 'DROP USER <pleroma_db>;'`
|
5. Drop the existing database and user if restoring in-place:
|
||||||
6. Restore the database schema and pleroma postgres role the with the original `setup_db.psql` if you have it: `sudo -Hu postgres psql -f config/setup_db.psql`.
|
```
|
||||||
|
# sudo -Hu postgres dropdb <pleroma_db>
|
||||||
|
# sudo -Hu postgres dropuser <pleroma_user>
|
||||||
|
```
|
||||||
|
6. Restore the database schema and pleroma database user the with the original `setup_db.psql` if you have it:
|
||||||
|
```
|
||||||
|
# sudo -Hu postgres psql -f config/setup_db.psql
|
||||||
|
```
|
||||||
|
|
||||||
Alternatively, run the `mix pleroma.instance gen` task again. You can ignore most of the questions, but make the database user, name, and password the same as found in your backup of `config/prod.secret.exs`. Then run the restoration of the pleroma role and schema with of the generated `config/setup_db.psql` as instructed above. You may delete the `config/generated_config.exs` file as it is not needed.
|
Alternatively, run the `mix pleroma.instance gen` task again. You can ignore most of the questions, but make the database user, name, and password the same as found in your backup of `config/prod.secret.exs`. Then run the restoration of the pleroma user and schema with the generated `config/setup_db.psql` as instructed above. You may delete the `config/generated_config.exs` file as it is not needed.
|
||||||
|
|
||||||
7. Now restore the Pleroma instance's data into the empty database schema: `sudo -Hu postgres pg_restore -d <pleroma_db> -v -1 </path/to/backup_location/pleroma.pgdump>`
|
7. Now restore the Pleroma instance's schema into the empty database schema:
|
||||||
8. If you installed a newer Pleroma version, you should run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
|
```
|
||||||
9. Restart the Pleroma service.
|
# sudo -Hu postgres pg_restore -d <pleroma_db> -v -s -1 </path/to/backup_location/pleroma.pgdump>
|
||||||
10. Run `sudo -Hu postgres vacuumdb --all --analyze-in-stages`. This will quickly generate the statistics so that postgres can properly plan queries.
|
```
|
||||||
11. If setting up on a new server configure Nginx by using the `installation/pleroma.nginx` config sample or reference the Pleroma installation guide for your OS which contains the Nginx configuration instructions.
|
8. Now restore the Pleroma instance's data into the database:
|
||||||
|
```
|
||||||
|
# sudo -Hu postgres pg_restore -d <pleroma_db> -v -a -1 --disable-triggers </path/to/backup_location/pleroma.pgdump>
|
||||||
|
```
|
||||||
|
9. If you installed a newer Pleroma version, you should run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
|
||||||
|
10. Generate the statistics so that PostgreSQL can properly plan queries:
|
||||||
|
```
|
||||||
|
# sudo -Hu postgres vacuumdb -v --all --analyze-in-stages
|
||||||
|
```
|
||||||
|
11. Restart the Pleroma service:
|
||||||
|
```
|
||||||
|
# sudo systemctl start pleroma
|
||||||
|
```
|
||||||
|
12. If setting up on a new server, configure Nginx by using your original configuration or by using the `installation/pleroma.nginx` config sample or reference the Pleroma installation guide for your OS which contains the Nginx configuration instructions.
|
||||||
|
|
||||||
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
||||||
|
|
||||||
|
|
@ -32,10 +64,26 @@
|
||||||
1. Optionally you can remove the users of your instance. This will trigger delete requests for their accounts and posts. Note that this is 'best effort' and doesn't mean that all traces of your instance will be gone from the fediverse.
|
1. Optionally you can remove the users of your instance. This will trigger delete requests for their accounts and posts. Note that this is 'best effort' and doesn't mean that all traces of your instance will be gone from the fediverse.
|
||||||
* You can do this from the admin-FE where you can select all local users and delete the accounts using the *Moderate multiple users* dropdown.
|
* You can do this from the admin-FE where you can select all local users and delete the accounts using the *Moderate multiple users* dropdown.
|
||||||
* You can also list local users and delete them individually using the CLI tasks for [Managing users](./CLI_tasks/user.md).
|
* You can also list local users and delete them individually using the CLI tasks for [Managing users](./CLI_tasks/user.md).
|
||||||
2. Stop the Pleroma service `systemctl stop pleroma`
|
2. Stop the Pleroma service:
|
||||||
3. Disable pleroma from systemd `systemctl disable pleroma`
|
```
|
||||||
|
# systemctl stop pleroma
|
||||||
|
```
|
||||||
|
3. Disable pleroma from systemd:
|
||||||
|
```
|
||||||
|
# systemctl disable pleroma
|
||||||
|
```
|
||||||
4. Remove the files and folders you created during installation (see installation guide). This includes the pleroma, nginx and systemd files and folders.
|
4. Remove the files and folders you created during installation (see installation guide). This includes the pleroma, nginx and systemd files and folders.
|
||||||
5. Reload nginx now that the configuration is removed `systemctl reload nginx`
|
5. Reload nginx now that the configuration is removed:
|
||||||
6. Remove the database and database user `sudo -Hu postgres psql -c 'DROP DATABASE <pleroma_db>;';` `sudo -Hu postgres psql -c 'DROP USER <pleroma_db>;'`
|
```
|
||||||
7. Remove the system user `userdel pleroma`
|
# systemctl reload nginx
|
||||||
8. Remove the dependencies that you don't need anymore (see installation guide). Make sure you don't remove packages that are still needed for other software that you have running!
|
```
|
||||||
|
6. Remove the database and database user:
|
||||||
|
```
|
||||||
|
# sudo -Hu postgres dropdb <pleroma_db>
|
||||||
|
# sudo -Hu postgres dropuser <pleroma_user>
|
||||||
|
```
|
||||||
|
7. Remove the system user:
|
||||||
|
```
|
||||||
|
# userdel -r pleroma
|
||||||
|
```
|
||||||
|
8. Remove the dependencies that you don't need anymore (see installation guide). **Make sure you don't remove packages that are still needed for other software that you have running!**
|
||||||
|
|
|
||||||
|
|
@ -733,13 +733,11 @@ An example for SMTP adapter:
|
||||||
```elixir
|
```elixir
|
||||||
config :pleroma, Pleroma.Emails.Mailer,
|
config :pleroma, Pleroma.Emails.Mailer,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
adapter: Swoosh.Adapters.SMTP,
|
adapter: Swoosh.Adapters.Mua,
|
||||||
relay: "smtp.gmail.com",
|
relay: "smtp.gmail.com",
|
||||||
username: "YOUR_USERNAME@gmail.com",
|
auth: [username: "YOUR_USERNAME@gmail.com", password: "YOUR_SMTP_PASSWORD"],
|
||||||
password: "YOUR_SMTP_PASSWORD",
|
|
||||||
port: 465,
|
port: 465,
|
||||||
ssl: true,
|
protocol: :ssl
|
||||||
auth: :always
|
|
||||||
```
|
```
|
||||||
|
|
||||||
An example for Mua adapter:
|
An example for Mua adapter:
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,15 @@ defmodule Pleroma.Gopher.Server do
|
||||||
def init([ip, port]) do
|
def init([ip, port]) do
|
||||||
Logger.info("Starting gopher server on #{port}")
|
Logger.info("Starting gopher server on #{port}")
|
||||||
|
|
||||||
|
{:ok, _pid} =
|
||||||
:ranch.start_listener(
|
:ranch.start_listener(
|
||||||
:gopher,
|
:gopher,
|
||||||
100,
|
|
||||||
:ranch_tcp,
|
:ranch_tcp,
|
||||||
[ip: ip, port: port],
|
%{
|
||||||
|
num_acceptors: 100,
|
||||||
|
max_connections: 100,
|
||||||
|
socket_opts: [ip: ip, port: port]
|
||||||
|
},
|
||||||
__MODULE__.ProtocolHandler,
|
__MODULE__.ProtocolHandler,
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
@ -43,13 +47,13 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
|
|
||||||
def start_link(ref, socket, transport, opts) do
|
def start_link(ref, transport, opts) do
|
||||||
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])
|
pid = spawn_link(__MODULE__, :init, [ref, transport, opts])
|
||||||
{:ok, pid}
|
{:ok, pid}
|
||||||
end
|
end
|
||||||
|
|
||||||
def init(ref, socket, transport, [] = _Opts) do
|
def init(ref, transport, opts \\ []) do
|
||||||
:ok = :ranch.accept_ack(ref)
|
{:ok, socket} = :ranch.handshake(ref, opts)
|
||||||
loop(socket, transport)
|
loop(socket, transport)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,4 +130,66 @@ defmodule Pleroma.Hashtag do
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_recipients_for_activity(_activity), do: []
|
def get_recipients_for_activity(_activity), do: []
|
||||||
|
|
||||||
|
def search(query, options \\ []) do
|
||||||
|
limit = Keyword.get(options, :limit, 20)
|
||||||
|
offset = Keyword.get(options, :offset, 0)
|
||||||
|
|
||||||
|
search_terms =
|
||||||
|
query
|
||||||
|
|> String.downcase()
|
||||||
|
|> String.trim()
|
||||||
|
|> String.split(~r/\s+/)
|
||||||
|
|> Enum.filter(&(&1 != ""))
|
||||||
|
|> Enum.map(&String.trim_leading(&1, "#"))
|
||||||
|
|> Enum.filter(&(&1 != ""))
|
||||||
|
|
||||||
|
if Enum.empty?(search_terms) do
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
# Use PostgreSQL's ANY operator with array for efficient multi-term search
|
||||||
|
# This is much more efficient than multiple OR clauses
|
||||||
|
search_patterns = Enum.map(search_terms, &"%#{&1}%")
|
||||||
|
|
||||||
|
# Create ranking query that prioritizes exact matches and closer matches
|
||||||
|
# Use a subquery to properly handle computed columns in ORDER BY
|
||||||
|
base_query =
|
||||||
|
from(ht in Hashtag,
|
||||||
|
where: fragment("LOWER(?) LIKE ANY(?)", ht.name, ^search_patterns),
|
||||||
|
select: %{
|
||||||
|
name: ht.name,
|
||||||
|
# Ranking: exact matches get highest priority (0)
|
||||||
|
# then prefix matches (1), then contains (2)
|
||||||
|
match_rank:
|
||||||
|
fragment(
|
||||||
|
"""
|
||||||
|
CASE
|
||||||
|
WHEN LOWER(?) = ANY(?) THEN 0
|
||||||
|
WHEN LOWER(?) LIKE ANY(?) THEN 1
|
||||||
|
ELSE 2
|
||||||
|
END
|
||||||
|
""",
|
||||||
|
ht.name,
|
||||||
|
^search_terms,
|
||||||
|
ht.name,
|
||||||
|
^Enum.map(search_terms, &"#{&1}%")
|
||||||
|
),
|
||||||
|
# Secondary sort by name length (shorter names first)
|
||||||
|
name_length: fragment("LENGTH(?)", ht.name)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
from(result in subquery(base_query),
|
||||||
|
order_by: [
|
||||||
|
asc: result.match_rank,
|
||||||
|
asc: result.name_length,
|
||||||
|
asc: result.name
|
||||||
|
],
|
||||||
|
limit: ^limit,
|
||||||
|
offset: ^offset
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
|> Enum.map(& &1.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -157,26 +157,55 @@ defmodule Pleroma.Search.QdrantSearch do
|
||||||
end
|
end
|
||||||
|
|
||||||
defmodule Pleroma.Search.QdrantSearch.OpenAIClient do
|
defmodule Pleroma.Search.QdrantSearch.OpenAIClient do
|
||||||
use Tesla
|
|
||||||
alias Pleroma.Config.Getting, as: Config
|
alias Pleroma.Config.Getting, as: Config
|
||||||
|
|
||||||
plug(Tesla.Middleware.BaseUrl, Config.get([Pleroma.Search.QdrantSearch, :openai_url]))
|
def post(path, body) do
|
||||||
plug(Tesla.Middleware.JSON)
|
Tesla.post(client(), path, body)
|
||||||
|
end
|
||||||
|
|
||||||
plug(Tesla.Middleware.Headers, [
|
defp client do
|
||||||
{"Authorization",
|
Tesla.client(middleware())
|
||||||
"Bearer #{Pleroma.Config.get([Pleroma.Search.QdrantSearch, :openai_api_key])}"}
|
end
|
||||||
])
|
|
||||||
|
defp middleware do
|
||||||
|
[
|
||||||
|
{Tesla.Middleware.BaseUrl, Config.get([Pleroma.Search.QdrantSearch, :openai_url])},
|
||||||
|
Tesla.Middleware.JSON,
|
||||||
|
{Tesla.Middleware.Headers,
|
||||||
|
[
|
||||||
|
{"Authorization", "Bearer #{Config.get([Pleroma.Search.QdrantSearch, :openai_api_key])}"}
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defmodule Pleroma.Search.QdrantSearch.QdrantClient do
|
defmodule Pleroma.Search.QdrantSearch.QdrantClient do
|
||||||
use Tesla
|
|
||||||
alias Pleroma.Config.Getting, as: Config
|
alias Pleroma.Config.Getting, as: Config
|
||||||
|
|
||||||
plug(Tesla.Middleware.BaseUrl, Config.get([Pleroma.Search.QdrantSearch, :qdrant_url]))
|
def delete(path) do
|
||||||
plug(Tesla.Middleware.JSON)
|
Tesla.delete(client(), path)
|
||||||
|
end
|
||||||
plug(Tesla.Middleware.Headers, [
|
|
||||||
{"api-key", Pleroma.Config.get([Pleroma.Search.QdrantSearch, :qdrant_api_key])}
|
def post(path, body) do
|
||||||
])
|
Tesla.post(client(), path, body)
|
||||||
|
end
|
||||||
|
|
||||||
|
def put(path, body) do
|
||||||
|
Tesla.put(client(), path, body)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp client do
|
||||||
|
Tesla.client(middleware())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp middleware do
|
||||||
|
[
|
||||||
|
{Tesla.Middleware.BaseUrl, Config.get([Pleroma.Search.QdrantSearch, :qdrant_url])},
|
||||||
|
Tesla.Middleware.JSON,
|
||||||
|
{Tesla.Middleware.Headers,
|
||||||
|
[
|
||||||
|
{"api-key", Pleroma.Config.get([Pleroma.Search.QdrantSearch, :qdrant_api_key])}
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -273,13 +273,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do
|
def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do
|
||||||
with %User{is_active: true} = recipient <- User.get_cached_by_nickname(nickname),
|
with {:recipient_exists, %User{} = recipient} <-
|
||||||
{:ok, %User{is_active: true} = actor} <- User.get_or_fetch_by_ap_id(params["actor"]),
|
{:recipient_exists, User.get_cached_by_nickname(nickname)},
|
||||||
|
{:sender_exists, {:ok, %User{} = actor}} <-
|
||||||
|
{:sender_exists, User.get_or_fetch_by_ap_id(params["actor"])},
|
||||||
|
{:recipient_active, true} <- {:recipient_active, recipient.is_active},
|
||||||
|
{:sender_active, true} <- {:sender_active, actor.is_active},
|
||||||
true <- Utils.recipient_in_message(recipient, actor, params),
|
true <- Utils.recipient_in_message(recipient, actor, params),
|
||||||
params <- Utils.maybe_splice_recipient(recipient.ap_id, params) do
|
params <- Utils.maybe_splice_recipient(recipient.ap_id, params) do
|
||||||
Federator.incoming_ap_doc(params)
|
Federator.incoming_ap_doc(params)
|
||||||
json(conn, "ok")
|
json(conn, "ok")
|
||||||
else
|
else
|
||||||
|
{:recipient_exists, _} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:not_found)
|
||||||
|
|> json("User does not exist")
|
||||||
|
|
||||||
|
{:sender_exists, _} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:not_found)
|
||||||
|
|> json("Sender does not exist")
|
||||||
|
|
||||||
|
{:recipient_active, _} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:not_found)
|
||||||
|
|> json("User deactivated")
|
||||||
|
|
||||||
|
{:sender_active, _} ->
|
||||||
|
conn
|
||||||
|
|> put_status(:not_found)
|
||||||
|
|> json("Sender deactivated")
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
|
alias Pleroma.Hashtag
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ControllerHelper
|
alias Pleroma.Web.ControllerHelper
|
||||||
|
|
@ -120,69 +121,14 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
|
||||||
defp resource_search(:v2, "hashtags", query, options) do
|
defp resource_search(:v2, "hashtags", query, options) do
|
||||||
tags_path = Endpoint.url() <> "/tag/"
|
tags_path = Endpoint.url() <> "/tag/"
|
||||||
|
|
||||||
query
|
Hashtag.search(query, options)
|
||||||
|> prepare_tags(options)
|
|
||||||
|> Enum.map(fn tag ->
|
|> Enum.map(fn tag ->
|
||||||
%{name: tag, url: tags_path <> tag}
|
%{name: tag, url: tags_path <> tag}
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp resource_search(:v1, "hashtags", query, options) do
|
defp resource_search(:v1, "hashtags", query, options) do
|
||||||
prepare_tags(query, options)
|
Hashtag.search(query, options)
|
||||||
end
|
|
||||||
|
|
||||||
defp prepare_tags(query, options) do
|
|
||||||
tags =
|
|
||||||
query
|
|
||||||
|> preprocess_uri_query()
|
|
||||||
|> String.split(~r/[^#\w]+/u, trim: true)
|
|
||||||
|> Enum.uniq_by(&String.downcase/1)
|
|
||||||
|
|
||||||
explicit_tags = Enum.filter(tags, fn tag -> String.starts_with?(tag, "#") end)
|
|
||||||
|
|
||||||
tags =
|
|
||||||
if Enum.any?(explicit_tags) do
|
|
||||||
explicit_tags
|
|
||||||
else
|
|
||||||
tags
|
|
||||||
end
|
|
||||||
|
|
||||||
tags = Enum.map(tags, fn tag -> String.trim_leading(tag, "#") end)
|
|
||||||
|
|
||||||
tags =
|
|
||||||
if Enum.empty?(explicit_tags) && !options[:skip_joined_tag] do
|
|
||||||
add_joined_tag(tags)
|
|
||||||
else
|
|
||||||
tags
|
|
||||||
end
|
|
||||||
|
|
||||||
Pleroma.Pagination.paginate_list(tags, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp add_joined_tag(tags) do
|
|
||||||
tags
|
|
||||||
|> Kernel.++([joined_tag(tags)])
|
|
||||||
|> Enum.uniq_by(&String.downcase/1)
|
|
||||||
end
|
|
||||||
|
|
||||||
# If `query` is a URI, returns last component of its path, otherwise returns `query`
|
|
||||||
defp preprocess_uri_query(query) do
|
|
||||||
if query =~ ~r/https?:\/\// do
|
|
||||||
query
|
|
||||||
|> String.trim_trailing("/")
|
|
||||||
|> URI.parse()
|
|
||||||
|> Map.get(:path)
|
|
||||||
|> String.split("/")
|
|
||||||
|> Enum.at(-1)
|
|
||||||
else
|
|
||||||
query
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp joined_tag(tags) do
|
|
||||||
tags
|
|
||||||
|> Enum.map(fn tag -> String.capitalize(tag) end)
|
|
||||||
|> Enum.join()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp with_fallback(f, fallback \\ []) do
|
defp with_fallback(f, fallback \\ []) do
|
||||||
|
|
|
||||||
6
mix.exs
6
mix.exs
|
|
@ -135,7 +135,7 @@ defmodule Pleroma.Mixfile do
|
||||||
{:telemetry_metrics, "~> 0.6"},
|
{:telemetry_metrics, "~> 0.6"},
|
||||||
{:telemetry_poller, "~> 1.0"},
|
{:telemetry_poller, "~> 1.0"},
|
||||||
{:tzdata, "~> 1.0.3"},
|
{:tzdata, "~> 1.0.3"},
|
||||||
{:plug_cowboy, "~> 2.5"},
|
{:plug_cowboy, "~> 2.7"},
|
||||||
{:oban, "~> 2.19.0"},
|
{:oban, "~> 2.19.0"},
|
||||||
{:gettext, "~> 0.20"},
|
{:gettext, "~> 0.20"},
|
||||||
{:bcrypt_elixir, "~> 2.2"},
|
{:bcrypt_elixir, "~> 2.2"},
|
||||||
|
|
@ -146,8 +146,8 @@ defmodule Pleroma.Mixfile do
|
||||||
{:cachex, "~> 3.2"},
|
{:cachex, "~> 3.2"},
|
||||||
{:tesla, "~> 1.11"},
|
{:tesla, "~> 1.11"},
|
||||||
{:castore, "~> 1.0"},
|
{:castore, "~> 1.0"},
|
||||||
{:cowlib, "~> 2.9", override: true},
|
{:cowlib, "~> 2.15"},
|
||||||
{:gun, "~> 2.0.0-rc.1", override: true},
|
{:gun, "~> 2.2"},
|
||||||
{:finch, "~> 0.15"},
|
{:finch, "~> 0.15"},
|
||||||
{:jason, "~> 1.2"},
|
{:jason, "~> 1.2"},
|
||||||
{:mogrify, "~> 0.9.0", override: "true"},
|
{:mogrify, "~> 0.9.0", override: "true"},
|
||||||
|
|
|
||||||
24
mix.lock
24
mix.lock
|
|
@ -11,7 +11,7 @@
|
||||||
"cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"},
|
"cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"},
|
||||||
"calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"},
|
"calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"},
|
||||||
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e7b7cc34cc16b383461b966484c297e4ec9aeef6", [ref: "e7b7cc34cc16b383461b966484c297e4ec9aeef6"]},
|
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e7b7cc34cc16b383461b966484c297e4ec9aeef6", [ref: "e7b7cc34cc16b383461b966484c297e4ec9aeef6"]},
|
||||||
"castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
|
"castore": {:hex, :castore, "1.0.14", "4582dd7d630b48cf5e1ca8d3d42494db51e406b7ba704e81fbd401866366896a", [:mix], [], "hexpm", "7bc1b65249d31701393edaaac18ec8398d8974d52c647b7904d01b964137b9f4"},
|
||||||
"cc_precompiler": {:hex, :cc_precompiler, "0.1.9", "e8d3364f310da6ce6463c3dd20cf90ae7bbecbf6c5203b98bf9b48035592649b", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "9dcab3d0f3038621f1601f13539e7a9ee99843862e66ad62827b0c42b2f58a54"},
|
"cc_precompiler": {:hex, :cc_precompiler, "0.1.9", "e8d3364f310da6ce6463c3dd20cf90ae7bbecbf6c5203b98bf9b48035592649b", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "9dcab3d0f3038621f1601f13539e7a9ee99843862e66ad62827b0c42b2f58a54"},
|
||||||
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
|
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
|
||||||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
|
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||||
"cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"},
|
"cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"},
|
||||||
"covertool": {:hex, :covertool, "2.0.6", "4a291b4e3449025b0595d8f44c8d7635d4f48f033be2ce88d22a329f36f94a91", [:rebar3], [], "hexpm", "5db3fcd82180d8ea4ad857d4d1ab21a8d31b5aee0d60d2f6c0f9e25a411d1e21"},
|
"covertool": {:hex, :covertool, "2.0.6", "4a291b4e3449025b0595d8f44c8d7635d4f48f033be2ce88d22a329f36f94a91", [:rebar3], [], "hexpm", "5db3fcd82180d8ea4ad857d4d1ab21a8d31b5aee0d60d2f6c0f9e25a411d1e21"},
|
||||||
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
|
"cowboy": {:hex, :cowboy, "2.13.0", "09d770dd5f6a22cc60c071f432cd7cb87776164527f205c5a6b0f24ff6b38990", [:make, :rebar3], [{:cowlib, ">= 2.14.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e724d3a70995025d654c1992c7b11dbfea95205c047d86ff9bf1cda92ddc5614"},
|
||||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
||||||
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
|
"cowlib": {:hex, :cowlib, "2.15.0", "3c97a318a933962d1c12b96ab7c1d728267d2c523c25a5b57b0f93392b6e9e25", [:make, :rebar3], [], "hexpm", "4f00c879a64b4fe7c8fcb42a4281925e9ffdb928820b03c3ad325a617e857532"},
|
||||||
"credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"},
|
"credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"},
|
||||||
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
|
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
"floki": {:hex, :floki, "0.35.2", "87f8c75ed8654b9635b311774308b2760b47e9a579dabf2e4d5f1e1d42c39e0b", [:mix], [], "hexpm", "6b05289a8e9eac475f644f09c2e4ba7e19201fd002b89c28c1293e7bd16773d9"},
|
"floki": {:hex, :floki, "0.35.2", "87f8c75ed8654b9635b311774308b2760b47e9a579dabf2e4d5f1e1d42c39e0b", [:mix], [], "hexpm", "6b05289a8e9eac475f644f09c2e4ba7e19201fd002b89c28c1293e7bd16773d9"},
|
||||||
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
|
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
|
||||||
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
|
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
|
||||||
"gun": {:hex, :gun, "2.0.1", "160a9a5394800fcba41bc7e6d421295cf9a7894c2252c0678244948e3336ad73", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "a10bc8d6096b9502205022334f719cc9a08d9adcfbfc0dbee9ef31b56274a20b"},
|
"gun": {:hex, :gun, "2.2.0", "b8f6b7d417e277d4c2b0dc3c07dfdf892447b087f1cc1caff9c0f556b884e33d", [:make, :rebar3], [{:cowlib, ">= 2.15.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "76022700c64287feb4df93a1795cff6741b83fb37415c40c34c38d2a4645261a"},
|
||||||
"hackney": {:hex, :hackney, "1.18.2", "d7ff544ddae5e1cb49e9cf7fa4e356d7f41b283989a1c304bfc47a8cc1cf966f", [:rebar3], [{:certifi, "~>2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "af94d5c9f97857db257090a4a10e5426ecb6f4918aa5cc666798566ae14b65fd"},
|
"hackney": {:hex, :hackney, "1.18.2", "d7ff544ddae5e1cb49e9cf7fa4e356d7f41b283989a1c304bfc47a8cc1cf966f", [:rebar3], [{:certifi, "~>2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "af94d5c9f97857db257090a4a10e5426ecb6f4918aa5cc666798566ae14b65fd"},
|
||||||
"hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"},
|
"hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"},
|
||||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||||
|
|
@ -80,8 +80,8 @@
|
||||||
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
|
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||||
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
|
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
|
||||||
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
|
"mimerl": {:hex, :mimerl, "1.4.0", "3882a5ca67fbbe7117ba8947f27643557adec38fa2307490c4c4207624cb213b", [:rebar3], [], "hexpm", "13af15f9f68c65884ecca3a3891d50a7b57d82152792f3e19d88650aa126b144"},
|
||||||
"mint": {:hex, :mint, "1.6.1", "065e8a5bc9bbd46a41099dfea3e0656436c5cbcb6e741c80bd2bad5cd872446f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4fc518dcc191d02f433393a72a7ba3f6f94b101d094cb6bf532ea54c89423780"},
|
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
|
||||||
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
|
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
|
||||||
"mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"},
|
"mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"},
|
||||||
"mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"},
|
"mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"},
|
||||||
|
|
@ -108,9 +108,9 @@
|
||||||
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"},
|
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"},
|
||||||
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
|
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
|
||||||
"phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"},
|
"phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"},
|
||||||
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
|
"plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"},
|
||||||
"plug_cowboy": {:hex, :plug_cowboy, "2.7.1", "87677ffe3b765bc96a89be7960f81703223fe2e21efa42c125fcd0127dd9d6b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "02dbd5f9ab571b864ae39418db7811618506256f6d13b4a45037e5fe78dc5de3"},
|
"plug_cowboy": {:hex, :plug_cowboy, "2.7.4", "729c752d17cf364e2b8da5bdb34fb5804f56251e88bb602aff48ae0bd8673d11", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9b85632bd7012615bae0a5d70084deb1b25d2bcbb32cab82d1e9a1e023168aa3"},
|
||||||
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
|
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
|
||||||
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
|
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
|
||||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
|
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
|
||||||
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
|
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
|
||||||
|
|
@ -124,7 +124,7 @@
|
||||||
"prometheus_phx": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus-phx.git", "9cd8f248c9381ffedc799905050abce194a97514", [branch: "no-logging"]},
|
"prometheus_phx": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus-phx.git", "9cd8f248c9381ffedc799905050abce194a97514", [branch: "no-logging"]},
|
||||||
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},
|
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},
|
||||||
"quantile_estimator": {:hex, :quantile_estimator, "0.2.1", "ef50a361f11b5f26b5f16d0696e46a9e4661756492c981f7b2229ef42ff1cd15", [:rebar3], [], "hexpm", "282a8a323ca2a845c9e6f787d166348f776c1d4a41ede63046d72d422e3da946"},
|
"quantile_estimator": {:hex, :quantile_estimator, "0.2.1", "ef50a361f11b5f26b5f16d0696e46a9e4661756492c981f7b2229ef42ff1cd15", [:rebar3], [], "hexpm", "282a8a323ca2a845c9e6f787d166348f776c1d4a41ede63046d72d422e3da946"},
|
||||||
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
|
"ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"},
|
||||||
"recon": {:hex, :recon, "2.5.4", "05dd52a119ee4059fa9daa1ab7ce81bc7a8161a2f12e9d42e9d551ffd2ba901c", [:mix, :rebar3], [], "hexpm", "e9ab01ac7fc8572e41eb59385efeb3fb0ff5bf02103816535bacaedf327d0263"},
|
"recon": {:hex, :recon, "2.5.4", "05dd52a119ee4059fa9daa1ab7ce81bc7a8161a2f12e9d42e9d551ffd2ba901c", [:mix, :rebar3], [], "hexpm", "e9ab01ac7fc8572e41eb59385efeb3fb0ff5bf02103816535bacaedf327d0263"},
|
||||||
"remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]},
|
"remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]},
|
||||||
"rustler": {:hex, :rustler, "0.30.0", "cefc49922132b072853fa9b0ca4dc2ffcb452f68fb73b779042b02d545e097fb", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "9ef1abb6a7dda35c47cfc649e6a5a61663af6cf842a55814a554a84607dee389"},
|
"rustler": {:hex, :rustler, "0.30.0", "cefc49922132b072853fa9b0ca4dc2ffcb452f68fb73b779042b02d545e097fb", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "9ef1abb6a7dda35c47cfc649e6a5a61663af6cf842a55814a554a84607dee389"},
|
||||||
|
|
@ -139,14 +139,14 @@
|
||||||
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"},
|
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"},
|
||||||
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.2.0", "b583c3f18508f5c5561b674d16cf5d9afd2ea3c04505b7d92baaeac93c1b8260", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "9cba950e1c4733468efbe3f821841f34ac05d28e7af7798622f88ecdbbe63ea3"},
|
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.2.0", "b583c3f18508f5c5561b674d16cf5d9afd2ea3c04505b7d92baaeac93c1b8260", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "9cba950e1c4733468efbe3f821841f34ac05d28e7af7798622f88ecdbbe63ea3"},
|
||||||
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
|
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
|
||||||
"tesla": {:hex, :tesla, "1.11.0", "81b2b10213dddb27105ec6102d9eb0cc93d7097a918a0b1594f2dfd1a4601190", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "b83ab5d4c2d202e1ea2b7e17a49f788d49a699513d7c4f08f2aef2c281be69db"},
|
"tesla": {:hex, :tesla, "1.15.3", "3a2b5c37f09629b8dcf5d028fbafc9143c0099753559d7fe567eaabfbd9b8663", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.21", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:mox, "~> 1.0", [hex: :mox, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "98bb3d4558abc67b92fb7be4cd31bb57ca8d80792de26870d362974b58caeda7"},
|
||||||
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
|
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
|
||||||
"timex": {:hex, :timex, "3.7.7", "3ed093cae596a410759104d878ad7b38e78b7c2151c6190340835515d4a46b8a", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "0ec4b09f25fe311321f9fc04144a7e3affe48eb29481d7a5583849b6c4dfa0a7"},
|
"timex": {:hex, :timex, "3.7.7", "3ed093cae596a410759104d878ad7b38e78b7c2151c6190340835515d4a46b8a", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "0ec4b09f25fe311321f9fc04144a7e3affe48eb29481d7a5583849b6c4dfa0a7"},
|
||||||
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
|
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
|
||||||
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
|
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
|
||||||
"tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"},
|
"tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"},
|
||||||
"ueberauth": {:hex, :ueberauth, "0.10.7", "5a31cbe11e7ce5c7484d745dc9e1f11948e89662f8510d03c616de03df581ebd", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0bccf73e2ffd6337971340832947ba232877aa8122dba4c95be9f729c8987377"},
|
"ueberauth": {:hex, :ueberauth, "0.10.7", "5a31cbe11e7ce5c7484d745dc9e1f11948e89662f8510d03c616de03df581ebd", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0bccf73e2ffd6337971340832947ba232877aa8122dba4c95be9f729c8987377"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"},
|
||||||
"unsafe": {:hex, :unsafe, "1.0.2", "23c6be12f6c1605364801f4b47007c0c159497d0446ad378b5cf05f1855c0581", [:mix], [], "hexpm", "b485231683c3ab01a9cd44cb4a79f152c6f3bb87358439c6f68791b85c2df675"},
|
"unsafe": {:hex, :unsafe, "1.0.2", "23c6be12f6c1605364801f4b47007c0c159497d0446ad378b5cf05f1855c0581", [:mix], [], "hexpm", "b485231683c3ab01a9cd44cb4a79f152c6f3bb87358439c6f68791b85c2df675"},
|
||||||
"vix": {:hex, :vix, "0.26.0", "027f10b6969b759318be84bd0bd8c88af877445e4e41cf96a0460392cea5399c", [:make, :mix], [{:castore, "~> 1.0 or ~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.2 or ~> 0.1.4", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8 or ~> 0.7.3", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "71b0a79ae7f199cacfc8e679b0e4ba25ee47dc02e182c5b9097efb29fbe14efd"},
|
"vix": {:hex, :vix, "0.26.0", "027f10b6969b759318be84bd0bd8c88af877445e4e41cf96a0460392cea5399c", [:make, :mix], [{:castore, "~> 1.0 or ~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.2 or ~> 0.1.4", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8 or ~> 0.7.3", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "71b0a79ae7f199cacfc8e679b0e4ba25ee47dc02e182c5b9097efb29fbe14efd"},
|
||||||
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
|
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,133 @@ defmodule Pleroma.HashtagTest do
|
||||||
assert {:name, {"can't be blank", [validation: :required]}} in changeset.errors
|
assert {:name, {"can't be blank", [validation: :required]}} in changeset.errors
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "search_hashtags" do
|
||||||
|
test "searches hashtags by partial match" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("car")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("racecar")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("nascar")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("bicycle")
|
||||||
|
|
||||||
|
results = Hashtag.search("car")
|
||||||
|
assert "car" in results
|
||||||
|
assert "racecar" in results
|
||||||
|
assert "nascar" in results
|
||||||
|
refute "bicycle" in results
|
||||||
|
|
||||||
|
results = Hashtag.search("race")
|
||||||
|
assert "racecar" in results
|
||||||
|
refute "car" in results
|
||||||
|
refute "nascar" in results
|
||||||
|
refute "bicycle" in results
|
||||||
|
|
||||||
|
results = Hashtag.search("nonexistent")
|
||||||
|
assert results == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "searches hashtags by multiple words in query" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("computer")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("laptop")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("desktop")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("phone")
|
||||||
|
|
||||||
|
# Search for "new computer" - should return "computer"
|
||||||
|
results = Hashtag.search("new computer")
|
||||||
|
assert "computer" in results
|
||||||
|
refute "laptop" in results
|
||||||
|
refute "desktop" in results
|
||||||
|
refute "phone" in results
|
||||||
|
|
||||||
|
# Search for "computer laptop" - should return both
|
||||||
|
results = Hashtag.search("computer laptop")
|
||||||
|
assert "computer" in results
|
||||||
|
assert "laptop" in results
|
||||||
|
refute "desktop" in results
|
||||||
|
refute "phone" in results
|
||||||
|
|
||||||
|
# Search for "new phone" - should return "phone"
|
||||||
|
results = Hashtag.search("new phone")
|
||||||
|
assert "phone" in results
|
||||||
|
refute "computer" in results
|
||||||
|
refute "laptop" in results
|
||||||
|
refute "desktop" in results
|
||||||
|
end
|
||||||
|
|
||||||
|
test "supports pagination" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("alpha")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("beta")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("gamma")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("delta")
|
||||||
|
|
||||||
|
results = Hashtag.search("a", limit: 2)
|
||||||
|
assert length(results) == 2
|
||||||
|
|
||||||
|
results = Hashtag.search("a", limit: 2, offset: 1)
|
||||||
|
assert length(results) == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
test "handles matching many search terms" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("computer")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("laptop")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("phone")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("tablet")
|
||||||
|
|
||||||
|
results = Hashtag.search("new fast computer laptop phone tablet device")
|
||||||
|
assert "computer" in results
|
||||||
|
assert "laptop" in results
|
||||||
|
assert "phone" in results
|
||||||
|
assert "tablet" in results
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ranks results by match quality" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("my_computer")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("computer_science")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("computer")
|
||||||
|
|
||||||
|
results = Hashtag.search("computer")
|
||||||
|
|
||||||
|
# Exact match first
|
||||||
|
assert Enum.at(results, 0) == "computer"
|
||||||
|
|
||||||
|
# Prefix match would be next
|
||||||
|
assert Enum.at(results, 1) == "computer_science"
|
||||||
|
|
||||||
|
# worst match is last
|
||||||
|
assert Enum.at(results, 2) == "my_computer"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "prioritizes shorter names when ranking is equal" do
|
||||||
|
# Create hashtags with same ranking but different lengths
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("car")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("racecar")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("nascar")
|
||||||
|
|
||||||
|
# Search for "car" - shorter names should come first
|
||||||
|
results = Hashtag.search("car")
|
||||||
|
# Shortest exact match first
|
||||||
|
assert Enum.at(results, 0) == "car"
|
||||||
|
assert "racecar" in results
|
||||||
|
assert "nascar" in results
|
||||||
|
end
|
||||||
|
|
||||||
|
test "handles hashtag symbols in search query" do
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("computer")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("laptop")
|
||||||
|
{:ok, _} = Hashtag.get_or_create_by_name("phone")
|
||||||
|
|
||||||
|
results_with_hash = Hashtag.search("#computer #laptop")
|
||||||
|
results_without_hash = Hashtag.search("computer laptop")
|
||||||
|
|
||||||
|
assert results_with_hash == results_without_hash
|
||||||
|
|
||||||
|
results_mixed = Hashtag.search("#computer laptop #phone")
|
||||||
|
assert "computer" in results_mixed
|
||||||
|
assert "laptop" in results_mixed
|
||||||
|
assert "phone" in results_mixed
|
||||||
|
|
||||||
|
results_only_hash = Hashtag.search("#computer")
|
||||||
|
results_no_hash = Hashtag.search("computer")
|
||||||
|
assert results_only_hash == results_no_hash
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ defmodule Pleroma.Search.QdrantSearchTest do
|
||||||
})
|
})
|
||||||
|
|
||||||
Config
|
Config
|
||||||
|> expect(:get, 3, fn
|
|> expect(:get, 4, fn
|
||||||
[Pleroma.Search, :module], nil ->
|
[Pleroma.Search, :module], nil ->
|
||||||
QdrantSearch
|
QdrantSearch
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ defmodule Pleroma.Search.QdrantSearchTest do
|
||||||
})
|
})
|
||||||
|
|
||||||
Config
|
Config
|
||||||
|> expect(:get, 3, fn
|
|> expect(:get, 4, fn
|
||||||
[Pleroma.Search, :module], nil ->
|
[Pleroma.Search, :module], nil ->
|
||||||
QdrantSearch
|
QdrantSearch
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ defmodule Pleroma.Search.QdrantSearchTest do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Config
|
Config
|
||||||
|> expect(:get, 6, fn
|
|> expect(:get, 7, fn
|
||||||
[Pleroma.Search, :module], nil ->
|
[Pleroma.Search, :module], nil ->
|
||||||
QdrantSearch
|
QdrantSearch
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -923,23 +923,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
assert Activity.get_by_ap_id(data["id"])
|
assert Activity.get_by_ap_id(data["id"])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it rejects an invalid incoming activity", %{conn: conn, data: data} do
|
|
||||||
user = insert(:user, is_active: false)
|
|
||||||
|
|
||||||
data =
|
|
||||||
data
|
|
||||||
|> Map.put("bcc", [user.ap_id])
|
|
||||||
|> Kernel.put_in(["object", "bcc"], [user.ap_id])
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> assign(:valid_signature, true)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/inbox", data)
|
|
||||||
|
|
||||||
assert "Invalid request." == json_response(conn, 400)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
|
test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
|
|
@ -1305,6 +1288,50 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
|
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
|
||||||
assert Activity.get_by_ap_id(data["id"])
|
assert Activity.get_by_ap_id(data["id"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it returns an error when receiving an activity sent to a deactivated user", %{
|
||||||
|
conn: conn,
|
||||||
|
data: data
|
||||||
|
} do
|
||||||
|
user = insert(:user)
|
||||||
|
{:ok, _} = User.set_activation(user, false)
|
||||||
|
|
||||||
|
data =
|
||||||
|
data
|
||||||
|
|> Map.put("bcc", [user.ap_id])
|
||||||
|
|> Kernel.put_in(["object", "bcc"], [user.ap_id])
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:valid_signature, true)
|
||||||
|
|> put_req_header("content-type", "application/activity+json")
|
||||||
|
|> post("/users/#{user.nickname}/inbox", data)
|
||||||
|
|
||||||
|
assert "User deactivated" == json_response(conn, 404)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns an error when receiving an activity sent from a deactivated user", %{
|
||||||
|
conn: conn,
|
||||||
|
data: data
|
||||||
|
} do
|
||||||
|
sender = insert(:user)
|
||||||
|
user = insert(:user)
|
||||||
|
{:ok, _} = User.set_activation(sender, false)
|
||||||
|
|
||||||
|
data =
|
||||||
|
data
|
||||||
|
|> Map.put("bcc", [user.ap_id])
|
||||||
|
|> Map.put("actor", sender.ap_id)
|
||||||
|
|> Kernel.put_in(["object", "bcc"], [user.ap_id])
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:valid_signature, true)
|
||||||
|
|> put_req_header("content-type", "application/activity+json")
|
||||||
|
|> post("/users/#{user.nickname}/inbox", data)
|
||||||
|
|
||||||
|
assert "Sender deactivated" == json_response(conn, 404)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /users/:nickname/outbox" do
|
describe "GET /users/:nickname/outbox" do
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
||||||
|
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.Endpoint
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import ExUnit.CaptureLog
|
import ExUnit.CaptureLog
|
||||||
import Tesla.Mock
|
import Tesla.Mock
|
||||||
|
|
@ -66,9 +65,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
||||||
[account | _] = results["accounts"]
|
[account | _] = results["accounts"]
|
||||||
assert account["id"] == to_string(user_three.id)
|
assert account["id"] == to_string(user_three.id)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
assert results["hashtags"] == []
|
||||||
%{"name" => "private", "url" => "#{Endpoint.url()}/tag/private"}
|
|
||||||
]
|
|
||||||
|
|
||||||
[status] = results["statuses"]
|
[status] = results["statuses"]
|
||||||
assert status["id"] == to_string(activity.id)
|
assert status["id"] == to_string(activity.id)
|
||||||
|
|
@ -77,9 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
||||||
get(conn, "/api/v2/search?q=天子")
|
get(conn, "/api/v2/search?q=天子")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
assert results["hashtags"] == []
|
||||||
%{"name" => "天子", "url" => "#{Endpoint.url()}/tag/天子"}
|
|
||||||
]
|
|
||||||
|
|
||||||
[status] = results["statuses"]
|
[status] = results["statuses"]
|
||||||
assert status["id"] == to_string(activity.id)
|
assert status["id"] == to_string(activity.id)
|
||||||
|
|
@ -130,84 +125,97 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
||||||
assert [] = results["statuses"]
|
assert [] = results["statuses"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "constructs hashtags from search query", %{conn: conn} do
|
test "returns empty results when no hashtags match", %{conn: conn} do
|
||||||
results =
|
results =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "some text with #explicit #hashtags"})}")
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "nonexistent"})}")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
assert results["hashtags"] == []
|
||||||
%{"name" => "explicit", "url" => "#{Endpoint.url()}/tag/explicit"},
|
end
|
||||||
%{"name" => "hashtags", "url" => "#{Endpoint.url()}/tag/hashtags"}
|
|
||||||
]
|
test "searches hashtags by multiple words in query", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _activity1} = CommonAPI.post(user, %{status: "This is my new #computer"})
|
||||||
|
{:ok, _activity2} = CommonAPI.post(user, %{status: "Check out this #laptop"})
|
||||||
|
{:ok, _activity3} = CommonAPI.post(user, %{status: "My #desktop setup"})
|
||||||
|
{:ok, _activity4} = CommonAPI.post(user, %{status: "New #phone arrived"})
|
||||||
|
|
||||||
results =
|
results =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "john doe JOHN DOE"})}")
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "new computer"})}")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
|
||||||
%{"name" => "john", "url" => "#{Endpoint.url()}/tag/john"},
|
assert "computer" in hashtag_names
|
||||||
%{"name" => "doe", "url" => "#{Endpoint.url()}/tag/doe"},
|
refute "laptop" in hashtag_names
|
||||||
%{"name" => "JohnDoe", "url" => "#{Endpoint.url()}/tag/JohnDoe"}
|
refute "desktop" in hashtag_names
|
||||||
]
|
refute "phone" in hashtag_names
|
||||||
|
|
||||||
results =
|
results =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "accident-prone"})}")
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "computer laptop"})}")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
|
||||||
%{"name" => "accident", "url" => "#{Endpoint.url()}/tag/accident"},
|
assert "computer" in hashtag_names
|
||||||
%{"name" => "prone", "url" => "#{Endpoint.url()}/tag/prone"},
|
assert "laptop" in hashtag_names
|
||||||
%{"name" => "AccidentProne", "url" => "#{Endpoint.url()}/tag/AccidentProne"}
|
refute "desktop" in hashtag_names
|
||||||
]
|
refute "phone" in hashtag_names
|
||||||
|
|
||||||
results =
|
|
||||||
conn
|
|
||||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "https://shpposter.club/users/shpuld"})}")
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
|
||||||
%{"name" => "shpuld", "url" => "#{Endpoint.url()}/tag/shpuld"}
|
|
||||||
]
|
|
||||||
|
|
||||||
results =
|
|
||||||
conn
|
|
||||||
|> get(
|
|
||||||
"/api/v2/search?#{URI.encode_query(%{q: "https://www.washingtonpost.com/sports/2020/06/10/" <> "nascar-ban-display-confederate-flag-all-events-properties/"})}"
|
|
||||||
)
|
|
||||||
|> json_response_and_validate_schema(200)
|
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
|
||||||
%{"name" => "nascar", "url" => "#{Endpoint.url()}/tag/nascar"},
|
|
||||||
%{"name" => "ban", "url" => "#{Endpoint.url()}/tag/ban"},
|
|
||||||
%{"name" => "display", "url" => "#{Endpoint.url()}/tag/display"},
|
|
||||||
%{"name" => "confederate", "url" => "#{Endpoint.url()}/tag/confederate"},
|
|
||||||
%{"name" => "flag", "url" => "#{Endpoint.url()}/tag/flag"},
|
|
||||||
%{"name" => "all", "url" => "#{Endpoint.url()}/tag/all"},
|
|
||||||
%{"name" => "events", "url" => "#{Endpoint.url()}/tag/events"},
|
|
||||||
%{"name" => "properties", "url" => "#{Endpoint.url()}/tag/properties"},
|
|
||||||
%{
|
|
||||||
"name" => "NascarBanDisplayConfederateFlagAllEventsProperties",
|
|
||||||
"url" =>
|
|
||||||
"#{Endpoint.url()}/tag/NascarBanDisplayConfederateFlagAllEventsProperties"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "supports pagination of hashtags search results", %{conn: conn} do
|
test "supports pagination of hashtags search results", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _activity1} = CommonAPI.post(user, %{status: "First #alpha hashtag"})
|
||||||
|
{:ok, _activity2} = CommonAPI.post(user, %{status: "Second #beta hashtag"})
|
||||||
|
{:ok, _activity3} = CommonAPI.post(user, %{status: "Third #gamma hashtag"})
|
||||||
|
{:ok, _activity4} = CommonAPI.post(user, %{status: "Fourth #delta hashtag"})
|
||||||
|
|
||||||
results =
|
results =
|
||||||
conn
|
conn
|
||||||
|> get(
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "a", limit: 2, offset: 1})}")
|
||||||
"/api/v2/search?#{URI.encode_query(%{q: "#some #text #with #hashtags", limit: 2, offset: 1})}"
|
|
||||||
)
|
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert results["hashtags"] == [
|
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
|
||||||
%{"name" => "text", "url" => "#{Endpoint.url()}/tag/text"},
|
|
||||||
%{"name" => "with", "url" => "#{Endpoint.url()}/tag/with"}
|
# Should return 2 hashtags (alpha, beta, gamma, delta all contain 'a')
|
||||||
]
|
# With offset 1, we skip the first one, so we get 2 of the remaining 3
|
||||||
|
assert length(hashtag_names) == 2
|
||||||
|
assert Enum.all?(hashtag_names, &String.contains?(&1, "a"))
|
||||||
|
end
|
||||||
|
|
||||||
|
test "searches real hashtags from database", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _activity1} = CommonAPI.post(user, %{status: "Check out this #car"})
|
||||||
|
{:ok, _activity2} = CommonAPI.post(user, %{status: "Fast #racecar on the track"})
|
||||||
|
{:ok, _activity3} = CommonAPI.post(user, %{status: "NASCAR #nascar racing"})
|
||||||
|
|
||||||
|
results =
|
||||||
|
conn
|
||||||
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "car"})}")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
|
||||||
|
|
||||||
|
# Should return car, racecar, and nascar since they all contain "car"
|
||||||
|
assert "car" in hashtag_names
|
||||||
|
assert "racecar" in hashtag_names
|
||||||
|
assert "nascar" in hashtag_names
|
||||||
|
|
||||||
|
# Search for "race" - should return racecar
|
||||||
|
results =
|
||||||
|
conn
|
||||||
|
|> get("/api/v2/search?#{URI.encode_query(%{q: "race"})}")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
hashtag_names = Enum.map(results["hashtags"], & &1["name"])
|
||||||
|
|
||||||
|
assert "racecar" in hashtag_names
|
||||||
|
refute "car" in hashtag_names
|
||||||
|
refute "nascar" in hashtag_names
|
||||||
end
|
end
|
||||||
|
|
||||||
test "excludes a blocked users from search results", %{conn: conn} do
|
test "excludes a blocked users from search results", %{conn: conn} do
|
||||||
|
|
@ -314,7 +322,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
||||||
[account | _] = results["accounts"]
|
[account | _] = results["accounts"]
|
||||||
assert account["id"] == to_string(user_three.id)
|
assert account["id"] == to_string(user_three.id)
|
||||||
|
|
||||||
assert results["hashtags"] == ["2hu"]
|
assert results["hashtags"] == []
|
||||||
|
|
||||||
[status] = results["statuses"]
|
[status] = results["statuses"]
|
||||||
assert status["id"] == to_string(activity.id)
|
assert status["id"] == to_string(activity.id)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
defmodule Pleroma.Web.Plugs.CacheTest do
|
defmodule Pleroma.Web.Plugs.CacheTest do
|
||||||
# Relies on Cachex, has to stay synchronous
|
# Relies on Cachex, has to stay synchronous
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
use Plug.Test
|
import Plug.Conn
|
||||||
|
import Plug.Test
|
||||||
|
|
||||||
alias Pleroma.Web.Plugs.Cache
|
alias Pleroma.Web.Plugs.Cache
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.DigestPlugTest do
|
defmodule Pleroma.Web.Plugs.DigestPlugTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
use Plug.Test
|
import Plug.Conn
|
||||||
|
import Plug.Test
|
||||||
|
|
||||||
test "digest algorithm is taken from digest header" do
|
test "digest algorithm is taken from digest header" do
|
||||||
body = "{\"hello\": \"world\"}"
|
body = "{\"hello\": \"world\"}"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
defmodule Pleroma.Web.Plugs.IdempotencyPlugTest do
|
defmodule Pleroma.Web.Plugs.IdempotencyPlugTest do
|
||||||
# Relies on Cachex, has to stay synchronous
|
# Relies on Cachex, has to stay synchronous
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
use Plug.Test
|
import Plug.Conn
|
||||||
|
import Plug.Test
|
||||||
|
|
||||||
alias Pleroma.Web.Plugs.IdempotencyPlug
|
alias Pleroma.Web.Plugs.IdempotencyPlug
|
||||||
alias Plug.Conn
|
alias Plug.Conn
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.RemoteIpTest do
|
defmodule Pleroma.Web.Plugs.RemoteIpTest do
|
||||||
use ExUnit.Case
|
use ExUnit.Case
|
||||||
use Plug.Test
|
import Plug.Conn
|
||||||
|
import Plug.Test
|
||||||
|
|
||||||
alias Pleroma.Web.Plugs.RemoteIp
|
alias Pleroma.Web.Plugs.RemoteIp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.SetFormatPlugTest do
|
defmodule Pleroma.Web.Plugs.SetFormatPlugTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
use Plug.Test
|
import Plug.Conn
|
||||||
|
import Plug.Test
|
||||||
|
|
||||||
alias Pleroma.Web.Plugs.SetFormatPlug
|
alias Pleroma.Web.Plugs.SetFormatPlug
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.SetLocalePlugTest do
|
defmodule Pleroma.Web.Plugs.SetLocalePlugTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
use Plug.Test
|
import Plug.Test
|
||||||
|
|
||||||
alias Pleroma.Web.Plugs.SetLocalePlug
|
alias Pleroma.Web.Plugs.SetLocalePlug
|
||||||
alias Plug.Conn
|
alias Plug.Conn
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue