Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #665 Layer UUID handler #666

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
749c8ee
[Fixes #6929] Do not overwrite existing thumbnails if the image is b…
Feb 5, 2021
74b2729
[Fixes #6929] Do not overwrite existing thumbnails if the image is b…
afabiani Feb 5, 2021
38c7241
Add uuid handler setting
mattiagiupponi Feb 8, 2021
fd4690a
- minor updates
Feb 8, 2021
4c8e824
[Fixes #6938] Basic auth middleware (#6939)
Feb 8, 2021
38959bd
Implement layer embed view in GeoNode
afabiani Feb 9, 2021
1f8c053
Implement layer embed view in GeoNode
afabiani Feb 9, 2021
3548313
Bump setuptools from 52.0.0 to 53.0.0 (#6937)
dependabot[bot] Feb 9, 2021
c0f539d
Bump pytz from 2020.5 to 2021.1 (#6931)
dependabot[bot] Feb 9, 2021
c71fb94
Bump ipython from 7.19.0 to 7.20.0 (#6932)
dependabot[bot] Feb 9, 2021
93e847c
Update httplib2 requirement from <0.18.2 to <0.19.1 (#6933)
dependabot[bot] Feb 9, 2021
1e2e470
Bump owslib from 0.22.0 to 0.23.0 (#6935)
dependabot[bot] Feb 9, 2021
7e0ff1d
Bump sqlalchemy from 1.3.22 to 1.3.23 (#6936)
dependabot[bot] Feb 9, 2021
8ea3bc6
Bump boto3 from 1.16.60 to 1.17.4 (#6941)
dependabot[bot] Feb 9, 2021
0fff86a
[Dependencies] Align setup.cfg to requirements.txt
afabiani Feb 9, 2021
372123d
[Issue #6843] Remove six library (#6839)
burner761 Feb 10, 2021
f0b278d
Defer and preload assets to optimise page loading times (#6943)
Feb 10, 2021
5a08c8a
Add pluggable LAYER_UUID_HANDLER
mattiagiupponi Feb 10, 2021
cecb348
Typo removed from settings.py
mattiagiupponi Feb 10, 2021
36c28d6
Fix flake8 indentation in layer_utis
mattiagiupponi Feb 10, 2021
0ad9d61
fix typo in italian translation
giohappy Feb 10, 2021
935ffbd
[Regression] upload empty perms override default owner ones
afabiani Feb 10, 2021
3ae2a01
Merge branch 'master' of https://github.com/GeoNode/geonode
afabiani Feb 10, 2021
10a6643
[Issue #6843] Replace use of python_image_resize with Pillow image.re…
binkiesbane Feb 11, 2021
2f26d10
[Issue #6843] Simplify long conditionals (#6846)
burner761 Feb 11, 2021
94ed977
[Issue #6843] Split get/post/put handling (#6848)
niamh-av Feb 11, 2021
12c4f78
Resolves #665: add uuid as exposed parameter in api
mattiagiupponi Feb 15, 2021
a51ab70
Bump drf-spectacular from 0.13.1 to 0.13.2 (#6950)
dependabot[bot] Feb 15, 2021
ddcc1f0
Bump drf-extensions from 0.6.0 to 0.7.0 (#6948)
dependabot[bot] Feb 15, 2021
4401279
Bump tqdm from 4.56.0 to 4.56.2 (#6947)
dependabot[bot] Feb 15, 2021
2de34ea
Bump boto3 from 1.17.4 to 1.17.7 (#6949)
dependabot[bot] Feb 15, 2021
499dafa
[Dependencies] Align setup.cfg to requirements.txt
Feb 15, 2021
548aaf4
Merge branch 'master' of https://github.com/GeoNode/geonode
Feb 15, 2021
ce20d4d
Merge remote-tracking branch 'upstream/master' into layer_uuid_handler
mattiagiupponi Feb 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions geonode/api/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,11 @@ class GroupAuthorization(ApiLockdownAuthorization):
def read_list(self, object_list, bundle):
groups = super(GroupAuthorization, self).read_list(object_list, bundle)
user = bundle.request.user
if groups and (not user.is_authenticated or user.is_anonymous):
return groups.exclude(groupprofile__access='private')
elif groups and not user.is_superuser:
return groups.filter(Q(groupprofile__in=user.group_list_all()) | ~Q(groupprofile__access='private'))
if groups:
if not user.is_authenticated or user.is_anonymous:
return groups.exclude(groupprofile__access='private')
elif not user.is_superuser:
return groups.filter(Q(groupprofile__in=user.group_list_all()) | ~Q(groupprofile__access='private'))
return groups


Expand All @@ -182,8 +183,9 @@ class GroupProfileAuthorization(ApiLockdownAuthorization):
def read_list(self, object_list, bundle):
groups = super(GroupProfileAuthorization, self).read_list(object_list, bundle)
user = bundle.request.user
if groups and (not user.is_authenticated or user.is_anonymous):
return groups.exclude(access='private')
elif groups and not user.is_superuser:
return groups.filter(Q(pk__in=user.group_list_all()) | ~Q(access='private'))
if groups:
if not user.is_authenticated or user.is_anonymous:
return groups.exclude(access='private')
elif not user.is_superuser:
return groups.filter(Q(pk__in=user.group_list_all()) | ~Q(access='private'))
return groups
1 change: 1 addition & 0 deletions geonode/api/resourcebase_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class CommonMetaApi:
'owner': ALL_WITH_RELATIONS,
'date': ALL,
'purpose': ALL,
'uuid': ALL_WITH_RELATIONS,
'abstract': ALL
}
ordering = ['date', 'title', 'popular_count']
Expand Down
13 changes: 6 additions & 7 deletions geonode/base/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#
#########################################################################
import re
import six
import html
import logging

Expand Down Expand Up @@ -220,7 +219,7 @@ def render_options(self, selected_choices):
# Normalize to strings.
def _region_id_from_choice(choice):
if isinstance(choice, int) or \
(isinstance(choice, six.string_types) and choice.isdigit()):
(isinstance(choice, str) and choice.isdigit()):
return int(choice)
else:
return choice.id
Expand All @@ -232,7 +231,7 @@ def _region_id_from_choice(choice):
for option_value, option_label in self.choices:
if not isinstance(
option_label, (list, tuple)) and isinstance(
option_label, six.string_types):
option_label, str):
output.append(
self.render_option_value(
selected_choices,
Expand All @@ -243,18 +242,18 @@ def _region_id_from_choice(choice):
for option_value, option_label in self.choices:
if isinstance(
option_label, (list, tuple)) and not isinstance(
option_label, six.string_types):
option_label, str):
output.append(
format_html(
'<optgroup label="{}">',
force_text(option_value)))
for option in option_label:
if isinstance(
option, (list, tuple)) and not isinstance(
option, six.string_types):
option, str):
if isinstance(
option[1][0], (list, tuple)) and not isinstance(
option[1][0], six.string_types):
option[1][0], str):
for option_child in option[1][0]:
output.append(
self.render_option_value(
Expand Down Expand Up @@ -442,7 +441,7 @@ def clean_keywords(self):
_unsescaped_kwds = []
for k in keywords:
_k = ('%s' % re.sub(r'%([A-Z0-9]{2})', r'&#x\g<1>;', k.strip())).split(",")
if not isinstance(_k, six.string_types):
if not isinstance(_k, str):
for _kk in [html.unescape(x.strip()) for x in _k]:
# Simulate JS Unescape
_kk = _kk.replace('%u', r'\u').encode('unicode-escape').replace(
Expand Down
3 changes: 1 addition & 2 deletions geonode/base/management/commands/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#########################################################################

import os
import six
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
Expand Down Expand Up @@ -52,7 +51,7 @@ def confirm(prompt=None, resp=False):
prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y')

while True:
ans = six.moves.input(prompt)
ans = input(prompt)
if not ans:
return resp
if ans not in {'y', 'Y', 'n', 'N'}:
Expand Down
107 changes: 54 additions & 53 deletions geonode/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@

from mptt.models import MPTTModel, TreeForeignKey

from PIL import Image
from io import BytesIO
from resizeimage import resizeimage
from PIL import Image, ImageOps

from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
Expand All @@ -71,6 +69,7 @@
DEFAULT_SUPPLEMENTAL_INFORMATION)
from geonode.base.bbox_utils import BBOXHelper
from geonode.utils import (
is_monochromatic_image,
add_url_params,
bbox_to_wkt)
from geonode.groups.models import GroupProfile
Expand All @@ -83,6 +82,7 @@
from geonode.people.enumerations import ROLE_VALUES
from geonode.base.thumb_utils import (
thumb_path,
thumb_size,
remove_thumbs)

from pyproj import transform, Proj
Expand Down Expand Up @@ -930,28 +930,28 @@ def save(self, notify=False, *args, **kwargs):
_notification_sent = False

# Approval Notifications Here
if not _notification_sent and settings.ADMIN_MODERATE_UPLOADS:
if not self.__is_approved and self.is_approved:
# Set "approved" workflow permissions
self.set_workflow_perms(approved=True)
if not _notification_sent and settings.ADMIN_MODERATE_UPLOADS and \
not self.__is_approved and self.is_approved:
# Set "approved" workflow permissions
self.set_workflow_perms(approved=True)

# Send "approved" notification
notice_type_label = '%s_approved' % self.class_name.lower()
recipients = get_notification_recipients(notice_type_label, resource=self)
send_notification(recipients, notice_type_label, {'resource': self})
_notification_sent = True
# Send "approved" notification
notice_type_label = '%s_approved' % self.class_name.lower()
recipients = get_notification_recipients(notice_type_label, resource=self)
send_notification(recipients, notice_type_label, {'resource': self})
_notification_sent = True

# Publishing Notifications Here
if not _notification_sent and settings.RESOURCE_PUBLISHING:
if not self.__is_published and self.is_published:
# Set "published" workflow permissions
self.set_workflow_perms(published=True)
if not _notification_sent and settings.RESOURCE_PUBLISHING and \
not self.__is_published and self.is_published:
# Set "published" workflow permissions
self.set_workflow_perms(published=True)

# Send "published" notification
notice_type_label = '%s_published' % self.class_name.lower()
recipients = get_notification_recipients(notice_type_label, resource=self)
send_notification(recipients, notice_type_label, {'resource': self})
_notification_sent = True
# Send "published" notification
notice_type_label = '%s_published' % self.class_name.lower()
recipients = get_notification_recipients(notice_type_label, resource=self)
send_notification(recipients, notice_type_label, {'resource': self})
_notification_sent = True

# Updated Notifications Here
if not _notification_sent:
Expand Down Expand Up @@ -1130,22 +1130,22 @@ def license_light(self):
a = []
if not self.license:
return ''
if (not (self.license.name is None)) and (len(self.license.name) > 0):
if self.license.name is not None and (len(self.license.name) > 0):
a.append(self.license.name)
if (not (self.license.url is None)) and (len(self.license.url) > 0):
if self.license.url is not None and (len(self.license.url) > 0):
a.append("(" + self.license.url + ")")
return " ".join(a)

@property
def license_verbose(self):
a = []
if (not (self.license.name_long is None)) and (
if self.license.name_long is not None and (
len(self.license.name_long) > 0):
a.append(self.license.name_long + ":")
if (not (self.license.description is None)) and (
if self.license.description is not None and (
len(self.license.description) > 0):
a.append(self.license.description)
if (not (self.license.url is None)) and (len(self.license.url) > 0):
if self.license.url is not None and (len(self.license.url) > 0):
a.append("(" + self.license.url + ")")
return " ".join(a)

Expand Down Expand Up @@ -1459,14 +1459,16 @@ def save_thumbnail(self, filename, image):

try:
# Check that the image is valid
content_data = BytesIO(image)
im = Image.open(content_data)
im.verify() # verify that it is, in fact an image

name, ext = os.path.splitext(filename)
remove_thumbs(name)
if is_monochromatic_image(None, image):
if not self.thumbnail_url and not image:
raise Exception("Generated thumbnail image is blank")
else:
# Skip Image creation
image = None

if upload_path and image:
name, ext = os.path.splitext(filename)
remove_thumbs(name)
actual_name = storage.save(upload_path, ContentFile(image))
url = storage.url(actual_name)
_url = urlparse(url)
Expand All @@ -1490,9 +1492,7 @@ def save_thumbnail(self, filename, image):
im.thumbnail(
(_default_thumb_size['width'], _default_thumb_size['height']),
resample=Image.ANTIALIAS)
cover = resizeimage.resize_cover(
im,
[_default_thumb_size['width'], _default_thumb_size['height']])
cover = ImageOps.fit(im, (_default_thumb_size['width'], _default_thumb_size['height']))
cover.save(storage.path(_upload_path), format='JPEG')
except Exception as e:
logger.debug(e)
Expand All @@ -1504,11 +1504,12 @@ def save_thumbnail(self, filename, image):
site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
url = urljoin(site_url, url)

if thumb_size(_upload_path) == 0:
raise Exception("Generated thumbnail image is zero size")

# should only have one 'Thumbnail' link
_links = Link.objects.filter(resource=self, name='Thumbnail')
if _links and _links.count() > 1:
_links.delete()
obj, created = Link.objects.get_or_create(
Link.objects.filter(resource=self, name='Thumbnail').delete()
obj, _created = Link.objects.get_or_create(
resource=self,
name='Thumbnail',
defaults=dict(
Expand All @@ -1532,7 +1533,7 @@ def save_thumbnail(self, filename, image):
try:
Link.objects.filter(resource=self, name='Thumbnail').delete()
_thumbnail_url = staticfiles.static(settings.MISSING_THUMBNAIL)
obj, created = Link.objects.get_or_create(
obj, _created = Link.objects.get_or_create(
resource=self,
name='Thumbnail',
defaults=dict(
Expand All @@ -1559,19 +1560,6 @@ def set_missing_info(self):
It is mandatory to call it from descendant classes
but hard to enforce technically via signals or save overriding.
"""
from guardian.models import UserObjectPermission
logger.debug('Checking for permissions.')
# True if every key in the get_all_level_info dict is empty.
no_custom_permissions = UserObjectPermission.objects.filter(
content_type=ContentType.objects.get_for_model(
self.get_self_resource()), object_pk=str(
self.pk)).exists()

if not no_custom_permissions:
logger.debug(
'There are no permissions for this object, setting default perms.')
self.set_default_permissions()

user = None
if self.owner:
user = self.owner
Expand All @@ -1587,6 +1575,19 @@ def set_missing_info(self):
if self.metadata_author is None:
self.metadata_author = user

from guardian.models import UserObjectPermission
logger.debug('Checking for permissions.')
# True if every key in the get_all_level_info dict is empty.
no_custom_permissions = UserObjectPermission.objects.filter(
content_type=ContentType.objects.get_for_model(
self.get_self_resource()), object_pk=str(
self.pk)).exists()

if not no_custom_permissions:
logger.debug(
'There are no permissions for this object, setting default perms.')
self.set_default_permissions(owner=user)

def maintenance_frequency_title(self):
return [v for v in UPDATE_FREQUENCIES if v[0] == self.maintenance_frequency][0][1].title()

Expand Down
3 changes: 1 addition & 2 deletions geonode/base/populate_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################
import six
import logging
import os.path

Expand Down Expand Up @@ -110,7 +109,7 @@ def it():
itinst = it()

def callable():
return six.next(itinst)
return next(itinst)
return callable

next_date = get_test_date()
Expand Down
Loading