Skip to content

Commit 7232eba

Browse files
committed
wip: show the transfers
1 parent 0cb288d commit 7232eba

5 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
defmodule ApiWeb.TransferController do
2+
use ApiWeb.Web, :api_controller
3+
4+
@filters ~w(trip type)s
5+
@pagination_opts [:offset, :limit]
6+
7+
def state_module, do: State.Transfer
8+
def index_data(conn, params) do
9+
10+
with {:ok, filtered} <- Params.filter_params(params, @filters, conn) do
11+
filtered
12+
|> format_filters()
13+
|> State.Transfer.filter_by()
14+
|> State.all(Params.filter_opts(params, @pagination_opts, conn))
15+
else
16+
{:error, _, _} = error -> error
17+
end
18+
end
19+
20+
defp format_filters(filters) do
21+
filters
22+
|> Enum.flat_map(&do_format_filter/1)
23+
|> Enum.into(%{})
24+
end
25+
26+
defp do_format_filter({"trip", trip_string}) do
27+
case Params.split_on_comma(trip_string) do
28+
[] ->
29+
[]
30+
31+
trip_ids ->
32+
%{from_trip_ids: trip_ids}
33+
end
34+
end
35+
36+
defp do_format_filter({"type", type_string}) do
37+
case Params.split_on_comma(type_string) do
38+
[] ->
39+
[]
40+
41+
types ->
42+
%{types: types}
43+
end
44+
end
45+
46+
defp do_format_filter(_), do: []
47+
48+
def show_data(_conn, _params), do: []
49+
end

‎apps/api_web/lib/api_web/router.ex‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ defmodule ApiWeb.Router do
9797
resources("/trips", TripController, only: [:index, :show])
9898
resources("/alerts", AlertController, only: [:index, :show])
9999
resources("/facilities", FacilityController, only: [:index, :show])
100+
get("/transfers", TransferController, :index)
100101
resources("/live_facilities", LiveFacilityController, only: [:index, :show])
101102
resources("/live-facilities", LiveFacilityController, only: [:index, :show])
102103
resources("/services", ServiceController, only: [:index, :show])

‎apps/api_web/lib/api_web/swagger_helpers.ex‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ defmodule ApiWeb.SwaggerHelpers do
217217
Path.parameter(path_object, "filter[#{name}]", :query, :string, desc, format: :time)
218218
end
219219

220+
def filter_param(path_object, :trip_id, opts) do
221+
desc = opts[:desc] || ""
222+
223+
clean_opts = Keyword.take(opts, [:type, :required, :name, :in, :desc, :description])
224+
filter_param(path_object, :id, Keyword.merge(clean_opts, desc: desc, name: :trip))
225+
end
226+
220227
def filter_param(path_object, :stop_id, opts) do
221228
desc = opts[:desc] || ""
222229

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule ApiWeb.TransferView do
2+
use ApiWeb.Web, :api_view
3+
4+
attributes([
5+
:from_stop_id,
6+
:to_stop_id,
7+
:min_transfer_time,
8+
:min_walk_time,
9+
:min_wheelchair_time,
10+
:suggested_buffer_time,
11+
:wheelchair_transfer,
12+
:from_trip_id,
13+
:to_trip_id,
14+
:transfer_type
15+
])
16+
17+
end

‎apps/state/lib/state/transfer.ex‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,71 @@ defmodule State.Transfer do
88
fetched_filename: "transfers.txt",
99
parser: Parse.Transfers,
1010
recordable: Model.Transfer
11+
12+
@type filter_opts :: %{
13+
optional(:trips) => [Model.Trip.id()],
14+
optional(:types) => [String.t()]
15+
}
16+
17+
@type transfer_search :: (-> [Model.Transfer.t()])
18+
19+
@doc """
20+
Applies a filtered search on Transfers based on a map of filter values.
21+
22+
The allowed filterable keys are:
23+
:trips
24+
:types
25+
"""
26+
@spec filter_by(filter_opts) :: [Model.Transfer.t()]
27+
def filter_by(filters) when is_map(filters) do
28+
filters
29+
|> build_filtered_searches()
30+
|> do_searches()
31+
end
32+
33+
# Generate the functions needed to search concurrently
34+
@spec build_filtered_searches(filter_opts, [transfer_search]) :: [transfer_search]
35+
defp build_filtered_searches(filters, searches \\ [])
36+
37+
defp build_filtered_searches(%{types: types} = filters, searches) do
38+
types = Enum.map(types, &String.to_integer/1)
39+
search_operation = fn -> by_transfer_types(types) end
40+
41+
filters
42+
|> Map.drop([:types])
43+
|> build_filtered_searches([search_operation | searches])
44+
end
45+
46+
defp build_filtered_searches(%{trips: trip_ids} = filters, searches) do
47+
search_operation = fn -> by_from_trip_ids(trip_ids) end
48+
49+
filters
50+
|> Map.drop([:trips])
51+
|> build_filtered_searches([search_operation | searches])
52+
end
53+
54+
defp build_filtered_searches(_, searches), do: searches
55+
56+
@spec do_searches([transfer_search]) :: [Transfer.t()]
57+
defp do_searches([]), do: all()
58+
59+
defp do_searches(search_operations) do
60+
search_results =
61+
Stream.map(search_operations, fn search_operation ->
62+
case search_operation.() do
63+
results when is_list(results) ->
64+
results
65+
66+
_ ->
67+
[]
68+
end
69+
end)
70+
71+
Enum.to_list(
72+
Enum.reduce(search_results, :no_results, fn
73+
results, :no_results -> MapSet.new(results)
74+
results, acc -> results |> MapSet.new() |> MapSet.intersection(acc)
75+
end)
76+
)
77+
end
1178
end

0 commit comments

Comments
 (0)