summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Chathi <hubert@uhoreg.ca>2020-05-12 18:39:58 -0400
committerHubert Chathi <hubert@uhoreg.ca>2020-05-12 18:39:58 -0400
commit3bd34cf08e19d4eda8e4d722bccf7d7476ab684e (patch)
tree8522236eac895ab105c424739d5263fcfe99047c
parentfix typespec (diff)
add some more filtering methods and reduce duplicate code
-rw-r--r--lib/polyjuice/client/filter.ex281
-rw-r--r--test/polyjuice/client/filter_test.exs63
2 files changed, 197 insertions, 147 deletions
diff --git a/lib/polyjuice/client/filter.ex b/lib/polyjuice/client/filter.ex
index 91e0db2..fb8c6f1 100644
--- a/lib/polyjuice/client/filter.ex
+++ b/lib/polyjuice/client/filter.ex
@@ -128,49 +128,124 @@ defmodule Polyjuice.Client.Filter do
Map.put(filter, key, put(Map.get(filter, key, %{}), rest, val))
end
+ defmodule Event do
+ @moduledoc """
+ Create `EventFilter`s, `RoomEventFilter`s, `StateFilter`s, or `RoomFilter`s.
+
+ https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-user-userid-filter
+
+ These are filters that form part of a `Polyjuice.Client.Filter`. Not all of
+ the functions in here may apply to all the different types of filters.
+ """
+
+ @doc """
+ Add items to a list parameter in the filter.
+ """
+ @spec add_to_list(filter :: map, name :: String.t(), data :: list) :: map
+ def add_to_list(filter \\ %{}, name, data)
+ when is_map(filter) and is_binary(name) and is_list(data) do
+ Polyjuice.Client.Filter.update(
+ filter,
+ [name],
+ data,
+ &Enum.concat(&1, data)
+ )
+ end
+
+ @doc """
+ Include certain types of events.
+ """
+ @spec include_types(filter :: map, types :: list) :: map
+ def include_types(filter \\ %{}, types) when is_map(filter) and is_list(types),
+ do: add_to_list(filter, "types", types)
+
+ @doc """
+ Exclude certain types of events.
+ """
+ @spec exclude_types(filter :: map, types :: list) :: map
+ def exclude_types(filter \\ %{}, types) when is_map(filter) and is_list(types),
+ do: add_to_list(filter, "not_types", types)
+
+ @doc """
+ Include certain senders.
+ """
+ @spec include_senders(filter :: map, types :: list) :: map
+ def include_senders(filter \\ %{}, senders) when is_map(filter) and is_list(senders),
+ do: add_to_list(filter, "senders", senders)
+
+ @doc """
+ Exclude certain senders.
+ """
+ @spec exclude_senders(filter :: map, senders :: list) :: map
+ def exclude_senders(filter \\ %{}, senders) when is_map(filter) and is_list(senders),
+ do: add_to_list(filter, "not_senders", senders)
+
+ @doc """
+ Include certain rooms.
+ """
+ @spec include_rooms(filter :: map, rooms :: list) :: map
+ def include_rooms(filter \\ %{}, rooms) when is_map(filter) and is_list(rooms),
+ do: add_to_list(filter, "rooms", rooms)
+
+ @doc """
+ Exclude certain rooms.
+ """
+ @spec exclude_rooms(filter :: map, rooms :: list) :: map
+ def exclude_rooms(filter \\ %{}, rooms) when is_map(filter) and is_list(rooms),
+ do: add_to_list(filter, "not_rooms", rooms)
+
+ @doc """
+ Set the maximum number of events to return.
+ """
+ @spec limit(filter :: map, limit :: integer) :: map
+ def limit(filter \\ %{}, limit) when is_map(filter) and is_integer(limit),
+ do: Map.put(filter, "limit", limit)
+
+ @doc """
+ Set whether to include or exclude events that have a URL.
+
+ If `flag` is `true`, only events that have a `url` field will be included.
+ If `flag` is `false`, events that have a `url` field will be excluded.
+ """
+ @spec contains_url(filter :: map, flag :: boolean) :: map
+ def contains_url(%{} = filter \\ %{}, flag) when is_map(filter) and is_boolean(flag),
+ do: Map.put(filter, "contains_url", flag)
+ end
+
@doc """
- Allow certain types of presence events to be included.
+ Update the presence filter using a function.
"""
- @spec include_presence_types(filter :: map, types :: list) :: map
- def include_presence_types(filter \\ %{}, types)
-
- def include_presence_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "presence" => %{
- "types" => types
- }
- }
+ @spec presence(filter :: map, f :: function) :: map
+ def presence(filter, f) when is_function(f) do
+ Map.put(filter, "presence", f.(Map.get(filter, "presence", %{})))
end
- def include_presence_types(filter, types) when is_map(filter) and is_list(types) do
- update(
- filter,
- ["presence", "types"],
- types,
- &Enum.concat(&1, types)
- )
+ @doc """
+ Allow certain types of presence events to be included.
+ """
+ @spec include_presence_types(filter :: map, types :: list) :: map
+ def include_presence_types(filter \\ %{}, types) when is_map(filter) and is_list(types) do
+ presence(filter, &Polyjuice.Client.Filter.Event.include_types(&1, types))
end
@doc """
Don't allow certain types of presence events.
"""
@spec exclude_presence_types(filter :: map, types :: list) :: map
- def exclude_presence_types(filter \\ %{}, types)
-
- def exclude_presence_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "presence" => %{
- "not_types" => types
- }
- }
+ def exclude_presence_types(filter \\ %{}, types) do
+ presence(filter, &Polyjuice.Client.Filter.Event.exclude_types(&1, types))
end
- def exclude_presence_types(filter, types) when is_map(filter) and is_list(types) do
+ @doc """
+ Update the ephemeral filter using a function.
+ """
+ @spec ephemeral(filter :: map, f :: function) :: map
+ def ephemeral(filter, f) when is_function(f) do
update(
filter,
- ["presence", "not_types"],
- types,
- &Enum.concat(&1, types)
+ ["room", "ephemeral"],
+ f.(%{}),
+ f
)
end
@@ -178,49 +253,28 @@ defmodule Polyjuice.Client.Filter do
Allow certain types of ephemeral room events to be included.
"""
@spec include_ephemeral_types(filter :: map, types :: list) :: map
- def include_ephemeral_types(filter \\ %{}, types)
-
- def include_ephemeral_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "ephemeral" => %{
- "types" => types
- }
- }
- }
- end
-
- def include_ephemeral_types(filter, types) when is_map(filter) and is_list(types) do
- update(
- filter,
- ["room", "ephemeral", "types"],
- types,
- &Enum.concat(&1, types)
- )
+ def include_ephemeral_types(filter \\ %{}, types) do
+ ephemeral(filter, &Polyjuice.Client.Filter.Event.include_types(&1, types))
end
@doc """
Don't allow certain types of ephemeral room events.
"""
@spec exclude_ephemeral_types(filter :: map, types :: list) :: map
- def exclude_ephemeral_types(filter \\ %{}, types)
-
- def exclude_ephemeral_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "ephemeral" => %{
- "not_types" => types
- }
- }
- }
+ def exclude_ephemeral_types(filter \\ %{}, types) do
+ ephemeral(filter, &Polyjuice.Client.Filter.Event.exclude_types(&1, types))
end
- def exclude_ephemeral_types(filter, types) when is_map(filter) and is_list(types) do
+ @doc """
+ Update the state filter using a function.
+ """
+ @spec state(filter :: map, f :: function) :: map
+ def state(filter, f) when is_function(f) do
update(
filter,
- ["room", "ephemeral", "not_types"],
- types,
- &Enum.concat(&1, types)
+ ["room", "state"],
+ f.(%{}),
+ f
)
end
@@ -228,49 +282,28 @@ defmodule Polyjuice.Client.Filter do
Allow certain types of state events to be included.
"""
@spec include_state_types(filter :: map, types :: list) :: map
- def include_state_types(filter \\ %{}, types)
-
- def include_state_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "state" => %{
- "types" => types
- }
- }
- }
- end
-
- def include_state_types(filter, types) when is_map(filter) and is_list(types) do
- update(
- filter,
- ["room", "state", "types"],
- types,
- &Enum.concat(&1, types)
- )
+ def include_state_types(filter \\ %{}, types) do
+ state(filter, &Polyjuice.Client.Filter.Event.include_types(&1, types))
end
@doc """
Don't allow certain types of state events.
"""
@spec exclude_state_types(filter :: map, types :: list) :: map
- def exclude_state_types(filter \\ %{}, types)
-
- def exclude_state_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "state" => %{
- "not_types" => types
- }
- }
- }
+ def exclude_state_types(filter \\ %{}, types) do
+ state(filter, &Polyjuice.Client.Filter.Event.exclude_types(&1, types))
end
- def exclude_state_types(filter, types) when is_map(filter) and is_list(types) do
+ @doc """
+ Update the timeline filter using a function.
+ """
+ @spec timeline(filter :: map, f :: function) :: map
+ def timeline(filter, f) when is_function(f) do
update(
filter,
- ["room", "state", "not_types"],
- types,
- &Enum.concat(&1, types)
+ ["room", "timeline"],
+ f.(%{}),
+ f
)
end
@@ -278,70 +311,24 @@ defmodule Polyjuice.Client.Filter do
Allow certain types of timeline events to be included.
"""
@spec include_timeline_types(filter :: map, types :: list) :: map
- def include_timeline_types(filter \\ %{}, types)
-
- def include_timeline_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "timeline" => %{
- "types" => types
- }
- }
- }
- end
-
- def include_timeline_types(filter, types) when is_map(filter) and is_list(types) do
- update(
- filter,
- ["room", "timeline", "types"],
- types,
- &Enum.concat(&1, types)
- )
+ def include_timeline_types(filter \\ %{}, types) do
+ timeline(filter, &Polyjuice.Client.Filter.Event.include_types(&1, types))
end
@doc """
Don't allow certain types of timeline events.
"""
@spec exclude_timeline_types(filter :: map, types :: list) :: map
- def exclude_timeline_types(filter \\ %{}, types)
-
- def exclude_timeline_types(filter, types) when filter == %{} and is_list(types) do
- %{
- "room" => %{
- "timeline" => %{
- "not_types" => types
- }
- }
- }
- end
-
- def exclude_timeline_types(filter, types) when is_map(filter) and is_list(types) do
- update(
- filter,
- ["room", "timeline", "not_types"],
- types,
- &Enum.concat(&1, types)
- )
+ def exclude_timeline_types(filter \\ %{}, types) do
+ timeline(filter, &Polyjuice.Client.Filter.Event.exclude_types(&1, types))
end
@doc """
Set the maximum number of timeline events.
"""
@spec limit_timeline_events(filter :: map, limit :: integer) :: map
- def limit_timeline_events(filter \\ %{}, limit)
-
- def limit_timeline_events(filter, limit) when filter == %{} and is_integer(limit) do
- %{
- "room" => %{
- "timeline" => %{
- "limit" => limit
- }
- }
- }
- end
-
- def limit_timeline_events(filter, limit) when is_map(filter) and is_integer(limit) do
- put(filter, ["room", "timeline", "limit"], limit)
+ def limit_timeline_events(filter \\ %{}, limit) do
+ timeline(filter, &Polyjuice.Client.Filter.Event.limit(&1, limit))
end
@spec lazy_loading(filter :: map) :: map
diff --git a/test/polyjuice/client/filter_test.exs b/test/polyjuice/client/filter_test.exs
index 8057360..5101fdc 100644
--- a/test/polyjuice/client/filter_test.exs
+++ b/test/polyjuice/client/filter_test.exs
@@ -112,6 +112,20 @@ defmodule Polyjuice.Client.FilterTest do
}
}
+ assert Filter.include_timeline_types(["foo.*"])
+ |> Filter.exclude_timeline_types(["foo.bar"]) == %{
+ "room" => %{
+ "timeline" => %{"not_types" => ["foo.bar"], "types" => ["foo.*"]}
+ }
+ }
+
+ assert Filter.exclude_timeline_types(["foo.bar"])
+ |> Filter.include_timeline_types(["foo.*"]) == %{
+ "room" => %{
+ "timeline" => %{"not_types" => ["foo.bar"], "types" => ["foo.*"]}
+ }
+ }
+
assert Filter.limit_timeline_events(10) == %{"room" => %{"timeline" => %{"limit" => 10}}}
assert Filter.lazy_loading() == %{
@@ -135,4 +149,53 @@ defmodule Polyjuice.Client.FilterTest do
}
}
end
+
+ test "event filter" do
+ assert Filter.Event.add_to_list("foo", ["bar"]) == %{"foo" => ["bar"]}
+
+ assert Filter.Event.include_types(["m.*"])
+ |> Filter.Event.exclude_types(["m.reaction"]) == %{
+ "types" => ["m.*"],
+ "not_types" => ["m.reaction"]
+ }
+
+ assert Filter.Event.exclude_types(["m.reaction"])
+ |> Filter.Event.include_types(["m.*"]) == %{
+ "types" => ["m.*"],
+ "not_types" => ["m.reaction"]
+ }
+
+ assert Filter.Event.include_senders(["@alice:example.org"])
+ |> Filter.Event.exclude_senders(["@bob:example.org"]) == %{
+ "senders" => ["@alice:example.org"],
+ "not_senders" => ["@bob:example.org"]
+ }
+
+ assert Filter.Event.include_senders(["@alice:example.org"])
+ |> Filter.Event.include_senders(["@bob:example.org"]) == %{
+ "senders" => ["@alice:example.org", "@bob:example.org"]
+ }
+
+ assert Filter.Event.exclude_senders(["@bob:example.org"])
+ |> Filter.Event.include_senders(["@alice:example.org"]) == %{
+ "senders" => ["@alice:example.org"],
+ "not_senders" => ["@bob:example.org"]
+ }
+
+ assert Filter.Event.include_rooms(["!room1"])
+ |> Filter.Event.exclude_rooms(["!room2"]) == %{
+ "rooms" => ["!room1"],
+ "not_rooms" => ["!room2"]
+ }
+
+ assert Filter.Event.exclude_rooms(["!room2"])
+ |> Filter.Event.include_rooms(["!room1"]) == %{
+ "rooms" => ["!room1"],
+ "not_rooms" => ["!room2"]
+ }
+
+ assert Filter.Event.limit(10) == %{"limit" => 10}
+
+ assert Filter.Event.contains_url(true) == %{"contains_url" => true}
+ end
end