def _set_title(self): xml = re.sub(r"\s+", " ", self.xml) matches = title_pattern.findall(xml) if len(matches) != 1: raise XLSFormError(_("There should be a single title."), matches) if matches: title_xml = matches[0][:XFORM_TITLE_LENGTH] else: title_xml = self.title[:XFORM_TITLE_LENGTH] if self.title else '' if self.title and title_xml != self.title: title_xml = self.title[:XFORM_TITLE_LENGTH] if isinstance(self.xml, b): self.xml = self.xml.decode('utf-8') self.xml = title_pattern.sub(u"<h:title>%s</h:title>" % title_xml, self.xml) self._set_hash() if contains_xml_invalid_char(title_xml): raise XLSFormError( _("Title shouldn't have any invalid xml " "characters ('>' '&' '<')")) self.title = title_xml
def save(self, *args, **kwargs): update_fields = kwargs.get('update_fields') if update_fields: kwargs['update_fields'] = list( set(list(update_fields) + ['date_modified'])) if update_fields is None or 'title' in update_fields: self._set_title() if self.pk is None: self._set_hash() if update_fields is None or 'encrypted' in update_fields: self._set_encrypted_field() if update_fields is None or 'id_string' in update_fields: old_id_string = self.id_string if not self.deleted_at: self._set_id_string() # check if we have an existing id_string, # if so, the one must match but only if xform is NOT new if self.pk and old_id_string and old_id_string != self.id_string \ and self.num_of_submissions > 0: raise XLSFormError( _(u"Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % { 'new_id': self.id_string, 'old_id': old_id_string })) if getattr(settings, 'STRICT', True) and \ not re.search(r"^[\w-]+$", self.id_string): raise XLSFormError( _(u'In strict mode, the XForm ID must be a ' 'valid slug and contain no spaces.')) if not self.sms_id_string and (update_fields is None or 'id_string' in update_fields): try: # try to guess the form's wanted sms_id_string # from it's json rep (from XLSForm) # otherwise, use id_string to ensure uniqueness self.sms_id_string = json.loads(self.json).get( 'sms_keyword', self.id_string) except Exception: self.sms_id_string = self.id_string if update_fields is None or 'public_key' in update_fields: self._set_public_key_field() if 'skip_xls_read' in kwargs: del kwargs['skip_xls_read'] if (self.id_string and len( self.id_string) > self.MAX_ID_LENGTH) or \ (self.sms_id_string and len( self.sms_id_string) > self.MAX_ID_LENGTH): raise XLSFormError( _(u'The XForm id_string provided exceeds %s characters.' ' Please change the "id_string" or "form_id" values' 'in settings sheet or reduce the file name if you do' ' not have a settings sheets.' % self.MAX_ID_LENGTH)) super(XForm, self).save(*args, **kwargs)
def save(self, *args, **kwargs): self._set_title() self._set_description() old_id_string = self.id_string self._set_id_string() self._set_encrypted_field() # check if we have an existing id_string, # if so, the one must match but only if xform is NOT new if self.pk and old_id_string and old_id_string != self.id_string: raise XLSFormError( _("Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % {'new_id': self.id_string, 'old_id': old_id_string})) if getattr(settings, 'STRICT', True) and \ not re.search(r"^[\w-]+$", self.id_string): raise XLSFormError(_('In strict mode, the XForm ID must be a ' 'valid slug and contain no spaces.')) if not self.sms_id_string: try: # try to guess the form's wanted sms_id_string # from it's json rep (from XLSForm) # otherwise, use id_string to ensure uniqueness self.sms_id_string = json.loads(self.json).get('sms_keyword', self.id_string) except: self.sms_id_string = self.id_string super(XForm, self).save(*args, **kwargs)
def test_show_form_name_with_ampersand_in_title(self, mock_set_title): mock_set_title.side_effect = XLSFormError( u"Title shouldn't have an ampersand") response = self.client.get(self.url) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, u"Title shouldn't have an ampersand")
def save(self, *args, **kwargs): update_fields = kwargs.get('update_fields') if update_fields: kwargs['update_fields'] = list( set(list(update_fields) + ['date_modified'])) if update_fields is None or 'title' in update_fields: self._set_title() if update_fields is None or 'encrypted' in update_fields: self._set_encrypted_field() if update_fields is None or 'id_string' in update_fields: old_id_string = self.id_string if not self.deleted_at: self._set_id_string() # check if we have an existing id_string, # if so, the one must match but only if xform is NOT new if self.pk and old_id_string and old_id_string != self.id_string \ and self.num_of_submissions > 0: raise XLSFormError( _(u"Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s', if form has" " submissions." % { 'new_id': self.id_string, 'old_id': old_id_string })) if getattr(settings, 'STRICT', True) and \ not re.search(r"^[\w-]+$", self.id_string): raise XLSFormError( _(u'In strict mode, the XForm ID must be a ' 'valid slug and contain no spaces.')) if not self.sms_id_string and (update_fields is None or 'id_string' in update_fields): try: # try to guess the form's wanted sms_id_string # from it's json rep (from XLSForm) # otherwise, use id_string to ensure uniqueness self.sms_id_string = json.loads(self.json).get( 'sms_keyword', self.id_string) except: self.sms_id_string = self.id_string if 'skip_xls_read' in kwargs: del kwargs['skip_xls_read'] super(XForm, self).save(*args, **kwargs)
def _set_title(self): text = re.sub(r"\s+", " ", self.xml) matches = title_pattern.findall(text) title_xml = matches[0][:XFORM_TITLE_LENGTH] if len(matches) != 1: raise XLSFormError(_("There should be a single title."), matches) if self.title and title_xml != self.title: title_xml = self.title[:XFORM_TITLE_LENGTH] if isinstance(self.xml, str): self.xml = self.xml.decode('utf-8') self.xml = title_pattern.sub(u"<h:title>%s</h:title>" % title_xml, self.xml) if '&' in title_xml: raise XLSFormError(_("Title shouldn't have an ampersand")) self.title = title_xml
def test_xlsform_error_returns_400(self, mock_render): mock_render.side_effect = XLSFormError( u"Title shouldn't have an ampersand") self._login_user_and_profile() response = self.client.get(reverse(profile, kwargs={'username': "******"})) self.assertTrue(mock_render.called) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, "Title shouldn't have an ampersand")
def save(self, *args, **kwargs): self._set_title() self._set_description() old_id_string = self.id_string self._set_id_string() self._set_encrypted_field() # check if we have an existing id_string, # if so, the one must match but only if xform is NOT new if self.pk and old_id_string and old_id_string != self.id_string: raise XLSFormError( t("Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % { 'new_id': self.id_string, 'old_id': old_id_string })) if getattr(settings, 'STRICT', True) and \ not re.search(r"^[\w-]+$", self.id_string): raise XLSFormError( t('In strict mode, the XForm ID must be a ' 'valid slug and contain no spaces.')) super().save(*args, **kwargs)
def save(self, *args, **kwargs): skip_xls_read = kwargs.get('skip_xls_read') if self.xls and not skip_xls_read: default_name = None \ if not self.pk else self.survey.xml_instance().tagName survey_dict = process_xlsform(self.xls, default_name) if has_external_choices(survey_dict): self.has_external_choices = True survey = create_survey_element_from_dict(survey_dict) survey = check_version_set(survey) if get_columns_with_hxl(survey.get('children')): self.has_hxl_support = True # if form is being replaced, don't check for id_string uniqueness if self.pk is None: new_id_string = self.get_unique_id_string( survey.get('id_string')) self._id_string_changed = \ new_id_string != survey.get('id_string') survey['id_string'] = new_id_string # For flow results packages use the user defined id/uuid if self.xls.name.endswith('json'): self.uuid = FloipSurvey(self.xls).descriptor.get('id') if self.uuid: check_xform_uuid(self.uuid) elif self.id_string != survey.get('id_string'): raise XLSFormError( _((u"Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % { 'new_id': survey.get('id_string'), 'old_id': self.id_string }))) elif default_name and default_name != survey.get('name'): survey['name'] = default_name else: survey['id_string'] = self.id_string self.json = survey.to_json() self.xml = survey.to_xml() self.version = survey.get('version') self.last_updated_at = timezone.now() self.title = survey.get('title') self._mark_start_time_boolean() set_uuid(self) self._set_uuid_in_xml() self._set_hash() if 'skip_xls_read' in kwargs: del kwargs['skip_xls_read'] super(DataDictionary, self).save(*args, **kwargs)
def _set_title(self): text = re.sub(r"\s+", " ", self.xml) matches = title_pattern.findall(text) title_xml = matches[0][:XFORM_TITLE_LENGTH] if len(matches) != 1: raise XLSFormError(_("There should be a single title."), matches) if self.title and title_xml != self.title: title_xml = self.title[:XFORM_TITLE_LENGTH] self.xml = title_pattern.sub( u"<h:title>%s</h:title>" % title_xml, self.xml) self.title = title_xml
def _set_title(self): self.xml = smart_text(self.xml) text = re.sub(r'\s+', ' ', self.xml) matches = title_pattern.findall(text) title_xml = matches[0][:XFORM_TITLE_LENGTH] if len(matches) != 1: raise XLSFormError(t("There should be a single title."), matches) if self.title and title_xml != self.title: title_xml = self.title[:XFORM_TITLE_LENGTH] title_xml = saxutils.escape(title_xml) self.xml = title_pattern.sub("<h:title>%s</h:title>" % title_xml, self.xml) self.title = title_xml
def _set_id_string(self): matches = self.instance_id_regex.findall(self.xml) if len(matches) != 1: raise XLSFormError(_("There should be a single id string.")) self.id_string = matches[0]
def save(self, *args, **kwargs): skip_xls_read = kwargs.get('skip_xls_read') if self.xls and not skip_xls_read: default_name = None \ if not self.pk else self.survey.xml_instance().tagName try: if self.xls.name.endswith('csv'): # csv file gets closed in pyxform, make a copy self.xls.seek(0) file_object = io.BytesIO() file_object.write(self.xls.read()) file_object.seek(0) self.xls.seek(0) else: file_object = self.xls if self.xls.name.endswith('json'): survey_dict = FloipSurvey(self.xls).survey.to_json_dict() else: survey_dict = parse_file_to_json(self.xls.name, file_object=file_object) except csv.Error as e: newline_error = u'new-line character seen in unquoted field '\ u'- do you need to open the file in universal-newline '\ u'mode?' if newline_error == unicode(e): self.xls.seek(0) file_obj = StringIO(u'\n'.join( self.xls.read().splitlines())) survey_dict = parse_file_to_json(self.xls.name, default_name=default_name, file_object=file_obj) else: raise e if has_external_choices(survey_dict): self.survey_dict = survey_dict self.has_external_choices = True survey = create_survey_element_from_dict(survey_dict) survey = self._check_version_set(survey) if get_columns_with_hxl(survey.get('children')): self.has_hxl_support = True # if form is being replaced, don't check for id_string uniqueness if self.pk is None: new_id_string = self.get_unique_id_string( survey.get('id_string')) self._id_string_changed = \ new_id_string != survey.get('id_string') survey['id_string'] = new_id_string elif self.id_string != survey.get('id_string'): raise XLSFormError( _((u"Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % { 'new_id': survey.get('id_string'), 'old_id': self.id_string }))) elif default_name and default_name != survey.get('name'): survey['name'] = default_name else: survey['id_string'] = self.id_string self.json = survey.to_json() self.xml = survey.to_xml() self.version = survey.get('version') self.last_updated_at = timezone.now() self.title = survey.get('title') self._mark_start_time_boolean() self._set_hash() set_uuid(self) self._set_uuid_in_xml() if 'skip_xls_read' in kwargs: del kwargs['skip_xls_read'] super(DataDictionary, self).save(*args, **kwargs)
def _set_title(self): text = re.sub(r"\s+", " ", self.xml) matches = re.findall(r"<h:title>([^<]+)</h:title>", text) if len(matches) != 1: raise XLSFormError(_("There should be a single title."), matches) self.title = u"" if not matches else matches[0][:XFORM_TITLE_LENGTH]