def apply(self, id=None, data=None, errors=None, error_summary=None):
        """
        Form for a user to request to be an editor for a organisation.
        It sends an email to a suitable admin.
        """
        if not c.user:
            abort(401, _('You must be logged in to apply for membership'))

        if 'parent' in request.params and not id:
            id = request.params['parent']

        if id:
            c.group = model.Group.get(id)
            if not c.group:
                log.warning('Could not find organisation for name %s', id)
                abort(404, _('Publisher not found'))
            if 'save' in request.params and not errors:
                from ckanext.dgu_orgs.model.organisation_request import OrganisationRequest

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

                if model.Session.query(OrganisationRequest).filter_by(
                        user_name=c.user, group_name=id).all():
                    h.flash_error(
                        'A request for this organisation is already in the system. If you have waited more than a couple of days then <a href="http://data.gov.uk/contact">contact the data.gov.uk team</a>',
                        allow_html=True)
                    h.redirect_to('organisation_apply', id=id)
                    return
                else:
                    req = OrganisationRequest(user_name=c.user,
                                              group_name=id,
                                              reason=reason)
                    model.Session.add(req)
                    model.Session.commit()

                    return self._send_application(c.group, reason)
        else:
            c.possible_parents = model.Session.query(model.Group)\
                .filter(model.Group.state=='active').order_by(model.Group.title).all()

        data = data or {}
        errors = errors or {}
        error_summary = error_summary or {}

        data.update(request.params)

        vars = {'data': data, 'errors': errors, 'error_summary': error_summary}
        c.form = render('organisation/apply_form.html', extra_vars=vars)
        return render('organisation/apply.html')
    def index(self):

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author
        }
        data_dict = {'all_fields': True}

        try:
            check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # This used to be just used by the hierarchy but now is not, but it is
        # now used for search autocomplete and count.
        # c.all_groups = model.Session.query(model.Group).\
        #                filter(model.Group.type == 'organization').\
        #                filter(model.Group.state == 'active').\
        #                order_by('title')
        # c.page = AlphaPage(
        #     controller_name="ckanext.dgu_orgs.controllers.organisation:OrganisationController",
        #     collection=c.all_groups,
        #     page=request.params.get('page', 'A'),
        #     alpha_attribute='title',
        #     other_text=_('Other'),
        # )

        return render('organisation/index.html')
    def report_groups_without_admins(self):
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author
        }
        try:
            check_access('group_create', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        g_query = """SELECT g.* FROM public.group g WHERE id NOT IN
                    (SELECT group_id FROM public.member WHERE capacity='admin')
                    ORDER BY g.name;"""
        c.non_admin = model.Session.query(
            model.Group).from_statement(g_query).all()
        c.non_admin_count = len(c.non_admin)

        return render('organisation/report_groups_without_admins.html')
    def report_users_not_assigned_to_groups(self):
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author
        }
        try:
            check_access('group_create', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        query = """SELECT * FROM public.user WHERE id NOT IN
                (SELECT table_id FROM public.member WHERE table_name='user')
                ORDER BY created desc;"""
        c.unassigned_users = model.Session.query(
            model.User).from_statement(query).all()
        c.unassigned_users_count = len(c.unassigned_users)

        return render('organisation/report_users_not_assigned_to_groups.html')
    def report_users(self):
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author
        }
        try:
            check_access('group_create', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        q = model.Session.query(model.User).order_by(model.User.created.desc())
        c.count = q.count()

        c.page = h.Page(
            collection=q,
            page=int(request.params.get('page', 1)),
            url=h.pager_url,
            items_per_page=report_limit,
        )

        return render('organisation/report_users.html')
    def organisation_requests(self):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        from ckan import model
        from ckanext.dgu_orgs.model.organisation_request import OrganisationRequest

        organisation_requests = []
        for req in model.Session.query(OrganisationRequest).order_by(
                OrganisationRequest.date_of_request.desc()).all():
            item = {}
            item['user'] = model.Session.query(
                model.User).filter(model.User.name == req.user_name).one()
            item['group'] = model.Session.query(
                model.Group).filter(model.Group.name == req.group_name).one()
            item['emailed_to'] = find_group_admins(item['group'])[0]
            item['decision'] = req.decision
            item['date_of_request'] = req.date_of_request
            item['date_of_decision'] = req.date_of_decision
            item['login_token'] = req.login_token
            organisation_requests.append(item)

        c.organisation_requests = organisation_requests
        return render('data/organisation_requests.html')
    def _send_application(self, group, reason):
        from ckan.logic.action import error_summary
        from ckan.lib.mailer import mail_recipient
        from genshi.template.text import NewTextTemplate
        from pylons import config

        if not reason:
            h.flash_error(
                _("There was a problem with your submission, \
                             please correct it and try again"))
            errors = {"reason": ["No reason was supplied"]}
            return self.apply(group.id,
                              errors=errors,
                              error_summary=error_summary(errors))

        recipients, recipient_organisation = find_group_admins(group)

        if not recipients:
            if not config.get('dgu.admin.email'):
                log.error(
                    'User "%s" prevented from applying for organisation access for "%s" '
                    'because: dgu.admin.email is not setup in CKAN config.',
                    c.user, group.name)
                h.flash_error(
                    _("There is a problem with the system configuration"))
                errors = {"reason": ["data.gov.uk error"]}
                return self.apply(group.id,
                                  errors=errors,
                                  error_summary=error_summary(errors))
            recipients = [(config.get('dgu.admin.name',
                                      "DGU Admin"), config['dgu.admin.email'])]
            recipient_organisation = 'data.gov.uk admin team'

        url = urljoin(
            g.site_url,
            h.url_for(
                controller=
                'ckanext.dgu_orgs.controllers.organisation:OrganisationController',
                action='users',
                id=group.name))

        log.debug(
            'User "%s" requested organisation access for "%s" which was sent to admin %s (%r) with reason: %r',
            c.user, group.name, recipient_organisation, recipients, reason)
        extra_vars = {
            'group': group,
            'requester': c.userobj,
            'reason': reason,
            'accept_url': url
        }
        email_msg = render("email/join_publisher_request.txt",
                           extra_vars=extra_vars,
                           loader_class=NewTextTemplate)

        try:
            for (name, recipient) in recipients:
                mail_recipient(
                    name,
                    recipient,
                    subject=
                    'DGUKOrganisationRequest: Please add me as a data.gov.uk organisation',
                    body=email_msg)
        except Exception, e:
            h.flash_error(
                'There is a problem with the system configuration. Please instead <a href="http://data.gov.uk/contact">contact the data.gov.uk team</a>',
                allow_html=True)
            errors = {"reason": ["data.gov.uk error"]}
            log.error(
                'User "%s" prevented from applying for organisation access for "%s" because of mail configuration error: %s',
                c.user, group.name, e)
            return self.apply(group.id,
                              errors=errors,
                              error_summary=error_summary(errors))
            return self._add_users(c.group, request.params)

        data = data or {}
        errors = errors or {}
        error_summary = error_summary or {}

        data['users'] = []
        for capacity in ('admin', 'editor'):
            data['users'].extend({
                "name": user.name,
                "fullname": user.fullname,
                "capacity": capacity
            } for user in c.group.members_of_type(model.User, capacity).all())

        vars = {'data': data, 'errors': errors, 'error_summary': error_summary}
        c.form = render('organisation/users_form.html', extra_vars=vars)

        return render('organisation/users.html')

    def _redirect_if_previous_name(self, id):
        # If we can find id in the extras for any group we will use it
        # to re-direct the user to the new name for the group. If not then
        # we'll just let it fail.  If we find multiple groups with the name
        # we'll just redirect to the first match.
        import ckan.model as model

        match = model.Session.query(model.GroupExtra).\
            filter(model.GroupExtra.key.like('previous-name-%')).\
            filter(model.GroupExtra.value == id).\
            filter(model.GroupExtra.state=='active').order_by('key desc').first()
        if match: