mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2026-07-30 15:28:30 -04:00
Implement pagination and visibility settings in Immich integration. Updated tests to validate new behavior and ensure correct handling of multiple pages in album metadata retrieval.
This commit is contained in:
@@ -43,6 +43,9 @@ class ImmichViewTests(TestCase):
|
||||
_, kwargs = mock_post.call_args
|
||||
self.assertEqual(kwargs['json']['takenAfter'], '2024-06-15T00:00:00.000Z')
|
||||
self.assertEqual(kwargs['json']['takenBefore'], '2024-06-16T00:00:00.000Z')
|
||||
self.assertEqual(kwargs['json']['visibility'], 'timeline')
|
||||
self.assertEqual(kwargs['json']['page'], 1)
|
||||
self.assertEqual(kwargs['json']['size'], 1000)
|
||||
|
||||
@patch('integrations.views.immich_view.requests.get')
|
||||
@patch('integrations.views.immich_view.requests.post')
|
||||
@@ -72,8 +75,53 @@ class ImmichViewTests(TestCase):
|
||||
mock_post.assert_called_once()
|
||||
_, kwargs = mock_post.call_args
|
||||
self.assertEqual(kwargs['json']['albumIds'], ['album-1'])
|
||||
self.assertEqual(kwargs['json']['visibility'], 'timeline')
|
||||
self.assertEqual(len(response.data['results']), 2)
|
||||
|
||||
@patch('integrations.views.immich_view.requests.get')
|
||||
@patch('integrations.views.immich_view.requests.post')
|
||||
def test_album_metadata_search_paginates_past_first_page(self, mock_post, mock_get):
|
||||
mock_get_response = MagicMock()
|
||||
mock_get_response.json.return_value = {
|
||||
'id': 'album-1',
|
||||
'albumName': 'Large Album',
|
||||
}
|
||||
mock_get.return_value = mock_get_response
|
||||
|
||||
first_page_response = MagicMock()
|
||||
first_page_response.ok = True
|
||||
first_page_response.json.return_value = {
|
||||
'assets': {
|
||||
'items': [{'id': f'asset-{index}'} for index in range(1000)],
|
||||
'nextPage': '2',
|
||||
}
|
||||
}
|
||||
|
||||
second_page_response = MagicMock()
|
||||
second_page_response.ok = True
|
||||
second_page_response.json.return_value = {
|
||||
'assets': {
|
||||
'items': [{'id': 'asset-1000'}, {'id': 'asset-1001'}],
|
||||
'nextPage': None,
|
||||
}
|
||||
}
|
||||
|
||||
mock_post.side_effect = [first_page_response, second_page_response]
|
||||
|
||||
request = self.factory.get('/api/integrations/immich/albums/album-1/')
|
||||
force_authenticate(request, user=self.user)
|
||||
|
||||
response = self.album_view(request, albumid='album-1')
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(mock_post.call_count, 2)
|
||||
first_call_kwargs = mock_post.call_args_list[0].kwargs
|
||||
second_call_kwargs = mock_post.call_args_list[1].kwargs
|
||||
self.assertEqual(first_call_kwargs['json']['page'], 1)
|
||||
self.assertEqual(second_call_kwargs['json']['page'], 2)
|
||||
self.assertEqual(len(response.data['results']), 25)
|
||||
self.assertEqual(response.data['count'], 1002)
|
||||
|
||||
@patch('integrations.views.immich_view.requests.get')
|
||||
def test_album_uses_inline_assets_when_available(self, mock_get):
|
||||
mock_get_response = MagicMock()
|
||||
|
||||
@@ -17,6 +17,7 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
IMMICH_SEARCH_SIZE = 1000
|
||||
IMMICH_SEARCH_VISIBILITY = 'timeline'
|
||||
|
||||
class ImmichIntegrationView(viewsets.ViewSet):
|
||||
permission_classes = [IsAuthenticated]
|
||||
@@ -98,29 +99,60 @@ class ImmichIntegrationView(viewsets.ViewSet):
|
||||
search_type='metadata',
|
||||
not_found_code='immich.no_items_found',
|
||||
):
|
||||
try:
|
||||
url = f'{integration.server_url}/search/{search_type}'
|
||||
immich_fetch = requests.post(
|
||||
url,
|
||||
headers={'x-api-key': integration.api_key},
|
||||
json={'size': IMMICH_SEARCH_SIZE, **arguments},
|
||||
)
|
||||
res = immich_fetch.json()
|
||||
except requests.exceptions.ConnectionError:
|
||||
return self._immich_connection_error()
|
||||
url = f'{integration.server_url}/search/{search_type}'
|
||||
items = []
|
||||
page = 1
|
||||
|
||||
if not immich_fetch.ok:
|
||||
logger.warning(
|
||||
'Immich search request failed: status=%s response=%s',
|
||||
immich_fetch.status_code,
|
||||
res,
|
||||
)
|
||||
return self._immich_no_items_error(code=not_found_code)
|
||||
while True:
|
||||
try:
|
||||
immich_fetch = requests.post(
|
||||
url,
|
||||
headers={'x-api-key': integration.api_key},
|
||||
json={
|
||||
'size': IMMICH_SEARCH_SIZE,
|
||||
'page': page,
|
||||
'visibility': IMMICH_SEARCH_VISIBILITY,
|
||||
**arguments,
|
||||
},
|
||||
)
|
||||
res = immich_fetch.json()
|
||||
except requests.exceptions.ConnectionError:
|
||||
return self._immich_connection_error()
|
||||
|
||||
if 'assets' in res and 'items' in res['assets']:
|
||||
items = res['assets']['items']
|
||||
if items:
|
||||
return self._paginate_immich_assets(integration, request, items)
|
||||
if not immich_fetch.ok:
|
||||
logger.warning(
|
||||
'Immich search request failed: status=%s response=%s',
|
||||
immich_fetch.status_code,
|
||||
res,
|
||||
)
|
||||
return self._immich_no_items_error(code=not_found_code)
|
||||
|
||||
assets = res.get('assets')
|
||||
if not isinstance(assets, dict):
|
||||
break
|
||||
|
||||
page_items = assets.get('items') or []
|
||||
if page_items:
|
||||
items.extend(page_items)
|
||||
|
||||
next_page = assets.get('nextPage')
|
||||
if next_page:
|
||||
try:
|
||||
page = int(next_page)
|
||||
continue
|
||||
except (TypeError, ValueError):
|
||||
logger.warning(
|
||||
'Immich search returned invalid nextPage value: %s',
|
||||
next_page,
|
||||
)
|
||||
|
||||
if len(page_items) < IMMICH_SEARCH_SIZE:
|
||||
break
|
||||
|
||||
page += 1
|
||||
|
||||
if items:
|
||||
return self._paginate_immich_assets(integration, request, items)
|
||||
|
||||
return self._immich_no_items_error(code=not_found_code)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export let appVersion = 'v0.13.0-beta-072126';
|
||||
export let appVersion = 'v0.13.0-beta-072226';
|
||||
export let appCodename = 'Acadia';
|
||||
export let versionChangelog = 'https://github.com/seanmorley15/AdventureLog/releases/tag/v0.12.1';
|
||||
export let appTitle = 'AdventureLog';
|
||||
|
||||
Reference in New Issue
Block a user