From c69f72984313adc777935d26e236aaa8af568384 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Sat, 7 Feb 2026 23:25:05 -0600 Subject: [PATCH] First pass at Nostr filters --- lib/gc_index_relay/nostr/filter.ex | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 lib/gc_index_relay/nostr/filter.ex diff --git a/lib/gc_index_relay/nostr/filter.ex b/lib/gc_index_relay/nostr/filter.ex new file mode 100644 index 0000000..577bb0d --- /dev/null +++ b/lib/gc_index_relay/nostr/filter.ex @@ -0,0 +1,56 @@ +defmodule GcIndexRelay.Nostr.Filter do + alias GcIndexRelay.Repo + import Ecto.Query + + @derive [Jason.Encoder] + defstruct [:ids, :authors, :kinds, :tags, :since, :until, :limit] + + # TODO: Implement tag filtering + + @doc """ + Applies a filter to an Ecto query of Nostr events. + + ## Params + + - `query` - An Ecto query. This MUST be a query over the `GcIndexRelay.Nostr.Event` schema. + - `filter` - A `GcIndexRelay.Nostr.Filter` struct. + + ## Returns + + A filtered list of events in descending order of creation time. + """ + def apply(%Ecto.Query{} = query, %__MODULE__{} = filter) do + query + |> apply_ids(filter.ids) + |> apply_authors(filter.authors) + |> apply_kinds(filter.kinds) + |> apply_since(filter.since) + |> apply_until(filter.until) + |> preload(:tags) + # Always sort in descending order of creation time + |> order_by([e], desc: e.created_at) + |> apply_limit(filter.limit) + |> Repo.all() + end + + defp apply_ids(query, nil), do: query + defp apply_ids(query, []), do: query + defp apply_ids(query, ids), do: where(query, [e], e.id in ^ids) + + defp apply_authors(query, nil), do: query + defp apply_authors(query, []), do: query + defp apply_authors(query, authors), do: where(query, [e], e.author in ^authors) + + defp apply_kinds(query, nil), do: query + defp apply_kinds(query, []), do: query + defp apply_kinds(query, kinds), do: where(query, [e], e.kind in ^kinds) + + defp apply_since(query, nil), do: query + defp apply_since(query, since), do: where(query, [e], e.created_at >= ^since) + + defp apply_until(query, nil), do: query + defp apply_until(query, until), do: where(query, [e], e.created_at <= ^until) + + defp apply_limit(query, nil), do: query + defp apply_limit(query, limit), do: limit(query, ^limit) +end