Esempio n. 1
0
def get_project(request):
    ows_project = None

    form = forms.ViewerForm(request.GET)
    if not form.is_valid():
        raise Http404

    context = {}
    project = form.cleaned_data['PROJECT']

    if project:
        project = clean_project_name(project)
        ows_project_name = get_last_project_version(project)
        if not ows_project_name:
            raise Http404

        ows_project = ows_project_name

        metadata_filename = os.path.join(settings.GISLAB_WEB_PROJECT_ROOT,
                                         ows_project_name + '.meta')
        try:
            metadata = MetadataParser(metadata_filename)
        except:
            raise InvalidProjectException

        if metadata.expiration:
            expiration_date = datetime.datetime.strptime(
                metadata.expiration, "%d.%m.%Y").date()
            if datetime.date.today() > expiration_date:
                raise ProjectExpiredException

    # Authentication
    allow_anonymous = metadata.authentication == 'all' if project else True
    owner_authentication = metadata.authentication == 'owner' if project else False

    if not request.user.is_authenticated() and allow_anonymous:
        # login as quest and continue
        user = models.GislabUser.get_guest_user()
        if user:
            login(request, user)
        else:
            raise RuntimeError("Anonymous user is not configured")

    if not allow_anonymous and (not request.user.is_authenticated()
                                or request.user.is_guest):
        raise LoginRequiredException
    if owner_authentication and not request.user.is_superuser:
        project_owner = project.split('/', 1)[0]
        if project_owner != request.user.username:
            raise AccessDeniedException

    if project:
        ows_url = project_ows_url(ows_project)
        context['units'] = {
            'meters': 'm',
            'feet': 'ft',
            'miles': 'mi',
            'degrees': 'dd'
        }[metadata.units] or 'dd'
        use_mapcache = metadata.use_mapcache
        #use_mapcache = False
        project_tile_resolutions = metadata.tile_resolutions

        context['projection'] = metadata.projection
        context['tile_resolutions'] = project_tile_resolutions
        context['scales'] = metadata.scales

        # BASE LAYERS
        baselayers_tree = metadata.base_layers
        base = form.cleaned_data['BASE']
        if base:
            # TODO:
            #update_layers(baselayers_tree, base)
            pass

        # ensure that a blank base layer is always used
        if not baselayers_tree:
            baselayers_tree = [{
                'name': 'BLANK',
                'type': 'BLANK',
                'title': 'Blank Layer',
                'resolutions': project_tile_resolutions
            }]
        context['base_layers'] = baselayers_tree

        # OVERLAYS LAYERS
        layers_tree = metadata.overlays
        layers = form.cleaned_data['OVERLAY']
        # override layers tree with LAYERS GET parameter if provided
        if layers:
            # TODO:
            #update_layers(layers_tree, layers)
            pass
        context['layers'] = layers_tree

        if use_mapcache:
            project_hash = hashlib.md5(project).hexdigest()
            project_layers_info = get_project_layers_info(
                project_hash, metadata.publish_date_unix)
            if not project_layers_info:
                store_project_layers_info(project_hash,
                                          metadata.publish_date_unix,
                                          metadata.extent,
                                          project_tile_resolutions,
                                          metadata.projection['code'])

            context['mapcache_url'] = project_tile_url(
                project, metadata.publish_date_unix)
            context['legend_url'] = project_legend_url(
                project, metadata.publish_date_unix)
        else:
            context['legend_url'] = ows_url
        if metadata.vector_layers:
            context['vectorlayers_url'] = project_vectorlayers_url(ows_project)

        context.update({
            'project': project,
            'ows_project': ows_project_name,
            'ows_url': ows_url,
            'wms_url': urllib.unquote(secure_url(request, ows_url)),
            'project_extent': metadata.extent,
            'zoom_extent': form.cleaned_data['EXTENT'] or metadata.zoom_extent,
            # TODO: Don't forget!!!
            #'print_composers': metadata.composer_templates if not request.user.is_guest else None,
            # Temporary allow print for guest users, until proper login/logout will be implemented
            'print_composers': metadata.composer_templates,
            'root_title': metadata.title,
            'author': metadata.contact_person,
            'email': metadata.contact_mail,
            'phone': metadata.contact_phone,
            'organization': metadata.contact_organization,
            'abstract': metadata.abstract,
            'online_resource': metadata.online_resource,
            'access_constrains': metadata.access_constrains,
            'fees': metadata.fees,
            'keyword_list': metadata.keyword_list,
            'publish_user': metadata.gislab_user,
            'publish_date': metadata.publish_date,
            'publish_date_unix': int(metadata.publish_date_unix),
            'expiration_date': metadata.expiration,
            'selection_color':
            metadata.selection_color[:-2],  #strip alpha channel,
            'position_precision': metadata.position_precision,
            'topics': metadata.topics,
            'vector_layers': metadata.vector_layers is not None,
        })
        if metadata.message:
            valid_until = datetime.datetime.strptime(
                metadata.message['valid_until'], "%d.%m.%Y").date()
            if datetime.date.today() <= valid_until:
                context['message'] = metadata.message['text'].replace(
                    '\n', '<br />')
        # Update projects registry
        project_info = {
            'gislab_version':
            metadata.gislab_version,
            'gislab_user':
            metadata.gislab_user,
            'gislab_unique_id':
            metadata.gislab_unique_id,
            'publish_date':
            datetime.datetime.fromtimestamp(metadata.publish_date_unix),
            'last_display':
            datetime.datetime.now()
        }
        try:
            rows = models.Project_registry.objects.filter(
                project=project).update(**project_info)
            if not rows:
                models.Project_registry(project=project, **project_info).save()
        except:
            raise
    else:
        context.update({
            'project':
            'empty',
            'root_title':
            _('Empty Project'),
            'project_extent':
            [-20037508.34, -20037508.34, 20037508.34, 20037508.34],
            'tile_resolutions':
            OSM_RESOLUTIONS,
            'scales':
            OSM_SCALES,
            'projection': {
                'code': 'EPSG:3857',
                'is_geographic': False
            },
            'units':
            'm'
        })
        context['zoom_extent'] = form.cleaned_data['EXTENT'] or context[
            'project_extent']
        context['base_layers'] = [OSM_LAYER]

    #context['gislab_unique_id'] = GISLAB_VERSION.get('GISLAB_UNIQUE_ID', 'unknown')
    context['gislab_version'] = webgis.VERSION
    context['gislab_homepage'] = 'http://imincik.github.io/gis-lab'
    context['gislab_documentation'] = 'https://github.com/imincik/gis-lab/wiki'
    return context
