diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-03-02 16:14:45 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-03-02 16:41:08 +0100 |
commit | 0dc167611a2f9fecc58b9709487362ceb3eb9752 (patch) | |
tree | 734d1eddcc720b9663852845862095979bc415a9 /ishtar_common/management/commands/ishtar_maintenance.py | |
parent | f4d375c0e76b9d01bf5ac8311c220d5d80a55b41 (diff) | |
download | Ishtar-0dc167611a2f9fecc58b9709487362ceb3eb9752.tar.bz2 Ishtar-0dc167611a2f9fecc58b9709487362ceb3eb9752.zip |
Maintenance scripts: delete deprecated and migrate to ishtar_maintenance
Diffstat (limited to 'ishtar_common/management/commands/ishtar_maintenance.py')
-rw-r--r-- | ishtar_common/management/commands/ishtar_maintenance.py | 135 |
1 files changed, 117 insertions, 18 deletions
diff --git a/ishtar_common/management/commands/ishtar_maintenance.py b/ishtar_common/management/commands/ishtar_maintenance.py index 4f050088e..d57fb575e 100644 --- a/ishtar_common/management/commands/ishtar_maintenance.py +++ b/ishtar_common/management/commands/ishtar_maintenance.py @@ -1,14 +1,18 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- from argparse import RawTextHelpFormatter import csv import datetime import os +import tempfile +import shutil import sys from django.apps import apps from django.conf import settings +from django.contrib.auth.management import create_permissions +from django.core.exceptions import FieldDoesNotExist from django.core.management.base import BaseCommand, CommandError from django.template.defaultfilters import slugify @@ -28,8 +32,12 @@ if not os.path.exists(log_path): os.mkdir(log_path, mode=0o770) -def task_update_search_vectors(quiet=False, log=False): +def task_update_search_vectors(options): + quiet = options.get("quiet", False) + log = options.get("log", False) for model in apps.get_models(): + if options.get('model', None) and model.__name__ != options['model']: + continue if not hasattr(model, "update_search_vector") or \ not (getattr(model, "BASE_SEARCH_VECTORS", None) or getattr(model, "INT_SEARCH_VECTORS", None) or @@ -64,8 +72,12 @@ def task_update_search_vectors(quiet=False, log=False): _end_task(changed_nb, msg, quiet, store_results, log, log_name, csv_cols) -def task_check_cached_label(quiet=False, log=False): +def task_check_cached_label(options): + quiet = options.get("quiet", False) + log = options.get("log", False) for model in apps.get_models(): + if options.get('model', None) and model.__name__ != options['model']: + continue if model.__name__.startswith("Historical"): continue if hasattr(model, "CACHED_LABELS") and model.CACHED_LABELS: @@ -116,6 +128,32 @@ def task_check_cached_label(quiet=False, log=False): _end_task(changed_nb, msg, quiet, store_results, log, log_name, csv_cols) +def task_update_external_id(options): + quiet = options.get("quiet", False) + for model in apps.get_models(): + if options.get('model', None) and model.__name__ != options['model']: + continue + if model.__name__.startswith("Historical"): + continue + if not bool( + [k for k in dir(model) if k == "external_id"]): + continue + msg = "-> processing {}: ".format(model._meta.verbose_name) + ln = model.objects.count() + for idx, item in enumerate(model.objects.all()): + item.skip_history_when_saving = True + item.external_id = "" + item.complete_identifier = "" + item._no_move = True + if not quiet: + cmsg = "\r{} {}/{}".format(msg, idx + 1, ln) + sys.stdout.write(cmsg) + sys.stdout.flush() + item.save() + if not quiet: + sys.stdout.write("\n") + + def _end_task(changed_nb, msg, quiet, store_results, log, log_name, csv_cols): if not quiet: if changed_nb: @@ -134,7 +172,8 @@ def _end_task(changed_nb, msg, quiet, store_results, log, log_name, csv_cols): sys.stdout.write(f"log: {path} written.\n") -def task_main_image(quiet=False, log=False): +def task_main_image(options): + quiet = options.get("quiet", False) for model in apps.get_models(): if not issubclass(model, models_common.DocumentItem): continue @@ -155,14 +194,44 @@ def task_main_image(quiet=False, log=False): sys.stdout.write(f"{nb} main image fixed for {model.__name__}\n") -def task_missing_parcels(quiet=False, log=False): +def task_regenerate_qrcodes(options): + quiet = options.get("quiet", False) + secure = not options['no-https'] + for model in apps.get_models(): + if options.get('model', None) and model.__name__ != options['model']: + continue + try: + model._meta.get_field('qrcode') + except FieldDoesNotExist: + continue + msg = "-> processing {}: ".format(model._meta.verbose_name) + ln = model.objects.count() + tmpdir = tempfile.mkdtemp("-qrcode") + for idx, obj in enumerate(model.objects.all()): + obj.skip_history_when_saving = True + obj._no_move = True + if not quiet: + cmsg = "\r{} {}/{}".format(msg, idx + 1, ln) + sys.stdout.write(cmsg) + sys.stdout.flush() + obj.generate_qrcode(secure=secure, tmpdir=tmpdir) + shutil.rmtree(tmpdir) + if not quiet: + sys.stdout.write("\n") + + +def task_regenerate_permissions(options): + for app in ['ishtar_common', 'archaeological_operations', + 'archaeological_context_records', + 'archaeological_finds', 'archaeological_warehouse']: + create_permissions(apps.get_app_config(app)) + + +def task_missing_parcels(options): + quiet = options.get("quiet", False) Parcel = apps.get_model("archaeological_operations", "Parcel") q = Parcel.objects.filter(context_record__isnull=False, operation=None) nb = q.count() - if not nb: - if not quiet: - sys.stdout.write("No parcel to fix.\n") - return for idx, parcel in enumerate(q.all()): if not quiet: sys.stdout.write(f"\r[{percent(idx, nb)}] {idx + 1}/{nb}") @@ -175,6 +244,13 @@ def task_missing_parcels(quiet=False, log=False): parcel.save() if not quiet: sys.stdout.write("\n") + if not options.get("clean", False): + return + q = Parcel.objects.filter(associated_file=None, operation=None) + nb = q.count() + q.delete() + if not quiet: + sys.stdout.write(f"{nb} orphan parcel deleted.\n") def percent(current, total): @@ -186,21 +262,34 @@ def get_time(): TASKS = { - "main_image": { + "fix_main_image": { "help": "for items with images and no main image, put the first one created as a main image", "action": task_main_image, }, - "cached_label": { - "help": "regenerate cached label on all tables", + "fix_missing_parcels": { + "help": "fix lost parcel association on operation from context records. " + "With --clean option delete orphan parcels.", + "action": task_missing_parcels, + }, + "update_cached_label": { + "help": "regenerate cached label", "action": task_check_cached_label, }, + "update_permissions": { + "help": "regenerate basic model permissions", + "action": task_regenerate_permissions, + }, + "update_qrcodes": { + "help": "regenerate qrcodes", + "action": task_regenerate_qrcodes, + }, "update_search_vector": { - "help": "regenerate search vectors on all tables", + "help": "regenerate search vectors", "action": task_update_search_vectors, }, - "operation_missing_parcels": { - "help": "fix lost parcel association on operation from context records.", - "action": task_missing_parcels, + "update_external_ids": { + "help": "regenerate external and complete ID", + "action": task_update_external_id, }, } @@ -226,22 +315,32 @@ class Command(BaseCommand): ) parser.add_argument("task", help=task_help) parser.add_argument( + '--model', type=str, default='', dest='model', + help='Specific model to update') + parser.add_argument( "--quiet", dest="quiet", action="store_true", help="Quiet output" ) parser.add_argument( "--log", dest="log", action="store_true", help="Log into a file" ) + parser.add_argument( + '--no-https', dest='no-https', action='store_true', + default=False, + help="[update_qrcodes] Use this parameter if https is not available") + parser.add_argument( + '--clean', dest='clean', action='store_true', + default=False, + help="[operation_missing_parcels] Delete orphan parcel after fix") def handle(self, *args, **options): if options["task"] not in TASKS.keys(): msg = f"{options['task']} is not a valid task. Available tasks are:\n" msg += "\n".join(TASKS.keys()) raise CommandError(msg) - log = options["log"] quiet = options["quiet"] if not quiet: sys.stdout.write(f"[{get_time()}] Processing task {options['task']}\n") - errors = TASKS[options["task"]]["action"](quiet=quiet, log=log) + errors = TASKS[options["task"]]["action"](options) if not errors: if not quiet: sys.stdout.write(f"[{get_time()}] Task {options['task']} finished\n") |