frenzy/lib/frenzy_web/controllers/fervor/items_controller.ex

125 lines
2.9 KiB
Elixir
Raw Normal View History

2019-03-31 14:52:56 +00:00
defmodule FrenzyWeb.Fervor.ItemsController do
use FrenzyWeb, :controller
2020-06-07 15:14:01 +00:00
alias Frenzy.{Repo, Item}
2019-03-31 14:52:56 +00:00
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(groups: [:feeds])
feeds = Enum.flat_map(user.groups, fn g -> g.feeds end)
item = Repo.get(Item, id)
if Enum.any?(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