Esempio n. 1
0
def _extractCategories(request, lang, separator):
    """
    Helper function to extract the categories of the database and their
    translations.
    """

    def _processCategories(originalCategoryList, translatedCategoryList, type, separator):

        categories = []
        strings = []

        originalCategories = sorted(originalCategoryList.getCategories(), key=lambda c:c.getId())
        translatedCategories = sorted(translatedCategoryList.getCategories(), key=lambda c:c.getId())

        for i, originalCategory in enumerate(originalCategories):
            translatedCategory = translatedCategories[i]

            # Add each category only once
            if originalCategory.getName() not in categories:
                categories.append(originalCategory.getName())
                strings.append(separator.join([
                    originalCategory.getName(),
                    translatedCategory.getTranslation(True),
                    type
                ]))

            # Subcategories
            originalSubcategories = sorted(originalCategory.getThematicgroups(), key=lambda c:c.getId())
            translatedSubcategories = sorted(translatedCategory.getThematicgroups(), key=lambda c:c.getId())

            for j, originalSubcategory in enumerate(originalSubcategories):
                translatedSubcategory = translatedSubcategories[j]

                # Add each subcategory only once
                if originalSubcategory.getName() not in categories:
                    categories.append(originalSubcategory.getName())
                    strings.append(separator.join([
                        originalSubcategory.getName(),
                        translatedSubcategory.getTranslation(True),
                        type
                    ]))

        return strings

    strings = []
    strings.append(separator.join([
        'Name (original)',
        'Name (translation)',
        'Type',
        'Additional comments'
    ]))

    for t in ['activities', 'stakeholders']:
        strings += _processCategories(
            getCategoryList(request, t, lang='en'),
            getCategoryList(request, t, lang=lang),
            t,
            separator)

    return strings
Esempio n. 2
0
def getFilterKeys(request):
    """
    Return two lists (the first for Activities, the second for Stakeholders)
    with the keys which can be filtered.
    Each list contains:
    - [0]: display name (translated)
    - [1]: internal name
    - [2]: the type of the key
    """

    def getList(categoryList):
        list = []
        for key in categoryList.getFilterableKeys():
            name = key.getName()
            translation = key.getTranslatedName()
            type = key.getType()
            list.append([
                translation if translation is not None else name,
                name,
                type.lower()
            ])
        return list

    aList = getList(getCategoryList(request, 'activities'))
    shList = getList(getCategoryList(request, 'stakeholders'))

    return aList, shList
Esempio n. 3
0
def getOverviewKeys(request):
    """
    Return two lists (the first for Activities, the second for Stakeholders)
    with the keys which are to be used in the involvement overview. Because
    these are the keys of the other side, the first one actually contains the
    keys for Stakeholders, the second one the keys for Activities!
    """
    return (
        getCategoryList(request, 'activities').getInvolvementOverviewKeyNames(),
        getCategoryList(request, 'stakeholders').getInvolvementOverviewKeyNames()
    )
Esempio n. 4
0
def get_default_search_key(request, item_type):

    category_list = getCategoryList(request, item_type)
    search_key = category_list.get_default_search_key()
    if search_key:
        return search_key.getTranslatedName(), search_key.getName()
    return None, None
Esempio n. 5
0
def form_geomtaggroups(request):
    """
    Simple service to return all the mainkeys of taggroups which can have
    geometries as defined in the configuration yaml.
    """
    categorylist = getCategoryList(request, 'activities')
    return {
        'mainkeys': categorylist.getMainkeyWithGeometry(withTranslation=True)
    }
Esempio n. 6
0
def getFilterValuesForKey(request, predefinedType=None, predefinedKey=None):
    """
    Return a JSON representation of all the values for a given key.
    The JSON array contains an array for each entry with:
    - [0]: The display name (translated)
    - [1]: The internal name
    """

    type = request.params.get('type', predefinedType)
    key = request.params.get('key', predefinedKey)

    if type is None:
        return {
            'error': 'No type specified.'
        }

    if key is None:
        return {
            'error': 'No key specified'
        }

    itemType = None
    if type == 'a':
        itemType = 'activities'
    elif type == 'sh':
        itemType = 'stakeholders'

    if itemType is None:
        return {
            'error': 'Type not valid.'
        }

    categoryList = getCategoryList(request, itemType)

    tag = categoryList.findTagByKeyName(key)

    if tag is None:
        return {
            'error': 'Key not found.'
        }

    values = tag.getValues()

    if len(values) == 0:
        return {
            'error': 'No values found for this key.'
        }

    ret = []
    for v in sorted(values, key=lambda val: val.getOrderValue()):
        ret.append([
            v.getTranslation(),
            v.getName()
        ])

    return ret
Esempio n. 7
0
def getGridColumnKeys(request, itemType):
    """
    Return the keys used for the grid columns in the order specified in the
    configuration yaml.
    It returns an array where each entry contains
    - the original key name (used for ordering the column)
    - the translated key name (for display purposes)
    """
    categoryList = getCategoryList(request, itemType)
    keys = []
    for key in sorted(categoryList.getGridColumnKeyNames(), key=lambda k: k[2]):
        keys.append([key[0], key[1]])
    return keys
Esempio n. 8
0
def form_geomtaggroups(request):
    """
    Simple service to return all the mainkeys of taggroups which can have
    geometries as defined in the configuration yaml.
    """
    categorylist = getCategoryList(request, 'activities')
    # TODO: Once the QGIS-Plugin is adapted to match the new output of this
    # function, remove the parameter (withTranslation=False) from the function 
    # call below.
    # The new output is as follows:
    # {
    #   'mainkeys': [
    #       [TRANSLATION, ORIGINAL]
    #   ]
    # }
    return {'mainkeys': categorylist.getMainkeyWithGeometry(withTranslation=True)}
Esempio n. 9
0
def getMapSymbolKeys(request):
    """
    Return a list with the keys which are used for the map symbols.
    Each entry of the array has
    - name of the key (translated)
    - name of the key (original)
    - mapsymbol data (usually an order number)
    If there is an attribute set, it is moved to the top of the list with the
    help of the order number
    """
    mapSymbolKeys = getCategoryList(request, 'activities').getMapSymbolKeyNames()

    attrs = request.params.get('attrs', None)

    if attrs is not None:
        for m in mapSymbolKeys:
            if m[1] in attrs:
                m[2] = 0

    return sorted(mapSymbolKeys, key=lambda k: k[2])
Esempio n. 10
0
    def download_customize(self, item_type):
        """

        """
        item_type = validate_item_type(item_type)

        if self.request.POST:
            format = self.request.POST.get('format', 'csv')
            involvements = self.request.POST.get('involvements', 'full')
            attributes = self.request.POST.getall('attributes')
            if format == 'csv':
                header, rows = to_flat_table(
                    self.request, item_type, involvements=involvements,
                    columns=attributes)
                return render_to_response(
                    'csv', {'header': header, 'rows': rows}, self.request)

        # Order matters: The first entry is the default value.
        formats = [
            ('csv', 'CSV'),
        ]
        attributes = []
        for config_key in getCategoryList(
                self.request, item_type).getAllKeys():
            attributes.append((
                config_key.getName(), config_key.getTranslatedName()))
        if item_type == 'a':
            template = get_customized_template_path(
                self.request, 'activities/download.mak')
        else:
            template = get_customized_template_path(
                self.request, 'stakeholders/download.mak')
        template_values = {
            'profile': get_current_profile(self.request),
            'locale': get_current_locale(self.request),
            'formats': formats,
            'attributes': attributes
        }
        return render_to_response(template, template_values, self.request)
Esempio n. 11
0
def read_one(request):
    """
    Read one Stakeholder based on ID and return all versions of this
    Stakeholder. Also return pending versions by currently logged in user and
    all pending versions of this Stakeholder if logged in as moderator.
    Default output format: JSON
    """

    # Handle the parameters (locale, profile)
    bv = BaseView(request)
    bv._handle_parameters()

    try:
        output_format = request.matchdict['output']
    except KeyError:
        output_format = 'json'

    uid = request.matchdict.get('uid', None)
    if check_valid_uuid(uid) is not True:
        raise HTTPNotFound()

    if output_format == 'json':
        stakeholders = stakeholder_protocol3.read_one(request, uid=uid,
            public=False)
        return render_to_response('json', stakeholders, request)
    elif output_format == 'html':
        # Show the details of a Stakeholder by rendering the form in readonly
        # mode.
        stakeholders = stakeholder_protocol3.read_one(request, uid=uid,
            public=False, translate=False)
        version = request.params.get('v', None)
        if (stakeholders and 'data' in stakeholders
            and len(stakeholders['data']) != 0):
            for sh in stakeholders['data']:
                if 'version' in sh:
                    if version is None:
                        # If there is no version provided, show the first
                        # version visible to the user
                        version = str(sh['version'])
                    if str(sh['version']) == version:
                        templateValues = renderReadonlyForm(request, 'stakeholders', sh)
                        templateValues['profile'] = get_current_profile(request)
                        templateValues['locale'] = get_current_locale(request)

                        # Append the short uid and the uid to the templates values
                        templateValues['uid'] = uid
                        templateValues['shortuid'] = uid.split("-")[0]
                        # Append also the site key from the commenting system
                        templateValues['site_key'] = comments_sitekey(request)['site_key']
                        # and the url of the commenting system
                        templateValues['comments_url'] = request.registry.settings['lmkp.comments_url']

                        return render_to_response(
                            getTemplatePath(request, 'stakeholders/details.mak'),
                            templateValues,
                            request
                        )
        return HTTPNotFound()
    elif output_format == 'form':
        if request.user is None:
            # Make sure the user is logged in
            raise HTTPForbidden()
        # Query the Stakeholders with the given identifier
        stakeholders = stakeholder_protocol3.read_one(request, uid=uid,
            public=False, translate=False)
        version = request.params.get('v', None)
        if (stakeholders and 'data' in stakeholders
            and len(stakeholders['data']) != 0):
            for sh in stakeholders['data']:
                if 'version' in sh:
                    if version is None:
                        # If there is no version provided, show the first
                        # version visible to the user
                        version = str(sh['version'])
                    if str(sh['version']) == version:
                        templateValues = renderForm(request, 'stakeholders', itemJson=sh)
                        if isinstance(templateValues, Response):
                            return templateValues
                        templateValues['profile'] = get_current_profile(request)
                        templateValues['locale'] = get_current_locale(request)
                        return render_to_response(
                            getTemplatePath(request, 'stakeholders/form.mak'),
                            templateValues,
                            request
                        )
        return HTTPNotFound()
    elif output_format in ['review', 'compare']:
        if output_format == 'review':
            # Only moderators can see the review page.
            isLoggedIn, isModerator = checkUserPrivileges(request)
            if isLoggedIn is False or isModerator is False:
                raise HTTPForbidden()

        camefrom = request.params.get('camefrom', '')
        
        review = StakeholderReview(request)
        availableVersions = None
        recalculated = False
        defaultRefVersion, defaultNewVersion = review._get_valid_versions(
            Stakeholder, uid)
            
        refVersion = request.params.get('ref', None)
        if refVersion is not None:
            try:
                refVersion = int(refVersion)
            except:
                refVersion = None
        if refVersion is None or output_format == 'review':
            # No reference version indicated, use the default one
            # Also use the default one for review because it cannot be changed.
            refVersion = defaultRefVersion
        else:
            availableVersions = review._get_available_versions(Stakeholder, uid, 
                review=output_format=='review')
            # Check if the indicated reference version is valid
            if refVersion not in [v.get('version') for v in availableVersions]:
                refVersion = defaultRefVersion
        
        newVersion = request.params.get('new', None)
        if newVersion is not None:
            try:
                newVersion = int(newVersion)
            except:
                newVersion = None
        if newVersion is None:
            # No new version indicated, use the default one
            newVersion = defaultNewVersion
        else:
            if availableVersions is None:
                availableVersions = review._get_available_versions(Stakeholder, 
                    uid, review=output_format=='review')
            # Check if the indicated new version is valid
            if newVersion not in [v.get('version') for v in availableVersions]:
                newVersion = defaultNewVersion
                
        if output_format == 'review':
            # If the Stakeholders are to be reviewed, only the changes which 
            # were applied to the newVersion are of interest
            stakeholders, recalculated = review.get_comparison(Stakeholder, uid, 
                refVersion, newVersion)
        else:
            # If the Stakeholders are compared, the versions as they are stored
            # in the database are of interest, without any recalculation
            stakeholders = [
                stakeholder_protocol3.read_one_by_version(request, uid, 
                    refVersion, translate=False
                ),
                stakeholder_protocol3.read_one_by_version(request, uid, 
                    newVersion, translate=False
                )
            ]
        templateValues = renderReadonlyCompareForm(request, 'stakeholders', 
            stakeholders[0], stakeholders[1], review=output_format=='review')
        # Collect metadata for the reference version
        refMetadata = {}
        if stakeholders[0] is not None:
            refMetadata = stakeholders[0].get_metadata(request)
        # Collect metadata and missing keys for the new version
        newMetadata = {}
        missingKeys = []
        reviewable = False
        if stakeholders[1] is not None:
            stakeholders[1].mark_complete(get_mandatory_keys(request, 'sh', False))
            missingKeys = stakeholders[1]._missing_keys
            localizer = get_localizer(request)
            if localizer.locale_name != 'en':
                db_lang = Session.query(Language).filter(Language.locale == localizer.locale_name).first()
                missingKeys = get_translated_db_keys(SH_Key, missingKeys, db_lang)
                missingKeys = [m[1] for m in missingKeys]
            newMetadata = stakeholders[1].get_metadata(request)
            
            reviewable = (len(missingKeys) == 0 and 
                'reviewableMessage' in templateValues and
                templateValues['reviewableMessage'] is None)
            
        if output_format == 'review':
            pendingVersions = []
            if availableVersions is None:
                availableVersions = review._get_available_versions(Stakeholder, 
                    uid, review=output_format=='review')
            for v in sorted(availableVersions, key=lambda v:v.get('version')):
                if v.get('status') == 1:
                    pendingVersions.append(v.get('version'))
            templateValues['pendingVersions'] = pendingVersions
            
        templateValues.update({
            'identifier': uid,
            'refVersion': refVersion,
            'refMetadata': refMetadata,
            'newVersion': newVersion,
            'newMetadata': newMetadata,
            'missingKeys': missingKeys,
            'reviewable': reviewable,
            'recalculated': recalculated,
            'camefrom': camefrom,
            'profile': get_current_profile(request),
            'locale': get_current_locale(request)
        })
        
        if output_format == 'review':
            return render_to_response(
                getTemplatePath(request, 'stakeholders/review.mak'),
                templateValues,
                request
            )
        else:
            return render_to_response(
                getTemplatePath(request, 'stakeholders/compare.mak'),
                templateValues,
                request
            )
    elif output_format == 'formtest':
        # Test if a Stakeholder is valid according to the form configuration
        stakeholders = stakeholder_protocol3.read_one(request, uid=uid,
            public=False, translate=False)
        version = request.params.get('v', None)
        if (stakeholders and 'data' in stakeholders
            and len(stakeholders['data']) != 0):
            for sh in stakeholders['data']:
                if 'version' in sh:
                    if version is None:
                        version = str(sh['version'])
                    if str(sh['version']) == version:
                        categorylist = getCategoryList(request, 'stakeholders')
                        return render_to_response('json',
                            checkValidItemjson(categorylist, sh), request)
        return HTTPNotFound()
    else:
        # If the output format was not found, raise 404 error
        raise HTTPNotFound()
