api: add pagination (limit/offset) and downloaded filter to media endpoint
The /api/v1/media endpoint was loading ALL media items from the database with no pagination, causing timeouts with large libraries (1800+ items per source). Now supports: - ?limit=N (default 50) - ?offset=N (default 0) - ?downloaded=true (filter to only downloaded media) - Ordered by uploaded_at desc
This commit is contained in:
@@ -23,8 +23,20 @@ defmodule Pinchflat.Media do
|
|||||||
|
|
||||||
Returns [%MediaItem{}, ...].
|
Returns [%MediaItem{}, ...].
|
||||||
"""
|
"""
|
||||||
def list_media_items do
|
def list_media_items(opts \\ []) do
|
||||||
Repo.all(MediaItem)
|
limit = Keyword.get(opts, :limit, 50)
|
||||||
|
offset = Keyword.get(opts, :offset, 0)
|
||||||
|
downloaded_only = Keyword.get(opts, :downloaded_only, false)
|
||||||
|
|
||||||
|
query = from mi in MediaItem, limit: ^limit, offset: ^offset, order_by: [desc: mi.uploaded_at]
|
||||||
|
|
||||||
|
query = if downloaded_only do
|
||||||
|
from mi in query, where: not is_nil(mi.media_downloaded_at)
|
||||||
|
else
|
||||||
|
query
|
||||||
|
end
|
||||||
|
|
||||||
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
@@ -72,8 +84,20 @@ defmodule Pinchflat.Media do
|
|||||||
|
|
||||||
Returns [%MediaItem{}, ...].
|
Returns [%MediaItem{}, ...].
|
||||||
"""
|
"""
|
||||||
def list_media_items_for_source(source_id) do
|
def list_media_items_for_source(source_id, opts \\ []) do
|
||||||
Repo.all(from mi in MediaItem, where: mi.source_id == ^source_id)
|
limit = Keyword.get(opts, :limit, 50)
|
||||||
|
offset = Keyword.get(opts, :offset, 0)
|
||||||
|
downloaded_only = Keyword.get(opts, :downloaded_only, false)
|
||||||
|
|
||||||
|
query = from mi in MediaItem, where: mi.source_id == ^source_id, limit: ^limit, offset: ^offset, order_by: [desc: mi.uploaded_at]
|
||||||
|
|
||||||
|
query = if downloaded_only do
|
||||||
|
from mi in query, where: not is_nil(mi.media_downloaded_at)
|
||||||
|
else
|
||||||
|
query
|
||||||
|
end
|
||||||
|
|
||||||
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|||||||
@@ -12,13 +12,17 @@ defmodule PinchflatWeb.Api.V1.ApiMediaItemController do
|
|||||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||||
|
|
||||||
def index(conn, params) do
|
def index(conn, params) do
|
||||||
|
limit = parse_param(params, "limit", 50)
|
||||||
|
offset = parse_param(params, "offset", 0)
|
||||||
|
downloaded_only = params["downloaded"] == "true"
|
||||||
|
|
||||||
media_items =
|
media_items =
|
||||||
case params do
|
case params do
|
||||||
%{"source_id" => source_id} ->
|
%{"source_id" => source_id} ->
|
||||||
Media.list_media_items_for_source(source_id)
|
Media.list_media_items_for_source(source_id, limit: limit, offset: offset, downloaded_only: downloaded_only)
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
Media.list_media_items()
|
Media.list_media_items(limit: limit, offset: offset, downloaded_only: downloaded_only)
|
||||||
end
|
end
|
||||||
|
|
||||||
media_items = Repo.preload(media_items, :source)
|
media_items = Repo.preload(media_items, :source)
|
||||||
@@ -93,4 +97,15 @@ defmodule PinchflatWeb.Api.V1.ApiMediaItemController do
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp parse_param(params, key, default) do
|
||||||
|
case Map.get(params, key) do
|
||||||
|
nil -> default
|
||||||
|
value ->
|
||||||
|
case Integer.parse(value) do
|
||||||
|
{n, _} -> n
|
||||||
|
:error -> default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user