Skip to content

Commit

Permalink
[Fixes #12369] Create a command to regenerate the XML metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
etj committed Jul 9, 2024
1 parent 7a99ec8 commit 9750436
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 2 deletions.
34 changes: 34 additions & 0 deletions geonode/base/management/command_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import logging
from django.conf import settings

Check warning on line 2 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L1-L2

Added lines #L1 - L2 were not covered by tests

DEFAULT_COMMAND_LOGGER_NAME = "geonode.commands"

Check warning on line 4 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L4

Added line #L4 was not covered by tests


def setup_logger(logger_name=DEFAULT_COMMAND_LOGGER_NAME, formatter_name="command", handler_name="command"):

Check warning on line 7 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L7

Added line #L7 was not covered by tests
if logger_name not in settings.LOGGING["loggers"]:
format = "%(levelname)-7s %(asctime)s %(message)s"

Check warning on line 9 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L9

Added line #L9 was not covered by tests

settings.LOGGING["formatters"][formatter_name] = {

Check warning on line 11 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L11

Added line #L11 was not covered by tests
"format": format
}
settings.LOGGING["handlers"][handler_name] = {

Check warning on line 14 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L14

Added line #L14 was not covered by tests
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": formatter_name
}
settings.LOGGING["loggers"][logger_name] = {

Check warning on line 19 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L19

Added line #L19 was not covered by tests
"handlers": [handler_name],
"level": "INFO",
"propagate": False
}

handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(fmt=format))
handler.setLevel(logging.DEBUG)

Check warning on line 27 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L25-L27

Added lines #L25 - L27 were not covered by tests

logger = logging.getLogger(logger_name)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.propagate = False

Check warning on line 32 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L29-L32

Added lines #L29 - L32 were not covered by tests

return logger

Check warning on line 34 in geonode/base/management/command_utils.py

View check run for this annotation

Codecov / codecov/patch

geonode/base/management/command_utils.py#L34

Added line #L34 was not covered by tests
Empty file.
Empty file.
126 changes: 126 additions & 0 deletions geonode/catalogue/management/commands/regenerate_xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2023 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

import logging

Check warning on line 21 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L21

Added line #L21 was not covered by tests

from django.core.management.base import BaseCommand

Check warning on line 23 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L23

Added line #L23 was not covered by tests

from geonode.base.management import command_utils
from geonode.base.models import ResourceBase
from geonode.layers.models import Dataset

Check warning on line 27 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L25-L27

Added lines #L25 - L27 were not covered by tests


logger = logging.getLogger(__name__)

Check warning on line 30 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L30

Added line #L30 was not covered by tests


class Command(BaseCommand):
help = "Re-create XML metadata documents"

Check warning on line 34 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L33-L34

Added lines #L33 - L34 were not covered by tests

def add_arguments(self, parser):
parser.add_argument(

Check warning on line 37 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L36-L37

Added lines #L36 - L37 were not covered by tests
'-l',
'--layer',
dest="layers",
action='append',
help="Only process specified layers ")

parser.add_argument(

Check warning on line 44 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L44

Added line #L44 was not covered by tests
"--skip-logger-setup",
action="store_false",
dest="setup_logger",
help='Skips setup of the "geonode.br" logger, "br" handler and "br" format if not present in settings',
)
parser.add_argument(

Check warning on line 50 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L50

Added line #L50 was not covered by tests
'-d',
'--dry-run',
dest="dry-run",
action='store_true',
help="Do not actually perform any change")

def handle(self, **options):
requested_layers = options.get('layers')
dry_run = options.get('dry-run')

Check warning on line 59 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L57-L59

Added lines #L57 - L59 were not covered by tests

if options.get("setup_logger"):
logger = command_utils.setup_logger()

Check warning on line 62 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L62

Added line #L62 was not covered by tests

logger.info(f"==== Running command {__name__}")
logger.info(f"{self.help}")
logger.info("")

Check warning on line 66 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L64-L66

Added lines #L64 - L66 were not covered by tests

logger.debug(f"DRY-RUN is {dry_run}")
logger.debug(f"LAYERS is {requested_layers}")