Esempio n. 12
0
def getActiveFilters(request):
    """
    Get the active filters of a request in a list.
    The list contains another list for each active filter with
    - [0]: the query string as provided in the parameter
    - [1]: a clean text representation (translated) of the filter
    """

    _ = request.translate

    # Map the operators
    operators = {
        'like': '=',
        'nlike': '!=',
        'ilike': '=',
        'eq': '=',
        'ne': '!=',
        'lt': '<',
        'lte': '<=',
        'gt': '>',
        'gte': '>='
    }

    aList = getCategoryList(request, 'activities')
    shList = getCategoryList(request, 'stakeholders')

    # Extract query_strings from url
    scheme, netloc, path, query_string, fragment = urlsplit(request.url)
    queryparams = parse_qs(query_string)

    filters = []
    for q in queryparams:
        if q.startswith('a__') or q.startswith('sh__'):
            queryparts = q.split('__')

            if len(queryparts) != 3:
                continue

            if queryparts[0] == 'a':
                itemName = render(
                    getTemplatePath(request, 'parts/items/activity.mak'), {}, request
                )
                configList = aList
            elif queryparts[0] == 'sh':
                itemName = render(
                    getTemplatePath(request, 'parts/items/stakeholder.mak'), {}, request
                )
                configList = shList
            else:
                continue

            key = queryparts[1]
            op = queryparts[2]

            # Use translated key for display
            displayKey = key
            tag = configList.findTagByKeyName(key)
            if tag is not None:
                displayKey = tag.getKey().getTranslatedName()

            for v in queryparams[q]:
                # Use translated value for display
                displayValue = v
                if tag is not None:
                    valueObject = tag.findValueByName(v)
                    if valueObject is not None:
                        displayValue = valueObject.getTranslation()
                q_string = '%s=%s' % (q, v)
                q_display = ('(%s) %s %s %s' % (itemName, displayKey,
                    operators[op], displayValue))
                filters.append([q_string, q_display])

    return filters
Esempio n. 13
0
    def read_one(self, public=False):
        """
        Return one :term:`Stakeholder`.

        .. seealso::
            :ref:`read-one`

        Read one :term:`Stakeholder` or one version of a
        :term:`Stakeholder`. By default, this is the latest visible
        version to the current user. This means that logged in users can
        see their own pending version and moderators of the current
        profile can see a pending version as well. If you don't want to
        see a version pending, consider using
        :class:`lmkp.views.stakeholders.StakeholderView.read_one_public`
        instead.

        Args:
            ``public`` (bool): A boolean indicating to return only a
            version visible to the public (eg. pending) or not.

        Matchdict parameters:

            ``/stakeholders/{output}/{uid}``

            ``output`` (str): If the output format is not valid, a 404
            Response is returned.

            The following output formats are supported:

                ``json``: Return the :term:`Stakeholder` as JSON. All
                versions visible to the current user are returned.

                ``html``: Return the :term:`Stakeholder` as HTML (eg.
                the `Detail View`).

                ``form``: Returns the form to edit an existing
                :term:`Stakeholder`.

                ``compare``: Return the page to compare two versions of
                the :term:`Stakeholder`.

                ``review``: Return the page to review a pending version
                of a :term:`Stakeholder`.

            ``uid`` (str): An :term:`Stakeholder` :term:`UID`.

        Request parameters:
            ``translate`` (bool): Return translated values or not. This
            is only valid for the output format ``json``.

            ``v`` (int): Indicate a specific version to return. This is
            only valid for the output formats ``html`` and ``form``.

            ``camefrom`` (uid): Only valid for output format ``review``.
            Indicate a :term:`Activity` to return to after reviewing the
            :term:`Stakeholder`.

            ``ref`` (int) and ``new`` (int): Indicate specific versions.
            This is only valid for the output formats ``compare`` and
            ``review``.

        Returns:
            ``HTTPResponse``. Either a HTML or a JSON response.
        """
        output_format = get_output_format(self.request)

        uid = self.request.matchdict.get('uid', None)
        if validate_uuid(uid) is not True:
            raise HTTPNotFound()

        if output_format == 'json':

            translate = self.request.params.get(
                'translate', 'true').lower() == 'true'

            item = stakeholder_protocol.read_one(
                self.request, uid=uid, public=public, translate=translate)

            return render_to_response('json', item, self.request)

        elif output_format == 'html':

            version = self.request.params.get('v', None)

            item = stakeholder_protocol.read_one(
                self.request, uid=uid, public=public, translate=False)

            for i in item.get('data', []):

                item_version = i.get('version')
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    template_values = self.get_base_template_values()
                    template_values.update(renderReadonlyForm(
                        self.request, 'stakeholders', i))
                    template_values.update({
                        'uid': uid,
                        'shortuid': shorten_uuid(uid),
                        'version': version,
                        'site_key': comments_sitekey(self.request)['site_key'],
                        'comments_url': self.request.registry.settings[
                            'lmkp.comments_url']
                    })

                    return render_to_response(
                        get_customized_template_path(
                            self.request, 'stakeholders/details.mak'),
                        template_values, self.request)

            return HTTPNotFound()

        elif output_format == 'form':

            is_logged_in, __ = get_user_privileges(self.request)
            if not is_logged_in:
                raise HTTPForbidden()

            version = self.request.params.get('v', None)

            item = stakeholder_protocol.read_one(
                self.request, uid=uid, public=False, translate=False)

            for i in item.get('data', []):

                item_version = i.get('version')
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    template_values = renderForm(
                        self.request, 'stakeholders', itemJson=i)
                    if isinstance(template_values, Response):
                        return template_values

                    template_values.update(self.get_base_template_values())

                    return render_to_response(
                        get_customized_template_path(
                            self.request, 'stakeholders/form.mak'),
                        template_values, self.request)

            return HTTPNotFound()

        elif output_format in ['review', 'compare']:

            if output_format == 'review':
                # Only moderators can see the review page.
                is_logged_in, is_moderator = get_user_privileges(self.request)
                if not is_logged_in or not is_moderator:
                    raise HTTPForbidden()

            review = StakeholderReview(self.request)
            is_review = output_format == 'review'
            available_versions = review._get_available_versions(
                Stakeholder, uid, review=is_review)
            recalculated = False
            default_ref_version, default_new_version = review.\
                _get_valid_versions(Stakeholder, uid)

            try:
                ref_version = int(self.request.params.get('ref'))
            except:
                ref_version = None

            # For review or if no valid reference version is provided, use the
            # default reference version.
            if (output_format == 'review' or ref_version is None
                    or ref_version not in [
                        v.get('version') for v in available_versions]):
                ref_version = default_ref_version

            try:
                new_version = int(self.request.params.get('new'))
            except:
                new_version = None

            if new_version is None or new_version not in [
                    v.get('version') for v in available_versions]:
                new_version = default_new_version

            if output_format == 'review':
                # If the Items are to be reviewed, only the changes which were
                # applied to the new_version are of interest
                items, recalculated = review.get_comparison(
                    Stakeholder, uid, ref_version, new_version)
            else:
                # If the Items are to be compared, the versions as they are
                # stored in the database are of interest, without any
                # recalculation
                items = [
                    stakeholder_protocol.read_one_by_version(
                        self.request, uid, ref_version, translate=False
                    ),
                    stakeholder_protocol.read_one_by_version(
                        self.request, uid, new_version, translate=False
                    )
                ]

            template_values = renderReadonlyCompareForm(
                self.request, 'stakeholders', items[0], items[1],
                review=is_review)

            # Collect the metadata
            ref_metadata = {}
            new_metadata = {}
            missing_keys = []
            reviewable = False
            if items[0] is not None:
                ref_metadata = items[0].get_metadata(self.request)
            # Collect metadata and missing keys for the new version
            if items[1] is not None:
                new_metadata = items[1].get_metadata(self.request)

                items[1].mark_complete(get_mandatory_keys(
                    self.request, 'sh', False))
                missing_keys = items[1]._missing_keys
                localizer = get_localizer(self.request)
                if localizer.locale_name != 'en':
                    db_lang = Session.query(Language).filter(
                        Language.locale == localizer.locale_name).first()
                    missing_keys = get_translated_db_keys(
                        SH_Key, missing_keys, db_lang)
                    missing_keys = [m[1] for m in missing_keys]

                reviewable = (len(missing_keys) == 0 and
                              'reviewableMessage' in template_values
                              and template_values['reviewableMessage'] is None)

            if output_format == 'review':
                pending_versions = []
                for v in sorted(
                        available_versions, key=lambda v: v.get('version')):
                    if v.get('status') == 1:
                        pending_versions.append(v.get('version'))
                template_values['pendingVersions'] = pending_versions

            template_values.update(self.get_base_template_values())
            template_values.update({
                'identifier': uid,
                'refVersion': ref_version,
                'refMetadata': ref_metadata,
                'newVersion': new_version,
                'newMetadata': new_metadata,
                'missingKeys': missing_keys,
                'reviewable': reviewable,
                'recalculated': recalculated,
                'camefrom': self.request.params.get('camefrom', ''),
            })

            if output_format == 'review':
                template = get_customized_template_path(
                    self.request, 'stakeholders/review.mak')
            else:
                template = get_customized_template_path(
                    self.request, 'stakeholders/compare.mak')

            return render_to_response(template, template_values, self.request)

        elif output_format == 'formtest':

            version = self.request.params.get('v', None)

            # Test if an Item is valid according to the form configuration
            items = stakeholder_protocol.read_one(
                self.request, uid=uid, public=False, translate=False)

            for i in item.get('data', []):

                item_version = i.get('version')
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    categorylist = getCategoryList(
                        self.request, 'stakeholders')
                    return render_to_response(
                        'json', checkValidItemjson(categorylist, i),
                        self.request)

            return HTTPNotFound()

        else:
            raise HTTPNotFound()
