|
31 | 31 | AWS_S3_BASE_URL,
|
32 | 32 | generate_image_path,
|
33 | 33 | )
|
| 34 | +from tqdm import tqdm |
34 | 35 |
|
35 | 36 | # wger
|
36 | 37 | from wger.core.models.language import Language
|
@@ -247,54 +248,71 @@ def sync_ingredients(
|
247 | 248 | remote_url=settings.WGER_SETTINGS['WGER_INSTANCE'],
|
248 | 249 | language_codes: Optional[str] = None,
|
249 | 250 | style_fn=lambda x: x,
|
| 251 | + show_progress_bar: bool = False, |
250 | 252 | ):
|
251 | 253 | """Synchronize the ingredients from the remote server"""
|
252 |
| - |
253 |
| - def _sync_ingredients(language_codes: Optional[int] = None): |
254 |
| - if language_codes is not None: |
255 |
| - url = make_uri( |
256 |
| - INGREDIENTS_ENDPOINT, |
257 |
| - server_url=remote_url, |
258 |
| - query={'limit': API_MAX_ITEMS, 'language__in': language_codes}, |
259 |
| - ) |
260 |
| - else: |
261 |
| - url = make_uri( |
262 |
| - INGREDIENTS_ENDPOINT, |
263 |
| - server_url=remote_url, |
264 |
| - query={'limit': API_MAX_ITEMS}, |
265 |
| - ) |
266 |
| - for data in get_paginated(url, headers=wger_headers()): |
267 |
| - uuid = data['uuid'] |
268 |
| - name = data['name'] |
269 |
| - |
270 |
| - ingredient_data = extract_info_from_wger_api(data).dict() |
271 |
| - ingredient_data['uuid'] = uuid |
272 |
| - |
273 |
| - ingredient, created = Ingredient.objects.update_or_create( |
274 |
| - uuid=uuid, defaults=ingredient_data |
275 |
| - ) |
276 |
| - |
277 |
| - print_fn(f'{"created" if created else "updated"} ingredient {uuid} - {name}') |
278 |
| - |
279 | 254 | print_fn('*** Synchronizing ingredients...')
|
280 | 255 |
|
| 256 | + language_ids: List[str] | None = None |
281 | 257 | if language_codes is not None:
|
282 |
| - language_ids: List[int] = [] |
| 258 | + language_ids = [] |
283 | 259 | for code in language_codes.split(','):
|
284 | 260 | # Leaving the try except in here even though we've already validated on the sync-ingredients command itself.
|
285 | 261 | # This is in case we ever want to re-use this function for anything else where user can input language codes.
|
286 | 262 | try:
|
287 | 263 | lang = load_language(code, default_to_english=False)
|
288 |
| - language_ids.append(lang.id) |
| 264 | + language_ids.append(str(lang.id)) |
289 | 265 | except Language.DoesNotExist as e:
|
290 | 266 | print_fn(
|
291 | 267 | f'Error: The language code you provided ("{code}") does not exist in this database. Please try again.'
|
292 | 268 | )
|
293 | 269 | return 0
|
294 | 270 |
|
295 |
| - for language_id in language_ids: |
296 |
| - _sync_ingredients(language_id) |
297 |
| - else: |
298 |
| - _sync_ingredients() |
| 271 | + query: dict[str, str | int] = {'limit': API_MAX_ITEMS} |
| 272 | + if language_ids is not None: |
| 273 | + query['language__in'] = ','.join(language_ids) |
| 274 | + |
| 275 | + url = make_uri( |
| 276 | + INGREDIENTS_ENDPOINT, |
| 277 | + server_url=remote_url, |
| 278 | + query=query, |
| 279 | + ) |
| 280 | + |
| 281 | + # Fetch once to retrieve the number of results |
| 282 | + response = requests.get(url, headers=wger_headers()).json() |
| 283 | + total_ingredients = response['count'] |
| 284 | + total_pages = total_ingredients // API_MAX_ITEMS |
| 285 | + |
| 286 | + ingredient_nr = 1 |
| 287 | + page_nr = 1 |
| 288 | + pbar = tqdm( |
| 289 | + total=total_ingredients, |
| 290 | + unit='ingredients', |
| 291 | + desc='Syncing progress', |
| 292 | + unit_scale=True |
| 293 | + ) |
| 294 | + for data in get_paginated(url, headers=wger_headers()): |
| 295 | + uuid = data['uuid'] |
| 296 | + |
| 297 | + ingredient_data = extract_info_from_wger_api(data).dict() |
| 298 | + ingredient_data['uuid'] = uuid |
| 299 | + |
| 300 | + Ingredient.objects.update_or_create( |
| 301 | + uuid=uuid, |
| 302 | + defaults=ingredient_data |
| 303 | + ) |
| 304 | + |
| 305 | + if show_progress_bar: |
| 306 | + pbar.update(1) |
| 307 | + else: |
| 308 | + # Note that get_paginated returns the individual result entries from the pages. |
| 309 | + # To get the current page, we need to calculate this ourselves. |
| 310 | + ingredient_nr += 1 |
| 311 | + if ingredient_nr % API_MAX_ITEMS == 0: |
| 312 | + page_nr += 1 |
| 313 | + print_fn(f'Processing ingredients, page {page_nr: >4} of {total_pages}') |
| 314 | + |
| 315 | + pbar.close() |
299 | 316 |
|
300 | 317 | print_fn(style_fn('done!\n'))
|
| 318 | + return None |
0 commit comments