diff --git a/felt/core/__init__.py b/felt/core/__init__.py index 6d100ad..6df5332 100644 --- a/felt/core/__init__.py +++ b/felt/core/__init__.py @@ -6,7 +6,8 @@ AuthState, ObjectType, LayerExportResult, - UsageType + UsageType, + LayerSupport ) from .auth import OAuthWorkflow # noqa from .map import Map # noqa diff --git a/felt/core/enums.py b/felt/core/enums.py index 0ee429c..f1f5bbe 100644 --- a/felt/core/enums.py +++ b/felt/core/enums.py @@ -55,6 +55,26 @@ class LayerExportResult(Enum): Canceled = auto() +class LayerSupport(Enum): + """ + Reasons why a layer is not supported + """ + Supported = auto() + NotImplementedProvider = auto() + NotImplementedLayerType = auto() + EmptyLayer = auto() + + def should_report(self) -> bool: + """ + Returns True if the layer support should be reported to Felt + usage API + """ + return self not in ( + LayerSupport.Supported, + LayerSupport.EmptyLayer + ) + + class UsageType(Enum): """ Usage types for reporting plugin usage diff --git a/felt/core/layer_exporter.py b/felt/core/layer_exporter.py index 2605493..abe2536 100644 --- a/felt/core/layer_exporter.py +++ b/felt/core/layer_exporter.py @@ -60,7 +60,10 @@ QgsRasterRange ) -from .enums import LayerExportResult +from .enums import ( + LayerExportResult, + LayerSupport +) from .exceptions import LayerPackagingException from .layer_style import LayerStyle from .logger import Logger @@ -108,7 +111,8 @@ def __del__(self): self.temp_dir.cleanup() @staticmethod - def can_export_layer(layer: QgsMapLayer) -> Tuple[bool, str]: + def can_export_layer(layer: QgsMapLayer) \ + -> Tuple[LayerSupport, str]: """ Returns True if a layer can be exported, and an explanatory string if not @@ -116,23 +120,28 @@ def can_export_layer(layer: QgsMapLayer) -> Tuple[bool, str]: if isinstance(layer, QgsVectorLayer): # Vector layers must have some features if layer.featureCount() == 0: - return False, 'Layer is empty' + return LayerSupport.EmptyLayer, 'Layer is empty' - return True, '' + return LayerSupport.Supported, '' if isinstance(layer, QgsRasterLayer): if layer.providerType() in ( 'gdal', 'virtualraster' ): - return True, '' + return LayerSupport.Supported, '' - return False, '{} raster layers are not yet supported'.format( - layer.providerType() + return ( + LayerSupport.NotImplementedProvider, + '{} raster layers are not yet supported'.format( + layer.providerType()) ) - return False, '{} layers are not yet supported'.format( - layer.__class__.__name__ + return ( + LayerSupport.NotImplementedLayerType, + '{} layers are not yet supported'.format( + layer.__class__.__name__ + ) ) @staticmethod diff --git a/felt/core/map_uploader.py b/felt/core/map_uploader.py index 86e71fb..5e169e6 100644 --- a/felt/core/map_uploader.py +++ b/felt/core/map_uploader.py @@ -54,6 +54,7 @@ from .map_utils import MapUtils from .multi_step_feedback import MultiStepFeedback from .s3_upload_parameters import S3UploadParameters +from .enums import LayerSupport class MapUploaderTask(QgsTask): @@ -102,7 +103,8 @@ def __init__(self, self.layers = [ layer.clone() for layer in visible_layers if - LayerExporter.can_export_layer(layer)[0] + LayerExporter.can_export_layer(layer)[ + 0] == LayerSupport.Supported ] self._build_unsupported_layer_details(project, visible_layers) @@ -152,8 +154,8 @@ def _build_unsupported_layer_details(self, unsupported_layer_type_count = defaultdict(int) unsupported_layer_names = set() for layer in layers: - can_export, reason = LayerExporter.can_export_layer(layer) - if can_export: + support, reason = LayerExporter.can_export_layer(layer) + if not support.should_report(): continue unsupported_layer_names.add(layer.name()) @@ -161,7 +163,10 @@ def _build_unsupported_layer_details(self, if layer.type() == QgsMapLayer.PluginLayer: id_string = layer.pluginLayerType() else: - id_string = str(layer.__class__.__name__) + id_string = '{}:{}'.format( + layer.__class__.__name__, + layer.providerType() + ) unsupported_layer_type_count[id_string] = ( unsupported_layer_type_count[id_string] + 1) diff --git a/felt/plugin.py b/felt/plugin.py index 98a5005..11f3e1b 100644 --- a/felt/plugin.py +++ b/felt/plugin.py @@ -40,7 +40,8 @@ from .core import ( AuthState, - LayerExporter + LayerExporter, + LayerSupport ) from .gui import ( @@ -241,7 +242,8 @@ def _layer_tree_view_context_menu_about_to_show(self, menu: QMenu): if layer is None: return - if LayerExporter.can_export_layer(layer)[0]: + if (LayerExporter.can_export_layer(layer)[0] == + LayerSupport.Supported): menus = [action for action in menu.children() if isinstance(action, QMenu) and action.objectName() == 'exportMenu'] diff --git a/felt/test/test_layer_exporter.py b/felt/test/test_layer_exporter.py index 0ccefb6..9025a6f 100644 --- a/felt/test/test_layer_exporter.py +++ b/felt/test/test_layer_exporter.py @@ -30,7 +30,8 @@ from .utilities import get_qgis_app from ..core import ( LayerExporter, - LayerExportResult + LayerExportResult, + LayerSupport ) QGIS_APP = get_qgis_app() @@ -48,20 +49,22 @@ def test_can_export_layer(self): file = str(TEST_DATA_PATH / 'points.gpkg') layer = QgsVectorLayer(file, 'test') self.assertTrue(layer.isValid()) - self.assertTrue(LayerExporter.can_export_layer(layer)[0]) + self.assertEqual( + LayerExporter.can_export_layer(layer)[0], LayerSupport.Supported) file = str(TEST_DATA_PATH / 'dem.tif') layer = QgsRasterLayer(file, 'test') self.assertTrue(layer.isValid()) - self.assertTrue(LayerExporter.can_export_layer(layer)[0]) + self.assertEqual( + LayerExporter.can_export_layer(layer)[0], LayerSupport.Supported) layer = QgsRasterLayer( 'crs=EPSG:3857&format&type=xyz&url=' 'https://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png' '&zmax=19&zmin=0', 'test', 'wms') - can_export, reason = LayerExporter.can_export_layer(layer) - self.assertFalse(can_export) + support, reason = LayerExporter.can_export_layer(layer) + self.assertEqual(support, LayerSupport.NotImplementedProvider) self.assertEqual(reason, 'wms raster layers are not yet supported') def test_file_name(self):