Esempio n. 14
0
def to_flat_table(request, item_type, involvements='full', columns=[]):

    # Query the Items with the protocol.
    # Important: Query the Items with the original database language! This
    # prevents errors when different main keys (eg. "Remark") have the exact
    # same translation. Instead, the translation happens when filling the row
    # with the help of the configs.
    item_type = validate_item_type(item_type)
    if item_type == 'a':
        items = activity_protocol.read_many(
            request, public=True, translate=False)
        other_item_type = validate_item_type('sh')
    else:
        # Query Stakeholders through Activities.
        items = stakeholder_protocol.read_many_by_activities(
            request, public=True, translate=False)
        other_item_type = validate_item_type('a')

    META_HEADER = ['id', 'version', 'timestamp']
    if item_type == 'a':
        META_HEADER.append('geometry')

    config_taggroups = []
    max_involvements = 0

    # Collect the taggroups based on the form configuration.
    config_taggroups = []
    for config_taggroup in getCategoryList(
            request, item_type).getAllTaggroups():
        config_taggroup_entry = {
            'count': 0,
            'config': config_taggroup,
            'main_key': config_taggroup.getMaintag().getKey().getName()
        }
        config_taggroups.append(config_taggroup_entry)

    # Find out how many times each taggroup occurs. This defines how many
    # columns are needed in the table.
    for item in items.get('data', []):

        # Taggroups: Identified by their main tags.
        current_main_keys = []
        for main_key in get_main_keys_from_item_json(item):
            main_key_already_found = next(
                (i for i in current_main_keys if i['key'] == main_key), None)
            if main_key_already_found:
                main_key_already_found['count'] += 1
            else:
                current_main_keys.append({'key': main_key, 'count': 1})
        for main_key in current_main_keys:
            config_main_key = next((
                i for i in config_taggroups if i['main_key']
                == main_key['key']), None)
            if config_main_key is not None:
                config_main_key['count'] = max(
                    config_main_key['count'], main_key['count'])

        # Involvements
        if involvements != 'none':
            max_involvements = max(max_involvements, len(
                item.get('involvements', [])))

    # Create the headers
    header = []
    header.extend(META_HEADER)
    for config_taggroup_entry in config_taggroups:
        config_taggroup = config_taggroup_entry.get('config')
        config_mainkey = config_taggroup.getMaintag().getKey()
        for i in range(max(config_taggroup_entry.get('count'), 1)):
            for config_tag in sorted(
                    config_taggroup.getTags(),
                    key=lambda t: t != config_taggroup.getMaintag()):

                if (columns and config_tag.getKey().getName() not in columns):
                    continue

                key_name = config_tag.getKey().getTranslatedName()
                # If the taggroup contains multiple tags, add the main key as
                # prefix
                if len(config_taggroup.getTags()) > 1:
                    key_name = '%s_%s' % (
                        config_mainkey.getTranslatedName(), key_name)
                # If the taggroup is repeated, add a number as suffix.
                if (config_taggroup.getRepeatable()
                        or config_mainkey.getType().lower() in
                        ['checkbox', 'inputtoken']):
                    key_name = '%s_%s' % (key_name, i + 1)

                header.append(unicode("%s" % key_name).encode('utf-8'))

                if columns:
                    try:
                        config_taggroup_entry['columns'].append(key_name)
                    except KeyError:
                        config_taggroup_entry['columns'] = [key_name]

    if involvements != 'none':
        inv_keys = [
            i[0] for i in getCategoryList(
                request, other_item_type).getInvolvementOverviewKeyNames()]

        involvement_header = inv_keys + ['inv_role', 'inv_id']
        for i in range(max_involvements):
            for inv_header in involvement_header:
                inv_key_name = '%s_%s' % (inv_header, i + 1)
                header.append(unicode("%s" % inv_key_name).encode('utf-8'))

    # Create the rows
    rows = []
    for item in items.get('data', []):
        row = []

        # Metadata
        for key in META_HEADER:
            if key == 'geometry':
                row.append(",".join(
                    map(str, item.get(key, {}).get("coordinates", []))))
            else:
                row.append(item.get(key, None))

        # Taggroups
        for config_taggroup_entry in config_taggroups:
            found_taggroups = []
            config_taggroup = config_taggroup_entry.get('config')
            config_mainkey = config_taggroup.getMaintag().getKey()

            for taggroup in sorted(
                    item.get('taggroups', []),
                    key=lambda tg: tg.get('tg_id', 0)):

                if taggroup['main_tag']['key'] != config_mainkey.getName():
                    continue

                for config_tag in sorted(
                        config_taggroup.getTags(),
                        key=lambda t: t != config_taggroup.getMaintag()):

                    if (columns and config_tag.getKey().getName()
                            not in columns):
                        continue

                    value = get_value_by_key_from_taggroup_json(
                        taggroup, config_tag.getKey().getName())

                    for config_value in config_tag.getValues():
                        if config_value.getName() == value:
                            value = config_value.getTranslation()

                    if (config_tag.getKey().getType().lower() == 'file'
                            and value):
                        # Uploaded files are displayed with a URL to view the
                        # file
                        files = []
                        try:
                            for v in value.split(','):
                                filename = unicode(
                                    '%s' % v.split('|')[0]).encode('utf-8')
                                url = request.route_url(
                                    'file_view', action='view',
                                    identifier=v.split('|')[1])
                                files.append('%s (%s)' % (filename, url))
                            value = '|'.join(files)
                        except:
                            pass

                    if not value:
                        value = ''

                    found_taggroups.append(
                        unicode("%s" % value).encode("utf-8"))

            # Fill up the rest of the values with None
            if columns:
                try:
                    taggroup_length = len(config_taggroup_entry['columns'])
                except KeyError:
                    taggroup_length = 0
            else:
                taggroup_length = max(
                    config_taggroup_entry.get('count'), 1) * len(
                        config_taggroup.getTags())
            found_taggroups.extend(
                [None] * (taggroup_length - len(found_taggroups)))

            row.extend(found_taggroups)

        # Involvements
        if involvements != 'none':
            inv_row = []
            for involvement in sorted(
                item.get('involvements', []), key=lambda i: (
                    i.get('role_id'), i.get('timestamp'))):
                inv_data = [None] * len(involvement_header)

                # Overview keys
                for i, config_sh_key in enumerate(
                        involvement_header[:len(involvement_header) - 2]):
                    inv_value = get_value_by_key_from_item_json(
                        involvement.get('data', {}), config_sh_key)
                    inv_data[i] = unicode("%s" % inv_value).encode("utf-8")

                # Metadata
                inv_data[len(inv_data) - 2] = involvement.get('role', None)
                inv_data[len(inv_data) - 1] = involvement.get('data', {}).get(
                    'id', None)
                inv_row.extend(inv_data)

            # Fill the rest with None
            inv_row.extend([None] * (
                len(involvement_header) * max_involvements - len(inv_row)))
            row.extend(inv_row)

        rows.append(row)

    return header, rows
