fix(feeds): Only provide future events in ICS/Atom feeds
Closes #1246 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
5ae2e2254a
commit
f3a443138a
|
@ -418,12 +418,35 @@ defmodule Mobilizon.Events do
|
||||||
do: list_organized_events_for_group(group, :public, nil, nil, page, limit)
|
do: list_organized_events_for_group(group, :public, nil, nil, page, limit)
|
||||||
|
|
||||||
def list_public_events_for_actor(%Actor{id: actor_id}, page, limit) do
|
def list_public_events_for_actor(%Actor{id: actor_id}, page, limit) do
|
||||||
|
actor_id
|
||||||
|
|> do_list_public_events_for_actor()
|
||||||
|
|> Page.build_page(page, limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Lists public upcoming events for the actor, with all associations loaded.
|
||||||
|
"""
|
||||||
|
@spec list_public_upcoming_events_for_actor(Actor.t(), integer | nil, integer | nil) ::
|
||||||
|
Page.t(Event.t())
|
||||||
|
def list_public_upcoming_events_for_actor(actor, page \\ nil, limit \\ nil)
|
||||||
|
|
||||||
|
def list_public_upcoming_events_for_actor(%Actor{type: :Group} = group, page, limit),
|
||||||
|
do: list_organized_events_for_group(group, :public, DateTime.utc_now(), nil, page, limit)
|
||||||
|
|
||||||
|
def list_public_upcoming_events_for_actor(%Actor{id: actor_id}, page, limit) do
|
||||||
|
actor_id
|
||||||
|
|> do_list_public_events_for_actor()
|
||||||
|
|> event_filter_begins_on(DateTime.utc_now(), nil)
|
||||||
|
|> Page.build_page(page, limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec do_list_public_events_for_actor(integer()) :: Ecto.Query.t()
|
||||||
|
defp do_list_public_events_for_actor(actor_id) do
|
||||||
actor_id
|
actor_id
|
||||||
|> event_for_actor_query()
|
|> event_for_actor_query()
|
||||||
|> filter_public_visibility()
|
|> filter_public_visibility()
|
||||||
|> filter_draft()
|
|> filter_draft()
|
||||||
|> preload_for_event()
|
|> preload_for_event()
|
||||||
|> Page.build_page(page, limit)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec list_organized_events_for_actor(Actor.t(), integer | nil, integer | nil) ::
|
@spec list_organized_events_for_actor(Actor.t(), integer | nil, integer | nil) ::
|
||||||
|
@ -905,6 +928,21 @@ defmodule Mobilizon.Events do
|
||||||
|> Page.build_page(page, limit)
|
|> Page.build_page(page, limit)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the list of upcoming participations for an actor.
|
||||||
|
"""
|
||||||
|
@spec list_upcoming_event_participations_for_actor(Actor.t(), integer | nil, integer | nil) ::
|
||||||
|
Page.t(Participant.t())
|
||||||
|
def list_upcoming_event_participations_for_actor(
|
||||||
|
%Actor{id: actor_id},
|
||||||
|
page \\ nil,
|
||||||
|
limit \\ nil
|
||||||
|
) do
|
||||||
|
actor_id
|
||||||
|
|> event_participations_for_actor_query(DateTime.utc_now())
|
||||||
|
|> Page.build_page(page, limit)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Counts participant participants (participants with no extra role)
|
Counts participant participants (participants with no extra role)
|
||||||
"""
|
"""
|
||||||
|
@ -1572,16 +1610,24 @@ defmodule Mobilizon.Events do
|
||||||
from(p in Participant, where: p.event_id == ^event_id)
|
from(p in Participant, where: p.event_id == ^event_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec event_participations_for_actor_query(integer) :: Ecto.Query.t()
|
@spec event_participations_for_actor_query(integer, DateTime.t() | nil) :: Ecto.Query.t()
|
||||||
def event_participations_for_actor_query(actor_id) do
|
defp event_participations_for_actor_query(actor_id, after_date \\ nil)
|
||||||
from(
|
|
||||||
p in Participant,
|
defp event_participations_for_actor_query(actor_id, nil) do
|
||||||
join: e in Event,
|
do_event_participations_for_actor_query(actor_id)
|
||||||
on: p.event_id == e.id,
|
end
|
||||||
where: p.actor_id == ^actor_id and p.role != ^:not_approved,
|
|
||||||
preload: [:event],
|
defp event_participations_for_actor_query(actor_id, %DateTime{} = after_date) do
|
||||||
order_by: [desc: e.begins_on]
|
actor_id
|
||||||
)
|
|> do_event_participations_for_actor_query()
|
||||||
|
|> where([_p, e], e.begins_on > ^after_date)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_event_participations_for_actor_query(actor_id) do
|
||||||
|
Participant
|
||||||
|
|> join(:inner, [p], e in Event, on: p.event_id == e.id)
|
||||||
|
|> where([p], p.actor_id == ^actor_id and p.role != ^:not_approved)
|
||||||
|
|> order_by([_p, e], desc: e.begins_on)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec sessions_for_event_query(integer) :: Ecto.Query.t()
|
@spec sessions_for_event_query(integer) :: Ecto.Query.t()
|
||||||
|
|
|
@ -17,7 +17,7 @@ defmodule Mobilizon.Service.Export.Common do
|
||||||
case Actors.get_actor_by_name(name) do
|
case Actors.get_actor_by_name(name) do
|
||||||
%Actor{} = actor ->
|
%Actor{} = actor ->
|
||||||
if Actor.is_public_visibility?(actor) do
|
if Actor.is_public_visibility?(actor) do
|
||||||
%Page{elements: events} = Events.list_public_events_for_actor(actor, 1, limit)
|
%Page{elements: events} = Events.list_public_upcoming_events_for_actor(actor, 1, limit)
|
||||||
%Page{elements: posts} = Posts.get_public_posts_for_group(actor, 1, limit)
|
%Page{elements: posts} = Posts.get_public_posts_for_group(actor, 1, limit)
|
||||||
{:ok, actor, events, posts}
|
{:ok, actor, events, posts}
|
||||||
else
|
else
|
||||||
|
@ -108,7 +108,7 @@ defmodule Mobilizon.Service.Export.Common do
|
||||||
|
|
||||||
@spec fetch_identity_participations(Actor.t(), integer()) :: Page.t(Participant.t())
|
@spec fetch_identity_participations(Actor.t(), integer()) :: Page.t(Participant.t())
|
||||||
defp fetch_identity_participations(%Actor{} = actor, limit) do
|
defp fetch_identity_participations(%Actor{} = actor, limit) do
|
||||||
with %Page{} = page <- Events.list_event_participations_for_actor(actor, 1, limit) do
|
with %Page{} = page <- Events.list_upcoming_event_participations_for_actor(actor, 1, limit) do
|
||||||
page
|
page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,12 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
event1 = insert(:event, organizer_actor: actor, tags: [tag1])
|
event1 = insert(:event, organizer_actor: actor, tags: [tag1])
|
||||||
event2 = insert(:event, organizer_actor: actor, tags: [tag1, tag2])
|
event2 = insert(:event, organizer_actor: actor, tags: [tag1, tag2])
|
||||||
|
|
||||||
|
event3 =
|
||||||
|
insert(:event,
|
||||||
|
organizer_actor: actor,
|
||||||
|
begins_on: DateTime.add(DateTime.utc_now(), -2, :day)
|
||||||
|
)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> get(
|
|> get(
|
||||||
|
@ -36,6 +42,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
|
|
||||||
Enum.each(entries, fn entry ->
|
Enum.each(entries, fn entry ->
|
||||||
assert entry.title in [event1.title, event2.title]
|
assert entry.title in [event1.title, event2.title]
|
||||||
|
refute entry.title == event3.title
|
||||||
end)
|
end)
|
||||||
|
|
||||||
# It seems categories takes term instead of Label
|
# It seems categories takes term instead of Label
|
||||||
|
@ -112,7 +119,15 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
attributed_to: group,
|
attributed_to: group,
|
||||||
tags: [tag1, tag2],
|
tags: [tag1, tag2],
|
||||||
title: "Event Two",
|
title: "Event Two",
|
||||||
begins_on: DateTime.add(DateTime.utc_now(), 3_600 * 12 * 4)
|
begins_on: DateTime.add(DateTime.utc_now(), 4, :day)
|
||||||
|
)
|
||||||
|
|
||||||
|
event3 =
|
||||||
|
insert(:event,
|
||||||
|
organizer_actor: actor,
|
||||||
|
attributed_to: group,
|
||||||
|
title: "Event Three",
|
||||||
|
begins_on: DateTime.add(DateTime.utc_now(), -2, :day)
|
||||||
)
|
)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -131,6 +146,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
|
|
||||||
Enum.each(entries, fn entry ->
|
Enum.each(entries, fn entry ->
|
||||||
assert entry.summary in [event1.title, event2.title]
|
assert entry.summary in [event1.title, event2.title]
|
||||||
|
refute entry.summary == event3.title
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert entry1.categories == [tag1.title]
|
assert entry1.categories == [tag1.title]
|
||||||
|
@ -217,8 +233,10 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
actor2 = insert(:actor, user: user)
|
actor2 = insert(:actor, user: user)
|
||||||
event1 = insert(:event)
|
event1 = insert(:event)
|
||||||
event2 = insert(:event)
|
event2 = insert(:event)
|
||||||
|
event3 = insert(:event, begins_on: DateTime.add(DateTime.utc_now(), -5, :day))
|
||||||
insert(:participant, event: event1, actor: actor1)
|
insert(:participant, event: event1, actor: actor1)
|
||||||
insert(:participant, event: event2, actor: actor2)
|
insert(:participant, event: event2, actor: actor2)
|
||||||
|
insert(:participant, event: event3, actor: actor2)
|
||||||
feed_token = insert(:feed_token, user: user, actor: nil)
|
feed_token = insert(:feed_token, user: user, actor: nil)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -240,6 +258,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
|
|
||||||
Enum.each(entries, fn entry ->
|
Enum.each(entries, fn entry ->
|
||||||
assert entry.title in [event1.title, event2.title]
|
assert entry.title in [event1.title, event2.title]
|
||||||
|
refute entry.title == event3.title
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -251,8 +270,10 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
actor2 = insert(:actor, user: user)
|
actor2 = insert(:actor, user: user)
|
||||||
event1 = insert(:event)
|
event1 = insert(:event)
|
||||||
event2 = insert(:event)
|
event2 = insert(:event)
|
||||||
|
event3 = insert(:event, begins_on: DateTime.add(DateTime.utc_now(), -5, :day))
|
||||||
insert(:participant, event: event1, actor: actor1)
|
insert(:participant, event: event1, actor: actor1)
|
||||||
insert(:participant, event: event2, actor: actor2)
|
insert(:participant, event: event2, actor: actor2)
|
||||||
|
insert(:participant, event: event3, actor: actor1)
|
||||||
feed_token = insert(:feed_token, user: user, actor: actor1)
|
feed_token = insert(:feed_token, user: user, actor: actor1)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -274,6 +295,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
|
|
||||||
[entry] = feed.entries
|
[entry] = feed.entries
|
||||||
assert entry.title == event1.title
|
assert entry.title == event1.title
|
||||||
|
refute entry.title == event3.title
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns 404 for an not existing feed", %{conn: conn} do
|
test "it returns 404 for an not existing feed", %{conn: conn} do
|
||||||
|
@ -298,8 +320,10 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
actor2 = insert(:actor, user: user)
|
actor2 = insert(:actor, user: user)
|
||||||
event1 = insert(:event)
|
event1 = insert(:event)
|
||||||
event2 = insert(:event)
|
event2 = insert(:event)
|
||||||
|
event3 = insert(:event, begins_on: DateTime.add(DateTime.utc_now(), -5, :day))
|
||||||
insert(:participant, event: event1, actor: actor1)
|
insert(:participant, event: event1, actor: actor1)
|
||||||
insert(:participant, event: event2, actor: actor2)
|
insert(:participant, event: event2, actor: actor2)
|
||||||
|
insert(:participant, event: event3, actor: actor1)
|
||||||
feed_token = insert(:feed_token, user: user, actor: nil)
|
feed_token = insert(:feed_token, user: user, actor: nil)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -318,6 +342,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
|
|
||||||
Enum.each(entries, fn entry ->
|
Enum.each(entries, fn entry ->
|
||||||
assert entry.summary in [event1.title, event2.title]
|
assert entry.summary in [event1.title, event2.title]
|
||||||
|
refute entry.summary == event3.title
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -329,8 +354,10 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
actor2 = insert(:actor, user: user)
|
actor2 = insert(:actor, user: user)
|
||||||
event1 = insert(:event)
|
event1 = insert(:event)
|
||||||
event2 = insert(:event)
|
event2 = insert(:event)
|
||||||
|
event3 = insert(:event, begins_on: DateTime.add(DateTime.utc_now(), -5, :day))
|
||||||
insert(:participant, event: event1, actor: actor1)
|
insert(:participant, event: event1, actor: actor1)
|
||||||
insert(:participant, event: event2, actor: actor2)
|
insert(:participant, event: event2, actor: actor2)
|
||||||
|
insert(:participant, event: event3, actor: actor1)
|
||||||
feed_token = insert(:feed_token, user: user, actor: actor1)
|
feed_token = insert(:feed_token, user: user, actor: actor1)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -348,6 +375,7 @@ defmodule Mobilizon.Web.FeedControllerTest do
|
||||||
[entry1] = ExIcal.parse(conn.resp_body)
|
[entry1] = ExIcal.parse(conn.resp_body)
|
||||||
assert entry1.summary == event1.title
|
assert entry1.summary == event1.title
|
||||||
assert entry1.categories == event1.tags |> Enum.map(& &1.title)
|
assert entry1.categories == event1.tags |> Enum.map(& &1.title)
|
||||||
|
refute entry1.summary == event3.title
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns 404 for an not existing feed", %{conn: conn} do
|
test "it returns 404 for an not existing feed", %{conn: conn} do
|
||||||
|
|
Loading…
Reference in a new issue