defmodule FrenzyWeb.Fervor.FeedsController do use FrenzyWeb, :controller alias Frenzy.{Repo, Feed, Item} import Ecto.Query alias FrenzyWeb.Fervor.Paginator plug :get_specific_feed def get_specific_feed(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) do user = conn.assigns[:user] |> Repo.preload(groups: [:feeds]) {id, _} = Integer.parse(id) feeds = Enum.flat_map(user.groups, fn g -> g.feeds end) case Enum.find(feeds, fn f -> f.id == id end) do nil -> conn |> put_status(404) |> json(%{error: "Unknown feed"}) |> halt() feed -> assign(conn, :feed, feed) end end def get_specific_feed(conn, _opts), do: conn def feeds_list(conn, _params) do user = conn.assigns[:user] |> Repo.preload(groups: [:feeds]) feeds = user.groups |> Enum.flat_map(fn g -> g.feeds end) |> Enum.map(&Feed.to_fervor/1) json(conn, feeds) end def specific_feed(conn, _params) do feed = conn.assigns[:feed] json(conn, Feed.to_fervor(feed)) end def specific_feed_items(conn, params) do feed = conn.assigns[:feed] feed_id = feed.id query = from(i in Item, where: i.feed_id == ^feed_id) query = case Map.get(params, "only") do "read" -> from(i in query, where: i.read) "unread" -> from(i in query, where: not i.read) _ -> query end |> Paginator.paginate(params) |> Paginator.limit(params) items = query |> Repo.all() |> Enum.map(&Item.to_fervor/1) json(conn, items) end def create(conn, %{"feed_url" => feed_url, "group_ids" => group_ids}) do case Integer.parse(group_ids) do {_, rest} when rest != "" -> conn |> put_status(400) |> json(%{error: "Could not create feed. Exactly 1 group must be provided."}) {group_id, _} -> user = conn.assigns[:user] |> Repo.preload(:groups) case Enum.find(user.groups, fn g -> g.id == group_id end) do nil -> conn |> put_status(400) |> json(%{error: "Could not create feed. Invalid group."}) group -> changeset = Ecto.build_assoc(group, :feeds, %{ feed_url: feed_url }) {:ok, feed} = Repo.insert(changeset) feed = Frenzy.UpdateFeeds.refresh(Frenzy.UpdateFeeds, feed) json(conn, Feed.to_fervor(feed)) end end end def create(conn, _params) do conn |> put_status(400) |> json(%{ error: "Could not create feed", error_description: "feed URL and one group ID must be provided" }) end def delete(conn, _params) do feed = conn.assigns[:feed] {:ok, _} = Repo.delete(feed) send_resp(conn, 204, "") end end