Esempio n. 15
0
def read_one(request):
    """
    Read one Activity based on ID and return all versions of this Activity. Also
    return pending versions by currently logged in user and all pending versions
    of this Activity if logged in as moderator.
    Default output format: JSON
    """

    # Handle the parameters (locale, profile)
    bv = BaseView(request)
    bv._handle_parameters()

    try:
        output_format = request.matchdict['output']
    except KeyError:
        output_format = 'json'

    uid = request.matchdict.get('uid', None)
    if check_valid_uuid(uid) is not True:
        raise HTTPNotFound()

    if output_format == 'json':
        activities = activity_protocol3.read_one(request, uid=uid, public=False)
        return render_to_response('json', activities, request)
    elif output_format == 'html':
        # Show the details of an Activity by rendering the form in readonly
        # mode.
        activities = activity_protocol3.read_one(request, uid=uid, public=False,
                                                 translate=False)
        version = request.params.get('v', None)
        if activities and 'data' in activities and len(activities['data']) != 0:
            for a in activities['data']:
                if 'version' in a:
                    if version is None:
                        # If there was no version provided, show the first
                        # version visible to the user
                        version = str(a['version'])
                    if str(a['version']) == version:
                        templateValues = renderReadonlyForm(request, 'activities', a)
                        templateValues['profile'] = get_current_profile(request)
                        templateValues['locale'] = get_current_locale(request)

                        # Append the short uid and the uid to the templates values
                        templateValues['uid'] = uid
                        templateValues['version'] = version
                        templateValues['shortuid'] = uid.split("-")[0]
                        # Append also the site key from the commenting system
                        templateValues['site_key'] = comments_sitekey(request)['site_key']
                        # and the url of the commenting system
                        templateValues['comments_url'] = request.registry.settings['lmkp.comments_url']

                        return render_to_response(
                                                  getTemplatePath(request, 'activities/details.mak'),
                                                  templateValues,
                                                  request
                                                  )
        return HTTPNotFound()
    elif output_format == 'form':
        if request.user is None:
            # Make sure the user is logged in
            raise HTTPForbidden()
        # Query the Activities wih the given identifier
        activities = activity_protocol3.read_one(request, uid=uid, public=False,
                                                 translate=False)
        version = request.params.get('v', None)
        if activities and 'data' in activities and len(activities['data']) != 0:
            for a in activities['data']:
                if 'version' in a:
                    if version is None:
                        # If there was no version provided, show the first
                        # version visible to the user
                        version = str(a['version'])
                    if str(a['version']) == version:
                        templateValues = renderForm(request, 'activities', itemJson=a)
                        if isinstance(templateValues, Response):
                            return templateValues
                        templateValues['profile'] = get_current_profile(request)
                        templateValues['locale'] = get_current_locale(request)
                        templateValues['uid'] = uid
                        templateValues['version'] = version
                        return render_to_response(
                                                  getTemplatePath(request, 'activities/form.mak'),
                                                  templateValues,
                                                  request
                                                  )
        return HTTPNotFound()
    elif output_format in ['review', 'compare']:
        if output_format == 'review':
            # Only moderators can see the review page.
            isLoggedIn, isModerator = checkUserPrivileges(request)
            if isLoggedIn is False or isModerator is False:
                raise HTTPForbidden()
        
        review = ActivityReview(request)
        availableVersions = None
        recalculated = False
        defaultRefVersion, defaultNewVersion = review._get_valid_versions(
                                                                          Activity, uid)
            
        refVersion = request.params.get('ref', None)
        if refVersion is not None:
            try:
                refVersion = int(refVersion)
            except:
                refVersion = None
        if refVersion is None or output_format == 'review':
            # No reference version indicated, use the default one
            # Also use the default one for review because it cannot be changed.
            refVersion = defaultRefVersion
        else:
            availableVersions = review._get_available_versions(Activity, uid, 
                                                               review=output_format == 'review')
            # Check if the indicated reference version is valid
            if refVersion not in [v.get('version') for v in availableVersions]:
                refVersion = defaultRefVersion
        
        newVersion = request.params.get('new', None)
        if newVersion is not None:
            try:
                newVersion = int(newVersion)
            except:
                newVersion = None
        if newVersion is None:
            # No new version indicated, use the default one
            newVersion = defaultNewVersion
        else:
            if availableVersions is None:
                availableVersions = review._get_available_versions(Activity, 
                                                                   uid, review=output_format == 'review')
            # Check if the indicated new version is valid
            if newVersion not in [v.get('version') for v in availableVersions]:
                newVersion = defaultNewVersion
        
        if output_format == 'review':
            # If the Activities are to be reviewed, only the changes which were
            # applied to the newVersion are of interest
            activities, recalculated = review.get_comparison(Activity, uid, 
                                                             refVersion, newVersion)
        else:
            # If the Activities are compared, the versions as they are stored
            # in the database are of interest, without any recalculation
            activities = [
                activity_protocol3.read_one_by_version(request, uid, refVersion,
                                                       geometry='full', translate=False
                                                       ),
                activity_protocol3.read_one_by_version(request, uid, newVersion,
                                                       geometry='full', translate=False
                                                       )
            ]
        templateValues = renderReadonlyCompareForm(request, 'activities', 
                                                   activities[0], activities[1], review=output_format == 'review')
        # Collect metadata for the reference version
        refMetadata = {}
        if activities[0] is not None:
            refMetadata = activities[0].get_metadata(request)
        # Collect metadata and missing keys for the new version
        newMetadata = {}
        missingKeys = []
        reviewable = False
        if activities[1] is not None:
            activities[1].mark_complete(get_mandatory_keys(request, 'a', False))
            missingKeys = activities[1]._missing_keys
            localizer = get_localizer(request)
            if localizer.locale_name != 'en':
                db_lang = Session.query(Language).filter(Language.locale == localizer.locale_name).first()
                missingKeys = get_translated_db_keys(A_Key, missingKeys, db_lang)
                missingKeys = [m[1] for m in missingKeys]
                
            newMetadata = activities[1].get_metadata(request)
            
            reviewable = (len(missingKeys) == 0 and 
                          'reviewableMessage' in templateValues and
                          templateValues['reviewableMessage'] is None)
        
        if output_format == 'review':
            pendingVersions = []
            if availableVersions is None:
                availableVersions = review._get_available_versions(Activity, 
                                                                   uid, review=output_format == 'review')
            for v in sorted(availableVersions, key=lambda v:v.get('version')):
                if v.get('status') == 1:
                    pendingVersions.append(v.get('version'))
            templateValues['pendingVersions'] = pendingVersions
        
        templateValues.update({
                              'identifier': uid,
                              'refVersion': refVersion,
                              'refMetadata': refMetadata,
                              'newVersion': newVersion,
                              'newMetadata': newMetadata,
                              'missingKeys': missingKeys,
                              'reviewable': reviewable,
                              'recalculated': recalculated,
                              'profile': get_current_profile(request),
                              'locale': get_current_locale(request)
                              })
        
        if output_format == 'review':
            return render_to_response(
                                      getTemplatePath(request, 'activities/review.mak'),
                                      templateValues,
                                      request
                                      )
        else:
            return render_to_response(
                                      getTemplatePath(request, 'activities/compare.mak'),
                                      templateValues,
                                      request
                                      )
    elif output_format == 'geojson':
        # A version is required
        version = request.params.get('v', None)
        if version is None:
            raise HTTPBadRequest('You must specify a version as parameter ?v=X')
        translate = request.params.get('translate', 'true').lower() == 'true'
        activities = activity_protocol3.read_one_geojson_by_version(request, 
                                                                    uid, version, translate=translate)
        return render_to_response('json', activities, request)
    elif output_format == 'formtest':
        # Test if an Activity is valid according to the form configuration
        activities = activity_protocol3.read_one(request, uid=uid, public=False,
                                                 translate=False)
        version = request.params.get('v', None)
        if activities and 'data' in activities and len(activities['data']) != 0:
            for a in activities['data']:
                if 'version' in a:
                    if version is None:
                        version = str(a['version'])
                    if str(a['version']) == version:
                        categorylist = getCategoryList(request, 'activities')
                        return render_to_response('json',
                                                  checkValidItemjson(categorylist, a), request)
        return HTTPNotFound()
    # Output the areal statistics for the requested activity based on the
    # Web Processing Service
    elif output_format == 'statistics':

        # Try to get the base URL to the web processing service which provides
        # the areal statistics.
        # If no web processing service is configured, it is assumed that the
        # platform does not provide the areal statistics
        try:
            wps_host = request.registry.settings['lmkp.base_wps']
        except KeyError:
            raise HTTPNotFound()

        spatial_accuracy_map = get_spatial_accuracy_map(request)

        # Check if the spatial accuracy map is configured in the application.yml
        # file
        if spatial_accuracy_map is None:
            raise HTTPNotFound()

        # Show the details of an Activity by rendering the form in readonly
        # mode.
        activities = activity_protocol3.read_one(request, uid=uid, public=False,
                                                 translate=False)

        activity = activities['data'][0]
        coords = activity['geometry']['coordinates']

        for taggroup in activity['taggroups']:
            if taggroup['main_tag']['key'] == _(u"Spatial Accuracy"):
                spatial_accuracy = taggroup['main_tag']['value']

                buffer = spatial_accuracy_map[spatial_accuracy]

        wps_parameters = {
        "ServiceProvider": "",
        "metapath": "",
        "Service": "WPS",
        "Request": "Execute",
        "Version": "1.0.0",
        "Identifier": "BufferStatistics",
        "DataInputs": "lon=%s;lat=%s;epsg=4326;buffer=%s" % (coords[0], coords[1], buffer),
        "RawDataOutput": 'bufferstatistics@mimeType=application/json'
        }

        if not wps_host.endswith("?"):
            wps_host = "%s?" % wps_host
        for k, v in wps_parameters.items():
            wps_host = "%s%s=%s&" % (wps_host, k, v)

        log.debug("Accessing: %s" % wps_host)

        try:
            handle = urllib.urlopen(wps_host)
        except IOError:
            return HTTPInternalServerError("Remote server not accessible.")
        templateValues = json.loads(handle.read())
        templateValues['uid'] = uid
        templateValues['shortuid'] = uid.split("-")[0]
        return render_to_response(
                                  getTemplatePath(request, 'activities/statistics.mak'),
                                  templateValues,
                                  request
                                  )
    else:
        # If the output format was not found, raise 404 error
        raise HTTPNotFound()