Esempio n. 2
0
def get_project(request):
    ows_project = None

    form = forms.ViewerForm(request.GET)
    if not form.is_valid():
        raise Http404

    context = {}
    project = form.cleaned_data['PROJECT']

    if project:
        project = clean_project_name(project)
        ows_project_name = get_last_project_version(project)
        if not ows_project_name:
            raise Http404

        ows_project = ows_project_name

        metadata_filename = os.path.join(settings.GISQUICK_PROJECT_ROOT,
                                         ows_project_name + '.meta')
        try:
            metadata = MetadataParser(metadata_filename)
        except:
            raise InvalidProjectException

        if metadata.expiration:
            expiration_date = datetime.datetime.strptime(
                metadata.expiration, "%d.%m.%Y").date()
            if datetime.date.today() > expiration_date:
                project_data = _project_basic_data(metadata)
                project_data['status'] = 410
                return project_data

    # Authentication
    allow_anonymous = metadata.authentication == 'all' if project else True
    owner_authentication = metadata.authentication == 'owner' if project else False

    if not allow_anonymous and (not request.user.is_authenticated()
                                or request.user.is_guest):
        project_data = _project_basic_data(metadata)
        project_data['status'] = 401
        return project_data

    if owner_authentication and not request.user.is_superuser:
        project_owner = project.split('/', 1)[0]
        if project_owner != request.user.username:
            project_data = _project_basic_data(metadata)
            project_data['status'] = 403
            return project_data

    if project:
        ows_url = project_ows_url(ows_project)
        context['units'] = {
            'meters': 'm',
            'feet': 'ft',
            'miles': 'mi',
            'degrees': 'dd'
        }[metadata.units] or 'dd'
        use_mapcache = metadata.use_mapcache
        #use_mapcache = False
        project_tile_resolutions = metadata.tile_resolutions

        context['projection'] = metadata.projection
        context['tile_resolutions'] = project_tile_resolutions
        context['scales'] = metadata.scales

        # BASE LAYERS
        baselayers_tree = _convert_layers_metadata(metadata.base_layers)
        base = form.cleaned_data['BASE']
        if base:
            # TODO:
            #update_layers(baselayers_tree, base)
            pass

        # ensure that a blank base layer is always used
        if not baselayers_tree:
            blank_layer = dict(BLANK_LAYER)
            blank_layer['resolutions'] = project_tile_resolutions
            baselayers_tree = [blank_layer]
        context['base_layers'] = baselayers_tree

        # OVERLAYS LAYERS
        info = _layers_names(metadata.overlays)
        _convert_topics(metadata.topics, info)
        layers_tree = _convert_layers_names(metadata.overlays, info)
        layers = form.cleaned_data['OVERLAY']
        # override layers tree with LAYERS GET parameter if provided
        if layers:
            # TODO:
            #update_layers(layers_tree, layers)
            pass
        context['layers'] = layers_tree

        if use_mapcache:
            project_hash = hashlib.md5(project.encode('utf-8')).hexdigest()
            project_layers_info = get_project_layers_info(
                project_hash, metadata.publish_date_unix)
            if not project_layers_info:
                store_project_layers_info(project_hash,
                                          metadata.publish_date_unix,
                                          metadata.extent,
                                          project_tile_resolutions,
                                          metadata.projection['code'])

            context['mapcache_url'] = project_tile_url(
                project, metadata.publish_date_unix)
            context['legend_url'] = project_legend_url(
                project, metadata.publish_date_unix)

        else:
            context['legend_url'] = ows_url
        if metadata.vector_layers:
            context['vectorlayers_url'] = project_vectorlayers_url(ows_project)

        context.update({
            'project':
            project,
            'ows_project':
            ows_project_name,
            'ows_url':
            ows_url,
            'wms_url':
            urllib.parse.unquote(ows_url),
            'project_extent':
            metadata.extent,
            'zoom_extent':
            form.cleaned_data['EXTENT'] or metadata.zoom_extent,
            'print_composers':
            metadata.composer_templates if not request.user.is_guest else None,
            'info_panel':
            metadata.info_panel,
            'root_title':
            metadata.title,
            'author':
            metadata.contact_person,
            'email':
            metadata.contact_mail,
            'phone':
            metadata.contact_phone,
            'organization':
            metadata.contact_organization,
            'abstract':
            metadata.abstract,
            'online_resource':
            metadata.online_resource,
            'access_constrains':
            metadata.access_constrains,
            'fees':
            metadata.fees,
            'keyword_list':
            metadata.keyword_list,
            'publish_user':
            metadata.gislab_user,
            'publish_date':
            metadata.publish_date,
            'publish_date_unix':
            int(metadata.publish_date_unix),
            'expiration_date':
            metadata.expiration,
            'selection_color':
            metadata.selection_color[:-2],  #strip alpha channel,
            'position_precision':
            metadata.position_precision,
            'topics':
            metadata.topics,
            'authentication':
            metadata.authentication,
            'plugin_version':
            metadata.plugin_version
        })
        if metadata.message:
            valid_until = datetime.datetime.strptime(
                metadata.message['valid_until'], "%d.%m.%Y").date()
            if datetime.date.today() <= valid_until:
                context['message'] = metadata.message['text'].replace(
                    '\n', '<br />')
        # Update projects registry
        project_info = {
            'plugin_version':
            metadata.plugin_version or '',
            'gislab_user':
            metadata.gislab_user,
            'publish_date':
            datetime.datetime.fromtimestamp(metadata.publish_date_unix),
            'last_display':
            datetime.datetime.now()
        }
        try:
            rows = models.Project_registry.objects.filter(
                project=project).update(**project_info)
            if not rows:
                models.Project_registry(project=project, **project_info).save()
        except:
            raise
    else:
        context.update({
            'project':
            'empty',
            'root_title':
            _('Empty Project'),
            'project_extent':
            [-20037508.34, -20037508.34, 20037508.34, 20037508.34],
            'tile_resolutions':
            OSM_RESOLUTIONS,
            'scales':
            OSM_SCALES,
            'projection': {
                'code': 'EPSG:3857',
                'is_geographic': False
            },
            'position_precision': {
                'decimal_places': 2
            },
            'units':
            'm',
            'authentication':
            'all',
            'topics': [],
            'layers': [],
            'ows_url':
            ''
        })
        context['zoom_extent'] = form.cleaned_data['EXTENT'] or context[
            'project_extent']
        context['base_layers'] = [OSM_LAYER]

    context['gislab_version'] = webgis.VERSION
    context['gislab_homepage'] = settings.GISQUICK_HOMEPAGE
    context['gislab_documentation'] = settings.GISQUICK_DOCUMENTATION_PAGE
    context['status'] = 200
    return context
