Merge branch 'feature/2438-users-posts-total-count' into 'develop'
Feature/2438 users/instances posts total count Closes #2438 See merge request pleroma/pleroma!3270
This commit is contained in:
commit
8d2ea95402
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -10,19 +10,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
||||
- **Breaking**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
|
||||
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
|
||||
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
|
||||
- Polls now always return a `voters_count`, even if they are single-choice.
|
||||
- Admin Emails: The ap id is used as the user link in emails now.
|
||||
- Improved registration workflow for email confirmation and account approval modes.
|
||||
- Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries.
|
||||
- Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators.
|
||||
- Admin API: Reports now ordered by newest
|
||||
- Deprecated `Pleroma.Uploaders.S3, :public_endpoint`. Now `Pleroma.Upload, :base_url` is the standard configuration key for all uploaders.
|
||||
- Improved Apache webserver support: updated sample configuration, MediaProxy cache invalidation verified with the included sample script
|
||||
- Improve OAuth 2.0 provider support. A missing `fqn` field was added to the response, but does not expose the user's email address.
|
||||
|
||||
<details>
|
||||
<summary>API Changes</summary>
|
||||
|
||||
- **Breaking:** AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||
- **Breaking:** AdminAPI changed User field `approval_pending` to `is_approved`
|
||||
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
|
||||
- **Breaking:** AdminAPI `GET /api/pleroma/admin/users/:nickname_or_id/statuses` changed response format and added the number of total users posts.
|
||||
- **Breaking:** AdminAPI `GET /api/pleroma/admin/instances/:instance/statuses` changed response format and added the number of total users posts.
|
||||
- Admin API: Reports now ordered by newest
|
||||
|
||||
</details>
|
||||
|
||||
### Added
|
||||
|
||||
- Reports now generate notifications for admins and mods.
|
||||
|
|
|
@ -287,7 +287,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
|||
- *optional* `with_reblogs`: `true`/`false` – allows to see reblogs (default is false)
|
||||
- Response:
|
||||
- On failure: `Not found`
|
||||
- On success: JSON array of user's latest statuses
|
||||
- On success: JSON, where:
|
||||
- `total`: total count of the statuses for the user
|
||||
- `activities`: list of the statuses for the user
|
||||
|
||||
```json
|
||||
{
|
||||
"total" : 1,
|
||||
"activities": [
|
||||
// activities list
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## `GET /api/pleroma/admin/instances/:instance/statuses`
|
||||
|
||||
|
@ -300,7 +311,18 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
|||
- *optional* `with_reblogs`: `true`/`false` – allows to see reblogs (default is false)
|
||||
- Response:
|
||||
- On failure: `Not found`
|
||||
- On success: JSON array of instance's latest statuses
|
||||
- On success: JSON, where:
|
||||
- `total`: total count of the statuses for the instance
|
||||
- `activities`: list of the statuses for the instance
|
||||
|
||||
```json
|
||||
{
|
||||
"total" : 1,
|
||||
"activities": [
|
||||
// activities list
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## `GET /api/pleroma/admin/statuses`
|
||||
|
||||
|
|
|
@ -591,7 +591,21 @@ def fetch_user_abstract_activities(user, reading_user, params \\ %{}) do
|
|||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
def fetch_user_activities(user, reading_user, params \\ %{}) do
|
||||
def fetch_user_activities(user, reading_user, params \\ %{})
|
||||
|
||||
def fetch_user_activities(user, reading_user, %{total: true} = params) do
|
||||
result = fetch_activities_for_user(user, reading_user, params)
|
||||
|
||||
Keyword.put(result, :items, Enum.reverse(result[:items]))
|
||||
end
|
||||
|
||||
def fetch_user_activities(user, reading_user, params) do
|
||||
user
|
||||
|> fetch_activities_for_user(reading_user, params)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
defp fetch_activities_for_user(user, reading_user, params) do
|
||||
params =
|
||||
params
|
||||
|> Map.put(:type, ["Create", "Announce"])
|
||||
|
@ -616,10 +630,20 @@ def fetch_user_activities(user, reading_user, params \\ %{}) do
|
|||
}
|
||||
|> user_activities_recipients()
|
||||
|> fetch_activities(params, pagination_type)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
def fetch_statuses(reading_user, %{total: true} = params) do
|
||||
result = fetch_activities_for_reading_user(reading_user, params)
|
||||
Keyword.put(result, :items, Enum.reverse(result[:items]))
|
||||
end
|
||||
|
||||
def fetch_statuses(reading_user, params) do
|
||||
reading_user
|
||||
|> fetch_activities_for_reading_user(params)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
defp fetch_activities_for_reading_user(reading_user, params) do
|
||||
params = Map.put(params, :type, ["Create", "Announce"])
|
||||
|
||||
%{
|
||||
|
@ -628,7 +652,6 @@ def fetch_statuses(reading_user, params) do
|
|||
}
|
||||
|> user_activities_recipients()
|
||||
|> fetch_activities(params, :offset)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
defp user_activities_recipients(%{godmode: true}), do: []
|
||||
|
|
|
@ -85,17 +85,18 @@ def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
|||
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||
{page, page_size} = page_params(params)
|
||||
|
||||
activities =
|
||||
result =
|
||||
ActivityPub.fetch_statuses(nil, %{
|
||||
instance: instance,
|
||||
limit: page_size,
|
||||
offset: (page - 1) * page_size,
|
||||
exclude_reblogs: not with_reblogs
|
||||
exclude_reblogs: not with_reblogs,
|
||||
total: true
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity})
|
||||
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
|
||||
end
|
||||
|
||||
def list_user_statuses(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do
|
||||
|
@ -105,18 +106,19 @@ def list_user_statuses(%{assigns: %{user: admin}} = conn, %{"nickname" => nickna
|
|||
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname, for: admin) do
|
||||
{page, page_size} = page_params(params)
|
||||
|
||||
activities =
|
||||
result =
|
||||
ActivityPub.fetch_user_activities(user, nil, %{
|
||||
limit: page_size,
|
||||
offset: (page - 1) * page_size,
|
||||
godmode: godmode,
|
||||
exclude_reblogs: not with_reblogs,
|
||||
pagination_type: :offset
|
||||
pagination_type: :offset,
|
||||
total: true
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity})
|
||||
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
|
||||
else
|
||||
_ -> {:error, :not_found}
|
||||
end
|
||||
|
|
|
@ -13,6 +13,10 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
|
|||
|
||||
defdelegate merge_account_views(user), to: AdminAPI.AccountView
|
||||
|
||||
def render("index.json", %{total: total} = opts) do
|
||||
%{total: total, activities: safe_render_many(opts.activities, __MODULE__, "show.json", opts)}
|
||||
end
|
||||
|
||||
def render("index.json", opts) do
|
||||
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
|
||||
end
|
||||
|
|
|
@ -405,13 +405,9 @@ test "need_reboot flag", %{conn: conn} do
|
|||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
|
||||
date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
|
||||
date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
|
||||
|
||||
insert(:note_activity, user: user, published: date1)
|
||||
insert(:note_activity, user: user, published: date2)
|
||||
insert(:note_activity, user: user, published: date3)
|
||||
insert(:note_activity, user: user)
|
||||
insert(:note_activity, user: user)
|
||||
insert(:note_activity, user: user)
|
||||
|
||||
%{user: user}
|
||||
end
|
||||
|
@ -419,23 +415,22 @@ test "need_reboot flag", %{conn: conn} do
|
|||
test "renders user's statuses", %{conn: conn, user: user} do
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
|
||||
|
||||
assert json_response(conn, 200) |> length() == 3
|
||||
assert %{"total" => 3, "activities" => activities} = json_response(conn, 200)
|
||||
assert length(activities) == 3
|
||||
end
|
||||
|
||||
test "renders user's statuses with pagination", %{conn: conn, user: user} do
|
||||
conn1 = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=1")
|
||||
%{"total" => 3, "activities" => [activity1]} =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=1")
|
||||
|> json_response(200)
|
||||
|
||||
response1 = json_response(conn1, 200)
|
||||
%{"total" => 3, "activities" => [activity2]} =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=2")
|
||||
|> json_response(200)
|
||||
|
||||
assert response1 |> length() == 1
|
||||
|
||||
conn2 = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=2")
|
||||
|
||||
response2 = json_response(conn2, 200)
|
||||
|
||||
assert response2 |> length() == 1
|
||||
|
||||
refute response1 == response2
|
||||
refute activity1 == activity2
|
||||
end
|
||||
|
||||
test "doesn't return private statuses by default", %{conn: conn, user: user} do
|
||||
|
@ -443,9 +438,12 @@ test "doesn't return private statuses by default", %{conn: conn, user: user} do
|
|||
|
||||
{:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
|
||||
%{"total" => 4, "activities" => activities} =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/statuses")
|
||||
|> json_response(200)
|
||||
|
||||
assert json_response(conn, 200) |> length() == 4
|
||||
assert length(activities) == 4
|
||||
end
|
||||
|
||||
test "returns private statuses with godmode on", %{conn: conn, user: user} do
|
||||
|
@ -453,9 +451,12 @@ test "returns private statuses with godmode on", %{conn: conn, user: user} do
|
|||
|
||||
{:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
|
||||
%{"total" => 5, "activities" => activities} =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert json_response(conn, 200) |> length() == 5
|
||||
assert length(activities) == 5
|
||||
end
|
||||
|
||||
test "excludes reblogs by default", %{conn: conn, user: user} do
|
||||
|
@ -463,13 +464,17 @@ test "excludes reblogs by default", %{conn: conn, user: user} do
|
|||
{:ok, activity} = CommonAPI.post(user, %{status: "."})
|
||||
{:ok, %Activity{}} = CommonAPI.repeat(activity.id, other_user)
|
||||
|
||||
conn_res = get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses")
|
||||
assert json_response(conn_res, 200) |> length() == 0
|
||||
assert %{"total" => 0, "activities" => []} ==
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/#{other_user.nickname}/statuses")
|
||||
|> json_response(200)
|
||||
|
||||
conn_res =
|
||||
get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true")
|
||||
|
||||
assert json_response(conn_res, 200) |> length() == 1
|
||||
assert %{"total" => 1, "activities" => [_]} =
|
||||
conn
|
||||
|> get(
|
||||
"/api/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true"
|
||||
)
|
||||
|> json_response(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -859,33 +864,30 @@ test "GET /instances/:instance/statuses", %{conn: conn} do
|
|||
insert_pair(:note_activity, user: user)
|
||||
activity = insert(:note_activity, user: user2)
|
||||
|
||||
ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
|
||||
%{"total" => 2, "activities" => activities} =
|
||||
conn |> get("/api/pleroma/admin/instances/archae.me/statuses") |> json_response(200)
|
||||
|
||||
response = json_response(ret_conn, 200)
|
||||
assert length(activities) == 2
|
||||
|
||||
assert length(response) == 2
|
||||
%{"total" => 1, "activities" => [_]} =
|
||||
conn |> get("/api/pleroma/admin/instances/test.com/statuses") |> json_response(200)
|
||||
|
||||
ret_conn = get(conn, "/api/pleroma/admin/instances/test.com/statuses")
|
||||
|
||||
response = json_response(ret_conn, 200)
|
||||
|
||||
assert length(response) == 1
|
||||
|
||||
ret_conn = get(conn, "/api/pleroma/admin/instances/nonexistent.com/statuses")
|
||||
|
||||
response = json_response(ret_conn, 200)
|
||||
|
||||
assert Enum.empty?(response)
|
||||
%{"total" => 0, "activities" => []} =
|
||||
conn |> get("/api/pleroma/admin/instances/nonexistent.com/statuses") |> json_response(200)
|
||||
|
||||
CommonAPI.repeat(activity.id, user)
|
||||
|
||||
ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
|
||||
response = json_response(ret_conn, 200)
|
||||
assert length(response) == 2
|
||||
%{"total" => 2, "activities" => activities} =
|
||||
conn |> get("/api/pleroma/admin/instances/archae.me/statuses") |> json_response(200)
|
||||
|
||||
ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses?with_reblogs=true")
|
||||
response = json_response(ret_conn, 200)
|
||||
assert length(response) == 3
|
||||
assert length(activities) == 2
|
||||
|
||||
%{"total" => 3, "activities" => activities} =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/instances/archae.me/statuses?with_reblogs=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert length(activities) == 3
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue