def geoserver_post_save_thumbnail(sender, instance, **kwargs): # Creating Layer Thumbnail # some thumbnail generators will update thumbnail_url. If so, don't # immediately re-generate the thumbnail here. use layer#save(update_fields=['thumbnail_url']) try: instance.refresh_from_db() logger.debug(f"... Creating Thumbnail for Layer {instance.title}") _recreate_thumbnail = False if 'update_fields' in kwargs and kwargs['update_fields'] is not None and \ 'thumbnail_url' in kwargs['update_fields']: _recreate_thumbnail = True if not instance.thumbnail_url or \ instance.thumbnail_url == staticfiles.static(settings.MISSING_THUMBNAIL) or \ is_monochromatic_image(instance.thumbnail_url): _recreate_thumbnail = True if _recreate_thumbnail: geoserver_create_thumbnail.apply_async((( instance.id, False, True, ))) else: logger.debug( f"... Thumbnail for Layer {instance.title} already exists: {instance.thumbnail_url}" ) except Exception as e: logger.exception(e)
def geoserver_post_save_layers(self, instance_id, *args, **kwargs): """ Runs update layers. """ instance = None try: instance = Layer.objects.get(id=instance_id) except Layer.DoesNotExist: logger.debug(f"Layer id {instance_id} does not exist yet!") raise lock_id = f'{self.request.id}' with AcquireLock(lock_id) as lock: if lock.acquire() is True: # Don't run this signal if is a Layer from a remote service if getattr(instance, "remote_service", None) is not None: return if instance.storeType == "remoteStore": return # Don't run this signal handler if it is a tile layer or a remote store (Service) # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr( instance, 'storeType') in ['tileStore', 'remoteStore']: return instance if isinstance(instance, ResourceBase): if hasattr(instance, 'layer'): instance = instance.layer else: return geonode_upload_sessions = UploadSession.objects.filter( resource=instance) geonode_upload_sessions.update(processed=False) gs_resource = None values = None _tries = 0 _max_tries = getattr(ogc_server_settings, "MAX_RETRIES", 2) # If the store in None then it's a new instance from an upload, # only in this case run the geoserver_upload method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is no file. if base_file is None: return gs_name, workspace, values, gs_resource = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, charset=instance.charset) values, gs_resource = fetch_gs_resource(instance, values, _tries) while not gs_resource and _tries < _max_tries: values, gs_resource = fetch_gs_resource( instance, values, _tries) _tries += 1 # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) if gs_resource: logger.debug("Found geoserver resource for this layer: %s" % instance.name) gs_resource.metadata_links = metadata_links instance.gs_resource = gs_resource # Update Attribution link if instance.poc: # gsconfig now utilizes an attribution dictionary gs_resource.attribution = { 'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None } profile = get_user_model().objects.get( username=instance.poc.username) site_url = settings.SITEURL.rstrip( '/') if settings.SITEURL.startswith( 'http') else settings.SITEURL gs_resource.attribution_link = site_url + profile.get_absolute_url( ) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ try: # This is usually done in Layer.pre_save, however if the hooks # are bypassed by custom create/updates we need to ensure the # bbox is calculated properly. bbox = gs_resource.native_bbox instance.set_bbox_polygon( [bbox[0], bbox[2], bbox[1], bbox[3]], gs_resource.projection) except Exception as e: logger.exception(e) if instance.srid: instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" elif instance.bbox_polygon is not None: # Guessing 'EPSG:4326' by default instance.srid = 'EPSG:4326' else: raise GeoNodeException( "Invalid Projection. Layer is missing CRS!") # Iterate over values from geoserver. for key in ['alternate', 'store', 'storeType']: # attr_name = key if 'typename' not in key else 'alternate' # print attr_name setattr(instance, key, values[key]) try: if settings.RESOURCE_PUBLISHING: if instance.is_published != gs_resource.advertised: gs_resource.advertised = 'true' if not settings.FREETEXT_KEYWORDS_READONLY: # AF: Warning - this won't allow people to have empty keywords on GeoNode if len(instance.keyword_list() ) == 0 and gs_resource.keywords: for keyword in gs_resource.keywords: if keyword not in instance.keyword_list(): instance.keywords.add(keyword) if any(instance.keyword_list()): keywords = instance.keyword_list() gs_resource.keywords = [ kw for kw in list(set(keywords)) ] # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) except Exception as e: msg = ( 'Error while trying to save resource named %s in GeoServer, ' 'try to use: "%s"' % (gs_resource, str(e))) e.args = (msg, ) logger.exception(e) # store the resource to avoid another geoserver call in the post_save to_update = { 'title': instance.title or instance.name, 'abstract': instance.abstract or "", 'alternate': instance.alternate, 'bbox_polygon': instance.bbox_polygon, 'srid': 'EPSG:4326' } if is_monochromatic_image(instance.thumbnail_url): to_update['thumbnail_url'] = staticfiles.static( settings.MISSING_THUMBNAIL) # Save all the modified information in the instance without triggering signals. try: with transaction.atomic(): ResourceBase.objects.filter( id=instance.resourcebase_ptr.id).update( **to_update) # to_update['name'] = instance.name, to_update[ 'workspace'] = gs_resource.store.workspace.name to_update['store'] = gs_resource.store.name to_update['storeType'] = instance.storeType to_update['typename'] = instance.alternate Layer.objects.filter(id=instance.id).update( **to_update) # Refresh from DB instance.refresh_from_db() except Exception as e: logger.exception(e) # Refreshing CSW records logger.debug( f"... Updating the Catalogue entries for Layer {instance.title}" ) try: catalogue_post_save(instance=instance, sender=instance.__class__) except Exception as e: logger.exception(e) # Refreshing layer links logger.debug( f"... Creating Default Resource Links for Layer {instance.title}" ) try: set_resource_default_links(instance, instance, prune=True) except Exception as e: logger.exception(e) # Save layer attributes logger.debug( f"... Refresh GeoServer attributes list for Layer {instance.title}" ) try: set_attributes_from_geoserver(instance) except Exception as e: logger.exception(e) # Save layer styles logger.debug( f"... Refresh Legend links for Layer {instance.title}") try: set_styles(instance, gs_catalog) except Exception as e: logger.exception(e) # Invalidate GeoWebCache for the updated resource try: _stylefilterparams_geowebcache_layer(instance.alternate) _invalidate_geowebcache_layer(instance.alternate) except Exception: pass # Creating Layer Thumbnail by sending a signal from geonode.geoserver.signals import geoserver_post_save_complete geoserver_post_save_complete.send(sender=instance.__class__, instance=instance) try: geonode_upload_sessions = UploadSession.objects.filter( resource=instance) geonode_upload_sessions.update(processed=True) except Exception as e: logger.exception(e) # Updating HAYSTACK Indexes if needed if settings.HAYSTACK_SEARCH: call_command('update_index')