Esempio n. 16
0
def get_mandatory_keys(request, item, translated=False):
    if item == 'a':
        configList = getCategoryList(request, 'activities')
    elif item == 'sh':
        configList = getCategoryList(request, 'stakeholders')
    return configList.getDesiredKeyNames(translated=translated)
Esempio n. 17
0
def _extractKeyValues(request, itemType, lang, separator):
    """
    Helper function to extract the keys and values of the database and their
    translations.
    """

    keys = []
    values = []
    strings = []
    valueStrings = []

    originalCategoryList = getCategoryList(request, itemType, lang='en')
    translatedCategoryList = getCategoryList(request, itemType, lang=lang)

    originalTags = sorted(originalCategoryList.getAllTags(), key=lambda t:t.getKey().getName())
    translatedTags = sorted(translatedCategoryList.getAllTags(), key=lambda t:t.getKey().getName())

    strings.append(separator.join([
        'Name (original)',              # [0]
        'Name (translation)',           # [1]
        'Helptext (original)',          # [2]
        'Helptext (translation)',       # [3]
        'Type',                         # [4]
        'Belongs to Key',               # [5]
        'Additional comments'           # [6]
    ]))

    # Keys
    for i, originalTag in enumerate(originalTags):

        originalKeyName = originalTag.getKey().getTranslatedName()

        # Add each key only once
        if originalKeyName in keys:
            continue

        keys.append(originalKeyName)
        originalKey = originalTag.getKey()
        translatedTag = translatedTags[i]
        translatedKey = translatedTag.getKey()
        strings.append(separator.join([
            originalKeyName,
            translatedKey.getTranslatedName(True),
            originalKey.getTranslatedHelptext(),
            translatedKey.getTranslatedHelptext(True),
            'key',
            '-'
        ]))

        originalValues = sorted(originalTag.getValues(), key=lambda val: val.getName())
        translatedValues = sorted(translatedTag.getValues(), key=lambda val: val.getName())

        if len(originalValues) > 0 and len(translatedValues) == len(originalValues):
            for j, originalValue in enumerate(originalValues):

                originalValueName = originalValue.getTranslation()

                # Add each value only once
                if originalValueName in values:
                    continue

                values.append(originalValueName)
                translatedValue = translatedValues[j]
                valueStrings.append(separator.join([
                    originalValueName,
                    translatedValue.getTranslation(True),
                    '',
                    '',
                    'value',
                    originalKeyName
                ]))

    return strings + valueStrings
