def succeed(): """ """ # Request all submitted values profile_field = self.request.POST.get("profile") username_field = self.request.POST.get("username") firstname_field = self.request.POST.get("firstname") lastname_field = self.request.POST.get("lastname") password_field = self.request.POST.get("password") email_field = self.request.POST.get("email") # Get the selected profile selected_profile = Session.query(Profile).filter( Profile.code == profile_field).first() # Get the initial user group user_group = Session.query(Group).filter( Group.name == "editors").first() # Create an activation uuid activation_uuid = uuid.uuid4() # Create a new user new_user = User(username_field, password_field, email_field, firstname=firstname_field, lastname=lastname_field, activation_uuid=activation_uuid, registration_timestamp=datetime.now()) # Set the user profile new_user.profiles = [selected_profile] new_user.groups = [user_group] # Commit the new user Session.add(new_user) activation_dict = { "firstname": new_user.firstname, "lastname": new_user.lastname, "activation_link": "http://%s/users/activate?uuid=%s&username="******"%s" % ( self.request.environ['HTTP_HOST'], activation_uuid, new_user.username) } email_text = render( get_customized_template_path( self.request, 'emails/account_activation.mak'), activation_dict, self.request) self._send_email( [email_field], _(u"Activate your Account"), email_text) return render_to_response( get_customized_template_path( self.request, 'users/registration_success.mak'), {}, self.request)
def notfound_view(request): """ Return the 404 Not Found page. Args: ``request`` (pyramid.request): A :term:`Pyramid` Request object Returns: ``HTTPResponse``. A HTML response. """ def _foo(): """ A stub function doing nothing. Used because the template requires a function request.current_route_url. """ pass request.response.status = 404 request.current_route_url = _foo view = BaseView(request) return render_to_response( get_customized_template_path(request, 'errors/notfound.mak'), view.get_base_template_values(), request)
def login_form(self): """ Renders the simple login form """ # Prevent endless loops if self.request.referer is not None\ and self.request.referer != self.request.route_url('reset_form')\ and not self.request.referer.startswith( self.request.route_url('login_form')): came_from = self.request.referer else: came_from = self.request.route_url('map_view') # Make sure the user is not logged in principals = effective_principals(self.request) if "system.Authenticated" in principals: return HTTPFound(location=came_from) return render_to_response( get_customized_template_path(self.request, 'login_form.mak'), { 'came_from': came_from, 'warning': None }, self.request)
def charts(self): template_values = self.template_values chart_type = self.request.matchdict.get('type', 'bars') if chart_type == 'bars': params = self.request.matchdict.get('params') if params == ('sh',): template = 'barchart_sh' else: template = 'barchart_a' elif chart_type == 'stackedbars': template = 'stackedbarchart' elif chart_type == 'map': template = 'mapchart' profiles = sorted(get_profiles(), key=lambda profile: profile[0]) profiles.append(('global', 'global')) template_values.update({ 'profiles': profiles }) else: return HTTPNotFound() attr = self.request.params.get('attr', 0) template_values.update({ 'attr': attr }) return render_to_response( get_customized_template_path( self.request, 'charts/%s.mak' % template), template_values, self.request)
def approve(self): """ User moderation: approve newly activated users. """ # Get the URL parameters user_uuid = self.request.params.get("user") user_username = self.request.params.get("name") # Try to the user, who must not yet be approved user = Session.query(User).filter(and_( User.uuid == user_uuid, User.username == user_username, User.is_approved == False)).first() # Raise a BadRequest if no user is found if user is None: raise HTTPBadRequest( "User is already approved or does not exist in the database.") # Set the is_approved attribute to TRUE user.is_approved = True conf_dict = { "firstname": user.firstname, "lastname": user.lastname, "host": "http://%s" % self.request.environ['HTTP_HOST'] } email_text = render( get_customized_template_path( self.request, 'emails/account_approval_confirmation.mak'), conf_dict, request=self.request) # Send the email self._send_email( [user.email], "Account confirmation on %s" % "http://%s" % self.request.environ['HTTP_HOST'], email_text) # Return the username to the template return render_to_response( get_customized_template_path( self.request, 'users/approval_successful.mak'), { 'username': user_username }, self.request)
def reset(self): if self.request.params.get('came_from') is not None: came_from = self.request.params.get('came_from') else: came_from = self.request.route_url('map_view') # Make sure the user is not logged in principals = effective_principals(self.request) if "system.Authenticated" in principals: return HTTPFound(location=came_from) username = self.request.params.get("username") user = DBSession.query(User).filter(User.username == username).first() if user is None: msg = _(u"No registered user found with this email address.") return render_to_response( get_customized_template_path( self.request, 'users/reset_password_form.mak'), { 'came_from': came_from, 'warning': msg }, self.request) new_password = user.set_new_password() body = render( get_customized_template_path( self.request, 'emails/reset_password.mak'), { 'user': user.username, 'new_password': new_password }, self.request) self._send_email([user.email], _(u"Password reset"), body) return render_to_response( get_customized_template_path( self.request, 'users/reset_password_success.mak'), {}, self.request)
def download(self): """ """ return render_to_response( get_customized_template_path(self.request, 'download_view.mak'), { 'profile': get_current_profile(self.request), 'locale': get_current_locale(self.request) }, self.request)
def reset_form(self): came_from = self.request.params.get('came_from', None) return render_to_response( get_customized_template_path( self.request, 'users/reset_password_form.mak'), { 'came_from': came_from, "warning": None }, self.request)
def about_view(self): """ Returns the HTML page with the "about" information. :term:`Customized template` used: ``about_view.mak``. Returns: ``HTTPResponse``. A HTML response. """ return render_to_response( get_customized_template_path(self.request, 'about_view.mak'), self.template_values, self.request)
def partners_view(self): """ Returns the HTML page with the Partners. :term:`Customized template` used: ``partners_view.mak``. Returns: ``HTTPResponse``. A HTML response. """ return render_to_response( get_customized_template_path(self.request, 'partners_view.mak'), self.template_values, self.request)
def map_view(self): """ Returns the HTML page with the main map, eg. the Map View. :term:`Customized template` used: ``map_view.mak``. Returns: ``HTTPResponse``. A HTML response. """ return render_to_response( get_customized_template_path(self.request, 'map_view.mak'), self.template_values, self.request)
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)
def forbidden_view(request): """ Return the 403 Forbidden page if the user is logged in but has no permissions to view the page. The login page is returned if the user is not logged in. Args: ``request`` (pyramid.request): A :term:`Pyramid` Request object Returns: ``HTTPResponse``. A HTML response. """ view = BaseView(request) is_logged_in, __ = get_user_privileges(request) # User is already logged in, show error message if is_logged_in: request.response.status = 403 return render_to_response( get_customized_template_path(request, 'errors/forbidden.mak'), view.get_base_template_values(), request) # User is not logged in: show login form else: came_from = request.url warning = _(u"Please login to access:") warning += "<br/>%s" % came_from template_values = view.get_base_template_values() template_values.update({ 'came_from': came_from, 'warning': warning }) return render_to_response( get_customized_template_path(request, 'login_form.mak'), template_values, request)
def index(self): """ Returns the root HTML page. This is the landing page, where users can for example select the profile before continuing to the map view. :term:`Customized template` used: ``landing_page.mak``. Returns: ``HTTPResponse``. A HTML response. """ return render_to_response( get_customized_template_path(self.request, 'landing_page.mak'), self.template_values, self.request)
def charts_view(self): """ Returns the HTML page with the chart, eg. the Chart View. For the time being, this view returns the overview view of the Charts. .. seealso:: :class:`lmkp.views.charts.ChartsView.charts_overview` Returns: ``HTTPResponse``. A HTML response. """ return HTTPFound(location=self.request.route_url('charts_overview')) return render_to_response( get_customized_template_path(self.request, 'charts_view.mak'), self.template_values, self.request)
def read_byuser(request): try: output_format = request.matchdict['output'] except KeyError: output_format = 'rss' if output_format == 'rss': template = 'changesets/byuser_rss.mak' elif output_format == 'html': template = 'changesets/byuser_html.mak' else: raise HTTPNotFound("Requested output format is not supported.") templateValues = changeset_protocol.read_many_byuser(request) return render_to_response( get_customized_template_path(request, template), templateValues, request)
def login(self): """ Login controller """ login_url = self.request.route_url('login') referrer = self.request.path if referrer == login_url: # never use the login form itself as came_from referrer = '/' came_from = self.request.params.get('came_from', referrer) login = '' password = '' # Prevent an empty header if /login is directly requested (should # actually never happen) headers = [] if 'form.submitted' in self.request.params: login = self.request.params['login'] password = self.request.params['password'] if User.check_password(login, password): log.debug('Login succeed') headers = remember( self.request, login, max_age=timedelta(days=30).total_seconds()) else: log.debug('Login failed') headers = forget(self.request) msg = _(u"Login failed! Please try again.") return render_to_response( get_customized_template_path( self.request, 'login_form.mak'), { 'came_from': came_from, 'warning': msg }, self.request) return HTTPFound(location=came_from, headers=headers)
def register(self): """ Returns and process user self registration form. """ _ = self.request.translate # Define a colander Schema for the self registration class Schema(colander.Schema): profile = colander.SchemaNode( colander.String(), widget=deform.widget.TextInputWidget(template='hidden'), name='profile', title='Profile', default=get_current_profile(self.request), missing=get_default_profile(self.request)) username = colander.SchemaNode( colander.String(), validator=_user_already_exists, title=_('Username')) password = colander.SchemaNode( colander.String(), validator=colander.Length(min=5), widget=deform.widget.CheckedPasswordWidget(size=20), title=_('Password')) firstname = colander.SchemaNode( colander.String(), missing=unicode(u''), title=_('First Name')) lastname = colander.SchemaNode( colander.String(), missing=unicode(u''), title=_('Last Name')) email = colander.SchemaNode( colander.String(), default='', title=_("Valid Email"), validator=_is_valid_email) schema = Schema() deform.Form.set_default_renderer(mako_renderer) buttons = [deform.Button( 'submit', _('Submit'), css_class='btn btn-primary')] form = deform.Form(schema, buttons=buttons) def succeed(): """ """ # Request all submitted values profile_field = self.request.POST.get("profile") username_field = self.request.POST.get("username") firstname_field = self.request.POST.get("firstname") lastname_field = self.request.POST.get("lastname") password_field = self.request.POST.get("password") email_field = self.request.POST.get("email") # Get the selected profile selected_profile = Session.query(Profile).filter( Profile.code == profile_field).first() # Get the initial user group user_group = Session.query(Group).filter( Group.name == "editors").first() # Create an activation uuid activation_uuid = uuid.uuid4() # Create a new user new_user = User(username_field, password_field, email_field, firstname=firstname_field, lastname=lastname_field, activation_uuid=activation_uuid, registration_timestamp=datetime.now()) # Set the user profile new_user.profiles = [selected_profile] new_user.groups = [user_group] # Commit the new user Session.add(new_user) activation_dict = { "firstname": new_user.firstname, "lastname": new_user.lastname, "activation_link": "http://%s/users/activate?uuid=%s&username="******"%s" % ( self.request.environ['HTTP_HOST'], activation_uuid, new_user.username) } email_text = render( get_customized_template_path( self.request, 'emails/account_activation.mak'), activation_dict, self.request) self._send_email( [email_field], _(u"Activate your Account"), email_text) return render_to_response( get_customized_template_path( self.request, 'users/registration_success.mak'), {}, self.request) ret = self._render_form(form, success=succeed) # 'ret' is a Response object if the form was submitted with success. In # this case, it is not possible to add any parameters to it. if not isinstance(ret, Response): self._handle_parameters() ret['profile'] = get_current_profile(self.request) ret['locale'] = get_current_locale(self.request) # Render the return values return render_to_response( get_customized_template_path( self.request, 'users/registration_form.mak'), ret, self.request) return ret
def account(self): """ Shows user account details to registered users. """ _ = self.request.translate userid = authenticated_userid(self.request) # Define a colander Schema for the self registration class Schema(colander.Schema): username = colander.SchemaNode( colander.String(), missing=None, widget=deform.widget.TextInputWidget( readonly=True, readonly_template='readonly/customTextinputReadonly'), title=_('Username')) password = colander.SchemaNode( colander.String(), validator=colander.Length(min=5), widget=deform.widget.CheckedPasswordWidget(size=20), title=_('Password')) firstname = colander.SchemaNode( colander.String(), missing=None, title=_('First Name')) lastname = colander.SchemaNode( colander.String(), missing=None, title=_('Last Name')) email = colander.SchemaNode( colander.String(), missing=None, widget=deform.widget.TextInputWidget( readonly=True, readonly_template='readonly/customTextinputReadonly'), title=_('Valid Email'),) schema = Schema() deform.Form.set_default_renderer(mako_renderer) form = deform.Form(schema, buttons=(deform.Button( title=_(u'Update'), css_class='btn btn-primary'), ), use_ajax=True) # Get the user data user = Session.query(User).filter(User.username == userid).first() data = { 'username': user.username, 'firstname': user.firstname, 'lastname': user.lastname, 'email': user.email } def succeed(): # Request all submitted values firstname_field = self.request.POST.get("firstname") lastname_field = self.request.POST.get("lastname") password_field = self.request.POST.get("password") # Update user fields user.firstname = firstname_field user.lastname = lastname_field if password_field is not None and password_field != '': user.password = password_field return Response( '<div class="alert alert-success">%s</div>' % _('Your user settings were updated.')) ret = self._render_form(form, success=succeed, appstruct=data) if not isinstance(ret, Response): self._handle_parameters() ret['profile'] = get_current_profile(self.request) ret['locale'] = get_current_locale(self.request) ret['username'] = user.username return render_to_response( get_customized_template_path( self.request, 'users/account_form.mak'), ret, self.request) return ret
def activate(self): """ """ activation_uuid = self.request.params.get("uuid") username = self.request.params.get("username") # Get the user user = Session.query(User).filter(and_( User.activation_uuid == activation_uuid, User.username == username, User.is_active == False)).first() # Raise a BadRequest if no user is found if user is None: raise HTTPBadRequest() # A timedelta of 48 hours equals 2 days delta = timedelta(hours=48) # Create a timezone info tz = psycopg2.tz.FixedOffsetTimezone(offset=0, name="UTC") # Check if the registration timestamp is not older than 48 hours if (datetime.now(tz) - delta) > user.registration_timestamp: raise HTTPBadRequest("Activation link has been expired.") # Set the user active and set the activation uuid to NULL user.is_active = True user.activation_uuid = None approval_dict = { "username": user.username, "firstname": user.firstname, "lastname": user.lastname, "email": user.email, "profiles": ",".join([p.code for p in user.profiles]), "approval_link": "http://%s/users/approve?user=%s&name=%s" % ( self.request.environ['HTTP_HOST'], user.uuid, user.username) } # Send an email to all moderators of the profile in which the user # registered. email_text = render( get_customized_template_path( self.request, 'emails/account_approval_request.mak'), approval_dict, request=self.request) # Determine profile. Each user should only have one profile when # registering! profiles = [p.code for p in user.profiles] if len(profiles) == 0: profile = get_default_profile(self.request) else: profile = profiles[0] # Find moderators of this profile moderators = Session.query(User).\ join(users_groups).\ join(Group).\ join(users_profiles).\ join(Profile).\ filter(Group.name == 'moderators').\ filter(Profile.code == profile) # A list with email addresses the email is sent to email_addresses = [] for m in moderators.all(): email_addresses.append(m.email) if len(email_addresses) == 0: # If no moderator, try to contact the administrators for admin_user in Session.query(User).join(users_groups).join( Group).filter(func.lower(Group.name) == 'administrators'): email_addresses.append(admin_user.email) log.debug( "No moderator found for profile %s. Approval emails will be " "sent to administrators: %s" % (profile, email_addresses)) else: log.debug( "Approval emails will be sent to moderators of %s profile: %s" % (profile, email_addresses)) # Send the email self._send_email( email_addresses, "User %s requests approval" % user.username, email_text) return render_to_response( get_customized_template_path( self.request, 'users/activation_successful.mak'), { 'username': user.username }, self.request)
def by_activities(self, public=False): """ Return many :term:`Stakeholders` based on :term:`Activities`. Based on the :term:`UIDs` of one or many :term:`Activities`, all :term:`Stakeholders` which are involved in the :term:`Activity` are returend. .. seealso:: :ref:`read-many` For each :term:`Stakeholder`, only one version is visible, always the latest visible version to the current user. This means that logged in users can see their own pending versions and moderators of the current profile can see pending versions as well. If you don't want to show pending versions, consider using :class:`lmkp.views.stakeholders.StakeholderView.by_activities_public` instead. By default, the :term:`Stakeholders` are ordered with the :term:`Stakeholder` having the most recent change being on top. Args: ``public`` (bool): A boolean indicating whether to return only versions visible to the public (eg. pending) or not. Matchdict parameters: ``/stakeholders/byactivities/{output}`` or ``/stakeholders/byactivities/{output}/{uids}`` ``output`` (str): If the output format is not valid, a 404 Response is returned. The following output formats are supported: ``json``: Return the :term:`Stakeholders` as JSON. ``html``: Return the :term:`Stakeholders` as HTML (eg. the `Grid View`) ``uids`` (str): An optional comma-separated list of :term:`Activity` :term:`UIDs`. Request parameters: ``page`` (int): The page parameter is used to paginate :term:`Items`. In combination with ``pagesize`` it defines the offset. ``pagesize`` (int): The pagesize parameter defines how many :term:`Items` are displayed at once. It is used in combination with ``page`` to allow pagination. ``status`` (str): Use the status parameter to limit results to displaying only versions with a certain :term:`status`. Returns: ``HTTPResponse``. Either a HTML or a JSON response. """ output_format = get_output_format(self.request) uids = self.request.matchdict.get('uids', '').split(',') # Remove any invalid UIDs for uid in uids: if validate_uuid(uid) is not True: uids.remove(uid) if output_format == 'json': items = stakeholder_protocol.read_many_by_activities( self.request, public=public, uids=uids) return render_to_response('json', items, self.request) elif output_format == 'html': page, page_size = get_page_parameters(self.request) items = stakeholder_protocol.read_many_by_activities( self.request, public=public, uids=uids, limit=page_size, offset=page_size * page - page_size) # Show a spatial filter only if there is no involvement # filter (no Activity UID set) spatial_filter = None if len(uids) == 0: spatial_filter = 'profile' if get_bbox_parameters( self.request)[0] == 'profile' else 'map' status_filter = None __, is_moderator = get_user_privileges(self.request) template_values = self.get_base_template_values() template_values.update({ 'data': items['data'] if 'data' in items else [], 'total': items['total'] if 'total' in items else 0, 'spatialfilter': spatial_filter, 'invfilter': uids, 'statusfilter': status_filter, 'currentpage': page, 'pagesize': page_size, 'is_moderator': is_moderator, 'handle_query_string': handle_query_string }) return render_to_response( get_customized_template_path( self.request, 'stakeholders/grid.mak'), template_values, self.request) else: raise HTTPNotFound()
def read_many(self, public=False): """ Return many :term:`Stakeholders`. .. seealso:: :ref:`read-many` For each :term:`Stakeholder`, only one version is visible, always the latest visible version to the current user. This means that logged in users can see their own pending versions and moderators of the current profile can see pending versions as well. If you don't want to show pending versions, consider using :class:`lmkp.views.stakeholders.StakeholderView.read_many_public` instead. By default, the :term:`Stakeholders` are ordered with the :term:`Stakeholder` having the most recent change being on top. Args: ``public`` (bool): A boolean indicating whether to return only versions visible to the public (eg. pending) or not. Matchdict parameters: ``/stakeholders/{output}`` ``output`` (str): If the output format is not valid, a 404 Response is returned. The following output formats are supported: ``json``: Return the :term:`Stakeholders` as JSON. ``html``: Return the :term:`Stakeholders` as HTML (eg. the `Grid View`) ``form``: Returns the form to create a new :term:`Stakeholder`. ``download``: Returns the page to download :term:`Stakeholders`. Request parameters: ``page`` (int): The page parameter is used to paginate :term:`Items`. In combination with ``pagesize`` it defines the offset. ``pagesize`` (int): The pagesize parameter defines how many :term:`Items` are displayed at once. It is used in combination with ``page`` to allow pagination. ``status`` (str): Use the status parameter to limit results to displaying only versions with a certain :term:`status`. Returns: ``HTTPResponse``. Either a HTML or a JSON response. """ output_format = get_output_format(self.request) if output_format == 'json': items = stakeholder_protocol.read_many(self.request, public=False) return render_to_response('json', items, self.request) elif output_format == 'html': page, page_size = get_page_parameters(self.request) items = stakeholder_protocol.read_many( self.request, public=public, limit=page_size, offset=page_size * page - page_size) spatial_filter = None status_filter = get_status_parameter(self.request) __, is_moderator = get_user_privileges(self.request) template_values = self.get_base_template_values() template_values.update({ 'data': items['data'] if 'data' in items else [], 'total': items['total'] if 'total' in items else 0, 'spatialfilter': spatial_filter, 'invfilter': None, 'statusfilter': status_filter, 'currentpage': page, 'pagesize': page_size, 'is_moderator': is_moderator, 'handle_query_string': handle_query_string }) return render_to_response( get_customized_template_path( self.request, 'stakeholders/grid.mak'), template_values, self.request) elif output_format == 'form': is_logged_in, __ = get_user_privileges(self.request) if not is_logged_in: raise HTTPForbidden() new_involvement = self.request.params.get('inv', None) template_values = renderForm( self.request, 'stakeholders', inv=new_involvement) if isinstance(template_values, Response): return template_values template_values.update({ 'profile': get_current_profile(self.request), 'locale': get_current_locale(self.request) }) return render_to_response( get_customized_template_path( self.request, 'stakeholders/form.mak'), template_values, self.request ) elif output_format == 'download': download_view = DownloadView(self.request) return download_view.download_customize('stakeholders') else: raise HTTPNotFound()
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 """ # 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 = urlparse.urlsplit( request.url) queryparams = urlparse.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( get_customized_template_path( request, 'parts/items/activity.mak'), {}, request ) configList = aList elif queryparts[0] == 'sh': itemName = render( get_customized_template_path( 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]: v = v.decode('utf-8') q = q.decode('utf-8') if type(displayKey) != unicode: displayKey = displayKey.decode('utf-8') # 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
def read_many(self, public=False): """ Return many :term:`Activities`. .. seealso:: :ref:`read-many` For each :term:`Activity`, only one version is visible, always the latest visible version to the current user. This means that logged in users can see their own pending versions and moderators of the current profile can see pending versions as well. If you don't want to show pending versions, consider using :class:`lmkp.views.activities.ActivityView.read_many_public` instead. By default, the :term:`Activities` are ordered with the :term:`Activity` having the most recent change being on top. Args: ``public`` (bool): A boolean indicating whether to return only versions visible to the public (eg. pending) or not. Matchdict parameters: ``/activities/{output}`` ``output`` (str): If the output format is not valid, a 404 Response is returned. The following output formats are supported: ``json``: Return the :term:`Activities` as JSON. ``geojson``: Return the :term:`Activities` as GeoJSON. ``html``: Return the :term:`Activities` as HTML (eg. the `Grid View`) ``form``: Returns the form to create a new :term:`Activity`. ``download``: Returns the page to download :term:`Activities`. Request parameters: ``page`` (int): The page parameter is used to paginate :term:`Items`. In combination with ``pagesize`` it defines the offset. ``pagesize`` (int): The pagesize parameter defines how many :term:`Items` are displayed at once. It is used in combination with ``page`` to allow pagination. ``status`` (str): Use the status parameter to limit results to displaying only versions with a certain :term:`status`. Returns: ``HTTPResponse``. Either a HTML or a JSON response. """ output_format = get_output_format(self.request) if output_format == "json": items = activity_protocol.read_many(self.request, public=public) return render_to_response("json", items, self.request) elif output_format == "geojson": items = activity_protocol.read_many_geojson(self.request, public=public) return render_to_response("json", items, self.request) elif output_format == "html": page, page_size = get_page_parameters(self.request) items = activity_protocol.read_many( self.request, public=public, limit=page_size, offset=page_size * page - page_size ) spatial_filter = "profile" if get_bbox_parameters(self.request)[0] == "profile" else "map" status_filter = get_status_parameter(self.request) __, is_moderator = get_user_privileges(self.request) template_values = self.get_base_template_values() template_values.update( { "data": items["data"] if "data" in items else [], "total": items["total"] if "total" in items else 0, "spatialfilter": spatial_filter, "invfilter": None, "statusfilter": status_filter, "currentpage": page, "pagesize": page_size, "is_moderator": is_moderator, "handle_query_string": handle_query_string, } ) return render_to_response( get_customized_template_path(self.request, "activities/grid.mak"), template_values, self.request ) elif output_format == "form": is_logged_in, __ = get_user_privileges(self.request) if not is_logged_in: raise HTTPForbidden() new_involvement = self.request.params.get("inv", None) template_values = renderForm(self.request, "activities", inv=new_involvement) if isinstance(template_values, Response): return template_values template_values.update(self.get_base_template_values()) template_values.update({"uid": "-", "version": 0}) return render_to_response( get_customized_template_path(self.request, "activities/form.mak"), template_values, self.request ) elif output_format == "download": download_view = DownloadView(self.request) return download_view.download_customize("activities") else: raise HTTPNotFound()
def by_stakeholders(self, public=False): """ Return many :term:`Activities` based on :term:`Stakeholders`. Based on the :term:`UIDs` of one or many :term:`Stakeholders`, all :term:`Activities` in which the :term:`Stakeholder` is involved are returned. .. seealso:: :ref:`read-many` For each :term:`Activity`, only one version is visible, always the latest visible version to the current user. This means that logged in users can see their own pending versions and moderators of the current profile can see pending versions as well. If you don't want to show pending versions, consider using :class:`lmkp.views.activities.ActivityView.by_stakeholder_public` instead. By default, the :term:`Activities` are ordered with the :term:`Activity` having the most recent change being on top. Args: ``public`` (bool): A boolean indicating whether to return only versions visible to the public (eg. pending) or not. Matchdict parameters: ``/activities/bystakeholders/{output}/{uids}`` ``output`` (str): If the output format is not valid, a 404 Response is returned. The following output formats are supported: ``json``: Return the :term:`Activities` as JSON. ``html``: Return the :term:`Activities` as HTML (eg. the `Grid View`) ``uids`` (str): A comma-separated list of :term:`Stakeholder` :term:`UIDs`. Request parameters: ``page`` (int): The page parameter is used to paginate :term:`Items`. In combination with ``pagesize`` it defines the offset. ``pagesize`` (int): The pagesize parameter defines how many :term:`Items` are displayed at once. It is used in combination with ``page`` to allow pagination. ``status`` (str): Use the status parameter to limit results to displaying only versions with a certain :term:`status`. Returns: ``HTTPResponse``. Either a HTML or a JSON response. """ output_format = get_output_format(self.request) uids = self.request.matchdict.get("uids", "").split(",") # Remove any invalid UIDs for uid in uids: if validate_uuid(uid) is not True: uids.remove(uid) if len(uids) == 0: raise HTTPNotFound() if output_format == "json": items = activity_protocol.read_many_by_stakeholders(self.request, uids=uids, public=public) return render_to_response("json", items, self.request) elif output_format == "html": page, page_size = get_page_parameters(self.request) items = activity_protocol.read_many_by_stakeholders( self.request, uids=uids, public=public, limit=page_size, offset=page_size * page - page_size ) # No spatial filter is used if the Activities are filtered # by a Stakeholder spatial_filter = None status_filter = None template_values = self.get_base_template_values() template_values.update( { "data": items["data"] if "data" in items else [], "total": items["total"] if "total" in items else 0, "spatialfilter": spatial_filter, "invfilter": uids, "statusfilter": status_filter, "currentpage": page, "pagesize": page_size, "handle_query_string": handle_query_string, } ) return render_to_response( get_customized_template_path(self.request, "activities/grid.mak"), template_values, self.request ) else: raise HTTPNotFound()
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()
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()
def history(self): """ Return the history of an :term:`Activity`. Logged in users can see their own pending versions and moderators of the current profile can see pending versions as well. By default, the versions are ordered with the most recent changes being on top. Matchdict parameters: ``/activities/history/{output}/{uid}`` ``output`` (str): If the output format is not valid, a 404 Response is returned. The following output formats are supported: ``html``: Return the history view as HTML. ``rss``: Return history view as RSS feed. ``uid`` (str): An :term:`Activity` :term:`UID`. 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() __, is_moderator = get_user_privileges(self.request) items, count = activity_protocol.read_one_history(self.request, uid=uid) active_version = None for i in items: if "statusName" in i: i["statusName"] = get_translated_status(self.request, i["statusName"]) if i.get("statusId") == 2: active_version = i.get("version") template_values = self.get_base_template_values() template_values.update( {"versions": items, "count": count, "activeVersion": active_version, "isModerator": is_moderator} ) if output_format == "html": template = get_customized_template_path(self.request, "activities/history.mak") elif output_format == "rss": template = get_customized_template_path(self.request, "activities/history_rss.mak") else: raise HTTPNotFound() return render_to_response(template, template_values, self.request)
def charts_overview(self): return render_to_response( get_customized_template_path(self.request, 'charts_view.mak'), self.get_base_template_values(), self.request)