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{}, ...].
|
||||
"""
|
||||
def list_media_items do
|
||||
Repo.all(MediaItem)
|
||||
def list_media_items(opts \\ []) do
|
||||
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
|
||||
|
||||
@doc """
|
||||
@@ -72,8 +84,20 @@ defmodule Pinchflat.Media do
|
||||
|
||||
Returns [%MediaItem{}, ...].
|
||||
"""
|
||||
def list_media_items_for_source(source_id) do
|
||||
Repo.all(from mi in MediaItem, where: mi.source_id == ^source_id)
|
||||
def list_media_items_for_source(source_id, opts \\ []) do
|
||||
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
|
||||
|
||||
@doc """
|
||||
|
||||
@@ -12,13 +12,17 @@ defmodule PinchflatWeb.Api.V1.ApiMediaItemController do
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
|
||||
def index(conn, params) do
|
||||
limit = parse_param(params, "limit", 50)
|
||||
offset = parse_param(params, "offset", 0)
|
||||
downloaded_only = params["downloaded"] == "true"
|
||||
|
||||
media_items =
|
||||
case params do
|
||||
%{"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
|
||||
|
||||
media_items = Repo.preload(media_items, :source)
|
||||
@@ -93,4 +97,15 @@ defmodule PinchflatWeb.Api.V1.ApiMediaItemController do
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user