From 2a11eadf685063d6ecfb90d79c1bbb5d75f93b28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 07:47:12 +0100 Subject: [PATCH 01/26] Bump urllib3 from 1.26.2 to 1.26.3 (#6908) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.2 to 1.26.3. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/1.26.3/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.2...1.26.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Toni --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5737510d620..34d79c32542 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ beautifulsoup4==4.9.3 httplib2<0.18.2 hyperlink==21.0.0 idna>=2.5,<2.11 -urllib3==1.26.2 +urllib3==1.26.3 Paver==1.3.4 python-slugify==4.0.1 decorator==4.4.2 From 040772e9a7209858e1547ed8eaadf67f8dea32cc Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 2 Feb 2021 15:42:44 +0100 Subject: [PATCH 02/26] [Fixes #6880] Circle CI upload tests fail irregulary (#6881) * [Fixes #6880] Circle CI upload tests fail irregulary * CircleCI test fix: sometimes expires due to upload timeout in the test environment * - Avoid infinite loop on upload testing * Revert "CircleCI test fix: sometimes expires due to upload timeout in the test environment" This reverts commit 66139fdbf0b7510a9829a3e01254f41782fb7e1d. Co-authored-by: Alessio Fabiani Co-authored-by: afabiani --- .circleci/config.yml | 1 + geonode/upload/tests/integration.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 084644f56b5..0e6e3ad92a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -107,6 +107,7 @@ jobs: docker-compose -f docker-compose-test.yml exec db psql -U postgres -d test_geonode_data -c 'CREATE EXTENSION IF NOT EXISTS postgis;' docker-compose -f docker-compose-test.yml exec django bash -c '<>' working_directory: ./ + no_output_timeout: 20m - run: name: Run pep8 checks command: | diff --git a/geonode/upload/tests/integration.py b/geonode/upload/tests/integration.py index 79dcea97b8a..19fbe74c96e 100644 --- a/geonode/upload/tests/integration.py +++ b/geonode/upload/tests/integration.py @@ -136,6 +136,7 @@ def tearDownClass(cls): def setUp(self): # await startup + self.wait_for_progress_cnt = 0 cl = Client( GEONODE_URL, GEONODE_USER, GEONODE_PASSWD ) @@ -169,6 +170,7 @@ def _post_teardown(self): pass def tearDown(self): + self.wait_for_progress_cnt = 0 connections.databases['default']['ATOMIC_REQUESTS'] = False for temp_file in self._tempfiles: @@ -423,9 +425,12 @@ def wait_for_progress(self, progress_url): resp = self.client.get(progress_url) json_data = resp.json() # "COMPLETE" state means done - if json_data.get('state', '') == 'RUNNING': - time.sleep(0.1) + if json_data.get('state', '') == 'RUNNING' and self.wait_for_progress_cnt < 300: + time.sleep(1.0) + self.wait_for_progress_cnt += 1 self.wait_for_progress(progress_url) + else: + self.wait_for_progress_cnt = 0 def temp_file(self, ext): fd, abspath = tempfile.mkstemp(ext) From 65c6267fe24e2f96ea0bad9399b8ef4c6c06e9f0 Mon Sep 17 00:00:00 2001 From: Alessio Fabiani Date: Tue, 2 Feb 2021 15:43:26 +0100 Subject: [PATCH 03/26] [Fixes #6914] Remove "add to basket" tool for documents and maps (#6915) --- .../templates/base/_resourcebase_snippet.html | 15 ++++++------ geonode/templates/search/_search_content.html | 23 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/geonode/base/templates/base/_resourcebase_snippet.html b/geonode/base/templates/base/_resourcebase_snippet.html index f1d8f210cc9..3662b7cba15 100644 --- a/geonode/base/templates/base/_resourcebase_snippet.html +++ b/geonode/base/templates/base/_resourcebase_snippet.html @@ -37,37 +37,36 @@

{{ item.title }}

+ {% endverbatim %} + + {% if facet_type == 'layers' %}
-

{% endverbatim %} +

{% verbatim %} + title="{% trans "Select" %}">

+ {% endif %} - {% endverbatim %} {% trans "Service is" %} {% trans "online" %} {% trans "Service is" %} {% trans "offline" %} - {% verbatim %} - {% endverbatim %} {% trans "Layer not ready yet. Still finalizing layer ingestion..." %} - {% verbatim %} - {% endverbatim %}
{% trans "SECURITY NOT YET SYNCHRONIZED" %} {% verbatim %}{% endverbatim %}{% trans "Sync permissions immediately" %}
{% trans "PENDING APPROVAL" %}
{% trans "UNPUBLISHED" %}
- {% verbatim %} + {% verbatim %}

{{ item.abstract.length > 300 ? '...' : ''}}

diff --git a/geonode/templates/search/_search_content.html b/geonode/templates/search/_search_content.html index 77762f6497a..f02f5c7eeb3 100644 --- a/geonode/templates/search/_search_content.html +++ b/geonode/templates/search/_search_content.html @@ -1,18 +1,23 @@ {% load i18n %}
- + + {% if facet_type == 'layers' %} + + + {% endif %}
- {% block bulk_perms_button %} -
- {% if facet_type == 'layers' %} -
- + + {% if facet_type == 'layers' %} + {% block bulk_perms_button %} +
+
+ +
- {% endif %} -
- {% endblock %} + {% endblock %} + {% endif %}
{% trans "Filters" %} From 158511a1633ec382fab72b872412d149383e1370 Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 2 Feb 2021 16:47:10 +0100 Subject: [PATCH 04/26] Added malnajdi as contributor --- .clabot | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.clabot b/.clabot index 448bcf08d34..49261933bfc 100644 --- a/.clabot +++ b/.clabot @@ -46,6 +46,7 @@ "burner761", "binkiesbane", "rukarangi", - "sarahsmi" + "sarahsmi", + "malnajdi" ] } From e9efc3dfd51549d129a7d29f7dacedd998fb09ab Mon Sep 17 00:00:00 2001 From: Florian Hoedt Date: Tue, 2 Feb 2021 17:59:24 +0100 Subject: [PATCH 05/26] [Fixes #6910] meaningful filename for document download (#6911) * get meaningful document filenames on download * - Strip extension from document title before slugify it (e.g.: image.jpg instead of imagejpg.jpg) Co-authored-by: afabiani Co-authored-by: Alessio Fabiani --- geonode/documents/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/geonode/documents/views.py b/geonode/documents/views.py index 56aac88a8cf..a4506f08fd0 100644 --- a/geonode/documents/views.py +++ b/geonode/documents/views.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # ######################################################################### - +import os import json import logging import traceback @@ -29,6 +29,7 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.template import loader from django.utils.translation import ugettext as _ +from django.utils.text import slugify from django.contrib.auth.decorators import login_required from django.conf import settings from django.urls import reverse @@ -193,7 +194,8 @@ def document_download(request, docid): '401.html', context={ 'error_message': _("You are not allowed to view this document.")}, request=request), status=401) register_event(request, EventType.EVENT_DOWNLOAD, document) - return DownloadResponse(document.doc_file) + filename = slugify(os.path.splitext(os.path.basename(document.title))[0]) + return DownloadResponse(document.doc_file, basename=f"{filename}.{document.extension}") class DocumentUploadView(CreateView): From 91f1a4e62b36ceaf75cad8b8c8b503b6c6589836 Mon Sep 17 00:00:00 2001 From: afabiani Date: Tue, 2 Feb 2021 19:29:25 +0100 Subject: [PATCH 06/26] - CircleCI Upload Tests: trying to reduce more the risk of infinite loop on "wait_for_progress" --- geonode/upload/tests/integration.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/geonode/upload/tests/integration.py b/geonode/upload/tests/integration.py index 19fbe74c96e..13c8777c10f 100644 --- a/geonode/upload/tests/integration.py +++ b/geonode/upload/tests/integration.py @@ -421,16 +421,21 @@ def upload_file(self, fname, final_check, final_check(check_name, resp, data) def wait_for_progress(self, progress_url): - if progress_url: - resp = self.client.get(progress_url) - json_data = resp.json() - # "COMPLETE" state means done - if json_data.get('state', '') == 'RUNNING' and self.wait_for_progress_cnt < 300: - time.sleep(1.0) - self.wait_for_progress_cnt += 1 - self.wait_for_progress(progress_url) + try: + if progress_url: + resp = self.client.get(progress_url) + json_data = resp.json() + # "COMPLETE" state means done + if json_data and json_data.get('state', '') == 'RUNNING' and \ + self.wait_for_progress_cnt < 100: + self.wait_for_progress_cnt += 1 + self.wait_for_progress(progress_url) + else: + self.wait_for_progress_cnt = 0 else: self.wait_for_progress_cnt = 0 + except Exception: + self.wait_for_progress_cnt = 0 def temp_file(self, ext): fd, abspath = tempfile.mkstemp(ext) From 5e77b398ec4067a20c1a2450b9d03fffd8c52a4d Mon Sep 17 00:00:00 2001 From: "Mohammed Y. Alnajdi" Date: Wed, 3 Feb 2021 11:47:49 +0300 Subject: [PATCH 07/26] [Fixes #6916] gsimporter.api.NotFound caused by missing trailing slash at the end of GEOSERVER_LOCATION (#6913) * [Fixes #6916] gsimporter.api.NotFound caused by missing trailing slash at the end of GEOSERVER_LOCATION * [Fixes #6916] unit test for GEOSERVER_LOCATION --- geonode/settings.py | 4 ++++ geonode/tests/smoke.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/geonode/settings.py b/geonode/settings.py index b4089a4c89d..73cecfc53d5 100644 --- a/geonode/settings.py +++ b/geonode/settings.py @@ -951,6 +951,10 @@ 'GEOSERVER_LOCATION', 'http://localhost:8080/geoserver/' ) +# add trailing slash to geoserver location url. +if not GEOSERVER_LOCATION.endswith('/'): + GEOSERVER_LOCATION = '{}/'.format(GEOSERVER_LOCATION) + GEOSERVER_PUBLIC_SCHEMA = os.getenv( 'GEOSERVER_PUBLIC_SCHEMA', SITE_HOST_SCHEMA ) diff --git a/geonode/tests/smoke.py b/geonode/tests/smoke.py index ff772631efa..8cba4d513c4 100644 --- a/geonode/tests/smoke.py +++ b/geonode/tests/smoke.py @@ -128,6 +128,12 @@ def test_opensearch_description(self): response = self.client.get(reverse('opensearch_dispatch')) self.assertEqual(response.status_code, 200) + # Settings Tests # + + def test_settings_geoserver_location(self): + '''Ensure GEOSERVER_LOCATION variable ends with /''' + self.assertTrue(settings.GEOSERVER_LOCATION.endswith('/')) + class GeoNodeUtilsTests(GeoNodeBaseTestSupport): From ec6d728f746fff7597c17192c2d1db8f283f3975 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:49:27 +0100 Subject: [PATCH 08/26] Bump django-cors-headers from 3.6.0 to 3.7.0 (#6901) Bumps [django-cors-headers](https://github.com/adamchainz/django-cors-headers) from 3.6.0 to 3.7.0. - [Release notes](https://github.com/adamchainz/django-cors-headers/releases) - [Changelog](https://github.com/adamchainz/django-cors-headers/blob/master/HISTORY.rst) - [Commits](https://github.com/adamchainz/django-cors-headers/compare/3.6.0...3.7.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 34d79c32542..5e4ac47b076 100644 --- a/requirements.txt +++ b/requirements.txt @@ -128,7 +128,7 @@ python_resize_image==1.1.19 # required by monitoring psutil==5.8.0 -django-cors-headers==3.6.0 +django-cors-headers==3.7.0 user-agents xmljson django-ipware<3.1 From c5432b5a47a3952a019df70a97c13ff40f30fa81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:50:35 +0100 Subject: [PATCH 09/26] Bump amqp from 5.0.3 to 5.0.5 (#6905) Bumps [amqp](https://github.com/celery/py-amqp) from 5.0.3 to 5.0.5. - [Release notes](https://github.com/celery/py-amqp/releases) - [Changelog](https://github.com/celery/py-amqp/blob/master/Changelog) - [Commits](https://github.com/celery/py-amqp/compare/v5.0.3...v5.0.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5e4ac47b076..aeea109ef36 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ psycopg2==2.8.6 Django==2.2.16 # Other -amqp==5.0.3 +amqp==5.0.5 pyyaml>=4.2b1 beautifulsoup4==4.9.3 httplib2<0.18.2 From 28424ca5ee82a78504d3f27df8e5e8bca43e1aa7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:51:55 +0100 Subject: [PATCH 10/26] Bump pip from 21.0 to 21.0.1 (#6900) Bumps [pip](https://github.com/pypa/pip) from 21.0 to 21.0.1. - [Release notes](https://github.com/pypa/pip/releases) - [Changelog](https://github.com/pypa/pip/blob/master/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/21.0...21.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aeea109ef36..e7a86a9b878 100644 --- a/requirements.txt +++ b/requirements.txt @@ -153,7 +153,7 @@ splinter==0.14.0 pytest-splinter==3.3.1 pytest-django==4.1.0 setuptools==52.0.0 -pip==21.0 +pip==21.0.1 Twisted==20.3.0 factory-boy==3.2.0 flaky==3.7.0 From be313d51d1ec5f39135a6e972b85894824feb789 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:53:29 +0100 Subject: [PATCH 11/26] Bump coverage from 5.3.1 to 5.4 (#6903) Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.3.1 to 5.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/coverage-5.3.1...coverage-5.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e7a86a9b878..7cccd294778 100644 --- a/requirements.txt +++ b/requirements.txt @@ -143,7 +143,7 @@ docker==4.4.1 invoke==1.5.0 # tests -coverage==5.3.1 +coverage==5.4 parse-type==0.5.2 requests-toolbelt==0.9.1 flake8==3.8.4 From f073274f8cf3f483d3f4ad05e98ca068846095f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:54:26 +0100 Subject: [PATCH 12/26] Bump pytest from 6.2.1 to 6.2.2 (#6907) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7cccd294778..df11d938624 100644 --- a/requirements.txt +++ b/requirements.txt @@ -147,7 +147,7 @@ coverage==5.4 parse-type==0.5.2 requests-toolbelt==0.9.1 flake8==3.8.4 -pytest==6.2.1 +pytest==6.2.2 pytest-bdd==4.0.2 splinter==0.14.0 pytest-splinter==3.3.1 From 9a3913e030be293b5f8befe058528b0a99256de4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 09:57:34 +0100 Subject: [PATCH 13/26] Bump djangorestframework-gis from 0.16 to 0.17 (#6902) Bumps [djangorestframework-gis](https://github.com/openwisp/django-rest-framework-gis) from 0.16 to 0.17. - [Release notes](https://github.com/openwisp/django-rest-framework-gis/releases) - [Changelog](https://github.com/openwisp/django-rest-framework-gis/blob/master/CHANGES.rst) - [Commits](https://github.com/openwisp/django-rest-framework-gis/compare/v0.16.0...v0.17.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index df11d938624..d8696e90d19 100644 --- a/requirements.txt +++ b/requirements.txt @@ -74,7 +74,7 @@ django-recaptcha==2.0.6 # REST djangorestframework==3.11.2 -djangorestframework-gis==0.16 +djangorestframework-gis==0.17 djangorestframework-guardian==0.3.0 drf-extensions==0.6.0 drf-writable-nested==0.6.2 From ae6f6c19aebab0f30dc69c0e2debd37eecf53822 Mon Sep 17 00:00:00 2001 From: afabiani Date: Wed, 3 Feb 2021 10:00:13 +0100 Subject: [PATCH 14/26] - Algin setup.cfg to requirements.txt --- setup.cfg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/setup.cfg b/setup.cfg index cd85711e3d4..3a5fd7f83a0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,13 +32,13 @@ install_requires = Django==2.2.16 # Other - amqp==5.0.3 + amqp==5.0.5 pyyaml>=4.2b1 beautifulsoup4==4.9.3 httplib2<0.18.2 hyperlink==21.0.0 idna>=2.5,<2.11 - urllib3==1.26.2 + urllib3==1.26.3 Paver==1.3.4 python-slugify==4.0.1 decorator==4.4.2 @@ -100,7 +100,7 @@ install_requires = # REST djangorestframework==3.11.2 - djangorestframework-gis==0.16 + djangorestframework-gis==0.17 djangorestframework-guardian==0.3.0 drf-extensions==0.6.0 drf-writable-nested==0.6.2 @@ -152,7 +152,7 @@ install_requires = # required by monitoring psutil==5.8.0 - django-cors-headers==3.6.0 + django-cors-headers==3.7.0 user-agents xmljson django-ipware<3.1 @@ -167,17 +167,17 @@ install_requires = invoke==1.5.0 # tests - coverage==5.3.1 + coverage==5.4 parse-type==0.5.2 requests-toolbelt==0.9.1 flake8==3.8.4 - pytest==6.2.1 + pytest==6.2.2 pytest-bdd==4.0.2 splinter==0.14.0 pytest-splinter==3.3.1 pytest-django==4.1.0 setuptools==52.0.0 - pip==21.0 + pip==21.0.1 Twisted==20.3.0 factory-boy==3.2.0 flaky==3.7.0 From 0dad216e9a7881df84d1097a69644470014d11d0 Mon Sep 17 00:00:00 2001 From: Alessio Fabiani Date: Wed, 3 Feb 2021 16:50:08 +0100 Subject: [PATCH 15/26] =?UTF-8?q?[Fixes=20#6922][REST=20API=20v2]=20Expose?= =?UTF-8?q?=20the=20curated=20thumbnail=20URL=20if=20it=20has=E2=80=A6=20(?= =?UTF-8?q?#6923)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Fixes #6922][REST API v2] Expose the curated thumbnail URL if it has been uploaded * - Add REST APIs test suite to CircleCI --- .circleci/config.yml | 7 ++++ geonode/base/api/serializers.py | 22 ++++++++++-- geonode/base/api/tests.py | 61 ++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0e6e3ad92a0..6802ecc357e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -131,6 +131,13 @@ workflows: test_suite: coverage run --branch --source=geonode manage.py test -v 3 --keepdb $(python -c "import sys;from geonode import settings;sys.stdout.write('\'' '\''.join([a+'\''.tests'\'' for a in settings.GEONODE_APPS]))") requires: - geonode_test_suite_smoke + - build: + name: geonode_test_rest_apis + load_docker_cache: true + save_docker_cache: false + test_suite: coverage run --branch --source=geonode manage.py test -v 3 --keepdb geonode.base.api.tests geonode.layers.api.tests geonode.maps.api.tests geonode.documents.api.tests geonode.geoapps.api.tests + requires: + - geonode_test_suite_smoke - build: name: geonode_test_integration_csw load_docker_cache: true diff --git a/geonode/base/api/serializers.py b/geonode/base/api/serializers.py index 1c74ccb570d..8762d54938a 100644 --- a/geonode/base/api/serializers.py +++ b/geonode/base/api/serializers.py @@ -17,6 +17,7 @@ # along with this program. If not, see . # ######################################################################### +from django.conf import settings from django.contrib.auth.models import Group from django.contrib.auth import get_user_model @@ -25,6 +26,7 @@ from dynamic_rest.serializers import DynamicEphemeralSerializer, DynamicModelSerializer from dynamic_rest.fields.fields import DynamicRelationField, DynamicComputedField +from urllib.parse import urljoin from avatar.templatetags.avatar_tags import avatar_url from geonode.base.models import ( @@ -147,6 +149,22 @@ def get_attribute(self, instance): return avatar_url(instance, self.avatar_size) +class ThumbnailUrlField(DynamicComputedField): + + def __init__(self, **kwargs): + super(ThumbnailUrlField, self).__init__(**kwargs) + + def get_attribute(self, instance): + thumbnail_url = instance.thumbnail_url + if hasattr(instance, 'curatedthumbnail'): + if hasattr(instance.curatedthumbnail.img_thumbnail, 'url'): + thumbnail_url = instance.curatedthumbnail.thumbnail_url + + if thumbnail_url and 'http' not in thumbnail_url: + thumbnail_url = urljoin(settings.SITEURL, thumbnail_url) + return thumbnail_url + + class UserSerializer(DynamicModelSerializer): class Meta: @@ -215,11 +233,11 @@ def __init__(self, *args, **kwargs): self.fields['featured'] = serializers.BooleanField() self.fields['is_published'] = serializers.BooleanField() self.fields['is_approved'] = serializers.BooleanField() - self.fields['thumbnail_url'] = serializers.CharField() self.fields['detail_url'] = serializers.CharField(read_only=True) self.fields['created'] = serializers.DateTimeField(read_only=True) self.fields['last_updated'] = serializers.DateTimeField(read_only=True) + self.fields['thumbnail_url'] = ThumbnailUrlField() self.fields['keywords'] = DynamicRelationField( HierarchicalKeywordSerializer, embed=False, many=True) self.fields['regions'] = DynamicRelationField( @@ -246,7 +264,7 @@ class Meta: 'spatial_representation_type', 'temporal_extent_start', 'temporal_extent_end', 'supplemental_information', 'data_quality_statement', 'group', 'popular_count', 'share_count', 'rating', 'featured', 'is_published', 'is_approved', - 'thumbnail_url', 'detail_url', 'created', 'last_updated' + 'detail_url', 'created', 'last_updated' # TODO # csw_typename, csw_schema, csw_mdsource, csw_insert_date, csw_type, csw_anytext, csw_wkt_geometry, # metadata_uploaded, metadata_uploaded_preserve, metadata_xml, diff --git a/geonode/base/api/tests.py b/geonode/base/api/tests.py index 4ead6cae7aa..e30b70edc10 100644 --- a/geonode/base/api/tests.py +++ b/geonode/base/api/tests.py @@ -18,25 +18,34 @@ # ######################################################################### import logging - +from PIL import Image +from io import BytesIO +from unittest.mock import patch from urllib.parse import urljoin +import django from django.urls import reverse +from django.core.files import File from django.conf.urls import url, include from django.views.generic import TemplateView +from django.views.i18n import JavaScriptCatalog from rest_framework.test import APITestCase, URLPatternsTestCase from guardian.shortcuts import get_anonymous_user from geonode.api.urls import router from geonode.base.models import ResourceBase +from geonode.base.models import CuratedThumbnail from geonode import geoserver from geonode.utils import check_ogc_backend +from geonode.services.views import services from geonode.base.populate_test_data import create_models logger = logging.getLogger(__name__) +test_image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0)) + class BaseApiTests(APITestCase, URLPatternsTestCase): @@ -58,6 +67,29 @@ class BaseApiTests(APITestCase, URLPatternsTestCase): url(r'^api/v2/', include(router.urls)), url(r'^api/v2/', include('geonode.api.urls')), url(r'^api/v2/api-auth/', include('rest_framework.urls', namespace='geonode_rest_framework')), + url(r'^$', + TemplateView.as_view(template_name='layers/layer_list.html'), + {'facet_type': 'layers', 'is_layer': True}, + name='layer_browse'), + url(r'^$', + TemplateView.as_view(template_name='maps/map_list.html'), + {'facet_type': 'maps', 'is_map': True}, + name='maps_browse'), + url(r'^$', + TemplateView.as_view(template_name='documents/document_list.html'), + {'facet_type': 'documents', 'is_document': True}, + name='document_browse'), + url(r'^$', + TemplateView.as_view(template_name='groups/group_list.html'), + name='group_list'), + url(r'^search/$', + TemplateView.as_view(template_name='search/search.html'), + name='search'), + url(r'^$', services, name='services'), + url(r'^invitations/', include( + 'geonode.invitations.urls', namespace='geonode.invitations')), + url(r'^i18n/', include(django.conf.urls.i18n), name="i18n"), + url(r'^jsi18n/$', JavaScriptCatalog.as_view(), {}, name='javascript-catalog') ] if check_ogc_backend(geoserver.BACKEND_PACKAGE): @@ -427,3 +459,30 @@ def test_resource_types(self): self.assertTrue('map' in response.data['resource_types']) self.assertTrue('document' in response.data['resource_types']) self.assertTrue('service' in response.data['resource_types']) + + @patch('PIL.Image.open', return_value=test_image) + def test_thumbnail_urls(self, img): + """ + Ensure the thumbnail url reflects the current active Thumb on the resource. + """ + # Admin + self.assertTrue(self.client.login(username='admin', password='admin')) + + resource = ResourceBase.objects.filter(owner__username='bobby').first() + url = reverse('base-resources-detail', kwargs={'pk': resource.pk}) + response = self.client.get(url, format='json') + self.assertEqual(response.status_code, 200) + self.assertEqual(int(response.data['resource']['pk']), int(resource.pk)) + thumbnail_url = response.data['resource']['thumbnail_url'] + self.assertIsNone(thumbnail_url) + + f = BytesIO(test_image.tobytes()) + f.name = 'test_image.jpeg' + curated_thumbnail = CuratedThumbnail.objects.create(resource=resource, img=File(f)) + + url = reverse('base-resources-detail', kwargs={'pk': resource.pk}) + response = self.client.get(url, format='json') + self.assertEqual(response.status_code, 200) + self.assertEqual(int(response.data['resource']['pk']), int(resource.pk)) + thumbnail_url = response.data['resource']['thumbnail_url'] + self.assertTrue(curated_thumbnail.thumbnail_url in thumbnail_url) From 30910b2c6abb5a93d295eb0855d917771d510377 Mon Sep 17 00:00:00 2001 From: Alessio Fabiani Date: Wed, 3 Feb 2021 16:50:37 +0100 Subject: [PATCH 16/26] [Fixes #6918] Removal of QGIS support (#6919) * [Cleanup and Refactor] Remove QGIS server backend dependencies * [Cleanup and Refactor] Remove QGIS server backend dependencies * - Fix LGTM issues --- .dockerignore | 2 - .gitignore | 2 - .travis.yml | 60 -- docker-compose-qgis-server.yml | 22 - geonode/api/api.py | 185 +--- geonode/api/authorization.py | 5 +- geonode/api/resourcebase_api.py | 89 +- .../base/management/commands/fixoauthuri.py | 2 +- .../commands/set_all_layers_metadata.py | 4 +- geonode/base/populate_test_data.py | 2 +- .../leaflet/layers/layer_leaflet_map.html | 106 -- geonode/layers/forms.py | 10 +- .../layers/templates/layers/layer_detail.html | 68 +- geonode/layers/tests.py | 16 +- geonode/layers/urls.py | 2 +- geonode/layers/utils.py | 30 +- geonode/layers/views.py | 21 +- geonode/local_settings.py.geoserver.sample | 2 - geonode/local_settings.py.qgis.sample | 138 --- geonode/maps/models.py | 4 +- geonode/maps/qgis_server_views.py | 612 ----------- geonode/maps/templates/maps/map_detail.html | 18 - geonode/maps/tests.py | 40 +- geonode/maps/tests_populate_maplayers.py | 2 +- geonode/maps/urls.py | 31 +- geonode/maps/views.py | 24 +- .../migrations/0030_auto_20210118_1112.py | 18 + geonode/proxy/views.py | 2 +- geonode/qgis_server/__init__.py | 24 - geonode/qgis_server/admin.py | 42 - geonode/qgis_server/apps.py | 35 - geonode/qgis_server/context_processors.py | 60 -- geonode/qgis_server/forms.py | 49 - geonode/qgis_server/gis_tools.py | 164 --- geonode/qgis_server/helpers.py | 980 ------------------ geonode/qgis_server/management/__init__.py | 19 - .../management/commands/__init__.py | 19 - .../delete_orphaned_qgis_server_layers.py | 34 - .../management/commands/import_qgis_styles.py | 52 - geonode/qgis_server/middleware.py | 56 - .../qgis_server/migrations/0001_initial.py | 40 - .../migrations/0002_qgisservermap.py | 40 - .../migrations/0003_auto_20170727_0509.py | 55 - .../migrations/0004_auto_20170805_0223.py | 44 - .../migrations/0005_auto_20170823_0341.py | 40 - .../migrations/0006_auto_20200321_1349.py | 18 - geonode/qgis_server/migrations/__init__.py | 19 - geonode/qgis_server/models.py | 389 ------- geonode/qgis_server/signals.py | 421 -------- geonode/qgis_server/tasks/__init__.py | 19 - geonode/qgis_server/tasks/update.py | 161 --- .../templates/qgis_server/base.html | 21 - .../qgis_server/forms/qml_style.html | 88 -- geonode/qgis_server/tests/__init__.py | 19 - geonode/qgis_server/tests/data/test.xml | 332 ------ geonode/qgis_server/tests/data/test_grid.qml | 16 - geonode/qgis_server/tests/test_helpers.py | 308 ------ geonode/qgis_server/tests/test_management.py | 181 ---- .../qgis_server/tests/test_qgis_settings.py | 73 -- geonode/qgis_server/tests/test_views.py | 750 -------------- .../qgis_server/tests/test_xml_utilities.py | 89 -- geonode/qgis_server/urls.py | 167 --- geonode/qgis_server/views.py | 885 ---------------- geonode/qgis_server/xml_utilities.py | 136 --- geonode/security/tests.py | 7 +- geonode/settings.py | 10 - geonode/static/geonode/js/upload/LayerInfo.js | 4 +- geonode/tests/base.py | 2 +- geonode/tests/csw.py | 28 +- geonode/tests/integration.py | 145 +-- geonode/upload/forms.py | 5 - geonode/upload/tests/test_settings.py | 2 - geonode/urls.py | 9 +- geonode/utils.py | 188 +--- package/support/geonode.local_settings | 2 - pavement.py | 118 +-- scripts/misc/qgis_server_setup.sh | 34 - 77 files changed, 103 insertions(+), 7813 deletions(-) delete mode 100644 docker-compose-qgis-server.yml delete mode 100644 geonode/local_settings.py.qgis.sample delete mode 100644 geonode/maps/qgis_server_views.py create mode 100644 geonode/people/migrations/0030_auto_20210118_1112.py delete mode 100644 geonode/qgis_server/__init__.py delete mode 100644 geonode/qgis_server/admin.py delete mode 100644 geonode/qgis_server/apps.py delete mode 100644 geonode/qgis_server/context_processors.py delete mode 100644 geonode/qgis_server/forms.py delete mode 100644 geonode/qgis_server/gis_tools.py delete mode 100644 geonode/qgis_server/helpers.py delete mode 100644 geonode/qgis_server/management/__init__.py delete mode 100644 geonode/qgis_server/management/commands/__init__.py delete mode 100644 geonode/qgis_server/management/commands/delete_orphaned_qgis_server_layers.py delete mode 100644 geonode/qgis_server/management/commands/import_qgis_styles.py delete mode 100644 geonode/qgis_server/middleware.py delete mode 100644 geonode/qgis_server/migrations/0001_initial.py delete mode 100644 geonode/qgis_server/migrations/0002_qgisservermap.py delete mode 100644 geonode/qgis_server/migrations/0003_auto_20170727_0509.py delete mode 100644 geonode/qgis_server/migrations/0004_auto_20170805_0223.py delete mode 100644 geonode/qgis_server/migrations/0005_auto_20170823_0341.py delete mode 100644 geonode/qgis_server/migrations/0006_auto_20200321_1349.py delete mode 100644 geonode/qgis_server/migrations/__init__.py delete mode 100644 geonode/qgis_server/models.py delete mode 100644 geonode/qgis_server/signals.py delete mode 100644 geonode/qgis_server/tasks/__init__.py delete mode 100644 geonode/qgis_server/tasks/update.py delete mode 100644 geonode/qgis_server/templates/qgis_server/base.html delete mode 100644 geonode/qgis_server/templates/qgis_server/forms/qml_style.html delete mode 100644 geonode/qgis_server/tests/__init__.py delete mode 100644 geonode/qgis_server/tests/data/test.xml delete mode 100644 geonode/qgis_server/tests/data/test_grid.qml delete mode 100644 geonode/qgis_server/tests/test_helpers.py delete mode 100644 geonode/qgis_server/tests/test_management.py delete mode 100644 geonode/qgis_server/tests/test_qgis_settings.py delete mode 100644 geonode/qgis_server/tests/test_views.py delete mode 100644 geonode/qgis_server/tests/test_xml_utilities.py delete mode 100644 geonode/qgis_server/urls.py delete mode 100644 geonode/qgis_server/views.py delete mode 100644 geonode/qgis_server/xml_utilities.py delete mode 100755 scripts/misc/qgis_server_setup.sh diff --git a/.dockerignore b/.dockerignore index ce2c0518645..7d2e8d9944b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,4 @@ geonode/uploaded -geonode/qgis_layer -geonode/qgis_tiles geonode/static_root geonode/static/.components geonode/static/node_modules diff --git a/.gitignore b/.gitignore index 33164c196b8..f05e035ea63 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,6 @@ geonode/local_settings.py # Uploaded files geonode/uploaded -geonode/qgis_layer -geonode/qgis_tiles #Testing output .coverage diff --git a/.travis.yml b/.travis.yml index a6eeac4a76a..030371da15a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,40 +71,6 @@ jobs: - MONITORING_ENABLED: 'False' - SESSION_EXPIRED_CONTROL_ENABLED: 'True' - - stage: unit-tests - name: "QGis Server-backend Core Modules Smoke Tests" - virtualenv: - system_site_packages: false - env: - - BACKEND: 'geonode.qgis_server' - - DJANGO_SETTINGS_MODULE: 'geonode.local_settings' - - DOCKER_COMPOSE_VERSION: 1.19.0 - - QGIS_SERVER_URL: http://localhost:9000/ - - SITEURL: http://localhost:8000/ - - QGIS_SERVER_PORT: 9000 - - ON_TRAVIS: 'True' - - TEST_RUN_CORE: 'True' - - MONITORING_ENABLED: 'False' - - SESSION_EXPIRED_CONTROL_ENABLED: 'True' - - CELERY_ALWAYS_EAGER: 'True' - - - stage: unit-tests - name: "QGis Server-backend Contrib Apps Smoke Tests" - virtualenv: - system_site_packages: false - env: - - BACKEND: 'geonode.qgis_server' - - DJANGO_SETTINGS_MODULE: 'geonode.local_settings' - - DOCKER_COMPOSE_VERSION: 1.19.0 - - QGIS_SERVER_URL: http://localhost:9000/ - - SITEURL: http://localhost:8000/ - - QGIS_SERVER_PORT: 9000 - - ON_TRAVIS: 'True' - - TEST_RUN_INTERNAL_APPS: 'True' - - MONITORING_ENABLED: 'False' - - SESSION_EXPIRED_CONTROL_ENABLED: 'True' - - CELERY_ALWAYS_EAGER: 'True' - - stage: integration-tests name: "Backend Integration Tests" virtualenv: @@ -150,27 +116,6 @@ jobs: - GEODATABASE_URL: 'postgis://geonode:geonode@localhost:5432/upload_test' - DEFAULT_BACKEND_DATASTORE: 'datastore' - - stage: integration-tests - name: "QGis Server Integration Tests" - virtualenv: - system_site_packages: false - env: - - BACKEND: 'geonode.qgis_server' - - DJANGO_SETTINGS_MODULE: 'geonode.local_settings' - - DOCKER_COMPOSE_VERSION: 1.19.0 - - QGIS_SERVER_URL: http://localhost:9000/ - - SITEURL: http://localhost:8000/ - - QGIS_SERVER_PORT: 9000 - - ON_TRAVIS: 'True' - - TEST_RUNNER_KEEPDB: 'True' - - TEST_RUN_INTEGRATION: 'True' - - TEST_RUN_INTEGRATION_SERVER: 'True' - - MONITORING_ENABLED: 'False' - - SESSION_EXPIRED_CONTROL_ENABLED: 'True' - - CELERY_ALWAYS_EAGER: 'True' - - DATABASE_URL: 'postgis://geonode:geonode@localhost:5432/upload_test' - - GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY: 'leaflet' - - stage: frontend-tests name: "BDD Tests" virtualenv: @@ -215,7 +160,6 @@ before_install: sudo apt-get update; mkdir -p $HOME/buildout-cache/{eggs,downloads}; scripts/misc/geoserver_server_setup.sh before_install; - scripts/misc/qgis_server_setup.sh before_install; sudo apt-get autoremove sqlite3; sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/12/main/postgresql.conf; sudo sed -i 's/peer/trust/' /etc/postgresql/12/main/pg_hba.conf; @@ -268,8 +212,6 @@ before_script: scripts/misc/create_dbs_travis.sh before_script; echo "For GeoServer Server Travis steps"; scripts/misc/geoserver_server_setup.sh before_script; - echo "For QGIS Server Travis steps"; - scripts/misc/qgis_server_setup.sh before_script; echo "Start NGINX server"; sudo nginx -s stop; sudo nginx -c `pwd`/scripts/misc/nginx_integration.conf; @@ -296,8 +238,6 @@ after_script: else echo "For GeoServer Server Travis steps"; scripts/misc/geoserver_server_setup.sh after_script; - echo "For QGIS Server Travis steps"; - scripts/misc/qgis_server_setup.sh after_script; echo "Stop NGINX server"; sudo nginx -c `pwd`/scripts/misc/nginx_integration.conf -s stop; echo "Cleanup"; diff --git a/docker-compose-qgis-server.yml b/docker-compose-qgis-server.yml deleted file mode 100644 index 9614ae7bb90..00000000000 --- a/docker-compose-qgis-server.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: '2' -services: - - qgis-server: - image: kartoza/geonode_qgis-server - volumes: - # Mount this volume from current directory to - # The absolute path, so these files were mounted - # with the same path - - './:${GEONODE_PROJECT_PATH}' - environment: - - QGIS_LOG_FILE=/tmp/qgis-server/qgis.log - - QGIS_SERVER_LOG_FILE=/tmp/qgis-server/qgis-server.log - - QGIS_DEBUG=5 - - QGIS_SERVER_LOG_LEVEL=5 - - QGIS_PLUGINPATH=/opt/qgis-server/plugins/ - # It is important to include this environment variable - # QGIS-Server:LTR cgi needs it - - QGIS_PROJECT_FILE= - ports: - - "${QGIS_SERVER_PORT}:80" - network_mode: "bridge" diff --git a/geonode/api/api.py b/geonode/api/api.py index 75f8320462f..e5f1e3b7b3d 100644 --- a/geonode/api/api.py +++ b/geonode/api/api.py @@ -30,19 +30,14 @@ from django.contrib.contenttypes.models import ContentType from django.conf import settings from django.db.models import Count -from django.http.response import HttpResponse -from django.template.response import TemplateResponse from django.utils.translation import get_language from avatar.templatetags.avatar_tags import avatar_url -from tastypie import http -from tastypie.exceptions import BadRequest -from geonode import qgis_server, geoserver +from geonode import geoserver from geonode.api.paginator import CrossSiteXHRPaginator from geonode.api.authorization import GeoNodeStyleAuthorization, ApiLockdownAuthorization, \ GroupAuthorization, GroupProfileAuthorization -from geonode.qgis_server.models import QGISServerStyle from guardian.shortcuts import get_objects_for_user from tastypie.bundle import Bundle @@ -600,178 +595,6 @@ class Meta: authorization = ApiLockdownAuthorization() -class QGISStyleResource(ModelResource): - """Styles API for QGIS Server backend.""" - - body = fields.CharField(attribute='body', use_in='detail') - name = fields.CharField(attribute='name') - title = fields.CharField(attribute='title') - layer = fields.ForeignKey( - 'geonode.api.resourcebase_api.LayerResource', - attribute='layer', - null=True) - style_url = fields.CharField(attribute='style_url') - type = fields.CharField(attribute='type') - - class Meta: - paginator_class = CrossSiteXHRPaginator - queryset = QGISServerStyle.objects.all() - resource_name = 'styles' - detail_uri_name = 'id' - allowed_methods = ['get', 'post', 'delete'] - authorization = GeoNodeStyleAuthorization() - filtering = { - 'id': ALL, - 'title': ALL, - 'name': ALL, - 'layer': ALL_WITH_RELATIONS - } - - def populate_object(self, style): - """Populate results with necessary fields - - :param style: Style objects - :type style: QGISServerStyle - :return: - """ - try: - qgis_layer = style.layer_styles.first() - """:type: geonode.qgis_server.QGISServerLayer""" - style.layer = qgis_layer.layer - style.type = 'qml' - except Exception: - pass - return style - - def build_filters(self, filters=None, **kwargs): - """Apply custom filters for layer.""" - filters = super(QGISStyleResource, self).build_filters( - filters, **kwargs) - # Convert layer__ filters into layer_styles__layer__ - updated_filters = {} - for key, value in filters.items(): - key = key.replace('layer__', 'layer_styles__layer__') - updated_filters[key] = value - return updated_filters - - def build_bundle(self, obj=None, data=None, request=None, **kwargs): - """Override build_bundle method to add additional info.""" - - if obj is None and self._meta.object_class: - obj = self._meta.object_class() - - elif obj: - obj = self.populate_object(obj) - - return Bundle( - obj=obj, - data=data, - request=request, - **kwargs) - - def post_list(self, request, **kwargs): - """Attempt to redirect to QGIS Server Style management. - - A post method should have the following field: - - name: Slug name of style - title: Title of style - style: the style file uploaded - - Also, should have kwargs: - - layername or layer__name: The layer name associated with the style - - or - - layer__id: The layer id associated with the style - - """ - from geonode.qgis_server.views import qml_style - - # Extract layer name information - POST = request.POST - FILES = request.FILES - layername = POST.get('layername') or POST.get('layer__name') - if not layername: - layer_id = POST.get('layer__id') - layer = Layer.objects.get(id=layer_id) - layername = layer.name - - # move style file - FILES['qml'] = FILES['style'] - - response = qml_style(request, layername) - - if isinstance(response, TemplateResponse): - if response.status_code == 201: - obj = QGISServerStyle.objects.get( - layer_styles__layer__name=layername, - name=POST['name']) - updated_bundle = self.build_bundle(obj=obj, request=request) - location = self.get_resource_uri(updated_bundle) - - if not self._meta.always_return_data: - return http.HttpCreated(location=location) - else: - updated_bundle = self.full_dehydrate(updated_bundle) - updated_bundle = self.alter_detail_data_to_serialize( - request, updated_bundle) - return self.create_response( - request, updated_bundle, - response_class=http.HttpCreated, - location=location) - else: - context = response.context_data - # Check form valid - style_upload_form = context['style_upload_form'] - if not style_upload_form.is_valid(): - raise BadRequest(style_upload_form.errors.as_text()) - alert_message = context['alert_message'] - raise BadRequest(alert_message) - elif isinstance(response, HttpResponse): - response_class = None - if response.status_code == 403: - response_class = http.HttpForbidden - return self.error_response( - request, response.content, - response_class=response_class) - - def delete_detail(self, request, **kwargs): - """Attempt to redirect to QGIS Server Style management.""" - from geonode.qgis_server.views import qml_style - style_id = kwargs.get('id') - - qgis_style = QGISServerStyle.objects.get(id=style_id) - layername = qgis_style.layer_styles.first().layer.name - - response = qml_style(request, layername, style_name=qgis_style.name) - - if isinstance(response, TemplateResponse): - if response.status_code == 200: - # style deleted - return http.HttpNoContent() - else: - context = response.context_data - # Check form valid - style_upload_form = context['style_upload_form'] - if not style_upload_form.is_valid(): - raise BadRequest(style_upload_form.errors.as_text()) - alert_message = context['alert_message'] - raise BadRequest(alert_message) - elif isinstance(response, HttpResponse): - response_class = None - if response.status_code == 403: - response_class = http.HttpForbidden - return self.error_response( - request, response.content, - response_class=response_class) - - def delete_list(self, request, **kwargs): - """Do not allow delete list""" - return http.HttpForbidden() - - class GeoserverStyleResource(ModelResource): """Styles API for Geoserver backend.""" body = fields.CharField( @@ -844,11 +667,7 @@ def build_bundle(self, obj=None, data=None, request=None, **kwargs): **kwargs) -if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - class StyleResource(QGISStyleResource): - """Wrapper for Generic Style Resource""" - pass -elif check_ogc_backend(geoserver.BACKEND_PACKAGE): +if check_ogc_backend(geoserver.BACKEND_PACKAGE): class StyleResource(GeoserverStyleResource): """Wrapper for Generic Style Resource""" pass diff --git a/geonode/api/authorization.py b/geonode/api/authorization.py index 9addb98f43f..237e65dd4e8 100644 --- a/geonode/api/authorization.py +++ b/geonode/api/authorization.py @@ -28,7 +28,7 @@ from django.conf import settings -from geonode import geoserver, qgis_server +from geonode import geoserver from geonode.utils import check_ogc_backend @@ -133,9 +133,6 @@ def filter_by_resource_ids(self, object_list, permitted_ids): """Filter Style queryset by permitted resource ids.""" if check_ogc_backend(geoserver.BACKEND_PACKAGE): return object_list.filter(layer_styles__id__in=permitted_ids) - elif check_ogc_backend(qgis_server.BACKEND_PACKAGE): - return object_list.filter( - layer_styles__layer__id__in=permitted_ids) def read_list(self, object_list, bundle): permitted_ids = get_objects_for_user( diff --git a/geonode/api/resourcebase_api.py b/geonode/api/resourcebase_api.py index 53d175d92d8..f3c902c2a98 100644 --- a/geonode/api/resourcebase_api.py +++ b/geonode/api/resourcebase_api.py @@ -18,17 +18,13 @@ # ######################################################################### import re -import json import logging -from django.urls import resolve from django.db.models import Q from django.http import HttpResponse from django.conf import settings from django.contrib.staticfiles.templatetags import staticfiles from tastypie.authentication import MultiAuthentication, SessionAuthentication -from django.template.response import TemplateResponse -from tastypie import http from tastypie.bundle import Bundle from tastypie.constants import ALL, ALL_WITH_RELATIONS @@ -46,7 +42,7 @@ from tastypie.utils.mime import build_content_type -from geonode import get_version, qgis_server, geoserver +from geonode import get_version, geoserver from geonode.layers.models import Layer from geonode.maps.models import Map from geonode.geoapps.models import GeoApp @@ -714,17 +710,7 @@ class LayerResource(CommonModelApi): null=True, use_in='all', default=[]) - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - default_style = fields.ForeignKey( - 'geonode.api.api.StyleResource', - attribute='qgis_default_style', - null=True) - styles = fields.ManyToManyField( - 'geonode.api.api.StyleResource', - attribute='qgis_styles', - null=True, - use_in='detail') - elif check_ogc_backend(geoserver.BACKEND_PACKAGE): + if check_ogc_backend(geoserver.BACKEND_PACKAGE): default_style = fields.ForeignKey( 'geonode.api.api.StyleResource', attribute='default_style', @@ -830,35 +816,12 @@ def dehydrate_ogc_links(self, bundle): def dehydrate_gtype(self, bundle): return bundle.obj.gtype - def populate_object(self, obj): - """Populate results with necessary fields - - :param obj: Layer obj - :type obj: Layer - :return: - """ - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - # Provides custom links for QGIS Server styles info - # Default style - try: - obj.qgis_default_style = obj.qgis_layer.default_style - except Exception: - obj.qgis_default_style = None - - # Styles - try: - obj.qgis_styles = obj.qgis_layer.styles - except Exception: - obj.qgis_styles = [] - return obj - def build_bundle( self, obj=None, data=None, request=None, **kwargs): """Override build_bundle method to add additional info.""" if obj is None and self._meta.object_class: obj = self._meta.object_class() - elif obj: obj = self.populate_object(obj) @@ -867,50 +830,14 @@ def build_bundle( data=data, request=request, **kwargs) - def patch_detail(self, request, **kwargs): - """Allow patch request to update default_style. - - Request body must match this: - - { - 'default_style': - } + def populate_object(self, obj): + """Populate results with necessary fields + :param obj: Layer obj + :type obj: Layer + :return: """ - reason = 'Can only patch "default_style" field.' - try: - body = json.loads(request.body) - if 'default_style' not in body: - return http.HttpBadRequest(reason=reason) - match = resolve(body['default_style']) - style_id = match.kwargs['id'] - api_name = match.kwargs['api_name'] - resource_name = match.kwargs['resource_name'] - if not (resource_name == 'styles' and api_name == 'api'): - raise Exception() - - from geonode.qgis_server.models import QGISServerStyle - - style = QGISServerStyle.objects.get(id=style_id) - - layer_id = kwargs['id'] - layer = Layer.objects.get(id=layer_id) - except Exception: - return http.HttpBadRequest(reason=reason) - - from geonode.qgis_server.views import default_qml_style - - request.method = 'POST' - response = default_qml_style( - request, - layername=layer.name, - style_name=style.name) - - if isinstance(response, TemplateResponse): - if response.status_code == 200: - return HttpResponse(status=200) - - return self.error_response(request, response.content) + return obj # copy parent attribute before modifying VALUES = CommonModelApi.VALUES[:] diff --git a/geonode/base/management/commands/fixoauthuri.py b/geonode/base/management/commands/fixoauthuri.py index ff5bbb3ed99..ca3c16f4afd 100644 --- a/geonode/base/management/commands/fixoauthuri.py +++ b/geonode/base/management/commands/fixoauthuri.py @@ -23,7 +23,7 @@ from oauth2_provider.models import Application from oauth2_provider.generators import generate_client_id, generate_client_secret -from geonode import geoserver, qgis_server # noqa +from geonode import geoserver # noqa from geonode.utils import check_ogc_backend diff --git a/geonode/base/management/commands/set_all_layers_metadata.py b/geonode/base/management/commands/set_all_layers_metadata.py index 2a0299bb1f5..a2247aca807 100644 --- a/geonode/base/management/commands/set_all_layers_metadata.py +++ b/geonode/base/management/commands/set_all_layers_metadata.py @@ -21,7 +21,7 @@ from django.core.management.base import BaseCommand from geonode.layers.models import Layer -from geonode import geoserver, qgis_server # noqa +from geonode import geoserver # noqa from geonode.catalogue.models import catalogue_post_save from geonode.geoserver.helpers import ogc_server_settings import logging @@ -41,8 +41,6 @@ if check_ogc_backend(geoserver.BACKEND_PACKAGE): from geonode.geoserver.helpers import set_attributes_from_geoserver as set_attributes -elif check_ogc_backend(qgis_server.BACKEND_PACKAGE): - from geonode.qgis_server.gis_tools import set_attributes class Command(BaseCommand): diff --git a/geonode/base/populate_test_data.py b/geonode/base/populate_test_data.py index f0ef01e3675..d38483347e7 100644 --- a/geonode/base/populate_test_data.py +++ b/geonode/base/populate_test_data.py @@ -36,7 +36,7 @@ from django.contrib.auth import get_user_model from django.core.files.uploadedfile import SimpleUploadedFile -from geonode import geoserver, qgis_server # noqa +from geonode import geoserver # noqa from geonode.maps.models import Map from geonode.layers.models import Layer from geonode.compat import ensure_string diff --git a/geonode/client/templates/leaflet/layers/layer_leaflet_map.html b/geonode/client/templates/leaflet/layers/layer_leaflet_map.html index 36d68f2e289..ce9fa957403 100644 --- a/geonode/client/templates/leaflet/layers/layer_leaflet_map.html +++ b/geonode/client/templates/leaflet/layers/layer_leaflet_map.html @@ -230,41 +230,6 @@ //adjust info L.control.navbar().addTo(map); } - - {% if OGC_SERVER.default.BACKEND == 'geonode.qgis_server' %} - {# expose map object to window #} - window.preview_map = map; - window.tile_layer = tile_layer; - - {# Trigger dialog for Style edit #} - $(".style-edit").on('click', function (event) { - $("#qgis-server-style-edit").modal('show'); - }); - - {# Attach form submit event #} - $("#qgis-server-style-add-form").on('submit', edit_style_on_submit); - - {# Attach handler for style change #} - $("input[name='style']").on('change', function(event){ - var $input = $(this); - if($input.prop('checked') == true){ - {# Tile url change #} - var url; - {% if resource.get_tiles_url %} - url = '{% url "qgis_server:tile" layername=resource.name style='style_name' %}'; - url = url.replace('style_name', $input.attr('id')); - url = decodeURIComponent(url); - tile_layer.setUrl(url); - {% endif %} - - {# Legend icon change #} - url = '{% url "qgis_server:legend" layername=resource.name style='style_name' %}'; - url = url.replace('style_name', $input.attr('id')); - url = decodeURIComponent(url); - $("#legend_icon").attr('src', url); - } - }); - {% endif %} }); function zoom_to_box(map, bbox) { @@ -274,75 +239,4 @@ ]; map.fitBounds(bounds); } - - - {% if OGC_SERVER.default.BACKEND == 'geonode.qgis_server' %} - - function createMapThumbnail() { - {# Use map extent #} - var map = window.preview_map; - var bbox = map.getBounds().toBBoxString(); - var data = { - 'bbox': bbox - }; - $.post('{% url "qgis_server:set-thumbnail" layername=resource.name %}', data); - } - - {# Event handler for style editing #} - function edit_style_on_submit(event){ - {# prevent form submit by default #} - var data = new FormData(); - $.each($("#id_qml")[0].files, function(i, file){ - data.append('qml', file); - }); - data.append('name', $("#id_name").val()); - data.append('title', $("#id_title").val()); - var action = $(this).attr('action'); - $.ajax({ - url: action, - data: data, - cache: false, - contentType: false, - processData: false, - type: 'POST', - success: function(data){ - if(data){ - $("#qgis-server-style-edit .modal-body").html(data); - $(document).ready(function() { - $("#qgis-server-style-add-form").on('submit', edit_style_on_submit); - }); - } - }, - error: function(jqXhr, textStatus, errorThrown){ - $("#qgis-server-style-edit .modal-body").html(jqXhr.responseText); - $(document).ready(function() { - $("#qgis-server-style-add-form").on('submit', edit_style_on_submit); - }); - } - }); - return false; - } - {% endif %} - -{% if OGC_SERVER.default.BACKEND == 'geonode.qgis_server' %} - - -{% endif %} diff --git a/geonode/layers/forms.py b/geonode/layers/forms.py index 8fd292d78fe..bba15a27675 100644 --- a/geonode/layers/forms.py +++ b/geonode/layers/forms.py @@ -25,7 +25,7 @@ from django import forms -from geonode import geoserver, qgis_server +from geonode import geoserver from geonode.utils import check_ogc_backend import json @@ -85,8 +85,6 @@ class LayerUploadForm(forms.Form): xml_file = forms.FileField(required=False) if check_ogc_backend(geoserver.BACKEND_PACKAGE): sld_file = forms.FileField(required=False) - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - qml_file = forms.FileField(required=False) charset = forms.CharField(required=False) metadata_uploaded_preserve = forms.BooleanField(required=False) @@ -102,8 +100,6 @@ class LayerUploadForm(forms.Form): # Adding style file based on the backend if check_ogc_backend(geoserver.BACKEND_PACKAGE): spatial_files.append('sld_file') - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - spatial_files.append('qml_file') spatial_files = tuple(spatial_files) @@ -218,8 +214,6 @@ def write_files(self): class NewLayerUploadForm(LayerUploadForm): if check_ogc_backend(geoserver.BACKEND_PACKAGE): sld_file = forms.FileField(required=False) - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - qml_file = forms.FileField(required=False) xml_file = forms.FileField(required=False) abstract = forms.CharField(required=False) @@ -238,8 +232,6 @@ class NewLayerUploadForm(LayerUploadForm): # Adding style file based on the backend if check_ogc_backend(geoserver.BACKEND_PACKAGE): spatial_files.append('sld_file') - if check_ogc_backend(qgis_server.BACKEND_PACKAGE): - spatial_files.append('qml_file') spatial_files = tuple(spatial_files) diff --git a/geonode/layers/templates/layers/layer_detail.html b/geonode/layers/templates/layers/layer_detail.html index f29caec6b26..ee15c48a46a 100644 --- a/geonode/layers/templates/layers/layer_detail.html +++ b/geonode/layers/templates/layers/layer_detail.html @@ -440,10 +440,6 @@

{% trans "Pick your download format:" %}

{% get_obj_perms request.user for resource.layer as "layer_perms" %} {% endif %} - {% if OGC_SERVER.default.BACKEND == 'geonode.qgis_server' %} - {% get_obj_perms request.user for resource.layer as "layer_perms" %} - {% endif %} -
  • @@ -496,14 +492,6 @@

    {% trans "Styles" %}

  • {% endif %} {% endif %} - {% elif OGC_SERVER.default.BACKEND == 'geonode.qgis_server' and not resource.service %} - {% if "change_layer_style" in layer_perms and preview == 'leaflet' %} - - {% endif %} {% endif %} {% if "change_resourcebase" in perms_list %}
    @@ -559,24 +547,24 @@

    {% trans "Layer" %}