def user_projects(request, username): if not request.user.is_authenticated() or request.user.is_guest: # redirect to login page login_url = secure_url(request, reverse('login')) return HttpResponseRedirect(set_query_parameters(login_url, {'next': secure_url(request)})) if not username: redirect_url = secure_url(request, reverse('viewer:user_projects', kwargs={'username': request.user.username})) return HttpResponseRedirect(redirect_url) if username != request.user.username: if not request.user.is_superuser: return HttpResponse("Access Denied", content_type='text/plain', status=403) else: try: request.user = models.GislabUser.objects.get(username=username) except models.GislabUser.DoesNotExist: return HttpResponse("User does not exist.", content_type='text/plain', status=403) projects = [{ 'title': _('Empty Project'), 'url': request.build_absolute_uri('/'), }] projects.extend(webclient.get_user_projects(request, username)) context = { 'username': username, 'projects': projects, 'debug': settings.DEBUG } return render(request, "viewer/user_projects.html", context, content_type="text/html")
def map(request): try: project_data = get_project(request) return render( request, "viewer/index.html", { 'user': request.user, 'project': json.dumps(project_data) }, content_type="text/html" ) except LoginRequiredException: # redirect to login page return HttpResponseRedirect( set_query_parameters( reverse('login'), {'next': request.get_full_path()} ) ) except AccessDeniedException: msg = "You don't have permissions for this project" status = 403 except InvalidProjectException: msg = "Error when loading project or project does not exist" status = 404 except ProjectExpiredException: msg = "Project has reached expiration date.", status = 410 except Exception, e: msg = "Server error" #TODO: log exception error raise status = 500
def mapcache_legend_request(self, request, project_hash, publish, layer_hash=None, zoom=None, format=None): params = { key.upper(): request.GET[key] for key in request.GET.iterkeys() } project = params['PROJECT'] + '.qgs' try: layer = WmsLayer( project=project_hash, publish=publish, name=layer_hash, provider_layers=params['LAYER'].encode('utf-8'), provider_url=set_query_parameters( settings.GISLAB_WEB_MAPSERVER_URL, {'MAP': project}), image_format=format, ) params.pop('PROJECT') params.pop('LAYER') return get_legendgraphic_response(layer, zoom, **params) except: raise Http404
def web_client(request): try: return webclient.project_request(request) except LoginRequired, e: # redirect to login page login_url = secure_url(request, reverse('login')) return HttpResponseRedirect(set_query_parameters(login_url, {'next': secure_url(request)}))
def ows(request): params = {key.upper(): request.GET[key] for key in request.GET.keys()} url = "{0}?{1}".format(settings.GISQUICK_MAPSERVER_URL.rstrip("/"), request.environ['QUERY_STRING']) abs_project = abs_project_path(params.get('MAP')) url = set_query_parameters(url, {'MAP': abs_project}) owsrequest = urllib.request.Request(url) owsrequest.add_header("User-Agent", "Gisquick") resp_content = b"" with contextlib.closing(urllib.request.urlopen(owsrequest)) as resp: while True: data = resp.read() if not data: break resp_content += data if params.get('REQUEST', '') == 'GetCapabilities': resp_content = resp_content.replace( settings.GISQUICK_MAPSERVER_URL.encode(), request.build_absolute_uri(request.path).encode()) content_type = resp.getheader('Content-Type') status = resp.getcode() return HttpResponse(resp_content, content_type=content_type, status=status)
def tile(request, project_hash, publish, layers_hash=None, z=None, x=None, y=None, format=None): params = {key.upper(): request.GET[key] for key in request.GET.keys()} project = params['PROJECT'] + '.qgs' mapserver_url = set_query_parameters(settings.GISQUICK_MAPSERVER_URL, {'MAP': abs_project_path(project)}) layer_params = get_project_layers_info(project_hash, publish, project=project) if layer_params: try: layer = WmsLayer(project=project_hash, publish=publish, name=layers_hash, provider_layers=params['LAYERS'].encode("utf-8"), provider_url=mapserver_url, image_format=format, tile_size=256, metasize=5, **layer_params) return get_tile_response(layer, z=z, x=x, y=y) except TileNotFoundException as e: raise Http404 raise Http404
def legend(request, project_hash, publish, layer_hash=None, zoom=None, format=None): params = {key.upper(): request.GET[key] for key in request.GET.keys()} project = params['PROJECT'] + '.qgs' mapserver_url = set_query_parameters(settings.GISQUICK_MAPSERVER_URL, {'MAP': abs_project_path(project)}) project_info = get_project_info(project_hash, publish, project=project) if not project_info: raise Http404 if not check_project_access(request, params['PROJECT'], project_info['authentication']): raise PermissionDenied try: layer = WmsLayer( project=project_hash, publish=publish, name=layer_hash, provider_layers=params['LAYER'].encode('utf-8'), provider_url=mapserver_url, image_format=format, ) params.pop('PROJECT') params.pop('LAYER') return get_legendgraphic_response(layer, zoom, **params) except: raise Http404
def tile(request, project_hash, publish, layers_hash=None, z=None, x=None, y=None, format=None): params = {key.upper(): request.GET[key] for key in request.GET.keys()} project = params['PROJECT'] + '.qgs' mapserver_url = set_query_parameters(settings.GISQUICK_MAPSERVER_URL, {'MAP': abs_project_path(project)}) project_info = get_project_info(project_hash, publish, project=project) if not project_info: raise Http404 if not check_project_access(request, params['PROJECT'], project_info['authentication']): raise PermissionDenied try: layer = WmsLayer(project=project_hash, publish=publish, name=layers_hash, provider_layers=params['LAYERS'].encode("utf-8"), provider_url=mapserver_url, image_format=format, tile_size=256, metasize=5, extent=project_info['extent'], resolutions=project_info['tile_resolutions'], projection=project_info['projection']['code']) return get_tile_response(layer, z=z, x=x, y=y) except TileNotFoundException as e: raise Http404
def page(request): try: return client.project_request(request) except LoginRequired, e: # redirect to login page login_url = secure_url(request, reverse('login')) return HttpResponseRedirect( set_query_parameters(login_url, {'next': secure_url(request)}))
def mapcache_legend_request(self, request, project_hash, publish, layer_hash=None, zoom=None, format=None): params = {key.upper(): request.GET[key] for key in request.GET.iterkeys()} project = params['PROJECT']+'.qgs' try: layer = WmsLayer( project=project_hash, publish=publish, name=layer_hash, provider_layers=params['LAYER'].encode('utf-8'), provider_url=set_query_parameters(settings.GISLAB_WEB_MAPSERVER_URL, {'MAP': project}), image_format=format, ) params.pop('PROJECT') params.pop('LAYER') return get_legendgraphic_response(layer, zoom, **params) except: raise Http404
def _test_geometry_filter(self): # test is not finished yet and now it's crashing due to bug in QGIS server geometry = ( '<Polygon>' '<exterior>' '<LinearRing>' '<posList>' '1881392.6859162913 6873826.01525614 ' '1881342.6859162913 6873912.61779651 ' '1881242.6859162913 6873912.61779651 ' '1881192.6859162913 6873826.01525614 ' '1881242.6859162913 6873739.41271576 ' '1881342.6859162913 6873739.41271576 ' '1881392.6859162913 6873826.01525614' '</posList>' '</LinearRing>' '</exterior>' '</Polygon>' ) spatial_filter = ( '<Filter>' '<ogc:Intersects>' '<ogc:PropertyName>geometry</ogc:PropertyName>' '{0}' '</ogc:Intersects>' '</Filter>' ).format(geometry) url = set_query_parameters( self.url, { 'SERVICE': 'WFS', 'VERSION': '1.0.0', 'REQUEST': 'GetFeature', 'TYPENAME': 'Places,Roads,Other', 'OUTPUTFORMAT': 'GeoJSON', 'FILTER': spatial_filter } ) # print "\nexport QUERY_STRING=\""+urllib.unquote(url)\ # .replace("http://localhost/cgi-bin/qgis_mapserv.fcgi?", "")+"\"" response = urllib2.urlopen(url).read() data = json.loads(response) features = data['features']
def _test_geometry_filter(self): # test is not finished yet and now it's crashing due to bug in QGIS server geometry = ( "<Polygon>" "<exterior>" "<LinearRing>" "<posList>" "1881392.6859162913 6873826.01525614 " "1881342.6859162913 6873912.61779651 " "1881242.6859162913 6873912.61779651 " "1881192.6859162913 6873826.01525614 " "1881242.6859162913 6873739.41271576 " "1881342.6859162913 6873739.41271576 " "1881392.6859162913 6873826.01525614" "</posList>" "</LinearRing>" "</exterior>" "</Polygon>" ) spatial_filter = ( "<Filter>" "<ogc:Intersects>" "<ogc:PropertyName>geometry</ogc:PropertyName>" "{0}" "</ogc:Intersects>" "</Filter>" ).format(geometry) url = set_query_parameters( self.url, { "SERVICE": "WFS", "VERSION": "1.0.0", "REQUEST": "GetFeature", "TYPENAME": "Places,Roads,Other", "OUTPUTFORMAT": "GeoJSON", "FILTER": spatial_filter, }, ) response = urllib.request.urlopen(url).read() data = json.loads(response) features = data["features"] self.assertEqual(len(features), 2)
def _test_geometry_filter(self): # test is not finished yet and now it's crashing due to bug in QGIS server geometry = ( '<Polygon>' '<exterior>' '<LinearRing>' '<posList>' '1881392.6859162913 6873826.01525614 ' '1881342.6859162913 6873912.61779651 ' '1881242.6859162913 6873912.61779651 ' '1881192.6859162913 6873826.01525614 ' '1881242.6859162913 6873739.41271576 ' '1881342.6859162913 6873739.41271576 ' '1881392.6859162913 6873826.01525614' '</posList>' '</LinearRing>' '</exterior>' '</Polygon>' ) spatial_filter = ( '<Filter>' '<ogc:Intersects>' '<ogc:PropertyName>geometry</ogc:PropertyName>' '{0}' '</ogc:Intersects>' '</Filter>' ).format(geometry) url = set_query_parameters( self.url, { 'SERVICE': 'WFS', 'VERSION': '1.0.0', 'REQUEST': 'GetFeature', 'TYPENAME': 'Places,Roads,Other', 'OUTPUTFORMAT': 'GeoJSON', 'FILTER': spatial_filter } ) response = urllib.request.urlopen(url).read() data = json.loads(response) features = data['features'] self.assertEqual(len(features), 2)
def user_projects(request, username): if not request.user.is_authenticated() or request.user.is_guest: # redirect to login page login_url = secure_url(request, reverse('login')) return HttpResponseRedirect( set_query_parameters(login_url, {'next': secure_url(request)})) if not username: redirect_url = user_projects_url(request.user.username) return HttpResponseRedirect(redirect_url) if username != request.user.username: if not request.user.is_superuser: return HttpResponse( "Access Denied", content_type='text/plain', status=403 ) else: try: request.user = models.GislabUser.objects.get(username=username) except models.GislabUser.DoesNotExist: return HttpResponse( "User does not exist.", content_type='text/plain', status=403 ) projects = [{ 'title': _('Empty Project'), 'url': request.build_absolute_uri('/'), }] projects.extend(get_user_projects(request, username)) context = { 'username': username, 'projects': projects, 'debug': settings.DEBUG } return render( request, "viewer/user_projects.html", context, content_type="text/html" )
def mapcache_tile_request(self, request, project_hash, publish, layers_hash=None, z=None, x=None, y=None, format=None): params = {key.upper(): request.GET[key] for key in request.GET.iterkeys()} project = params['PROJECT']+'.qgs' layer_params = get_project_layers_info(project_hash, publish, project=project) if layer_params: try: layer = WmsLayer( project=project_hash, publish=publish, name=layers_hash, provider_layers=params['LAYERS'].encode("utf-8"), provider_url=set_query_parameters(settings.GISLAB_WEB_MAPSERVER_URL, {'MAP': project}), image_format=format, tile_size=256, metasize=5, **layer_params ) return get_tile_response(layer, z=z, x=x, y=y) except TileNotFoundException, e: raise Http404
def ows(request): url = "{0}?{1}".format( settings.GISQUICK_MAPSERVER_URL.rstrip("/"), request.environ['QUERY_STRING'] ) query_params = parse_qs(request.environ['QUERY_STRING']) abs_project = abs_project_path(query_params.get('MAP')[0]) url = set_query_parameters(url, {'MAP': abs_project}) owsrequest = urllib.request.Request(url) owsrequest.add_header("User-Agent", "Gisquick") resp_content = b"" with contextlib.closing(urllib.request.urlopen(owsrequest)) as resp: while True: data = resp.read() if not data: break resp_content += data content_type = resp.getheader('Content-Type') status = resp.getcode() return HttpResponse(resp_content, content_type=content_type, status=status)
def get_user_projects(request, username): projects = [] projects_root = os.path.join(settings.GISQUICK_PROJECT_ROOT, username) project_prefix_length = len( os.path.join(settings.GISQUICK_PROJECT_ROOT, '')) for root, dirs, files in os.walk(projects_root, followlinks=True): if files: # analyze project filenames and group different publications of the same project into one record projects_files = {} project_pattern = re.compile('(.+)_(\d{10})\.qgs') for filename in files: match = project_pattern.match(filename) if match: project_name = match.group(1) project_timestamp = int(match.group(2)) elif filename.endswith('.qgs'): project_name = filename[:-4] project_timestamp = 0 else: continue metadata_filename = filename[:-4] + '.meta' if metadata_filename in files: if project_name not in projects_files: projects_files[project_name] = [(project_timestamp, filename)] else: projects_files[project_name].append( (project_timestamp, filename)) for project_name, info in projects_files.items(): # select last project version by timestamp last_project_filename = sorted(info, reverse=True)[0][1] project_filename = os.path.join(root, project_name) ows_project_filename = os.path.join(root, last_project_filename) project = clean_project_name( project_filename[project_prefix_length:]) ows_project = clean_project_name( ows_project_filename[project_prefix_length:]) metadata_filename = clean_project_name( ows_project_filename) + '.meta' try: metadata = MetadataParser(metadata_filename) url = set_query_parameters(map_url(), {'PROJECT': project}) ows_url = project_ows_url(ows_project) authentication = metadata.authentication # backward compatibility with older version if type(authentication) is dict: if authentication.get('allow_anonymous') and \ not authentication.get('require_superuser'): authentication = 'all' else: authentication = 'authenticated' projects.append({ 'title': metadata.title, 'url': url, 'project': project, 'ows_url': ows_url, 'cache': metadata.use_mapcache, 'authentication': authentication, 'publication_time_unix': int(metadata.publish_date_unix), 'publication_time': metadata.publish_date, 'expiration_time': metadata.expiration if metadata.expiration else '' #'expiration_time_unix': int(time.mktime(time.strptime(metadata.expiration, "%d.%m.%Y"))) if metadata.expiration else None }) except IOError: # metadata file does not exists or not valid pass return projects
def get_user_projects(request, username): projects = [] projects_root = os.path.join(settings.GISLAB_WEB_PROJECT_ROOT, username) project_prefix_length = len(os.path.join(settings.GISLAB_WEB_PROJECT_ROOT, '')) for root, dirs, files in os.walk(projects_root): if files: # analyze project filenames and group different publications of the same project into one record projects_files = {} project_pattern = re.compile('(.+)_(\d{10})\.qgs') for filename in files: match = project_pattern.match(filename) if match: project_name = match.group(1) project_timestamp = int(match.group(2)) elif filename.endswith('.qgs'): project_name = filename[:-4] project_timestamp = 0 else: continue metadata_filename = filename[:-4]+'.meta' if metadata_filename in files: if project_name not in projects_files: projects_files[project_name] = [(project_timestamp, filename)] else: projects_files[project_name].append((project_timestamp, filename)) for project_name, info in projects_files.items(): # select last project version by timestamp last_project_filename = sorted(info, reverse=True)[0][1] project_filename = os.path.join(root, project_name) ows_project_filename = os.path.join(root, last_project_filename) project = clean_project_name(project_filename[project_prefix_length:]) ows_project = clean_project_name(ows_project_filename[project_prefix_length:]) metadata_filename = clean_project_name(ows_project_filename) + '.meta' try: metadata = MetadataParser(metadata_filename) url = set_query_parameters(app_url(request, '/'), {'PROJECT': project}) ows_url = app_url(request, project_ows_url(ows_project)) authentication = metadata.authentication # backward compatibility with older version if type(authentication) is dict: if authentication.get('allow_anonymous') and \ not authentication.get('require_superuser'): authentication = 'all' else: authentication = 'authenticated' projects.append({ 'title': metadata.title, 'url': url, 'project': project, 'ows_url': ows_url, 'cache': metadata.use_mapcache, 'authentication': authentication, 'publication_time_unix': int(metadata.publish_date_unix), 'publication_time': metadata.publish_date, 'expiration_time': metadata.expiration if metadata.expiration else '' #'expiration_time_unix': int(time.mktime(time.strptime(metadata.expiration, "%d.%m.%Y"))) if metadata.expiration else None }) except IOError: # metadata file does not exists or not valid pass return projects
def ows(request): params = {key.upper(): request.GET[key] for key in request.GET.keys()} ows_project = clean_project_name(params.get('MAP')) project, timestamp = parse_project_name(ows_project) project_hash = hashlib.md5(project.encode('utf-8')).hexdigest() pi = get_project_info(project_hash, timestamp, project=ows_project) if not request.user.is_authenticated: basic_auth.is_authenticated(request) if not check_project_access(request, project, pi['authentication']): if not request.user.is_authenticated: response = HttpResponse('Authentication required', status=401) response['WWW-Authenticate'] = 'Basic realm=OWS API' return response raise PermissionDenied if params.get( 'SERVICE') == 'WFS' and params.get('REQUEST') != 'GetFeature': access_control = pi.get('access_control') if access_control and access_control['enabled']: root = etree.fromstring(request.body.decode()) for elem in root.findall('.//{*}Insert'): for child in elem.getchildren(): layer_name = etree.QName(child).localname if not check_layer_access(request.user, access_control, layer_name, 'insert'): raise PermissionDenied checks = [('.//{*}Update', 'update'), ('.//{*}Delete', 'delete')] for query_path, permission in checks: for elem in root.findall(query_path): layer_name = elem.get('typeName').split(':')[-1] if not check_layer_access(request.user, access_control, layer_name, permission): raise PermissionDenied url = "{0}?{1}".format(settings.GISQUICK_MAPSERVER_URL.rstrip("/"), request.environ['QUERY_STRING']) abs_project = abs_project_path(params.get('MAP')) url = set_query_parameters(url, {'MAP': abs_project}) if request.method == 'POST': owsrequest = urllib.request.Request(url, request.body) else: owsrequest = urllib.request.Request(url) owsrequest.add_header("User-Agent", "Gisquick") resp_content = b"" try: with contextlib.closing(urllib.request.urlopen(owsrequest)) as resp: while True: data = resp.read() if not data: break resp_content += data if params.get('REQUEST', '') == 'GetCapabilities': resp_content = resp_content.replace( settings.GISQUICK_MAPSERVER_URL.encode(), request.build_absolute_uri(request.path).encode()) content_type = resp.getheader('Content-Type') status = resp.getcode() return HttpResponse(resp_content, content_type=content_type, status=status) except urllib.error.HTTPError as e: # reason = e.read().decode("utf8") return HttpResponse(e.read(), content_type=e.headers.get_content_type(), status=e.code)
def get_ows_url(self, request): return set_query_parameters(reverse('viewer:owsrequest'), {'MAP': self.ows_project+'.qgs'})
def get_vectorlayers_url(self, request): return set_query_parameters(reverse('viewer:vectorlayers'), {'PROJECT': self.ows_project})
def project_ows_url(ows_project): return set_query_parameters(reverse('map:ows'), {'MAP': ows_project + '.qgs'})
def get_ows_url(self, request): return set_query_parameters(reverse('viewer:owsrequest'), {'MAP': self.ows_project + '.qgs'})
def project_ows_url(ows_project): return set_query_parameters( reverse('viewer:ows'), {'MAP': ows_project+'.qgs'} )
def project_vectorlayers_url(ows_project): return set_query_parameters( reverse('viewer:vectorlayers'), {'PROJECT': ows_project} )