|
| 1 | +from click import command, argument, option |
| 2 | +from cloudinary_cli.utils.utils import print_help_and_exit |
| 3 | +from cloudinary_cli.utils.api_utils import handle_api_command, regen_derived_version |
| 4 | +from cloudinary import api |
| 5 | +from cloudinary_cli.utils.utils import confirm_action, run_tasks_concurrently |
| 6 | +from cloudinary_cli.defaults import logger |
| 7 | + |
| 8 | +DEFAULT_MAX_RESULTS = 500 |
| 9 | + |
| 10 | + |
| 11 | +@command("regen_derived", |
| 12 | + short_help="""Regenerate all derived assets pertaining \ |
| 13 | + to a named transformation, or transformation string.""", |
| 14 | + help=""" |
| 15 | +\b |
| 16 | +Regenerate all derived assets pertaining to a specific named transformation, or transformation string. |
| 17 | +Use this after updating a named transformation to invalidate and repopulate the cache with up-to-date versions of the assets. |
| 18 | +Format: cld regen_derived <transformation_name> <command options> |
| 19 | +e.g. cld regen_derived t_named -A -ea -enu http://mywebhook.com |
| 20 | +""") |
| 21 | +@argument("trans_str") |
| 22 | +@option("-enu", "--eager_notification_url", help="Webhook notification URL.") |
| 23 | +@option("-ea", "--eager_async", is_flag=True, default=False, |
| 24 | + help="Generate asynchronously.") |
| 25 | +@option("-A", "--auto_paginate", is_flag=True, default=False, |
| 26 | + help="Auto-paginate Admin API calls.") |
| 27 | +@option("-F", "--force", is_flag=True, |
| 28 | + help="Skip initial and auto-paginate confirmation.") |
| 29 | +@option("-n", "--max_results", nargs=1, default=10, |
| 30 | + help="""The maximum number of results to return. |
| 31 | + Default: 10, maximum: 500.""") |
| 32 | +@option("-w", "--concurrent_workers", type=int, default=30, |
| 33 | + help="Specify the number of concurrent network threads.") |
| 34 | +def regen_derived(trans_str, eager_notification_url, |
| 35 | + eager_async, auto_paginate, force, |
| 36 | + max_results, concurrent_workers): |
| 37 | + |
| 38 | + if not any(trans_str): |
| 39 | + print_help_and_exit() |
| 40 | + |
| 41 | + if not force: |
| 42 | + if not confirm_action( |
| 43 | + f"Running this module will explicity " |
| 44 | + f"re-generate all the related derived assets " |
| 45 | + f"which will cause an increase in your transformation costs " |
| 46 | + f"based on the number of derived assets re-generated.\n" |
| 47 | + f"If running in auto-paginate (-A) mode, " |
| 48 | + f"multiple Admin API (rate-limited) calls will be made.\n" |
| 49 | + f"Continue? (y/N)"): |
| 50 | + logger.info("Stopping.") |
| 51 | + exit() |
| 52 | + else: |
| 53 | + logger.info("Continuing. You may use the -F " |
| 54 | + "flag to skip confirmation.") |
| 55 | + |
| 56 | + if auto_paginate: |
| 57 | + max_results = DEFAULT_MAX_RESULTS |
| 58 | + force = True |
| 59 | + |
| 60 | + params = ('transformation', trans_str, f'max_results={max_results}') |
| 61 | + trans_details = handle_api_command(params, (), (), None, None, None, |
| 62 | + doc_url="", api_instance=api, |
| 63 | + api_name="admin", |
| 64 | + auto_paginate=auto_paginate, |
| 65 | + force=force, return_data=True) |
| 66 | + derived_resources = trans_details.get('derived') |
| 67 | + if not derived_resources: |
| 68 | + logger.info("No derived assets are using this transformation.") |
| 69 | + exit() |
| 70 | + |
| 71 | + is_named = trans_details.get('named') |
| 72 | + eager_trans = normalise_trans_name(trans_str) if is_named else trans_str |
| 73 | + |
| 74 | + progress_msg = f"Regenerating {len(derived_resources)} derived asset(s)" |
| 75 | + if eager_async: |
| 76 | + progress_msg += f" with eager_async={eager_async}" |
| 77 | + logger.info(f"{progress_msg}...") |
| 78 | + |
| 79 | + regen_conc_list = [] |
| 80 | + for derived in derived_resources: |
| 81 | + public_id = derived.get('public_id') |
| 82 | + delivery_type = derived.get('type') |
| 83 | + res_type = derived.get('resource_type') |
| 84 | + regen_conc_list.append((public_id, delivery_type, res_type, |
| 85 | + eager_trans, eager_async, |
| 86 | + eager_notification_url)) |
| 87 | + |
| 88 | + run_tasks_concurrently(regen_derived_version, regen_conc_list, |
| 89 | + concurrent_workers) |
| 90 | + complete_msg = ('Regeneration in progress' |
| 91 | + if eager_async else 'Regeneration complete') |
| 92 | + logger.info(f"{complete_msg}. It may take up to 10 mins " |
| 93 | + "to see the changes. Please contact support " |
| 94 | + "if you still see the old media.") |
| 95 | + return True |
| 96 | + |
| 97 | + |
| 98 | +def normalise_trans_name(trans_name): |
| 99 | + return trans_name if trans_name.startswith('t_') else 't_' + trans_name |
0 commit comments