def logged_in(self): # we need to set the language via a redirect lang = session.pop('lang', None) session.save() # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: is_new = False is_sysadmin = new_authz.is_sysadmin(c.user) # Retrieve information about the current user context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'schema': schema.user_new_form_schema()} data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) # This check is not needed (or correct) for sys admins if not is_sysadmin: # Get all organizations and all groups the user belongs to orgs_q = model.Session.query(model.Group) \ .filter(model.Group.is_organization == True) \ .filter(model.Group.state == 'active') q = model.Session.query(model.Member) \ .filter(model.Member.table_name == 'user') \ .filter(model.Member.table_id == user_dict['id']) group_ids = [] for row in q.all(): group_ids.append(row.group_id) if not group_ids: is_new = True else: orgs_q = orgs_q.filter(model.Group.id.in_(group_ids)) orgs_list = model_dictize.group_list_dictize(orgs_q.all(), context) if len(orgs_list) == 0: is_new = True h.flash_success(_("<p><strong>Note</strong></p>" "<p>%s is now logged in</p>") % user_dict['display_name'], allow_html=True) if is_new: return h.redirect_to(controller='ckanext.canada.controller:CanadaController', action='view_new_user', locale=lang) else: return h.redirect_to(controller='package', action='search', locale=lang) else: h.flash_error(_('Login failed. Bad username or password.')) return h.redirect_to(controller='user', action='login', locale=lang)
def upload(self, id): package_type = self._get_package_type(id) geno = get_geno(package_type) lc = ckanapi.LocalCKAN(username=c.user) dataset = lc.action.package_show(id=id) try: if request.POST['xls_update'] == '': raise BadExcelData('You must provide a valid file') _process_upload_file( lc, dataset, request.POST['xls_update'].file, geno) h.flash_success(_( "Your file was successfully uploaded into the central system." )) redirect(h.url_for(controller='package', action='read', id=id)) except BadExcelData, e: org = lc.action.organization_show(id=dataset['owner_org']) return self.preview_table( resource_name=dataset['resources'][0]['name'], owner_org=org['name'], errors=[e.message])
def action_add_form(users_or_authz_groups): # The user is attempting to set new roles for a named user new_user = request.params.get('new_user_name') # this is the list of roles whose boxes were ticked checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')] # this is the list of all the roles that were in the submitted form submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')] # from this we can make a dictionary of the desired states # i.e. true for the ticked boxes, false for the unticked desired_roles = {} for r in submitted_roles: desired_roles[r]=False for r in checked_roles: desired_roles[r]=True # again, in order to avoid either creating a role twice or deleting one which is # non-existent, we need to get the users' current roles (if any) current_uors = get_userobjectroles() if users_or_authz_groups=='users': current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )] user_object = model.User.by_name(new_user) if user_object==None: # The submitted user does not exist. Bail with flash message h.flash_error('unknown user:'******'authz_groups': current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )] user_object = model.AuthorizationGroup.by_name(new_user) if user_object==None: # The submitted user does not exist. Bail with flash message h.flash_error('unknown authorization group:' + str (new_user)) else: # Whenever our desired state is different from our current state, change it. for (r,val) in desired_roles.items(): if val: if (r not in current_roles): model.add_authorization_group_to_role(user_object, r, group) else: if (r in current_roles): model.remove_authorization_group_from_role(user_object, r, group) h.flash_success("Authorization Group Added") else: assert False, "shouldn't be here" # and finally commit all these changes to the database model.repo.commit_and_remove()
def action_add_form(users_or_authz_groups): # The user is attempting to set new roles for a named user new_user = request.params.get('new_user_name') # this is the list of roles whose boxes were ticked checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')] # this is the list of all the roles that were in the submitted form submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')] # from this we can make a dictionary of the desired states # i.e. true for the ticked boxes, false for the unticked desired_roles = {} for r in submitted_roles: desired_roles[r]=False for r in checked_roles: desired_roles[r]=True # again, in order to avoid either creating a role twice or deleting one which is # non-existent, we need to get the users' current roles (if any) current_uors = get_userobjectroles() if users_or_authz_groups=='users': current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )] user_object = model.User.by_name(new_user) if user_object==None: # The submitted user does not exist. Bail with flash message h.flash_error('unknown user:'******'authz_groups': current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )] user_object = model.AuthorizationGroup.by_name(new_user) if user_object==None: # The submitted user does not exist. Bail with flash message h.flash_error('unknown authorization group:' + str (new_user)) else: # Whenever our desired state is different from our current state, change it. for (r,val) in desired_roles.items(): if val: if (r not in current_roles): model.add_authorization_group_to_role(user_object, r, pkg) else: if (r in current_roles): model.remove_authorization_group_from_role(user_object, r, pkg) h.flash_success("Authorization Group Added") else: assert False, "shouldn't be here" # and finally commit all these changes to the database model.repo.commit_and_remove()
def delete_record(self, id): lc = ckanapi.LocalCKAN(username=c.user) filters = {} package_type = self._get_package_type(id) for f in primary_key_fields(package_type): filters[f['datastore_id']] = request.POST.get(f['datastore_id'], '') package = lc.action.package_show(id=id) result = lc.action.datastore_search( resource_id=package['resources'][0]['id'], filters=filters, rows=2) # only need two to know if there are multiple matches records = result['records'] x_vars = {'filters': filters, 'action': 'edit'} if not records: x_vars['delete_errors'] = [_('No matching records found')] elif len(records) > 1: x_vars['delete_errors'] = [_('Multiple matching records found')] if 'delete_errors' in x_vars: c.pkg_dict = package return render(self._edit_template(package_type), extra_vars=x_vars) # XXX: can't avoid the race here with the existing datastore API. # datastore_delete doesn't support _id filters lc.action.datastore_delete( resource_id=package['resources'][0]['id'], filters=filters, ) h.flash_success(_( "Record deleted." )) redirect(h.url_for(controller='package', action='read', id=id))
def delete(self, id): """Provide a delete action, but only for UKLP datasets""" from ckan.lib.search import SearchIndexError context = { 'model': model, 'session': model.Session, 'user': c.user, } pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package') if request.params: # POST if 'cancel' in request.params: h.redirect_to(controller='package', action='read', id=id) elif 'delete' in request.params: try: package_name = pkg_dict['name'] get_action('package_delete')(context, {'id':id}) h.flash_success(_('Successfully deleted package.')) self._form_save_redirect(package_name, 'edit') except NotAuthorized: abort(401, _('Unauthorized to delete package %s') % id) except ObjectNotFound, e: abort(404, _('Package not found')) except DataError: abort(400, _(u'Integrity Error')) except SearchIndexError, e: abort(500, _(u'Unable to update search index.') + repr(e.args))
def delete(self, id): """Provide a delete action, but only for UKLP datasets""" from ckan.lib.search import SearchIndexError context = { 'model': model, 'session': model.Session, 'user': c.user, } pkg_dict = get_action('package_show')(context, { 'id': id }) # has side-effect of populating context.get('package') if request.params: # POST if 'cancel' in request.params: h.redirect_to(controller='package', action='read', id=id) elif 'delete' in request.params: try: package_name = pkg_dict['name'] get_action('package_delete')(context, {'id': id}) h.flash_success(_('Successfully deleted package.')) self._form_save_redirect(package_name, 'edit') except NotAuthorized: abort(401, _('Unauthorized to delete package %s') % id) except ObjectNotFound, e: abort(404, _('Package not found')) except DataError: abort(400, _(u'Integrity Error')) except SearchIndexError, e: abort(500, _(u'Unable to update search index.') + repr(e.args))
def validate_resource_edit(self, id, resource_id, data=None, errors=None, error_summary=None): ''' Intercept save_edit Replace author, maintainer, maintainer_email ''' if 'validation_schema' in request.POST and 'format' in request.POST: resource_format = request.POST.getone('format') validation_schema = request.POST.getone('validation_schema') if resource_format == 'CSV' and validation_schema and validation_schema != '': schema_url = plugin.generate_download_url(id, validation_schema) data_url = plugin.generate_download_url(id, resource_id) validation_url = "http://goodtables.okfnlabs.org/api/run?format=csv&schema={0}&data={1}&row_limit=100000&report_limit=1000&report_type=grouped".format( schema_url, data_url) req = requests.get(validation_url, verify=False) if req.status_code == requests.codes.ok: response_text = json.loads(req.text) if response_text['success']: h.flash_success( "CSV was validated successfully against the selected schema" ) else: h.flash_error( "CSV was NOT validated against the selected schema") return RESOURCE_EDIT(self, id, resource_id, data, errors, error_summary)
def success(self, label=None): label = request.params.get('label', label) h.flash_success('Upload successful') c.file_url = h.url_for('storage_file', label=label, qualified=True) c.upload_url = h.url_for('storage_upload') return render('storage/success.html')
def resource_edit(self, id, resource_id, data=None, errors=None, error_summary=None): try: return super(CanadaDatasetController, self).resource_edit( id, resource_id, data, errors, error_summary) except HTTPFound: h.flash_success(_(u'Resource updated.')) # resource read page is unfinished, return to dataset page h.redirect_to(controller='package', action='read', id=id)
def abort_harvest_job(self, harvest_job_id): try: toolkit.get_action('harvest_job_abort')(None, { "id": harvest_job_id }) h.flash_success(_('Harvest job ID %s - aborted' % harvest_job_id)) except Exception, e: h.flash_error( _('ERROR aborting harvest job ID %s' % harvest_job_id))
def success(self, label=None): label=request.params.get('label', label) h.flash_success('Upload successful') c.file_url = h.url_for('storage_file', label=label, qualified=True ) c.upload_url = h.url_for('storage_upload') return render('storage/success.html')
def create_request(self, pkg_id): pkg = Package.get(pkg_id) user = c.userobj if c.userobj else None if user: req = KataAccessRequest(user.id, pkg.id) req.save() url = h.url_for(controller='package', action='read', id=pkg_id) h.flash_success(_("You now requested editor rights to package %s" % pkg.name)) redirect(url) else: url = h.url_for(controller='package', action='read', id=pkg_id) h.flash_error(_("Please log in!")) redirect(url)
def unlock_access(self, id): q = model.Session.query(KataAccessRequest) q = q.filter_by(id=id) req = q.first() if req: user = User.get(req.user_id) pkg = Package.get(req.pkg_id) add_user_to_role(user, 'editor', pkg) url = h.url_for(controller='package', action='read', id=req.pkg_id) h.flash_success(_("%s now has editor rights to package %s" % (user.name, pkg.name))) req.delete() meta.Session.commit() redirect(url) else: h.flash_error(_("No such request found!")) redirect('/')
def follow(self, id): '''Start following this group.''' context = {'model': model, 'session': model.Session, 'user': c.user or c.author} data_dict = {'id': id} try: get_action('follow_group')(context, data_dict) h.flash_success(_("You are now following {0}").format(id)) except ValidationError as e: error_message = (e.extra_msg or e.message or e.error_summary or e.error_dict) h.flash_error(error_message) except NotAuthorized as e: h.flash_error(e.extra_msg) h.redirect_to(controller='group', action='read', id=id)
def package_delete(self, pkg_id): h.flash_success(_( '<strong>Note</strong><br> The dataset has been removed from' ' the Open Government Portal. <br/> The record may re-appear' ' if it is re-harvested or updated. Please ensure that the' ' record is deleted and purged from the source catalogue in' ' order to prevent it from reappearing.' ), allow_html=True ) lc = LocalCKAN(username=c.user) lc.action.package_delete(id=pkg_id) return h.redirect_to( controller='package', action='search' )
def package_undelete(self, pkg_id): h.flash_success(_( '<strong>Note</strong><br> The record has been restored.'), allow_html=True ) lc = LocalCKAN(username=c.user) lc.action.package_patch( id=pkg_id, state='active' ) return h.redirect_to( controller='package', action='read', id=pkg_id )
def delete(self, id): """Provide a delete ('withdraw') action, but only for UKLP datasets""" from ckan.lib.search import SearchIndexError context = { 'model': model, 'session': model.Session, 'user': c.user, } try: pkg_dict = get_action('package_show')(context, { 'id': id }) # has side-effect of populating context.get('package') except NotAuthorized: abort(401, 'Not authorized to delete package') except ObjectNotFound: abort(404, 'Dataset not found') if request.params: # POST if 'cancel' in request.params: h.redirect_to(controller='package', action='read', id=id) elif 'delete' in request.params: try: package_name = pkg_dict['name'] get_action('package_delete')(context, {'id': id}) is_uklp = get_from_flat_dict(pkg_dict['extras'], 'UKLP') == 'True' if is_uklp: action = 'withdrawn' resource_type = get_from_flat_dict( pkg_dict['extras'], 'resource-type') + ' record' else: action = 'deleted' resource_type = 'dataset' h.flash_success('Successfully %s %s.' \ % (action, resource_type)) self._form_save_redirect(package_name, 'edit') except NotAuthorized: abort(401, _('Unauthorized to delete package %s') % id) except ObjectNotFound, e: abort(404, _('Package not found')) except DataError: abort(400, _(u'Integrity Error')) except SearchIndexError, e: abort(500, _(u'Unable to update search index.') + repr(e.args))
def _send_application(self, group, reason): from genshi.template.text import NewTextTemplate 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=action.error_summary(errors)) admins = group.members_of_type(model.User, 'admin').all() recipients = [(u.fullname,u.email) for u in admins] if admins else \ [(config.get('ckan.admin.name', "CKAN Administrator"), config.get('ckan.admin.email', None), )] if not recipients: h.flash_error( _("There is a problem with the system configuration")) errors = {"reason": ["No group administrator exists"]} return self.apply(group.id, data=data, errors=errors, error_summary=action.error_summary(errors)) extra_vars = {'group': group, 'requester': c.userobj, 'reason': reason} email_msg = render("organizations/email/join_publisher_request.txt", extra_vars=extra_vars, loader_class=NewTextTemplate) try: for (name, recipient) in recipients: mailer.mail_recipient(name, recipient, "Publisher request", email_msg) except: h.flash_error( _("There is a problem with the system configuration")) errors = {"reason": ["No mail server was found"]} return self.apply(group.id, errors=errors, error_summary=action.error_summary(errors)) h.flash_success(_("Your application has been submitted")) h.redirect_to('publisher_read', id=group.name)
def _form_save_redirect(self, pkgname, action): '''This redirects the user to the CKAN package/read page, unless there is request parameter giving an alternate location, perhaps an external website. @param pkgname - Name of the package just edited @param action - What the action of the edit was ''' assert action in ('new', 'edit') if action == 'new': msg = _('<span class="new-dataset">Your catalog has been created.</span>') h.flash_success(msg, allow_html=True) url = request.params.get('return_to') or \ config.get('package_%s_return_url' % action) if url: url = url.replace('<NAME>', pkgname) else: url = h.url_for(controller='package', action='read', id=pkgname) redirect(url)
def _send_application( self, group, reason ): from genshi.template.text import NewTextTemplate 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=action.error_summary(errors)) admins = group.members_of_type( model.User, 'admin' ).all() recipients = [(u.fullname,u.email) for u in admins] if admins else \ [(config.get('ckan.admin.name', "CKAN Administrator"), config.get('ckan.admin.email', None), )] if not recipients: h.flash_error(_("There is a problem with the system configuration")) errors = {"reason": ["No group administrator exists"]} return self.apply(group.id, data=data, errors=errors, error_summary=action.error_summary(errors)) extra_vars = { 'group' : group, 'requester': c.userobj, 'reason' : reason } email_msg = render("organizations/email/join_publisher_request.txt", extra_vars=extra_vars, loader_class=NewTextTemplate) try: for (name,recipient) in recipients: mailer.mail_recipient(name, recipient, "Publisher request", email_msg) except: h.flash_error(_("There is a problem with the system configuration")) errors = {"reason": ["No mail server was found"]} return self.apply(group.id, errors=errors, error_summary=action.error_summary(errors)) h.flash_success(_("Your application has been submitted")) h.redirect_to( 'publisher_read', id=group.name)
def logged_in(self): # we need to set the language via a redirect # Lang is not being retrieved properly by the Babel i18n lib in # this redirect, so using this clunky workaround for now. lang = session.pop('lang', None) if lang is None: came_from = request.params.get('came_from', '') if came_from.startswith('/fr'): lang = 'fr' else: lang = 'en' session.save() # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: context = None data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) h.flash_success( _('<strong>Note</strong><br>{0} is now logged in').format( user_dict['display_name'] ), allow_html=True ) notice_no_access() return h.redirect_to( controller='ckanext.canada.controller:CanadaController', action='home', locale=lang) else: h.flash_error(_('Login failed. Bad username or password.')) return h.redirect_to( controller='user', action='login', locale=lang )
def unfollow(self, id): '''Stop following this group.''' context = {'model': model, 'session': model.Session, 'user': c.user or c.author} data_dict = {'id': id} try: get_action('unfollow_group')(context, data_dict) group_dict = get_action('group_show')(context, data_dict) h.flash_success(_("You are no longer following {0}").format( group_dict['title'])) except ValidationError as e: error_message = (e.extra_msg or e.message or e.error_summary or e.error_dict) h.flash_error(error_message) except (NotFound, NotAuthorized) as e: error_message = e.extra_msg or e.message h.flash_error(error_message) h.redirect_to(controller='group', action='read', id=id)
def contact(self, name=None): """ This action allows users to create an issue by filling in a contact form. """ import ckan.model as model from ckanext.redmine.client import RedmineClient print name extra_vars = {"data": {}, "errors": {}} client = RedmineClient(name) c.categories = client.load_categories() c.name = name if request.method == 'POST': data = clean_dict( unflatten(tuplize_dict(parse_params(request.POST)))) context = { 'model': model, 'session': model.Session, 'user': c.user } # Create the issue with the data we were passed. try: newid = get_action('issue_create')(context, data) if newid is None: self._save_on_fail(data) h.flash_success( _('Thank you for contacting us'.format(newid))) else: h.flash_success( _('Thank you for contacting us, please quote #{0} in future correspondence' .format(newid))) h.redirect_to(str(data.get('referer', '/'))) except ValidationError, e: extra_vars["errors"] = e.error_dict extra_vars["error_summary"] = e.error_summary extra_vars["data"] = data c.category_id = data.get('category', '')
def delete(self, id): """Provide a delete ('withdraw') action, but only for UKLP datasets""" from ckan.lib.search import SearchIndexError context = { 'model': model, 'session': model.Session, 'user': c.user, } try: pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package') except NotAuthorized: abort(401, 'Not authorized to delete package') except ObjectNotFound: abort(404, 'Dataset not found') if request.params: # POST if 'cancel' in request.params: h.redirect_to(controller='package', action='read', id=id) elif 'delete' in request.params: try: package_name = pkg_dict['name'] get_action('package_delete')(context, {'id':id}) is_uklp = get_from_flat_dict(pkg_dict['extras'], 'UKLP') == 'True' if is_uklp: action = 'withdrawn' resource_type = get_from_flat_dict(pkg_dict['extras'], 'resource-type') + ' record' else: action = 'deleted' resource_type = 'dataset' h.flash_success('Successfully %s %s.' \ % (action, resource_type)) self._form_save_redirect(package_name, 'edit') except NotAuthorized: abort(401, _('Unauthorized to delete package %s') % id) except ObjectNotFound, e: abort(404, _('Package not found')) except DataError: abort(400, _(u'Integrity Error')) except SearchIndexError, e: abort(500, _(u'Unable to update search index.') + repr(e.args))
def _form_save_redirect(self, pkgname, action): '''This redirects the user to the CKAN package/read page, unless there is request parameter giving an alternate location, perhaps an external website. @param pkgname - Name of the package just edited @param action - What the action of the edit was ''' assert action in ('new', 'edit') if action == 'new': msg = _('<span class="new-dataset">Congratulations, your dataset has been created. ' \ '<a href="%s">Upload or link ' \ 'some data now »</a></span>') msg = msg % h.url_for(controller='package', action='edit', id=pkgname, anchor='section-resources') h.flash_success(msg,allow_html=True) url = request.params.get('return_to') or \ config.get('package_%s_return_url' % action) if url: url = url.replace('<NAME>', pkgname) else: url = h.url_for(controller='package', action='read', id=pkgname) redirect(url)
def unfollow(self, id): '''Stop following this group.''' context = { 'model': model, 'session': model.Session, 'user': c.user or c.author } data_dict = {'id': id} try: get_action('unfollow_group')(context, data_dict) group_dict = get_action('group_show')(context, data_dict) h.flash_success( _("You are no longer following {0}").format( group_dict['title'])) except ValidationError as e: error_message = (e.extra_msg or e.message or e.error_summary or e.error_dict) h.flash_error(error_message) except (NotFound, NotAuthorized) as e: error_message = e.extra_msg or e.message h.flash_error(error_message) h.redirect_to(controller='group', action='read', id=id)
def contact(self, name=None): """ This action allows users to create an issue by filling in a contact form. """ import ckan.model as model from ckanext.redmine.client import RedmineClient print name extra_vars = { "data": {}, "errors": {} } client = RedmineClient(name) c.categories = client.load_categories() c.name = name if request.method == 'POST': data = clean_dict(unflatten(tuplize_dict(parse_params(request.POST)))) context = {'model': model, 'session': model.Session, 'user': c.user} # Create the issue with the data we were passed. try: newid = get_action('issue_create')(context, data) if newid is None: self._save_on_fail(data) h.flash_success(_('Thank you for contacting us'.format(newid))) else: h.flash_success(_('Thank you for contacting us, please quote #{0} in future correspondence'.format(newid))) h.redirect_to(str(data.get('referer', '/'))) except ValidationError, e: extra_vars["errors"] = e.error_dict extra_vars["error_summary"] = e.error_summary extra_vars["data"] = data c.category_id = data.get('category','')
def logged_in(self): # we need to set the language via a redirect lang = session.pop("lang", None) session.save() # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: context = None data_dict = {"id": c.user} user_dict = get_action("user_show")(context, data_dict) h.flash_success( _("<p><strong>Note</strong></p>" "<p>%s is now logged in</p>") % user_dict["display_name"], allow_html=True, ) return h.redirect_to(controller="package", action="search", locale=lang) else: h.flash_error(_("Login failed. Bad username or password.")) return h.redirect_to(controller="user", action="login", locale=lang)
def upload(self, id): package_type = self._get_package_type(id) geno = get_geno(package_type) lc = ckanapi.LocalCKAN(username=c.user) dataset = lc.action.package_show(id=id) try: if request.POST['xls_update'] == '': raise BadExcelData('You must provide a valid file') _process_upload_file(lc, dataset, request.POST['xls_update'].file, geno) h.flash_success( _("Your file was successfully uploaded into the central system." )) redirect(h.url_for(controller='package', action='read', id=id)) except BadExcelData, e: org = lc.action.organization_show(id=dataset['owner_org']) return self.preview_table( resource_name=dataset['resources'][0]['name'], owner_org=org['name'], errors=[e.message])
def delete_record(self, id, resource_id): lc = ckanapi.LocalCKAN(username=c.user) filters = {} res = lc.action.resource_show(id=resource_id) for f in recombinant_primary_key_fields(res['name']): filters[f['datastore_id']] = request.POST.get(f['datastore_id'], '') result = lc.action.datastore_search( resource_id=resource_id, filters=filters, rows=2) # only need two to know if there are multiple matches records = result['records'] x_vars = {'filters': filters, 'action': 'edit'} if not records: x_vars['delete_errors'] = [_('No matching records found')] elif len(records) > 1: x_vars['delete_errors'] = [_('Multiple matching records found')] if 'delete_errors' in x_vars: c.pkg_dict = dataset = lc.action.package_show(id=id) return render('recombinant/resource_edit.html', extra_vars=dict(x_vars, dataset=dataset, resource=res)) # XXX: can't avoid the race here with the existing datastore API. # datastore_delete doesn't support _id filters lc.action.datastore_delete( resource_id=resource_id, filters=filters, ) h.flash_success(_( "Record deleted." )) redirect(h.url_for( controller='ckanext.recombinant.controller:PreviewController', action='preview_table', id=id, resource_id=resource_id))
def delete(self, id): """Provide a delete ('withdraw') action, but only for UKLP datasets""" from ckan.lib.search import SearchIndexError context = {"model": model, "session": model.Session, "user": c.user} try: pkg_dict = get_action("package_show")( context, {"id": id} ) # has side-effect of populating context.get('package') except NotAuthorized: abort(401, "Not authorized to delete package") if request.params: # POST if "cancel" in request.params: h.redirect_to(controller="package", action="read", id=id) elif "delete" in request.params: try: package_name = pkg_dict["name"] get_action("package_delete")(context, {"id": id}) is_uklp = get_from_flat_dict(pkg_dict["extras"], "UKLP") == "True" if is_uklp: action = "withdrawn" resource_type = get_from_flat_dict(pkg_dict["extras"], "resource-type") + " record" else: action = "deleted" resource_type = "dataset" h.flash_success("Successfully %s %s." % (action, resource_type)) self._form_save_redirect(package_name, "edit") except NotAuthorized: abort(401, _("Unauthorized to delete package %s") % id) except ObjectNotFound, e: abort(404, _("Package not found")) except DataError: abort(400, _(u"Integrity Error")) except SearchIndexError, e: abort(500, _(u"Unable to update search index.") + repr(e.args))
def logged_in(self): # we need to set the language via a redirect lang = session.pop('lang', None) session.save() # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: context = None data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) h.flash_success(_("<p><strong>Note</strong></p>" "<p>%s is now logged in</p>") % user_dict['display_name'], allow_html=True) return h.redirect_to(controller='package', action='search', locale=lang) else: h.flash_error(_('Login failed. Bad username or password.')) return h.redirect_to(controller='user', action='login', locale=lang)
def upload(self, id): package_type = self._get_package_type(id) geno = get_geno(package_type) lc = ckanapi.LocalCKAN(username=c.user) dataset = lc.action.package_show(id=id) try: if request.POST['xls_update'] == '': raise BadExcelData('You must provide a valid file') _process_upload_file( lc, dataset, request.POST['xls_update'].file, geno) h.flash_success(_( "Your file was successfully uploaded into the central system." )) redirect(h.url_for(controller='package', action='read', id=id)) except BadExcelData, e: x_vars = {'errors': [e.message], 'action': 'edit'} c.pkg_dict = dataset return render(self._edit_template(package_type), extra_vars=x_vars)
def delete_records(self, id, resource_id): lc = ckanapi.LocalCKAN(username=c.user) filters = {} x_vars = {'filters': filters, 'action': 'edit'} pkg = lc.action.package_show(id=id) res = lc.action.resource_show(id=resource_id) org = lc.action.organization_show(id=pkg['owner_org']) dataset = lc.action.recombinant_show( dataset_type=pkg['type'], owner_org=org['name']) def delete_error(err): return render('recombinant/resource_edit.html', extra_vars={ 'delete_errors':[err], 'dataset':dataset, 'resource':res, 'organization':org, 'filters':filters, 'action':'edit'}) form_text = request.POST.get('bulk-delete', '') if not form_text: return delete_error(_('Required field')) pk_fields = recombinant_primary_key_fields(res['name']) ok_records = [] ok_filters = [] records = iter(form_text.split('\n')) for r in records: r = r.rstrip('\r') def record_fail(err): # move bad record to the top of the pile filters['bulk-delete'] = '\n'.join( [r] + list(records) + ok_records) return delete_error(err) split_on = '\t' if '\t' in r else ',' fields = [f for f in r.split(split_on)] if len(fields) != len(pk_fields): return record_fail(_('Wrong number of fields, expected {num}') .format(num=len(pk_fields))) filters.clear() for f, pkf in zip(fields, pk_fields): filters[pkf['datastore_id']] = f try: result = lc.action.datastore_search( resource_id=resource_id, filters=filters, limit=2) except ValidationError: return record_fail(_('Invalid fields')) found = result['records'] if not found: return record_fail(_('No matching records found "%s"') % u'", "'.join(fields)) if len(found) > 1: return record_fail(_('Multiple matching records found')) if r not in ok_records: ok_records.append(r) ok_filters.append(dict(filters)) if 'cancel' in request.POST: return render('recombinant/resource_edit.html', extra_vars={ 'delete_errors':[], 'dataset':dataset, 'resource':res, 'organization':org, 'filters':{'bulk-delete':u'\n'.join(ok_records)}, 'action':'edit'}) if not 'confirm' in request.POST: return render('recombinant/confirm_delete.html', extra_vars={ 'dataset':dataset, 'resource':res, 'num': len(ok_records), 'bulk_delete': u'\n'.join(ok_records # extra blank is needed to prevent field # from being completely empty + ([''] if '' in ok_records else [])) }) for f in ok_filters: lc.action.datastore_delete( resource_id=resource_id, filters=f, ) h.flash_success(_("{num} deleted.").format(num=len(ok_filters))) redirect(h.url_for( controller='ckanext.recombinant.controller:UploadController', action='preview_table', resource_name=res['name'], owner_org=org['name'], ))
class OrganisationController(OrganizationController): ## end hooks 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 _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)) h.flash_success( 'Your application has been submitted to administrator for: %s. If you do not hear back in a couple of days then <a href="http://data.gov.uk/contact">contact the data.gov.uk team</a>' % recipient_organisation, allow_html=True) h.redirect_to('organisation_read', id=group.name)
data_dict['url'] = '/dataset/%s' % c.pkg.name success = False try: res = get_action('comment_create')(context, data_dict) #res = {'id': dataset_id } success = True except ValidationError, ve: log.debug(ve) except Exception, e: log.debug(e) abort(403) if success: h.flash_success('<strong>' + _('Muy Bien') + '!</strong> ' + _( u'Su comentario ha sido puesto en cola para su revisión por los administradores del sitio y se publicará después de su aprobación.' ), allow_html=True) h.redirect_to( str('/dataset/%s#comment_%s' % (c.pkg.name, res['id']))) return render("package/read.html") def delete(self, dataset_id, comment_id): context = {'model': model, 'user': c.user} # Verifica que el usuario autenticado pueda ver el paquete # Se comenta para evitar que solo usuarios conectados puedan realizar comentarios data_dict = {'id': dataset_id} check_access('package_show', context, data_dict)
check_access('manage_users', context, data_dict) except NotAuthorized, error: abort(401, error.__str__()) group = model.Group.get(helpers.get_default_group()) data_dict['id'] = group.id role = data_dict['role'] if role == 'default': get_action('group_member_delete')(context, data_dict) h.flash_notice(_('User rights are removed.'), allow_html=True) else: get_action('group_member_create')(context, data_dict) h.flash_success(_('User Role is Updated Successfully.'), allow_html=True) url = h.url_for(controller='ckanext.ngds.ngdsui.controllers.user:UserController', action='manage_users') redirect(url) def member_list(self, group_name): """ Accepts a group name, which is configured in the site configuration file and returns users that are associated with the group. """ group = model.Group.get(group_name) q = model.Session.query(model.Member). \ filter(model.Member.group_id == group.id). \ filter(model.Member.state == "active"). \
def action_save_form(users_or_authz_groups): # The permissions grid has been saved # which is a grid of checkboxes named user$role rpi = request.params.items() # The grid passes us a list of the users/roles that were displayed submitted = [ a for (a,b) in rpi if (b == u'submitted')] # and also those which were checked checked = [ a for (a,b) in rpi if (b == u'on')] # from which we can deduce true/false for each user/role combination # that was displayed in the form table_dict={} for a in submitted: table_dict[a]=False for a in checked: table_dict[a]=True # now we'll split up the user$role strings to make a dictionary from # (user,role) to True/False, which tells us what we need to do. new_user_role_dict={} for (ur,val) in table_dict.items(): u,r = ur.split('$') new_user_role_dict[(u,r)] = val # we get the current user/role assignments # and make a dictionary of them current_uors = get_userobjectroles() if users_or_authz_groups=='users': current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user] elif users_or_authz_groups=='authz_groups': current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group] else: assert False, "shouldn't be here" current_user_role_dict={} for (u,r) in current_users_roles: current_user_role_dict[(u,r)]=True # and now we can loop through our dictionary of desired states # checking whether a change needs to be made, and if so making it # Here we check whether someone is already assigned a role, in order # to avoid assigning it twice, or attempting to delete it when it # doesn't exist. Otherwise problems can occur. if users_or_authz_groups=='users': for ((u,r), val) in new_user_role_dict.items(): if val: if not ((u,r) in current_user_role_dict): model.add_user_to_role(model.User.by_name(u),r,pkg) else: if ((u,r) in current_user_role_dict): model.remove_user_from_role(model.User.by_name(u),r,pkg) elif users_or_authz_groups=='authz_groups': for ((u,r), val) in new_user_role_dict.items(): if val: if not ((u,r) in current_user_role_dict): model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,pkg) else: if ((u,r) in current_user_role_dict): model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,pkg) else: assert False, "shouldn't be here" # finally commit the change to the database model.repo.commit_and_remove() h.flash_success("Changes Saved")
def upload(self, id): package_type = self._get_package_type(id) t = get_table(package_type) expected_sheet_name = t['xls_sheet_name'] try: lc = ckanapi.LocalCKAN(username=c.user) package = lc.action.package_show(id=id) owner_org = package['organization']['name'] if request.POST['xls_update'] == u'': msg = _('You must provide a valid file') raise ValidationError({'xls_update': [msg]}) upload_data = read_xls(request.POST['xls_update'].file) sheet_name, org_name = None, None try: sheet_name, org_name = next(upload_data) except: # XXX bare except because this can fail in all sorts of ways if asbool(config.get('debug', False)): # on debug we want the real error raise raise ValidationError({'xls_update': [_("The server encountered a problem processing the file " "uploaded. Please try copying your data into the latest " "version of the template and uploading again. If this " "problem continues, send your Excel file to " "[email protected] so we may investigate.")]}) if expected_sheet_name != sheet_name: raise ValidationError({'xls_update': [_('Invalid file for this data type. ' + 'Sheet must be labeled "{0}", ' + 'but you supplied a sheet labeled "{1}"').format( expected_sheet_name, sheet_name)]}) # is this the right sheet for this organization? if org_name != owner_org: msg = _( 'Invalid sheet for this organization. ' + 'Sheet must be labeled for {0}, ' + 'but you supplied a sheet for {1}').format( owner_org, org_name) raise ValidationError({'xls_update': [msg]}) resource_id = package['resources'][0]['id'] records = get_records(upload_data, t['fields']) method = 'upsert' if t.get('datastore_primary_key') else 'insert' try: lc.action.datastore_upsert( method=method, resource_id=resource_id, records=records) except NotAuthorized, na: msg = _( 'You do not have permission to upload to {0}').format( owner_org) raise ValidationError({'xls_update': [msg]}) h.flash_success(_( "Your file was successfully uploaded into the central system." )) redirect(h.url_for(controller='package', action='read', id=id))
def action_save_form(users_or_authz_groups): # The permissions grid has been saved # which is a grid of checkboxes named user$role rpi = request.params.items() # The grid passes us a list of the users/roles that were displayed submitted = [ a for (a,b) in rpi if (b == u'submitted')] # and also those which were checked checked = [ a for (a,b) in rpi if (b == u'on')] # from which we can deduce true/false for each user/role combination # that was displayed in the form table_dict={} for a in submitted: table_dict[a]=False for a in checked: table_dict[a]=True # now we'll split up the user$role strings to make a dictionary from # (user,role) to True/False, which tells us what we need to do. new_user_role_dict={} for (ur,val) in table_dict.items(): u,r = ur.split('$') new_user_role_dict[(u,r)] = val # we get the current user/role assignments # and make a dictionary of them current_uors = get_userobjectroles() if users_or_authz_groups=='users': current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user] elif users_or_authz_groups=='authz_groups': current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group] else: assert False, "shouldn't be here" current_user_role_dict={} for (u,r) in current_users_roles: current_user_role_dict[(u,r)]=True # and now we can loop through our dictionary of desired states # checking whether a change needs to be made, and if so making it # Here we check whether someone is already assigned a role, in order # to avoid assigning it twice, or attempting to delete it when it # doesn't exist. Otherwise problems can occur. if users_or_authz_groups=='users': for ((u,r), val) in new_user_role_dict.items(): if val: if not ((u,r) in current_user_role_dict): model.add_user_to_role(model.User.by_name(u),r,group) else: if ((u,r) in current_user_role_dict): model.remove_user_from_role(model.User.by_name(u),r,group) elif users_or_authz_groups=='authz_groups': for ((u,r), val) in new_user_role_dict.items(): if val: if not ((u,r) in current_user_role_dict): model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,group) else: if ((u,r) in current_user_role_dict): model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,group) else: assert False, "shouldn't be here" # finally commit the change to the database model.repo.commit_and_remove() h.flash_success("Changes Saved")
def _prepare_and_send(self, pkg_id, recipient_id, subject, prefix_template, suffix): """ Sends a message by email from the logged in user to the appropriate contact address of the given dataset. The prefix template should have formatting placeholders for the following arguments: {sender_name}, {sender_email}, {package_title}, {data_pid} :param pkg_id: package id :type pkg_id: string :param recipient_id: id of the recipient, as returned by utils.get_package_contacts :type recipient_id: string :param subject: the subject of the message :type subject: string :param prefix_template: the template for the prefix to be automatically included before the user message :type prefix_template: unicode :param suffix: an additional note to be automatically included after the user message :type suffix: unicode """ url = h.url_for(controller='package', action='read', id=pkg_id) if asbool(config.get('kata.contact_captcha')): try: captcha.check_recaptcha(request) except captcha.CaptchaError: h.flash_error(_(u'Bad Captcha. Please try again.')) redirect(url) if not request.params.get('accept_logging'): h.flash_error(_(u"Message not sent as logging wasn't permitted")) return redirect(url) if asbool(config.get('kata.disable_contact')): h.flash_error(_(u"Sending contact emails is prohibited for now. Please try again later or contact customer " u"service.")) return redirect(url) package = Package.get(pkg_id) package_title = package.title if package.title else package.name sender_addr = request.params.get('from_address') sender_name = request.params.get('from_name') recipient = self._get_contact_email(pkg_id, recipient_id) if not recipient: abort(404, _('Recipient not found')) user_msg = request.params.get('msg', '') ct = int(time.time()) try: check = self.crypto.decrypt(base64.b64decode(request.params.get('check_this_out'))) check = re.sub(' ', '', check) except TypeError: h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)")) return redirect(url) hp = request.params.get('hp') if hp or not check or (ct - int(check) < 20) or (ct - int(check) > 1200): h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)")) return redirect(url) if sender_addr and sender_name and \ isinstance(sender_name, basestring) and len(sender_name) >= 3: if user_msg: prefix = prefix_template.format( sender_name=sender_name, sender_email=sender_addr, package_title=package_title, data_pid=utils.get_primary_data_pid_from_package(package) ) log.info(u"Message {m} sent from {a} ({b}) to {r} about {c}, IP: {d}" .format(m=user_msg, a=sender_name, b=sender_addr, r=recipient, c=pkg_id, d=request.environ.get('REMOTE_ADDR', 'No remote address'))) full_msg = u"{a}{b}{c}".format(a=prefix, b=user_msg, c=suffix) self._send_message(subject, full_msg, recipient.get('email'), recipient.get('name')) h.flash_success(_(u"Message sent")) else: h.flash_error(_(u"No message")) else: h.flash_error(_(u"Message not sent. Please, provide reply address and name. Name must contain \ at least three letters.")) return redirect(url)
def delete_records(self, id, resource_id): lc = ckanapi.LocalCKAN(username=c.user) filters = {} x_vars = {'filters': filters, 'action': 'edit'} pkg = lc.action.package_show(id=id) res = lc.action.resource_show(id=resource_id) org = lc.action.organization_show(id=pkg['owner_org']) dataset = lc.action.recombinant_show(dataset_type=pkg['type'], owner_org=org['name']) def delete_error(err): return render('recombinant/resource_edit.html', extra_vars={ 'delete_errors': [err], 'dataset': dataset, 'resource': res, 'organization': org, 'filters': filters, 'action': 'edit' }) form_text = request.POST.get('bulk-delete', '') if not form_text: return delete_error(_('Required field')) pk_fields = recombinant_primary_key_fields(res['name']) ok_records = [] ok_filters = [] records = iter(form_text.split('\n')) for r in records: r = r.rstrip('\r') def record_fail(err): # move bad record to the top of the pile filters['bulk-delete'] = '\n'.join([r] + list(records) + ok_records) return delete_error(err) split_on = '\t' if '\t' in r else ',' fields = [f for f in r.split(split_on)] if len(fields) != len(pk_fields): return record_fail( _('Wrong number of fields, expected {num}').format( num=len(pk_fields))) filters.clear() for f, pkf in zip(fields, pk_fields): filters[pkf['datastore_id']] = f try: result = lc.action.datastore_search(resource_id=resource_id, filters=filters, limit=2) except ValidationError: return record_fail(_('Invalid fields')) found = result['records'] if not found: return record_fail( _('No matching records found "%s"') % u'", "'.join(fields)) if len(found) > 1: return record_fail(_('Multiple matching records found')) if r not in ok_records: ok_records.append(r) ok_filters.append(dict(filters)) if 'cancel' in request.POST: return render('recombinant/resource_edit.html', extra_vars={ 'delete_errors': [], 'dataset': dataset, 'resource': res, 'organization': org, 'filters': { 'bulk-delete': u'\n'.join(ok_records) }, 'action': 'edit' }) if not 'confirm' in request.POST: return render( 'recombinant/confirm_delete.html', extra_vars={ 'dataset': dataset, 'resource': res, 'num': len(ok_records), 'bulk_delete': u'\n'.join( ok_records # extra blank is needed to prevent field # from being completely empty + ([''] if '' in ok_records else [])) }) for f in ok_filters: lc.action.datastore_delete( resource_id=resource_id, filters=f, ) h.flash_success(_("{num} deleted.").format(num=len(ok_filters))) redirect( h.url_for( controller='ckanext.recombinant.controller:UploadController', action='preview_table', resource_name=res['name'], owner_org=org['name'], ))
class PublisherController(GroupController): ## end hooks 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')) # TODO: Fix this up, we only really need to do this when we are # showing the hierarchy (and then we should load on demand really). c.all_groups = model.Session.query(model.Group).\ filter(model.Group.type == 'publisher').\ filter(model.Group.state == 'active').\ order_by('title') c.page = AlphaPage( controller_name="ckanext.dgu.controllers.publisher:PublisherController", collection=c.all_groups, page=request.params.get('page', 'A'), alpha_attribute='title', other_text=_('Other'), ) return render('publisher/index.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)) # look for publisher admins up the tree recipients = [] recipient_publisher = None for publisher in go_up_tree(group): admins = publisher.members_of_type(model.User, 'admin').all() if admins: recipients = [(u.fullname,u.email) for u in admins] recipient_publisher = publisher.title break if not recipients: if not config.get('dgu.admin.email'): log.error('User "%s" prevented from applying for publisher 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": ["%s does not have an administrator user to contact" % group.name]} return self.apply(group.id, data=data, errors=errors, error_summary=error_summary(errors)) recipients = [(config.get('dgu.admin.name', "DGU Admin"), config['dgu.admin.email'])] recipient_publisher = 'data.gov.uk admin' log.debug('User "%s" requested publisher access for "%s" which was sent to admin %s (%r) with reason: %r', c.user, group.name, recipient_publisher, recipients, reason) extra_vars = { 'group' : group, 'requester': c.userobj, 'reason' : reason } 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, "Publisher request", email_msg) except Exception, e: h.flash_error(_("There is a problem with the system configuration")) errors = {"reason": ["No mail server was found"]} log.error('User "%s" prevented from applying for publisher 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)) h.flash_success("Your application has been submitted to administrator for: %s" % recipient_publisher) h.redirect_to( 'publisher_read', id=group.name)
# they have already been added? else: c.req.decision = True c.req.date_of_decision = datetime.datetime.utcnow() if not c.in_group: model.repo.new_revision() member = model.Member(group=c.req_group, table_id=c.req_user.id, table_name='user', capacity='editor') model.Session.add(member) msg = '<strong>%s</strong> was added to the organisation <strong>%s</strong>' % ( c.req_user.fullname, c.req_group.title) model.Session.commit() h.flash_success(msg, allow_html=True) h.redirect_to('organisation_request', token=token) else: return render('data/organisation_request.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 = {}
def _prepare_and_send(self, pkg_id, recipient_id, subject, prefix_template, suffix): """ Sends a message by email from the logged in user to the appropriate contact address of the given dataset. The prefix template should have formatting placeholders for the following arguments: {sender_name}, {sender_email}, {package_title}, {package_id} :param pkg_id: package id :type pkg_id: string :param recipient_id: id of the recipient, as returned by utils.get_package_contacts :type recipient_id: string :param subject: the subject of the message :type subject: string :param prefix_template: the template for the prefix to be automatically included before the user message :type prefix_template: unicode :param suffix: an additional note to be automatically included after the user message :type suffix: unicode """ url = h.url_for(controller='package', action='read', id=pkg_id) if asbool(config.get('kata.contact_captcha')): try: captcha.check_recaptcha(request) except captcha.CaptchaError: h.flash_error(_(u'Bad Captcha. Please try again.')) redirect(url) if not request.params.get('accept_logging'): h.flash_error(_(u"Message not sent as logging wasn't permitted")) return redirect(url) if asbool(config.get('kata.disable_contact')): h.flash_error(_(u"Sending contact emails is prohibited for now. Please try again later or contact customer " u"service.")) return redirect(url) package = Package.get(pkg_id) package_title = package.title if package.title else package.name sender_addr = request.params.get('from_address') sender_name = request.params.get('from_name') recipient = self._get_contact_email(pkg_id, recipient_id) if not recipient: abort(404, _('Recipient not found')) user_msg = request.params.get('msg', '') if request.params.get('hp'): h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)")) return redirect(url) if sender_addr and sender_name and \ isinstance(sender_name, basestring) and len(sender_name) >= 3: if user_msg: prefix = prefix_template.format( sender_name=sender_name, sender_email=sender_addr, package_title=package_title, package_id=pkg_id # above line was: metadata_pid=utils.get_primary_data_pid_from_package(package) ) log.info(u"Message {m} sent from {a} ({b}) to {r} about {c}, IP: {d}" .format(m=user_msg, a=sender_name, b=sender_addr, r=recipient, c=pkg_id, d=request.environ.get('REMOTE_ADDR', 'No remote address'))) full_msg = u"{a}{b}{c}".format(a=prefix, b=user_msg, c=suffix) self._send_message(subject, full_msg, recipient.get('email'), recipient.get('name')) h.flash_success(_(u"Message sent")) else: h.flash_error(_(u"No message")) else: h.flash_error(_(u"Message not sent. Please, provide reply address and name. Name must contain \ at least three letters.")) return redirect(url)
def success(self, label=None): label = request.params.get("label", label) h.flash_success("Upload successful") c.file_url = h.url_for("storage_file", label=label, qualified=True) c.upload_url = h.url_for("storage_upload") return render("storage/success.html")