diff --git a/lib/frenzy_web/controllers/fervor/items_controller.ex b/lib/frenzy_web/controllers/fervor/items_controller.ex index e59fbe1..c023809 100644 --- a/lib/frenzy_web/controllers/fervor/items_controller.ex +++ b/lib/frenzy_web/controllers/fervor/items_controller.ex @@ -1,12 +1,12 @@ defmodule FrenzyWeb.Fervor.ItemsController do use FrenzyWeb, :controller - alias Frenzy.{Repo, Item} + alias Frenzy.{Repo, Item, Group, Feed} import Ecto.Query alias FrenzyWeb.Fervor.Paginator plug :get_specific_item - def get_specific_item(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) do + def get_specific_item(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) when id != "sync" do user = conn.assigns[:user] |> Repo.preload(:feeds) item = Repo.get(Item, id) @@ -119,4 +119,42 @@ defmodule FrenzyWeb.Fervor.ItemsController do def unread_multiple(conn, params) do mark_multiple_items(conn, params, %{read: false}) end + + def sync(conn, params) do + sync_timestamp = Timex.now() + + feed_ids = + Group + |> where([g], g.user_id == ^conn.assigns.user.id) + |> join(:inner, [g], f in Feed, on: f.group_id == g.id) + |> select([g, f], f.id) + |> Repo.all() + + last_sync = + Map.get(params, "last_sync") + |> case do + s when is_binary(s) -> Timex.parse!(s, "{ISO:Extended:Z}") + _ -> nil + end + + {deleted_ids, upserted} = + case last_sync do + nil -> + items = Repo.all(from i in Item, where: not i.tombstone and i.feed_id in ^feed_ids) + {[], items} + + _ -> + all_items = + Repo.all(from i in Item, where: i.feed_id in ^feed_ids and i.updated_at >= ^last_sync) + + {tombstones, rest} = Enum.split_with(all_items, & &1.tombstone) + {Enum.map(tombstones, & &1.id), rest} + end + + json(conn, %{ + sync_timestamp: Timex.format!(sync_timestamp, "{ISO:Extended:Z}"), + delete: Enum.map(deleted_ids, &to_string/1), + upsert: Enum.map(upserted, &Item.to_fervor/1) + }) + end end diff --git a/lib/frenzy_web/router.ex b/lib/frenzy_web/router.ex index 39c161e..c5a0a27 100644 --- a/lib/frenzy_web/router.ex +++ b/lib/frenzy_web/router.ex @@ -99,6 +99,7 @@ defmodule FrenzyWeb.Router do post "/api/v1/feeds/:id/delete", FeedsController, :delete get "/api/v1/items", ItemsController, :items_list + get "/api/v1/items/sync", ItemsController, :sync get "/api/v1/items/:id", ItemsController, :specific_item post "/api/v1/items/:id/read", ItemsController, :read_specific_item post "/api/v1/items/:id/unread", ItemsController, :unread_specific_item