Check warning on line 69 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L68-L69

Added lines #L68 - L69 were not covered by tests

try:

Check warning on line 71 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L71

Added line #L71 was not covered by tests

layers = Dataset.objects.all()
tot = len(layers)
logger.info(f"Total layers in GeoNode: {tot}")
i = 0
cnt_ok = 0
cnt_bad = 0
cnt_skip = 0

Check warning on line 79 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L73-L79

Added lines #L73 - L79 were not covered by tests

instance: ResourceBase
for instance in layers:
i += 1
logger.info(f"- {i}/{tot} Processing layer {instance.id} [{instance.typename}] '{instance.title}'")

Check warning on line 84 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L83-L84

Added lines #L83 - L84 were not covered by tests

if requested_layers and instance.typename not in requested_layers:
logger.info(" - Layer filtered out by args")
cnt_skip += 1
continue

Check warning on line 89 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L87-L89

Added lines #L87 - L89 were not covered by tests

if instance.metadata_uploaded and instance.metadata_uploaded_preserve:
logger.info(" - Layer filtered out since it uses custom XML")
cnt_skip += 1
continue

Check warning on line 94 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L92-L94

Added lines #L92 - L94 were not covered by tests

try:
good = None

Check warning on line 97 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L96-L97

Added lines #L96 - L97 were not covered by tests
if not dry_run:
try:
try:

Check warning on line 100 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L99-L100

Added lines #L99 - L100 were not covered by tests
# the save() method triggers the metadata regeneration
instance.save()
good = True
except Exception as e:
logger.error(f"Error saving instance '{instance.title}': {e}")
raise e

Check warning on line 106 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L102-L106

Added lines #L102 - L106 were not covered by tests

except Exception as e:
logger.exception(f"Error processing '{instance.title}': {e}", e)

Check warning on line 109 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L108-L109

Added lines #L108 - L109 were not covered by tests

if dry_run or good:
logger.info(f" - Done {instance.name}")
cnt_ok += 1

Check warning on line 113 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L112-L113

Added lines #L112 - L113 were not covered by tests
else:
logger.warning(f"Metadata couldn't be regenerated for instance '{instance.title}' ")
cnt_bad += 1

Check warning on line 116 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L115-L116

Added lines #L115 - L116 were not covered by tests

except Exception as e:
raise e
except Exception as e:
raise e

Check warning on line 121 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L118-L121

Added lines #L118 - L121 were not covered by tests

logger.info("Work completed" + (" [DRYRUN]" if dry_run else ""))
logger.info(f"- Metadata regenerated : {cnt_ok}")
logger.info(f"- Metadata in error : {cnt_bad}")
logger.info(f"- Resources skipped : {cnt_skip}")

Check warning on line 126 in geonode/catalogue/management/commands/regenerate_xml.py

View check run for this annotation

Codecov / codecov/patch

geonode/catalogue/management/commands/regenerate_xml.py#L123-L126

Added lines #L123 - L126 were not covered by tests
7 changes: 5 additions & 2 deletions geonode/catalogue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,14 @@ def catalogue_post_save(instance, sender, **kwargs):
resource=resources.get(), url=metadata_url, extension="xml", link_type="metadata"
).update(**_d)

# generate an XML document (GeoNode's default is ISO)
if instance.metadata_uploaded and instance.metadata_uploaded_preserve:
md_doc = etree.tostring(dlxml.fromstring(instance.metadata_xml))
else:
md_doc = catalogue.catalogue.csw_gen_xml(instance, settings.CATALOG_METADATA_TEMPLATE)
# generate an XML document (GeoNode's default is ISO)
raw_xml = catalogue.catalogue.csw_gen_xml(instance, settings.CATALOG_METADATA_TEMPLATE)
md_obj = dlxml.fromstring(raw_xml, parser=etree.XMLParser(remove_blank_text=True))
md_doc = etree.tostring(md_obj, pretty_print=True, encoding="unicode")

try:
csw_anytext = catalogue.catalogue.csw_gen_anytext(md_doc)
except Exception as e:
Expand Down

0 comments on commit 9750436

Please sign in to comment.