forked from AkkomaGang/akkoma
Update stats admin endpoint
This commit is contained in:
parent
39d2f2118a
commit
cbe383ae83
6 changed files with 87 additions and 24 deletions
|
@ -40,7 +40,7 @@ def get_by_instance(instance) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_as_map() do
|
def get_sum() do
|
||||||
CounterCache
|
CounterCache
|
||||||
|> select([c], %{
|
|> select([c], %{
|
||||||
"public" => sum(c.public),
|
"public" => sum(c.public),
|
||||||
|
@ -49,6 +49,10 @@ def get_as_map() do
|
||||||
"direct" => sum(c.direct)
|
"direct" => sum(c.direct)
|
||||||
})
|
})
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
|
|> Enum.map(fn {visibility, dec_count} ->
|
||||||
|
{visibility, Decimal.to_integer(dec_count)}
|
||||||
|
end)
|
||||||
|
|> Enum.into(%{})
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(instance, values) do
|
def set(instance, values) do
|
||||||
|
|
|
@ -97,14 +97,11 @@ def calculate_stat_data do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_status_visibility_count do
|
def get_status_visibility_count(instance \\ nil) do
|
||||||
counter_cache = CounterCache.get_as_map()
|
if is_nil(instance) do
|
||||||
|
CounterCache.get_sum()
|
||||||
%{
|
else
|
||||||
public: counter_cache["status_visibility_public"] || 0,
|
CounterCache.get_by_instance(instance)
|
||||||
unlisted: counter_cache["status_visibility_unlisted"] || 0,
|
end
|
||||||
private: counter_cache["status_visibility_private"] || 0,
|
|
||||||
direct: counter_cache["status_visibility_direct"] || 0
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1122,11 +1122,10 @@ def oauth_app_delete(conn, params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats(conn, _) do
|
def stats(conn, params) do
|
||||||
count = Stats.get_status_visibility_count()
|
counters = Stats.get_status_visibility_count(params["instance"])
|
||||||
|
|
||||||
conn
|
json(conn, %{"status_visibility" => counters})
|
||||||
|> json(%{"status_visibility" => count})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp errors(conn, {:error, :not_found}) do
|
defp errors(conn, {:error, :not_found}) do
|
||||||
|
|
|
@ -43,7 +43,8 @@ def up do
|
||||||
END IF;
|
END IF;
|
||||||
IF TG_OP = 'INSERT' THEN
|
IF TG_OP = 'INSERT' THEN
|
||||||
visibility_new := activity_visibility(NEW.actor, NEW.recipients, NEW.data);
|
visibility_new := activity_visibility(NEW.actor, NEW.recipients, NEW.data);
|
||||||
IF NEW.data->>'type' = 'Create' THEN
|
IF NEW.data->>'type' = 'Create'
|
||||||
|
AND visibility_new IN ('public', 'unlisted', 'private', 'direct') THEN
|
||||||
EXECUTE format('INSERT INTO "counter_cache" ("instance", %1$I) VALUES ($1, 1)
|
EXECUTE format('INSERT INTO "counter_cache" ("instance", %1$I) VALUES ($1, 1)
|
||||||
ON CONFLICT ("instance") DO
|
ON CONFLICT ("instance") DO
|
||||||
UPDATE SET %1$I = "counter_cache".%1$I + 1', visibility_new)
|
UPDATE SET %1$I = "counter_cache".%1$I + 1', visibility_new)
|
||||||
|
@ -53,7 +54,10 @@ def up do
|
||||||
ELSIF TG_OP = 'UPDATE' THEN
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
visibility_new := activity_visibility(NEW.actor, NEW.recipients, NEW.data);
|
visibility_new := activity_visibility(NEW.actor, NEW.recipients, NEW.data);
|
||||||
visibility_old := activity_visibility(OLD.actor, OLD.recipients, OLD.data);
|
visibility_old := activity_visibility(OLD.actor, OLD.recipients, OLD.data);
|
||||||
IF (NEW.data->>'type' = 'Create') and (OLD.data->>'type' = 'Create') and visibility_new != visibility_old THEN
|
IF (NEW.data->>'type' = 'Create')
|
||||||
|
AND (OLD.data->>'type' = 'Create')
|
||||||
|
AND visibility_new != visibility_old
|
||||||
|
AND visibility_new IN ('public', 'unlisted', 'private', 'direct') THEN
|
||||||
EXECUTE format('UPDATE "counter_cache" SET
|
EXECUTE format('UPDATE "counter_cache" SET
|
||||||
%1$I = greatest("counter_cache".%1$I - 1, 0),
|
%1$I = greatest("counter_cache".%1$I - 1, 0),
|
||||||
%2$I = "counter_cache".%2$I + 1
|
%2$I = "counter_cache".%2$I + 1
|
||||||
|
|
|
@ -17,10 +17,11 @@ test "it ignores internal users" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "status visibility count" do
|
describe "status visibility sum count" do
|
||||||
test "on new status" do
|
test "on new status" do
|
||||||
|
instance2 = "instance2.tld"
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
other_user = insert(:user)
|
other_user = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
|
||||||
|
|
||||||
CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||||
|
|
||||||
|
@ -45,24 +46,24 @@ test "on new status" do
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert %{direct: 3, private: 4, public: 1, unlisted: 2} =
|
assert %{"direct" => 3, "private" => 4, "public" => 1, "unlisted" => 2} =
|
||||||
Pleroma.Stats.get_status_visibility_count()
|
Pleroma.Stats.get_status_visibility_count()
|
||||||
end
|
end
|
||||||
|
|
||||||
test "on status delete" do
|
test "on status delete" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||||
assert %{public: 1} = Pleroma.Stats.get_status_visibility_count()
|
assert %{"public" => 1} = Pleroma.Stats.get_status_visibility_count()
|
||||||
CommonAPI.delete(activity.id, user)
|
CommonAPI.delete(activity.id, user)
|
||||||
assert %{public: 0} = Pleroma.Stats.get_status_visibility_count()
|
assert %{"public" => 0} = Pleroma.Stats.get_status_visibility_count()
|
||||||
end
|
end
|
||||||
|
|
||||||
test "on status visibility update" do
|
test "on status visibility update" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||||
assert %{public: 1, private: 0} = Pleroma.Stats.get_status_visibility_count()
|
assert %{"public" => 1, "private" => 0} = Pleroma.Stats.get_status_visibility_count()
|
||||||
{:ok, _} = CommonAPI.update_activity_scope(activity.id, %{"visibility" => "private"})
|
{:ok, _} = CommonAPI.update_activity_scope(activity.id, %{"visibility" => "private"})
|
||||||
assert %{public: 0, private: 1} = Pleroma.Stats.get_status_visibility_count()
|
assert %{"public" => 0, "private" => 1} = Pleroma.Stats.get_status_visibility_count()
|
||||||
end
|
end
|
||||||
|
|
||||||
test "doesn't count unrelated activities" do
|
test "doesn't count unrelated activities" do
|
||||||
|
@ -73,8 +74,46 @@ test "doesn't count unrelated activities" do
|
||||||
CommonAPI.favorite(other_user, activity.id)
|
CommonAPI.favorite(other_user, activity.id)
|
||||||
CommonAPI.repeat(activity.id, other_user)
|
CommonAPI.repeat(activity.id, other_user)
|
||||||
|
|
||||||
assert %{direct: 0, private: 0, public: 1, unlisted: 0} =
|
assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 0} =
|
||||||
Pleroma.Stats.get_status_visibility_count()
|
Pleroma.Stats.get_status_visibility_count()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "status visibility by instance count" do
|
||||||
|
test "single instance" do
|
||||||
|
local_instance = Pleroma.Web.Endpoint.url() |> String.split("//") |> Enum.at(1)
|
||||||
|
instance2 = "instance2.tld"
|
||||||
|
user1 = insert(:user)
|
||||||
|
user2 = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
|
||||||
|
|
||||||
|
CommonAPI.post(user1, %{"visibility" => "public", "status" => "hey"})
|
||||||
|
|
||||||
|
Enum.each(1..5, fn _ ->
|
||||||
|
CommonAPI.post(user1, %{
|
||||||
|
"visibility" => "unlisted",
|
||||||
|
"status" => "hey"
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
Enum.each(1..10, fn _ ->
|
||||||
|
CommonAPI.post(user1, %{
|
||||||
|
"visibility" => "direct",
|
||||||
|
"status" => "hey @#{user2.nickname}"
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
Enum.each(1..20, fn _ ->
|
||||||
|
CommonAPI.post(user2, %{
|
||||||
|
"visibility" => "private",
|
||||||
|
"status" => "hey"
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert %{"direct" => 10, "private" => 0, "public" => 1, "unlisted" => 5} =
|
||||||
|
Pleroma.Stats.get_status_visibility_count(local_instance)
|
||||||
|
|
||||||
|
assert %{"direct" => 0, "private" => 20, "public" => 0, "unlisted" => 0} =
|
||||||
|
Pleroma.Stats.get_status_visibility_count(instance2)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3612,6 +3612,26 @@ test "status visibility count", %{conn: conn} do
|
||||||
assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} =
|
assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} =
|
||||||
response["status_visibility"]
|
response["status_visibility"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "by instance", %{conn: conn} do
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
user1 = insert(:user)
|
||||||
|
instance2 = "instance2.tld"
|
||||||
|
user2 = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
|
||||||
|
|
||||||
|
CommonAPI.post(user1, %{"visibility" => "public", "status" => "hey"})
|
||||||
|
CommonAPI.post(user2, %{"visibility" => "unlisted", "status" => "hey"})
|
||||||
|
CommonAPI.post(user2, %{"visibility" => "private", "status" => "hey"})
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> get("/api/pleroma/admin/stats", instance: instance2)
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} =
|
||||||
|
response["status_visibility"]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /api/pleroma/admin/oauth_app" do
|
describe "POST /api/pleroma/admin/oauth_app" do
|
||||||
|
|
Loading…
Reference in a new issue