def default_qml_style(request, layername, style_name=None): """Set default style used by layer. :param layername: The layer name in Geonode. :type layername: basestring :param style_name: The style name recognized by QGIS Server :type style_name: str """ layer = get_object_or_404(Layer, name=layername) if request.method == 'GET': # Handle querying default style name request default_style = layer.qgis_layer.default_style retval = { 'name': default_style.name, 'title': default_style.title, 'style_url': default_style.style_url } return HttpResponse(json.dumps(retval), content_type='application/json') elif request.method == 'POST': # For people who uses API request if not request.user.has_perm('change_resourcebase', layer.get_self_resource()): return HttpResponse( 'User does not have permission to change QML style.', status=403) if not style_name: return HttpResponseBadRequest() style_url = style_set_default_url(layer, style_name) response = requests.get(style_url) if not (response.status_code == 200 and response.content == 'OK'): return HttpResponseServerError('Failed to change default Style.' 'Error: {0}'.format( response.content)) # Succesfully change default style # Synchronize models style = layer.qgis_layer.styles.get(name=style_name) qgis_layer = layer.qgis_layer qgis_layer.default_style = style qgis_layer.save() alert_message = 'Successfully changed default style %s' % style_name return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': QGISLayerStyleUploadForm(), 'alert': True, 'alert_message': alert_message, 'alert_class': 'alert-success' }, status=200).render()
def qgis_server_urls(request): """Global values to pass to templates""" defaults = dict( UPLOADER_URL=reverse('data_upload') if getattr( settings, 'UPLOADER', dict()).get( 'BACKEND', 'geonode.rest') == 'geonode.importer' else reverse('layer_upload'), LAYER_ANCILLARY_FILES_UPLOAD_URL=reverse('layer_upload'), MAPFISH_PRINT_ENABLED=getattr(ogc_server_settings, 'MAPFISH_PRINT_ENABLED', False), PRINT_NG_ENABLED=getattr(ogc_server_settings, 'PRINT_NG_ENABLED', False), GEONODE_SECURITY_ENABLED=getattr(ogc_server_settings, 'GEONODE_SECURITY_ENABLED', False), GEOGIG_ENABLED=getattr(ogc_server_settings, 'GEOGIG_ENABLED', False), TIME_ENABLED=getattr( settings, 'UPLOADER', dict()).get( 'OPTIONS', dict()).get( 'TIME_ENABLED', False), MOSAIC_ENABLED=getattr( settings, 'UPLOADER', dict()).get( 'OPTIONS', dict()).get( 'MOSAIC_ENABLED', False), ) defaults['style_upload_form'] = QGISLayerStyleUploadForm() return defaults
def qml_style(request, layername, style_name=None): """Update/Retrieve QML style of a given QGIS Layer. :param layername: The layer name in Geonode. :type layername: basestring :param style_name: The style name recognized by QGIS Server :type style_name: str """ layer = get_object_or_404(Layer, name=layername) if request.method == 'GET': # Request QML from QGIS server if not style_name: # If no style name provided, then it is a List request styles_obj = None try: styles_obj = style_list(layer, internal=False) except BaseException: print 'Failed to fetch styles' styles_dict = [] if styles_obj: styles_dict = [model_to_dict(s) for s in styles_obj] # If no style returned by GetCapabilities, this is a bug in QGIS # Attempt to generate default style name if not styles_dict: style_url = style_get_url(layer, 'default') response = requests.get(style_url) if response.status_code == 200: style_url = style_add_url(layer, 'default') with open(layer.qgis_layer.qml_path, 'w') as f: f.write(response.content) response = requests.get(style_url) if response.status_code == 200: styles_obj = style_list(layer, internal=False) styles_dict = [model_to_dict(s) for s in styles_obj] response = HttpResponse( json.dumps(styles_dict), content_type='application/json') return response # Return XML file of the style style_url = style_get_url(layer, style_name, internal=False) response = requests.get(style_url) if response.status_code == 200: response = HttpResponse( response.content, content_type='text/xml') response[ 'Content-Disposition'] = 'attachment; filename=%s.qml' % ( style_name, ) else: response = HttpResponse( response.content, status=response.status_code) return response elif request.method == 'POST': # For people who uses API request if not request.user.has_perm( 'change_resourcebase', layer.get_self_resource()): return HttpResponse( 'User does not have permission to change QML style.', status=403) # Request about adding new QML style form = QGISLayerStyleUploadForm(request.POST, request.FILES) if not form.is_valid(): return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': form }, status=400).render() try: uploaded_qml = request.FILES['qml'] # update qml in uploaded media folder # check upload session, is qml file exists? layerfile_set = layer.upload_session.layerfile_set try: qml_layer_file = layerfile_set.get(name='qml') # if it is exists, we need to delete it, because it won't be # managed by geonode qml_layer_file.delete() except LayerFile.DoesNotExist: pass # update qml in QGIS Layer folder content = uploaded_qml.read() qgis_layer = get_object_or_404(QGISServerLayer, layer=layer) with open(qgis_layer.qml_path, mode='w') as f: f.write(content) # construct URL to post new QML style_name = request.POST['name'] style_title = request.POST['title'] if not style_name: # Assign default name name_format = 'style_%Y%m%d%H%M%S' current_time = datetime.datetime.utcnow() style_name = current_time.strftime(name_format) # Add new style style_url = style_add_url(layer, style_name) response = requests.get(style_url) if not (response.status_code == 200 and response.content == 'OK'): try: style_list(layer, internal=False) except BaseException: print 'Failed to fetch styles' return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': QGISLayerStyleUploadForm(), 'alert': True, 'alert_message': response.content, 'alert_class': 'alert-danger' }, status=response.status_code).render() # We succeeded on adding new style # Refresh style models try: style_list(layer, internal=False) qgis_style = layer.qgis_layer.styles.get(name=style_name) qgis_style.title = style_title qgis_style.save() alert_message = 'Successfully add style %s' % style_name except BaseException: alert_message = 'Failed to fetch styles' return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': form, 'alert': True, 'alert_class': 'alert-success', 'alert_message': alert_message }, status=201).render() except Exception as e: logger.exception(e) return HttpResponseServerError() elif request.method == 'DELETE': # Request to delete particular QML Style if not style_name: # Style name should exists return HttpResponseBadRequest('Style name not provided.') # Handle removing tile-style cache try: style = layer.qgis_layer.styles.get(name=style_name) shutil.rmtree(style.style_tile_cache_path) except BaseException: pass style_url = style_remove_url(layer, style_name) response = requests.get(style_url) if not (response.status_code == 200 and response.content == 'OK'): alert_message = response.content if 'NAME is NOT an existing style.' in response.content: alert_message = '%s is not an existing style' % style_name try: style_list(layer, internal=False) except BaseException: print 'Failed to fetch styles' return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': QGISLayerStyleUploadForm(), 'alert': True, 'alert_message': alert_message, 'alert_class': 'alert-danger' }, status=response.status_code).render() # Successfully removed styles # Handle when default style is deleted. # Will be handled by style_list method try: style_list(layer, internal=False) alert_message = 'Successfully deleted style %s' % style_name except BaseException: alert_message = 'Failed to fetch styles' return TemplateResponse( request, 'qgis_server/forms/qml_style.html', { 'resource': layer, 'style_upload_form': QGISLayerStyleUploadForm(), 'alert': True, 'alert_message': alert_message, 'alert_class': 'alert-success' }, status=200).render() return HttpResponseBadRequest()