def save_entry(self): '''Saves an answer POSTed to the form, and stores a new entry to it.''' collector, form = self._get_collector_and_form() if collector is None: return HTTPNotFound() form_schema, entry_form = self._get_schema_and_form(form) form_data = self.request.params.items() try: form_data = entry_form.validate(form_data) except d.ValidationFailure as e: return dict(collector=collector, entry_form=e.render(), form=form) entry = Entry() # Get the last increment of the entry number and update entry and form new_entry_number = form.last_entry_number + 1 entry.entry_number = new_entry_number entry.form = form entry.collector = collector sas.add(entry) sas.flush() form.last_entry_number = new_entry_number form.new_entries += 1 for f in form.fields: field = fields_dict[f.typ.name](f) field.save_data(entry, form_data['input-{}'.format(f.id)]) # Sends email to facilitator if that's the case if collector.email_each_entry: self._send_email_entry(entry) if collector.on_completion == 'url' and collector.thanks_url: return HTTPFound(location=collector.thanks_url) else: return HTTPFound(location=self.url( 'entry_form_slug', action='thank', slug=collector.slug))
def edit_category(self): '''Receives and validates POSTed data. If data is okay, creates the category. Otherwise, returns the form with errors. ''' user = self.request.user controls = self.request.POST.items() try: appstruct = new_category_form(user).validate(controls) except d.ValidationFailure as e: self.request.override_renderer = 'create_category.genshi' return dict(pagetitle=_("New category"), new_category_form=e.render()) user = self.request.user cat_name = appstruct['name'] cat_desc = appstruct['description'] if cat_name != '': category = sas.query(FormCategory) \ .filter(FormCategory.name==cat_name) \ .filter(FormCategory.user==user) \ .first() if category: # If the system found a category, don't create errors = _("That category already exists.") return {'errors': errors} else: # Create a category! new_category = FormCategory(name=cat_name, description=cat_desc, user=user) sas.add(new_category) sas.flush() all_data = user.all_categories_and_forms() return dict(changed=True, all_data=all_data)
def save_entry(self): '''Saves an answer POSTed to the form, and stores a new entry to it.''' collector, form = self._get_collector_and_form() if collector is None: return HTTPNotFound() form_schema, entry_form = self._get_schema_and_form(form) form_data = self.request.params.items() try: form_data = entry_form.validate(form_data) except d.ValidationFailure as e: return dict(collector=collector, entry_form=e.render(), form=form) entry = Entry() # Get the last increment of the entry number and update entry and form new_entry_number = form.last_entry_number + 1 entry.entry_number = new_entry_number entry.form = form entry.collector = collector sas.add(entry) sas.flush() form.last_entry_number = new_entry_number form.new_entries += 1 for f in form.fields: field = fields_dict[f.typ.name](f) field.save_data(entry, form_data['input-{}'.format(f.id)]) # Sends email to facilitator if that's the case if collector.email_each_entry: self._send_email_entry(entry) if collector.on_completion=='url' and collector.thanks_url: return HTTPFound(location=collector.thanks_url) else: return HTTPFound(location=self.url('entry_form_slug', action='thank', slug=collector.slug))
def save_website_code(self): '''Responds to the AJAX request and saves a collector.''' request = self.request posted = request.POST id = request.matchdict['id'] form_id = request.matchdict['form_id'] form = FormView(request)._get_form_if_belongs_to_user(form_id=form_id) if not form: return dict(error=_("Form not found.")) # Validate `posted` with colander: try: posted = website_code_schema.deserialize(posted) except c.Invalid as e: return e.asdict() # Validation passes, so create or update the model. if id == 'new': collector = WebsiteCodeCollector(form=form) sas.add(collector) else: collector = self._get_collector_if_belongs_to_user(id) # Copy the data self._parse_start_and_end_date(posted) for k, v in posted.items(): setattr(collector, k, v) sas.flush() return collector.to_dict()
def save_data(self, entry, value): list_type = self.field.get_option('list_type') if value: if value['option'] and value['option'] != c.null: if list_type != 'radio': for opt in filter(lambda o: o != '', value['option']): self.data = ListData() # TODO: Check if is a valid value self.data.value = opt self.data.entry_id = entry.id self.data.field_id = self.field.id sas.add(self.data) else: self.data = ListData() # TODO: Check if is a valid value self.data.value = value['option'] self.data.entry_id = entry.id self.data.field_id = self.field.id sas.add(self.data) if value.has_key('other') and value['other'] != '': moderated = self.field.get_option('moderated') case_sensitive = self.field.get_option('case_sensitive') if case_sensitive == 'true': option = sas.query(ListOption) \ .filter(ListOption.label == value['other']) \ .filter(ListOption.field_id == self.field.id) \ .first() else: option = sas.query(ListOption) \ .filter(ListOption.label.ilike(value['other'])) \ .filter(ListOption.field_id == self.field.id) \ .first() no_options = sas.query(ListOption) \ .filter(ListOption.field_id == self.field.id).count() if not option: lo = ListOption() lo.label = value['other'] lo.value = lo.label lo.field = self.field lo.position = no_options lo.status = 'Approved' if moderated == 'false' \ else 'Awaiting moderation' sas.add(lo) sas.flush() else: lo = option data = ListData() # TODO: Check if is a valid value data.value = lo.id data.entry_id = entry.id data.field_id = self.field.id sas.add(data)
def delete(self): collector = self._get_collector_if_belongs_to_user() if collector: sas.delete(collector) sas.flush() error = '' else: error = _("This collector does not exist.") return {'errors': error}
def delete(self): form = self._get_form_if_belongs_to_user() if form: sas.delete(form) sas.flush() error = '' else: error = _("This form does not exist.") user = self.request.user all_data = user.all_categories_and_forms() return {'error': error, 'all_data': all_data}
def delete(self): form = self._get_form_if_belongs_to_user() if form: sas.delete(form) sas.flush() error = "" else: error = _("This form does not exist.") user = self.request.user all_data = user.all_categories_and_forms() return {"error": error, "all_data": all_data}
def copy(self): form = self._get_form_if_belongs_to_user() if form: form_copy = form.copy() form_copy.name += " " + _("(copy)") sas.flush() error = "" else: error = _("This form does not exist.") user = self.request.user all_data = user.all_categories_and_forms() return {"errors": error, "all_data": all_data, "form_copy_id": form_copy.id}
def rename(self): cat_id = self.request.matchdict.get('id') cat_name = self.request.POST['category_name'] if cat_name != '': category = sas.query(FormCategory).filter(FormCategory.id==cat_id)\ .one() if category: category.name = cat_name sas.flush() errors = '' else: errors = _("Error finding category") return {'errors': errors}
def copy(self): form = self._get_form_if_belongs_to_user() if form: form_copy = form.copy() form_copy.name += " " + _("(copy)") sas.flush() error = '' else: error = _("This form does not exist.") user = self.request.user all_data = user.all_categories_and_forms() return {'errors': error, 'all_data': all_data, 'form_copy_id': form_copy.id}
def delete(self): user = self.request.user cat_id = int(self.request.matchdict.get('id')) category = sas.query(FormCategory).filter(FormCategory.id == cat_id) \ .filter(FormCategory.user==user).one() if category: sas.delete(category) sas.flush() errors = '' else: errors = _("This category does not exist.") if user.categories: categories_data = [cat.to_dict() for cat in user.categories] return {'errors': errors, 'categories': categories_data}
def save_options(self, options): '''Persists specific field properties.''' self.save_option('default', options['defaul']) # the default value for key in ('list_type', 'multiple_choice', 'sort_choices', 'new_option_label', 'min_num', # minimum number of choices 'max_num', # maximum number of choices 'size_options', # number of choices 'moderated', # other moderated 'new_option', # possible to add a new option 'case_sensitive', # other case sensitive 'opt_restrictions', # restricted number of options # 'export_in_columns', # when creating a CSV ): self.save_option(key, options[key]) inserted_options = {} for option_id, opt in options['options'].items(): if opt['option_id'] != 'new': lo = sas.query(ListOption).get(opt['option_id']) lo.label = opt['label'] lo.value = opt['value'] lo.opt_default = opt['opt_default'] lo.position = opt['position'] # lo.status = opt['status'] # To prevent KeyError, Nando changed the above line to: lo.status = opt.get('status', 'Form owner') else: lo = ListOption() lo.label = opt['label'] lo.value = opt['value'] lo.opt_default = opt['opt_default'] lo.field = self.field lo.position = opt['position'] lo.status = 'Form owner' sas.add(lo) sas.flush() inserted_options[option_id] = lo.id # Delete options for list_option_id in options['deleteOptions']: lo = sas.query(ListOption).get(list_option_id) if lo: sas.delete(lo) return {'insertedOptions': inserted_options}
def save_form(self): '''Responds to the AJAX request and saves a form with its fields.''' request = self.request # TODO: Clean the posted json from malicious attacks such as XSS posted = json.loads(request.POST.pop('json')) # Validate the form panel (especially form name length) # TODO: Using deform for this was a mistake. We should use colander # only, and display errors using javascript, as we did on the # following method "rename". form_props = [('_charset_', ''), ('__formid__', 'FirstPanel'), ('name', posted['form_title']), ('description', posted['form_desc']), ('rich', posted['rich']), ('use_rich', posted['use_rich']), ('submit_label', posted['submit_label']) ] dform = d.Form(form_schema, formid='FirstPanel') try: fprops = dform.validate(form_props) except d.ValidationFailure as e: # print(e.args, e.cstruct, e.error, e.field, e.message) return dict(panel_form=e.render(), error=_('Error loading your form')) # the form panel is validated and should always be returned panel_form = dform.render(form_props) # Validation passes, so create or update the form. form_id = posted['form_id'] if form_id == 'new': form = Form(user=request.user) sas.add(form) else: form = self._get_form_if_belongs_to_user(form_id=form_id) if not form: return dict(error=_('Form not found.')) # Set the form tab properties form.name = fprops['name'] form.description = fprops['description'] sl = fprops['submit_label'] form.submit_label = \ self.tr(sl) if isinstance(sl, TranslationString) else sl form.use_rich = posted['use_rich'] # Sanitize / scrub the rich HTML rich = posted['rich'] if rich: rich = self.clnr.clean_html(rich) form.rich = rich # Visual Tab Info st_id = posted['system_template_id'] if st_id: st = sas.query(FormTemplate). \ filter(FormTemplate.system_template_id == st_id).first() form.template = st if form_id == 'new': # TODO: really necessary anymore? sas.flush() # so we get the form id # Get field positions positions = {f[:-len("_container")]: p for p, f in \ enumerate(posted['fields_position'])} # Save/Update the fields # Fields to delete for f_id in posted['deleteFields']: # TODO: check what to do with the field answer data!!! field = sas.query(Field).join(Form).filter(Field.id == f_id)\ .filter(Form.user_id == request.user.id).first() sas.delete(field) new_fields_id = {} save_options_result = {} for f in posted['fields']: # Sanitize / scrub the rich HTML rich = f['rich'] if rich: f['rich'] = rich = self.clnr.clean_html(rich) if not f['field_id']: raise RuntimeError('Cannot instantiate a field of ID {}' \ .format(f['field_id'])) elif f['field_id'] == 'new': field_type = sas.query(FieldType) \ .filter(FieldType.name == f['type']).first() # To solve a bug where field.save_options() would fail because # of a missing field ID, we instantiate the field here and flush field = Field(typ=field_type, form=form, label=f['label'], description=f['description'], help_text=None, use_rich=f['use_rich'], rich=f['rich']) sas.add(field) sas.flush() # TODO: Populating the above instance variables is probably # redundantly done elsewhere, but it must be done here. else: field = sas.query(Field).get(f['field_id']) if not field: return dict(error=_("Sorry, your field could not be found: {}") \ .format(f['field_id'])) f['position'] = positions[f['id']] # Before the following call, the field must have an ID. # If the following line raises a FieldValidationError, Pyramid will # call the field_validation_error action. result = field.validate_and_save(f) if result: save_options_result[f['id']] = result # If is a new field, need to inform the client about # the field id on DB after a flush if f['field_id'] == 'new': sas.flush() new_fields_id[f['id']] = {'field_id': field.id} rdict = {'form_id': form.id, 'new_fields_id': new_fields_id, 'save_options_result': save_options_result, 'panel_form': panel_form, } return rdict
def save_form(self): """Responds to the AJAX request and saves a form with its fields.""" request = self.request # TODO: Clean the posted json from malicious attacks such as XSS posted = json.loads(request.POST.pop("json")) # Validate the form panel (especially form name length) # TODO: Using deform for this was a mistake. We should use colander # only, and display errors using javascript, as we did on the # following method "rename". form_props = [ ("_charset_", ""), ("__formid__", "FirstPanel"), ("name", posted["form_title"]), ("description", posted["form_desc"]), ("rich", posted["rich"]), ("use_rich", posted["use_rich"]), ("submit_label", posted["submit_label"]), ] dform = d.Form(form_schema, formid="FirstPanel") try: fprops = dform.validate(form_props) except d.ValidationFailure as e: # print(e.args, e.cstruct, e.error, e.field, e.message) return dict(panel_form=e.render(), error=_("Error loading your form")) # the form panel is validated and should always be returned panel_form = dform.render(form_props) # Validation passes, so create or update the form. form_id = posted["form_id"] if form_id == "new": form = Form(user=request.user) sas.add(form) else: form = self._get_form_if_belongs_to_user(form_id=form_id) if not form: return dict(error=_("Form not found.")) # Set the form tab properties form.name = fprops["name"] form.description = fprops["description"] sl = fprops["submit_label"] form.submit_label = self.tr(sl) if isinstance(sl, TranslationString) else sl form.use_rich = posted["use_rich"] # Sanitize / scrub the rich HTML rich = posted["rich"] if rich: rich = self.clnr.clean_html(rich) form.rich = rich # Visual Tab Info st_id = posted["system_template_id"] if st_id: st = sas.query(FormTemplate).filter(FormTemplate.system_template_id == st_id).first() form.template = st if form_id == "new": # TODO: really necessary anymore? sas.flush() # so we get the form id # Get field positions positions = {f[: -len("_container")]: p for p, f in enumerate(posted["fields_position"])} # Save/Update the fields # Fields to delete for f_id in posted["deleteFields"]: # TODO: check what to do with the field answer data!!! field = sas.query(Field).join(Form).filter(Field.id == f_id).filter(Form.user_id == request.user.id).first() sas.delete(field) new_fields_id = {} save_options_result = {} for f in posted["fields"]: # Sanitize / scrub the rich HTML rich = f["rich"] if rich: f["rich"] = rich = self.clnr.clean_html(rich) if not f["field_id"]: raise RuntimeError("Cannot instantiate a field of ID {}".format(f["field_id"])) elif f["field_id"] == "new": field_type = sas.query(FieldType).filter(FieldType.name == f["type"]).first() # To solve a bug where field.save_options() would fail because # of a missing field ID, we instantiate the field here and flush field = Field( typ=field_type, form=form, label=f["label"], description=f["description"], help_text=None, use_rich=f["use_rich"], rich=f["rich"], ) sas.add(field) sas.flush() # TODO: Populating the above instance variables is probably # redundantly done elsewhere, but it must be done here. else: field = sas.query(Field).get(f["field_id"]) if not field: return dict(error=_("Sorry, your field could not be found: {}").format(f["field_id"])) f["position"] = positions[f["id"]] # Before the following call, the field must have an ID. # If the following line raises a FieldValidationError, Pyramid will # call the field_validation_error action. result = field.validate_and_save(f) if result: save_options_result[f["id"]] = result # If is a new field, need to inform the client about # the field id on DB after a flush if f["field_id"] == "new": sas.flush() new_fields_id[f["id"]] = {"field_id": field.id} rdict = { "form_id": form.id, "new_fields_id": new_fields_id, "save_options_result": save_options_result, "panel_form": panel_form, } return rdict