Esempio n. 3
0
    def project_request(self, request):
        self.project = None
        self.ows_project = None
        self.project_metadata = None

        form = forms.ViewerForm(request.GET)
        if not form.is_valid():
            raise Http404

        context = {}
        project = form.cleaned_data['PROJECT']

        if project:
            project = clean_project_name(project)
            ows_project_name = get_last_project_version(project)
            self.project = project
            self.ows_project = ows_project_name

            metadata_filename = os.path.join(settings.GISLAB_WEB_PROJECT_ROOT,
                                             ows_project_name + '.meta')
            try:
                metadata = MetadataParser(metadata_filename)
                self.project_metadata = metadata
            except:
                return HttpResponse(
                    "Error when loading project or project does not exist",
                    content_type='text/plain',
                    status=404)
            if metadata.expiration:
                expiration_date = datetime.datetime.strptime(
                    metadata.expiration, "%d.%m.%Y").date()
                if datetime.date.today() > expiration_date:
                    return HttpResponse("Project has reached expiration date.",
                                        content_type='text/plain',
                                        status=410)

        # Authentication
        if project and type(metadata.authentication) is dict:
            # backward compatibility
            allow_anonymous = metadata.authentication.get('allow_anonymous')
            owner_authentication = False
        else:
            allow_anonymous = metadata.authentication == 'all' if project else True
            owner_authentication = metadata.authentication == 'owner' if project else False

        if not request.user.is_authenticated() and allow_anonymous:
            # login as quest and continue
            user = models.GislabUser.get_guest_user()
            if user:
                login(request, user)
            else:
                return HttpResponse("Anonymous user is not configured",
                                    content_type='text/plain',
                                    status=500)

        if (not allow_anonymous and
            (not request.user.is_authenticated() or request.user.is_guest)):
            raise LoginRequired()
        if owner_authentication and not request.user.is_superuser:
            project_owner = project.split('/', 1)[0]
            if project_owner != request.user.username:
                return HttpResponse(
                    "You don't have permissions for this project",
                    content_type='text/plain',
                    status=403)

        if project:
            ows_url = self.get_ows_url(request)
            context['units'] = {
                'meters': 'm',
                'feet': 'ft',
                'miles': 'mi',
                'degrees': 'dd'
            }[metadata.units] or 'dd'
            use_mapcache = metadata.use_mapcache
            #use_mapcache = False
            project_tile_resolutions = metadata.tile_resolutions

            context['projection'] = metadata.projection
            context['tile_resolutions'] = project_tile_resolutions
            context['scales'] = metadata.scales

            # converts tree with layers data into simple dictionary
            def collect_layers_capabilities(layers_data, capabilities=None):
                if capabilities is None:
                    capabilities = {}
                for layer_data in layers_data:
                    sublayers = layer_data.get('layers')
                    if sublayers:
                        collect_layers_capabilities(sublayers, capabilities)
                    else:
                        capabilities[layer_data['name']] = layer_data
                return capabilities

            # BASE LAYERS
            baselayers_tree = None
            base = form.cleaned_data['BASE']
            if base:
                base_layers_capabilities = collect_layers_capabilities(
                    metadata.base_layers)
                try:
                    baselayers_tree = parse_layers_param(
                        base, base_layers_capabilities)['layers']
                except LookupError, e:
                    return HttpResponse("Unknown base layer: {0}".format(
                        str(e)),
                                        content_type='text/plain',
                                        status=400)
            else:
                baselayers_tree = metadata.base_layers

            # ensure that a blank base layer is always used
            if not baselayers_tree:
                baselayers_tree = [{
                    'name': 'BLANK',
                    'type': 'BLANK',
                    'title': 'Blank Layer',
                    'resolutions': project_tile_resolutions
                }]
            context['base_layers'] = baselayers_tree

            # OVERLAYS LAYERS
            layers = form.cleaned_data['OVERLAY']
            # override layers tree with LAYERS GET parameter if provided
            if layers:
                overlays_capabilities = collect_layers_capabilities(
                    metadata.overlays) if metadata.overlays else {}
                try:
                    layers_tree = parse_layers_param(
                        layers, overlays_capabilities)['layers']
                except LookupError, e:
                    return HttpResponse("Unknown overlay layer: {0}".format(
                        str(e)),
                                        content_type='text/plain',
                                        status=400)