Esempio n. 18
0
    def read_one(self, public=False):
        """
        Return one :term:`Activity`.

        .. seealso::
            :ref:`read-one`

        Read one :term:`Activity` or one version of an :term:`Activity`.
        By default, this is the latest visible version to the current
        user. This means that logged in users can see their own pending
        version and moderators of the current profile can see a pending
        version as well. If you don't want to see a version pending,
        consider using
        :class:`lmkp.views.activities.ActivityView.read_one_public`
        instead.

        Args:
            ``public`` (bool): A boolean indicating to return only a
            version visible to the public (eg. pending) or not.

        Matchdict parameters:

            ``/activities/{output}/{uid}``

            ``output`` (str): If the output format is not valid, a 404
            Response is returned.

            The following output formats are supported:

                ``json``: Return the :term:`Activity` as JSON. All
                versions visible to the current user are returned.

                ``geojson``: Return the :term:`Activity` as GeoJSON. A
                version parameter is required.

                ``html``: Return the :term:`Activity` as HTML (eg. the
                `Detail View`).

                ``form``: Returns the form to edit an existing
                :term:`Activity`.

                ``compare``: Return the page to compare two versions of
                the :term:`Activity`.

                ``review``: Return the page to review a pending version
                of an :term:`Activity`.

                ``statistics``: Return a page with the areal statistics
                of an :term:`Activity`.

            ``uid`` (str): An :term:`Activity` :term:`UID`.

        Request parameters:
            ``translate`` (bool): Return translated values or not. This
            is only valid for the output formats ``json`` or
            ``geojson``.

            ``v`` (int): Indicate a specific version to return. This is
            only valid for the output formats ``geojson``, ``html`` and
            ``form``.

            ``inv`` (str): Only valid for output format ``form``.
            Indicate an involvement of the form to return to after
            creating a new :term:`Stakeholder`.

            ``ref`` (int) and ``new`` (int): Indicate specific versions.
            This is only valid for the output formats ``compare`` and
            ``review``.

        Returns:
            ``HTTPResponse``. Either a HTML or a JSON response.
        """
        output_format = get_output_format(self.request)

        uid = self.request.matchdict.get("uid", None)
        if validate_uuid(uid) is not True:
            raise HTTPNotFound()

        if output_format == "json":

            translate = self.request.params.get("translate", "true").lower() == "true"

            item = activity_protocol.read_one(self.request, uid=uid, public=public, translate=translate)

            return render_to_response("json", item, self.request)

        elif output_format == "geojson":

            # A version is required
            version = self.request.params.get("v", None)
            if version is None:
                raise HTTPBadRequest("You must specify a version as parameter ?v=X")

            translate = self.request.params.get("translate", "true").lower() == "true"

            item = activity_protocol.read_one_geojson_by_version(self.request, uid, version, translate=translate)

            return render_to_response("json", item, self.request)

        elif output_format == "html":

            version = self.request.params.get("v", None)

            item = activity_protocol.read_one(self.request, uid=uid, public=public, translate=False)

            for i in item.get("data", []):

                item_version = i.get("version")
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    template_values = self.get_base_template_values()
                    template_values.update(renderReadonlyForm(self.request, "activities", i))
                    template_values.update(
                        {
                            "uid": uid,
                            "shortuid": shorten_uuid(uid),
                            "version": version,
                            "site_key": comments_sitekey(self.request)["site_key"],
                            "comments_url": self.request.registry.settings["lmkp.comments_url"],
                        }
                    )

                    return render_to_response(
                        get_customized_template_path(self.request, "activities/details.mak"),
                        template_values,
                        self.request,
                    )

            return HTTPNotFound()

        elif output_format == "form":

            is_logged_in, __ = get_user_privileges(self.request)
            if not is_logged_in:
                raise HTTPForbidden()

            version = self.request.params.get("v", None)

            item = activity_protocol.read_one(self.request, uid=uid, public=False, translate=False)

            for i in item.get("data", []):

                item_version = i.get("version")
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    new_involvement = self.request.params.get("inv")

                    template_values = renderForm(self.request, "activities", itemJson=i, inv=new_involvement)
                    if isinstance(template_values, Response):
                        return template_values

                    template_values.update(self.get_base_template_values())
                    template_values.update({"uid": uid, "version": version})

                    return render_to_response(
                        get_customized_template_path(self.request, "activities/form.mak"), template_values, self.request
                    )

            return HTTPNotFound()

        elif output_format in ["review", "compare"]:

            if output_format == "review":
                # Only moderators can see the review page.
                is_logged_in, is_moderator = get_user_privileges(self.request)
                if not is_logged_in or not is_moderator:
                    raise HTTPForbidden()

            review = ActivityReview(self.request)
            is_review = output_format == "review"
            available_versions = review._get_available_versions(Activity, uid, review=is_review)
            recalculated = False
            default_ref_version, default_new_version = review._get_valid_versions(Activity, uid)

            try:
                ref_version = int(self.request.params.get("ref"))
            except:
                ref_version = None

            # For review or if no valid reference version is provided, use the
            # default reference version.
            if (
                output_format == "review"
                or ref_version is None
                or ref_version not in [v.get("version") for v in available_versions]
            ):
                ref_version = default_ref_version

            try:
                new_version = int(self.request.params.get("new"))
            except:
                new_version = None

            # If no valid new version is provided, use the default new version.
            if new_version is None or new_version not in [v.get("version") for v in available_versions]:
                new_version = default_new_version

            if output_format == "review":
                # If the Items are to be reviewed, only the changes which were
                # applied to the new_version are of interest
                items, recalculated = review.get_comparison(Activity, uid, ref_version, new_version)
            else:
                # If the Items are to be compared, the versions as they are
                # stored in the database are of interest, without any
                # recalculation
                items = [
                    activity_protocol.read_one_by_version(
                        self.request, uid, ref_version, geometry="full", translate=False
                    ),
                    activity_protocol.read_one_by_version(
                        self.request, uid, new_version, geometry="full", translate=False
                    ),
                ]

            template_values = renderReadonlyCompareForm(
                self.request, "activities", items[0], items[1], review=is_review
            )

            # Collect the metadata
            ref_metadata = {}
            new_metadata = {}
            missing_keys = []
            reviewable = False
            if items[0] is not None:
                ref_metadata = items[0].get_metadata(self.request)
            if items[1] is not None:
                new_metadata = items[1].get_metadata(self.request)

                items[1].mark_complete(get_mandatory_keys(self.request, "a", False))
                missing_keys = items[1]._missing_keys
                localizer = get_localizer(self.request)
                if localizer.locale_name != "en":
                    db_lang = Session.query(Language).filter(Language.locale == localizer.locale_name).first()
                    missing_keys = get_translated_db_keys(A_Key, missing_keys, db_lang)
                    missing_keys = [m[1] for m in missing_keys]

                reviewable = (
                    len(missing_keys) == 0
                    and "reviewableMessage" in template_values
                    and template_values["reviewableMessage"] is None
                )

            if output_format == "review":
                pending_versions = []
                for v in sorted(available_versions, key=lambda v: v.get("version")):
                    if v.get("status") == 1:
                        pending_versions.append(v.get("version"))
                template_values.update({"pendingVersions": pending_versions})

            template_values.update(self.get_base_template_values())
            template_values.update(
                {
                    "identifier": uid,
                    "refVersion": ref_version,
                    "refMetadata": ref_metadata,
                    "newVersion": new_version,
                    "newMetadata": new_metadata,
                    "missingKeys": missing_keys,
                    "reviewable": reviewable,
                    "recalculated": recalculated,
                }
            )

            if output_format == "review":
                template = get_customized_template_path(self.request, "activities/review.mak")
            else:
                template = get_customized_template_path(self.request, "activities/compare.mak")

            return render_to_response(template, template_values, self.request)

        elif output_format == "formtest":

            version = self.request.params.get("v", None)

            # Test if an Item is valid according to the form configuration
            items = activity_protocol.read_one(self.request, uid=uid, public=False, translate=False)

            for i in item.get("data", []):

                item_version = i.get("version")
                if version is None:
                    # If there was no version provided, show the first
                    # version visible to the user
                    version = str(item_version)

                if str(item_version) == version:

                    categorylist = getCategoryList(self.request, "activities")
                    return render_to_response("json", checkValidItemjson(categorylist, i), self.request)

            return HTTPNotFound()

        elif output_format == "statistics":

            # Try to get the base URL to the web processing service which
            # provides the areal statistics.
            # If no web processing service is configured, it is assumed that
            # the platform does not provide the areal statistics
            try:
                wps_host = self.request.registry.settings["lmkp.base_wps"]
            except KeyError:
                raise HTTPNotFound()

            # Check if the spatial accuracy map is configured in the
            # application .yml file
            spatial_accuracy_map = get_spatial_accuracy_map(self.request)
            if spatial_accuracy_map is None:
                raise HTTPNotFound()

            # Show the details of an Activity by rendering the form in readonly
            # mode.
            activities = activity_protocol.read_one(self.request, uid=uid, public=False, translate=False)

            activity = activities["data"][0]
            coords = activity["geometry"]["coordinates"]

            for taggroup in activity["taggroups"]:
                if taggroup["main_tag"]["key"] == "Spatial Accuracy":
                    spatial_accuracy = taggroup["main_tag"]["value"]

                    buffer = spatial_accuracy_map[spatial_accuracy]

            wps_parameters = {
                "ServiceProvider": "",
                "metapath": "",
                "Service": "WPS",
                "Request": "Execute",
                "Version": "1.0.0",
                "Identifier": "BufferStatistics",
                "DataInputs": "lon=%s;lat=%s;epsg=4326;buffer=%s" % (coords[0], coords[1], buffer),
                "RawDataOutput": "bufferstatistics@mimeType=application/json",
            }

            if not wps_host.endswith("?"):
                wps_host = "%s?" % wps_host
            for k, v in wps_parameters.items():
                wps_host = "%s%s=%s&" % (wps_host, k, v)

            log.debug("Accessing: %s" % wps_host)

            try:
                handle = urllib.urlopen(wps_host)
            except IOError:
                return HTTPInternalServerError("Remote server not accessible.")
            templateValues = json.loads(handle.read())
            templateValues["uid"] = uid
            templateValues["shortuid"] = uid.split("-")[0]
            return render_to_response(
                get_customized_template_path(self.request, "activities/statistics.mak"), templateValues, self.request
            )
        else:
            raise HTTPNotFound()