Packages
ami_models
0.1.0
Package containing all AMI Models shared between micro-services.
Retired package: Deprecated - faulty
Current section
Files
Jump to
Current section
Files
lib/ami/search.ex
defmodule Ami.Search do
use Ecto.Schema
import Ecto.{
Query,
Changeset
}
alias Ami.{
# Course,
Community,
# Tool,
Toolkit,
CourseSearch,
Repo,
User
# Like
}
schema "search" do
field(:term, :string, virtual: true)
field(:types, :string, virtual: true)
end
def changeset(search, params \\ %{}) do
cast(search, params, [:term])
end
def kv_options do
[
[key: "All", value: "all"],
[key: "Courses", value: "courses"],
[key: "Tools", value: "tools"],
[key: "Toolkits", value: "toolkits"],
[key: "Communities", value: "communities"]
]
end
def search_resources(%{"query" => term, "user_id" => user_id}) do
user = Repo.get(User, user_id)
courses =
case CourseSearch.search_for_user_with_term(user, term) do
{:ok, %{courses: course_periods, packages: _packages}} ->
course_periods
{:error, _} ->
[]
end
tools = __MODULE__.search_tools(term)
toolkits = __MODULE__.search_toolkits(term)
communities = __MODULE__.search_communities_for_user_with_term(user, term)
{:ok, %{courses: courses, tools: tools, toolkits: toolkits, communities: communities}}
end
def search_resources(%{"query" => term}) do
courses = CourseSearch.search_for_user_with_term(term)
tools = __MODULE__.search_tools(term)
toolkits = __MODULE__.search_toolkits(term)
communities = __MODULE__.search_public_universal_communities(term)
{:ok, %{courses: courses, tools: tools, toolkits: toolkits, communities: communities}}
end
def search_tools(term) do
Ecto.Adapters.SQL.query!(Ami.Repo, "SELECT * FROM tool_search($1)", [term])
|> result_to_tool_struct
end
def search_toolkits(term) do
Ecto.Adapters.SQL.query!(Ami.Repo, "SELECT * FROM toolkit_search($1)", [term])
|> result_to_toolkit_struct
|> Enum.map(&Toolkit.fetch_tools_count(&1))
end
def search_public_universal_communities(term) do
Ecto.Adapters.SQL.query!(Ami.Repo, "SELECT * FROM community_search($1)", [term])
|> result_to_community_struct
|> Enum.filter(&Community.public_or_universal?(&1))
|> Enum.map(&Community.fetch_members_count(&1))
end
def search_communities_for_user_with_term(user, term) do
Ecto.Adapters.SQL.query!(Ami.Repo, "SELECT * FROM community_search($1)", [term])
|> result_to_community_struct
|> keep_user_communities(user)
|> Enum.map(&Community.fetch_members_count(&1))
end
def search_my_resources(%{"query" => term}, user) do
communities = __MODULE__.search_communities_for_user_with_term(user, term)
tools = __MODULE__.search_my_tools(user, term)
toolkits = __MODULE__.search_my_toolkits(user, term)
{:ok, %{tools: tools, toolkits: toolkits, communities: communities}}
end
def search_my_tools(user, term) do
search_tools(term)
|> keep_user_tools(user)
end
def search_my_toolkits(user, term) do
search_toolkits(term)
|> keep_user_toolkits(user)
end
def search_my_community(
%{"query" => term, "community_id" => community_id},
_user
) do
community =
Ami.Repo.get(Ami.Community, community_id)
|> Ami.Repo.preload([:direct_tools, :direct_toolkits, :tools, toolkits: :tools])
courses = CourseSearch.search_for_community_with_term(community, term)
tools = search_tools(term) |> keep_community_tools(community)
toolkits = search_toolkits(term) |> keep_community_toolkits(community)
{:ok, %{courses: courses, tools: tools, toolkits: toolkits}}
end
defp result_to_tool_struct(res) do
cols = Enum.map(res.columns, &String.to_atom(&1))
Enum.map(res.rows, fn row -> struct(Ami.Tool, Enum.zip(cols, row)) end)
end
defp result_to_toolkit_struct(res) do
cols = Enum.map(res.columns, &String.to_atom(&1))
Enum.map(res.rows, fn row -> struct(Ami.Toolkit, Enum.zip(cols, row)) end)
end
defp result_to_community_struct(res) do
cols = Enum.map(res.columns, &String.to_atom(&1))
Enum.map(res.rows, fn row -> struct(Ami.Community, Enum.zip(cols, row)) end)
end
defp keep_user_communities(community_list, user) do
all_ids_set =
Enum.map(community_list, fn c -> c.id end)
|> MapSet.new()
universal_public_protected_ids_set =
Enum.filter(community_list, &Community.universal_or_public_or_protected?(&1))
|> Enum.filter(fn community -> community.is_dormant == false end)
|> Enum.map(fn c -> c.id end)
|> MapSet.new()
user_community_ids_set =
Community.get_awaken_communities_for(user)
|> Enum.map(fn c -> c.id end)
|> MapSet.new()
keep_ids =
MapSet.intersection(all_ids_set, user_community_ids_set)
|> MapSet.union(universal_public_protected_ids_set)
|> MapSet.to_list()
Repo.all(from(c in Community, where: c.id in ^keep_ids))
end
defp keep_user_tools(tools, user) do
fetched_tools_ids_set =
Enum.map(tools, fn t -> t.id end)
|> MapSet.new()
community_tool_ids_set =
Community.get_awaken_communities_for(user)
|> Enum.map(fn comm -> Repo.preload(comm, :tools).tools end)
|> List.flatten()
|> Enum.uniq()
|> Enum.map(fn t -> t.id end)
|> MapSet.new()
keep_ids =
MapSet.intersection(fetched_tools_ids_set, community_tool_ids_set)
|> MapSet.to_list()
Repo.all(from(t in Ami.Tool, where: t.id in ^keep_ids))
end
defp keep_user_toolkits(toolkits, user) do
fetched_toolkit_ids_set =
Enum.map(toolkits, fn tk -> tk.id end)
|> MapSet.new()
community_toolkit_ids_set =
Community.get_awaken_communities_for(user)
|> Enum.map(fn comm -> Repo.preload(comm, :toolkits).toolkits end)
|> List.flatten()
|> Enum.uniq()
|> Enum.map(fn tk -> tk.id end)
|> MapSet.new()
keep_ids =
MapSet.intersection(fetched_toolkit_ids_set, community_toolkit_ids_set)
|> MapSet.to_list()
Repo.all(from(tk in Ami.Toolkit, where: tk.id in ^keep_ids))
|> Enum.map(&Toolkit.fetch_tools_count(&1))
end
defp keep_community_tools(tools, community) do
fetched_tools_ids_set =
Enum.map(tools, fn t -> t.id end)
|> MapSet.new()
community_tool_ids =
community.tools
|> Enum.concat(community.direct_tools)
|> Enum.concat(List.flatten(Enum.map(community.toolkits, fn tk -> tk.tools end)))
|> Enum.uniq()
|> Enum.map(fn t -> t.id end)
|> MapSet.new()
keep_ids =
MapSet.intersection(fetched_tools_ids_set, community_tool_ids)
|> MapSet.to_list()
Repo.all(from(t in Ami.Tool, where: t.id in ^keep_ids))
end
defp keep_community_toolkits(toolkits, community) do
fetched_toolkit_ids_set =
Enum.map(toolkits, fn tk -> tk.id end)
|> MapSet.new()
community_toolkit_ids_set =
community.direct_toolkits
|> Enum.concat(community.toolkits)
|> Enum.uniq()
|> Enum.map(fn tk -> tk.id end)
|> MapSet.new()
keep_ids =
MapSet.intersection(fetched_toolkit_ids_set, community_toolkit_ids_set)
|> MapSet.to_list()
Repo.all(from(tk in Ami.Toolkit, where: tk.id in ^keep_ids))
|> Enum.map(&Toolkit.fetch_tools_count(&1))
end
end