diff --git a/docs/conf.py b/docs/conf.py index 1d759d6de..524da85e7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import sys from unittest.mock import MagicMock # If extensions (or modules to document with autodoc) are in another directory, diff --git a/pycsw/core/metadata.py b/pycsw/core/metadata.py index 4c1cf5785..d12148736 100644 --- a/pycsw/core/metadata.py +++ b/pycsw/core/metadata.py @@ -242,7 +242,8 @@ def _parse_csw(context, repos, record, identifier, pagesize=10): md.getrecords2(typenames=csw_typenames, resulttype='hits', outputschema=csw_outputschema) matches = md.results['matches'] - except: # this is a CSW, but server rejects query + except Exception: # this is a CSW, but server rejects query + LOGGER.debug('CSW query failed') raise RuntimeError(md.response) if pagesize > matches: @@ -1241,7 +1242,8 @@ def _parse_fgdc(context, repos, exml): try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) - except: # coordinates are corrupted, do not include + except Exception: + LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) @@ -1321,7 +1323,8 @@ def get_value_by_language(pt_group, language, pt_type='text'): data.geographic_bounding_box.east_bound_longitude, data.geographic_bounding_box.north_bound_latitude) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) - except: # coordinates are corrupted, do not include + except Exception: + LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) @@ -1608,7 +1611,8 @@ def _parse_iso(context, repos, exml): try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) - except: # coordinates are corrupted, do not include + except Exception: + LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) @@ -1686,7 +1690,8 @@ def _parse_dc(context, repos, exml): try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) - except: # coordinates are corrupted, do not include + except Exception: + LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) diff --git a/pycsw/ogc/csw/csw2.py b/pycsw/ogc/csw/csw2.py index 049af4adc..e3182b362 100644 --- a/pycsw/ogc/csw/csw2.py +++ b/pycsw/ogc/csw/csw2.py @@ -31,16 +31,10 @@ # ================================================================= import os -import sys -import cgi -from urllib.parse import quote, unquote -from io import StringIO from pycsw.core.etree import etree -from pycsw import oaipmh, opensearch, sru +from pycsw import opensearch from pycsw.ogc.csw.cql import cql2fes -from pycsw.plugins.profiles import profile as pprofile -import pycsw.plugins.outputschemas -from pycsw.core import config, log, metadata, util +from pycsw.core import metadata, util from pycsw.core.formats.fmt_json import xml2dict from pycsw.ogc.fes import fes1 import logging @@ -517,7 +511,8 @@ def getdomain(self): self.parent.context.namespaces)).text = pname try: operation, parameter = pname.split('.') - except: + except Exception as err: + LOGGER.debug(f'Cannot split pname: {err}') return node if (operation in self.parent.context.model['operations'].keys() and parameter in @@ -540,7 +535,8 @@ def getdomain(self): else: # it's a core queryable, map to internal typename model try: pname2 = self.parent.repository.queryables['_all'][pname]['dbcol'] - except: + except Exception as err: + LOGGER.debug(f'pname2 not found: {err}') pname2 = pname # decipher typename @@ -780,7 +776,7 @@ def getrecords(self): try: name, order = tmp.rsplit(':', 1) - except: + except Exception: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: must be in the format\ propertyname:A or propertyname:D') @@ -1989,7 +1985,8 @@ def exceptionreport(self, code, locator, text): try: language = self.parent.config['server'].get('language') ogc_schemas_base = self.parent.config['server'].get('ogc_schemas_base') - except: + except Exception: + LOGGER.debug('Dropping to default language and OGC schemas base') language = 'en-US' ogc_schemas_base = self.parent.context.ogc_schemas_base @@ -2023,7 +2020,8 @@ def write_boundingbox(bbox, nsmap): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None if len(bbox2) == 4: diff --git a/pycsw/ogc/csw/csw3.py b/pycsw/ogc/csw/csw3.py index 28bef1826..2438d3255 100644 --- a/pycsw/ogc/csw/csw3.py +++ b/pycsw/ogc/csw/csw3.py @@ -28,19 +28,12 @@ # # ================================================================= -import json import os -import sys -import cgi from time import time -from urllib.parse import quote, unquote -from io import StringIO from pycsw.core.etree import etree from pycsw.ogc.csw.cql import cql2fes -from pycsw import oaipmh, opensearch, sru -from pycsw.plugins.profiles import profile as pprofile -import pycsw.plugins.outputschemas -from pycsw.core import config, log, metadata, util +from pycsw import opensearch +from pycsw.core import metadata, util from pycsw.core.formats.fmt_json import xml2dict from pycsw.ogc.fes import fes1, fes2 import logging @@ -113,7 +106,8 @@ def getcapabilities(self): try: updatesequence = \ util.get_time_iso2unix(self.parent.repository.query_insert()) - except: + except Exception as err: + LOGGER.debug(f'Cannot set updatesequence: {err}') updatesequence = None node = etree.Element(util.nspath_eval('csw30:Capabilities', @@ -512,7 +506,8 @@ def getdomain(self): self.parent.context.namespaces)).text = pname try: operation, parameter = pname.split('.') - except: + except Exception as err: + LOGGER.debug(f'pname2 not found: {err}') return node if (operation in self.parent.context.model['operations'] and parameter in self.parent.context.model['operations'][operation]['parameters']): @@ -534,8 +529,8 @@ def getdomain(self): else: # it's a core queryable, map to internal typename model try: pname2 = self.parent.repository.queryables['_all'][pname]['dbcol'] - except: - pname2 = pname + except Exception as err: + LOGGER.debug(f'pname2 not found: {err}') # decipher typename dvtype = None @@ -810,7 +805,7 @@ def getrecords(self): try: name, order = tmp.rsplit(':', 1) - except: + except Exception: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: must be in the format\ propertyname:A or propertyname:D') @@ -2079,7 +2074,8 @@ def exceptionreport(self, code, locator, text): try: language = self.parent.config['server'].get('language') ogc_schemas_base = self.parent.config['server'].get('ogc_schemas_base') - except: + except Exception: + LOGGER.debug('Dropping to default language and OGC schemas base') language = 'en-US' ogc_schemas_base = self.parent.context.ogc_schemas_base @@ -2157,7 +2153,8 @@ def write_boundingbox(bbox, nsmap): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None if len(bbox2) == 4: diff --git a/pycsw/ogc/fes/fes1.py b/pycsw/ogc/fes/fes1.py index 2e443d84b..acb79e1e4 100644 --- a/pycsw/ogc/fes/fes1.py +++ b/pycsw/ogc/fes/fes1.py @@ -4,7 +4,7 @@ # Authors: Tom Kralidis # Angelos Tzotsos # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person @@ -416,7 +416,6 @@ def set_spatial_ranking(geometry): util.ranking_pass = True util.ranking_query_geometry = geometry.wkt elif geometry.type in ['LineString', 'Point']: - from shapely.geometry.base import BaseGeometry from shapely.geometry import box from shapely.wkt import loads,dumps ls = loads(geometry.wkt) diff --git a/pycsw/ogc/fes/fes2.py b/pycsw/ogc/fes/fes2.py index a29dcb946..7ce00d19b 100644 --- a/pycsw/ogc/fes/fes2.py +++ b/pycsw/ogc/fes/fes2.py @@ -4,7 +4,7 @@ # Authors: Tom Kralidis # Angelos Tzotsos # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person @@ -434,7 +434,6 @@ def set_spatial_ranking(geometry): util.ranking_pass = True util.ranking_query_geometry = geometry.wkt elif geometry.type in ['LineString', 'Point']: - from shapely.geometry.base import BaseGeometry from shapely.geometry import box from shapely.wkt import loads,dumps ls = loads(geometry.wkt) diff --git a/pycsw/ogc/gml/gml3.py b/pycsw/ogc/gml/gml3.py index f6edd4d16..ff51c2b8c 100644 --- a/pycsw/ogc/gml/gml3.py +++ b/pycsw/ogc/gml/gml3.py @@ -209,8 +209,9 @@ def transform(self, src, dest): proj_src = 'epsg:%s' % src proj_dst = 'epsg:%s' % dest transformer = Transformer.from_crs(proj_src, proj_dst, always_xy=True) - except: - raise RuntimeError('Invalid projection transformation') + except Exception as err: + msg = f'Invalid projection transformation: {err}' + raise RuntimeError(msg) geom = loads(self.wkt) diff --git a/pycsw/ogc/gml/gml32.py b/pycsw/ogc/gml/gml32.py index 2cc18d900..4fbb07011 100644 --- a/pycsw/ogc/gml/gml32.py +++ b/pycsw/ogc/gml/gml32.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -28,7 +28,6 @@ # # ================================================================= -from copy import deepcopy import logging from owslib import crs @@ -213,8 +212,9 @@ def transform(self, src, dest): proj_src = 'epsg:%s' % src proj_dst = 'epsg:%s' % dest transformer = Transformer.from_crs(proj_src, proj_dst, always_xy=True) - except: - raise RuntimeError('Invalid projection transformation') + except Exception as err: + msg = f'Invalid projection transformation: {err}' + raise RuntimeError(msg) geom = loads(self.wkt) diff --git a/pycsw/opensearch.py b/pycsw/opensearch.py index 167ba3143..1b558a153 100644 --- a/pycsw/opensearch.py +++ b/pycsw/opensearch.py @@ -31,7 +31,6 @@ # ================================================================= import logging -from urllib.parse import urlencode from pycsw.core import util from pycsw.core.etree import etree diff --git a/pycsw/plugins/outputschemas/atom.py b/pycsw/plugins/outputschemas/atom.py index 927901706..245296545 100644 --- a/pycsw/plugins/outputschemas/atom.py +++ b/pycsw/plugins/outputschemas/atom.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -28,7 +28,6 @@ # # ================================================================= -import os from pycsw.core import util from pycsw.core.etree import etree @@ -132,7 +131,8 @@ def write_extent(bbox, nsmap): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None where = etree.Element(util.nspath_eval('georss:where', NAMESPACES)) envelope = etree.SubElement(where, util.nspath_eval('gml:Envelope', nsmap), srsName='http://www.opengis.net/def/crs/EPSG/0/4326') diff --git a/pycsw/plugins/outputschemas/datacite.py b/pycsw/plugins/outputschemas/datacite.py index da372c04b..b005d63a3 100644 --- a/pycsw/plugins/outputschemas/datacite.py +++ b/pycsw/plugins/outputschemas/datacite.py @@ -11,7 +11,7 @@ # # This module intends to follow DataCite 4.3 # -# PyCSW Copyright (C) 2015 Tom Kralidis +# PyCSW Copyright (C) 2024 Tom Kralidis # Schema Copyright (C) 2016 CERN # Schema Copyright (C) 2019 Caltech # @@ -341,7 +341,8 @@ def write_record(result, esn, context, url=None): if bbox not in [None, '']: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None bounds = etree.SubElement(node, util.nspath_eval('geoLocations', NAMESPACES)) bound = etree.SubElement(bounds, util.nspath_eval('geoLocation', NAMESPACES)) diff --git a/pycsw/plugins/outputschemas/dif.py b/pycsw/plugins/outputschemas/dif.py index 12c3a2c7e..7ffdcb622 100644 --- a/pycsw/plugins/outputschemas/dif.py +++ b/pycsw/plugins/outputschemas/dif.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -198,12 +198,11 @@ def write_record(result, esn, context, url=None): def write_extent(bbox, nsmap): ''' Generate BBOX extent ''' - from shapely.wkt import loads - if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None extent = etree.Element(util.nspath_eval('dif:Spatial_Coverage', nsmap)) etree.SubElement(extent, util.nspath_eval('dif:Southernmost_Latitude', nsmap)).text = str(bbox2[1]) diff --git a/pycsw/plugins/outputschemas/fgdc.py b/pycsw/plugins/outputschemas/fgdc.py index 1d43d07d1..bd0dccc49 100644 --- a/pycsw/plugins/outputschemas/fgdc.py +++ b/pycsw/plugins/outputschemas/fgdc.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -166,7 +166,8 @@ def write_extent(bbox): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None spdom = etree.Element('spdom') diff --git a/pycsw/plugins/outputschemas/gm03.py b/pycsw/plugins/outputschemas/gm03.py index 9cfeeabef..bb207caaa 100644 --- a/pycsw/plugins/outputschemas/gm03.py +++ b/pycsw/plugins/outputschemas/gm03.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -228,7 +228,8 @@ def write_extent(bbox, nsmap): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None bounding_box = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox', NAMESPACES)) etree.SubElement(bounding_box, util.nspath_eval('gm03:northBoundLatitude', nsmap)).text = str(bbox2[3]) diff --git a/pycsw/plugins/profiles/apiso/apiso.py b/pycsw/plugins/profiles/apiso/apiso.py index 03b507feb..c95d045aa 100644 --- a/pycsw/plugins/profiles/apiso/apiso.py +++ b/pycsw/plugins/profiles/apiso/apiso.py @@ -31,7 +31,7 @@ # ================================================================= import os -from pycsw.core import config, util +from pycsw.core import util from pycsw.core.etree import etree from pycsw.plugins.profiles import profile @@ -707,7 +707,8 @@ def write_extent(bbox, nsmap): if bbox is not None: try: bbox2 = util.wkt2geom(bbox) - except: + except Exception as err: + LOGGER.debug(f'Geometry parsing error: {err}') return None extent = etree.Element(util.nspath_eval('gmd:extent', nsmap)) ex_extent = etree.SubElement(extent, util.nspath_eval('gmd:EX_Extent', nsmap)) diff --git a/pycsw/plugins/profiles/ebrim/ebrim.py b/pycsw/plugins/profiles/ebrim/ebrim.py index fb63ed100..53ca832c1 100644 --- a/pycsw/plugins/profiles/ebrim/ebrim.py +++ b/pycsw/plugins/profiles/ebrim/ebrim.py @@ -30,7 +30,7 @@ import os from pycsw.core.etree import etree -from pycsw.core import config, util +from pycsw.core import util from pycsw.ogc.csw.csw2 import write_boundingbox from pycsw.plugins.profiles import profile diff --git a/pycsw/plugins/repository/odc/odc.py b/pycsw/plugins/repository/odc/odc.py index c3d6a9592..7a7af2b3f 100644 --- a/pycsw/plugins/repository/odc/odc.py +++ b/pycsw/plugins/repository/odc/odc.py @@ -3,7 +3,7 @@ # # Authors: Tom Kralidis # -# Copyright (c) 2015 Tom Kralidis +# Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -28,11 +28,8 @@ # # ================================================================= -import os, sys - -from django.db import models from django.db import connection -from django.db.models import Avg, Max, Min, Count +from django.db.models import Max, Min, Count from django.conf import settings from pycsw.core import repository, util @@ -109,7 +106,6 @@ def query_domain(self, domain, typenames, domainquerytype='list', def query_insert(self, direction='max'): ''' Query to get latest (default) or earliest update to repository ''' - from datetime import datetime if direction == 'min': return Resource.objects.aggregate( Min('last_updated'))['last_updated__min'].strftime('%Y-%m-%dT%H:%M:%SZ') diff --git a/pycsw/server.py b/pycsw/server.py index cb3fad13c..917525240 100644 --- a/pycsw/server.py +++ b/pycsw/server.py @@ -392,8 +392,8 @@ def dispatch(self, writer=sys.stdout, write_headers=True): self.repository = rs_cls(self.context, repo_filter) LOGGER.debug('Custom repository %s loaded (%s)', rs, self.repository.dbtype) connection_done = True - except: - LOGGER.debug(f'Repository not loaded retry connection {max_attempts}') + except Exception as err: + LOGGER.debug(f'Repository not loaded retry connection {max_attempts}: {err}') max_attempts += 1 except Exception as err: msg = 'Could not load custom repository %s: %s' % (rs, err) @@ -422,8 +422,8 @@ def dispatch(self, writer=sys.stdout, write_headers=True): LOGGER.debug( 'Repository loaded (local): %s.' % self.repository.dbtype) connection_done = True - except: - LOGGER.debug(f'Repository not loaded retry connection {max_attempts}') + except Exception: + LOGGER.debug(f'Repository not loaded retry connection {max_attempts}: {err}') max_attempts += 1 except Exception as err: msg = 'Could not load repository (local): %s' % err @@ -814,7 +814,8 @@ def _cql_update_queryables_mappings(self, cql, mappings): for key in mappings.keys(): try: cql = cql.replace(key, mappings[key]['dbcol']) - except: + except KeyError: + LOGGER.debug('Setting without dbcol key') cql = cql.replace(key, mappings[key]) LOGGER.debug('Interpolated CQL text = %s.', cql) return cql