defmodule FrenzyWeb.Fervor.ItemsController do use FrenzyWeb, :controller alias Frenzy.{Repo, Item} import Ecto.Query alias FrenzyWeb.Fervor.Paginator plug :get_specific_item def get_specific_item(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) do user = conn.assigns[:user] |> Repo.preload(:feeds) item = Repo.get(Item, id) if Enum.any?(user.feeds, fn f -> f.id == item.feed_id end) do assign(conn, :item, item) else conn |> put_status(404) |> json(%{error: "Unknown item"}) |> halt() end end def get_specific_item(conn, _opts), do: conn def items_list(conn, params) do user = conn.assigns[:user] |> Repo.preload(groups: [:feeds]) feed_ids = user.groups |> Enum.flat_map(fn g -> g.feeds end) |> Enum.map(fn f -> f.id end) query = from(i in Item, where: i.feed_id in ^feed_ids) query = case Map.get(params, "only") do "read" -> from(i in query, where: i.read) "unread" -> from(i in query, where: not i.read) nil -> query end |> Paginator.paginate(params) |> Paginator.limit(params) items = query |> Repo.all() |> Enum.map(&Item.to_fervor/1) json(conn, items) end def specific_item(conn, _params) do item = conn.assigns[:item] json(conn, Item.to_fervor(item)) end def mark_item(conn, changes) do item = conn.assigns[:item] |> Repo.preload(:feed) changeset = Item.changeset(item, changes) {:ok, item} = Repo.update(changeset) json(conn, Item.to_fervor(item)) end def read_specific_item(conn, _params) do mark_item(conn, %{read: true}) end def unread_specific_item(conn, _params) do mark_item(conn, %{read: false}) end def mark_multiple_items(conn, %{"ids" => ids}, changes) do user = conn.assigns[:user] |> Repo.preload(groups: [:feeds]) feeds = Enum.flat_map(user.groups, fn g -> g.feeds end) read_ids = ids |> String.split(",") |> Enum.map(fn s -> {id, _} = s |> String.trim() |> Integer.parse() Repo.get(Item, id) end) |> Enum.filter(fn item -> Enum.any?(feeds, fn f -> f.id == item.feed_id end) end) |> Enum.map(fn item -> item = Repo.preload(item, :feed) changeset = Item.changeset(item, changes) case Repo.update(changeset) do {:ok, item} -> item.id _ -> nil end end) |> Enum.reject(&is_nil/1) json(conn, read_ids) end def mark_multiple_items(conn, _params, _changes) do conn |> put_status(400) |> json(%{error: "No items provided."}) end def read_multiple(conn, params) do mark_multiple_items(conn, params, %{read: true}) end def unread_multiple(conn, params) do mark_multiple_items(conn, params, %{read: false}) end end