def dict2xform(jsform, form_id, root=None, username=None, gen_uuid=False): """ Converts a dictionary containing submission data into an XML Submission for the appropriate form. :param jsform (dict): A python dictionary object containing the submission data :param form_id (str or XForm): An XForm object or a string value representing the forms id_string :param root (str): An optional string that should be used as the root nodes name. Defaults to None :param: username (str): An optional string representing a users username. Used alongside the `form_id` to locate the XForm object the user is trying to submit data too. Defaults to None :returns: Returns a string containing the Submission XML :rtype: str """ if not root: if username: if isinstance(form_id, XForm): root = form_id.survey.name else: form = XForm.objects.filter(id_string__iexact=form_id, user__username__iexact=username, deleted_at__isnull=True).first() root = form.survey.name if form else 'data' else: root = 'data' if gen_uuid: jsform['meta'] = {'instanceID': 'uuid:' + get_uuid(hex_only=False)} return "<?xml version='1.0' ?><{0} id='{1}'>{2}</{0}>".format( root, form_id, dict2xml(jsform))
def generate_uuid_if_missing(apps, schema_editor): """ Generate uuids for XForms without them """ XForm = apps.get_model('logger', 'XForm') for xform in XForm.objects.filter(uuid=''): xform.uuid = get_uuid() xform.save()
def add_submission_with(request, username, id_string): """ Returns JSON response with Enketo form url preloaded with coordinates. """ def geopoint_xpaths(username, id_string): """ Returns xpaths with elements of type 'geopoint'. """ data_dictionary = DataDictionary.objects.get( user__username__iexact=username, id_string__iexact=id_string) return [ e.get_abbreviated_xpath() for e in data_dictionary.get_survey_elements() if e.bind.get(u'type') == u'geopoint' ] value = request.GET.get('coordinates') xpaths = geopoint_xpaths(username, id_string) xml_dict = {} for path in xpaths: dpath_util.new(xml_dict, path, value) context = { 'username': username, 'id_string': id_string, 'xml_content': dict2xml(xml_dict) } instance_xml = loader.get_template("instance_add.xml")\ .render(context) url = settings.ENKETO_API_INSTANCE_IFRAME_URL return_url = reverse( 'thank_you_submission', kwargs={"username": username, "id_string": id_string}) if settings.DEBUG: openrosa_url = "https://dev.formhub.org/{}".format(username) else: openrosa_url = request.build_absolute_uri("/{}".format(username)) payload = { 'return_url': return_url, 'form_id': id_string, 'server_url': openrosa_url, 'instance': instance_xml, 'instance_id': get_uuid() } response = requests.post( url, data=payload, auth=(settings.ENKETO_API_TOKEN, ''), verify=getattr(settings, 'VERIFY_SSL', True)) return HttpResponse(response.text, content_type='application/json')
def test_post_submission_uuid_duplicate_no_username_provided(self): """ Test submission to a duplicate of a form with a different uuid from the original is properly routed to the request users version of the form """ alice_profile = self._create_user_profile({ 'username': '******', 'email': '*****@*****.**' }) s = self.surveys[0] media_file = "1335783522563.jpg" path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, media_file) with open(path, 'rb') as f: f = InMemoryUploadedFile(f, 'media_file', media_file, 'image/jpg', os.path.getsize(path), None) path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') path = self._add_uuid_to_submission_xml(path, self.xform) with open(path, 'rb') as sf: # Submits to the correct form count = XForm.objects.count() original_form_pk = self.xform.pk duplicate_form = self.xform duplicate_form.pk = None duplicate_form.uuid = get_uuid() duplicate_form.user = alice_profile.user duplicate_form.save() duplicate_form.refresh_from_db() self.assertNotEqual(original_form_pk, duplicate_form.pk) self.assertEqual(XForm.objects.count(), count + 1) request = self.factory.post('/submission', { 'xml_submission_file': sf, 'media_file': f }) response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 201) duplicate_form.refresh_from_db() self.assertEqual(duplicate_form.instances.all().count(), 1) self.assertEqual( XForm.objects.get( pk=original_form_pk).instances.all().count(), 0)
def set_uuid(obj): """ Only give an object a new UUID if it does not have one. """ if not obj.uuid: obj.uuid = get_uuid()
def save(self, *args, **kwargs): if not self.key: self.key = get_uuid() super(Widget, self).save(*args, **kwargs)