def download_instances(self, form_id, cursor=0, num_entries=100):
        self.logger.debug("Starting submissions download for %s" % form_id)
        if not self._get_response(self.submission_list_url,
                                  params={
                                      'formId': form_id,
                                      'numEntries': num_entries,
                                      'cursor': cursor
                                  }):
            self.logger.error("Fetching %s formId: %s, cursor: %s" %
                              (self.submission_list_url, form_id, cursor))
            return

        response = self._current_response
        self.logger.debug("Fetching %s formId: %s, cursor: %s" %
                          (self.submission_list_url, form_id, cursor))
        try:
            xml_doc = clean_and_parse_xml(response.content)
        except ExpatError:
            return

        instances = self.get_instances_uuids(xml_doc)
        path = os.path.join(self.forms_path, form_id, 'instances')

        for uuid in instances:
            self.logger.debug("Fetching %s %s submission" % (uuid, form_id))
            form_str = u'%(formId)s[@version=null and @uiVersion=null]/'\
                u'%(formId)s[@key=%(instanceId)s]' % {
                    'formId': form_id,
                    'instanceId': uuid
                }
            instance_path = os.path.join(path, uuid.replace(':', ''),
                                         'submission.xml')
            if not default_storage.exists(instance_path):
                if self._get_response(self.download_submission_url,
                                      params={'formId': form_str}):
                    instance_res = self._current_response
                    content = instance_res.content.strip()
                    default_storage.save(instance_path, ContentFile(content))
                else:
                    continue
            else:
                instance_res = default_storage.open(instance_path)
                content = instance_res.read()

            try:
                instance_doc = clean_and_parse_xml(content)
            except ExpatError:
                continue

            media_path = os.path.join(path, uuid.replace(':', ''))
            self.download_media_files(instance_doc, media_path)
            self.logger.debug("Fetched %s %s submission" % (form_id, uuid))

        if xml_doc.getElementsByTagName('resumptionCursor'):
            rs_node = xml_doc.getElementsByTagName('resumptionCursor')[0]
            cursor = rs_node.childNodes[0].nodeValue

            if self.resumption_cursor != cursor:
                self.resumption_cursor = cursor
                self.download_instances(form_id, cursor)
Example #2
0
    def download_instances(self, form_id, cursor=0, num_entries=100):
        self.logger.debug("Starting submissions download for %s" % form_id)
        if not self._get_response(self.submission_list_url,
                                  params={'formId': form_id,
                                          'numEntries': num_entries,
                                          'cursor': cursor}):
            self.logger.error("Fetching %s formId: %s, cursor: %s" %
                              (self.submission_list_url, form_id, cursor))
            return

        response = self._current_response
        self.logger.debug("Fetching %s formId: %s, cursor: %s" %
                          (self.submission_list_url, form_id, cursor))
        try:
            xml_doc = clean_and_parse_xml(response.content)
        except ExpatError:
            return

        instances = self.get_instances_uuids(xml_doc)
        path = os.path.join(self.forms_path, form_id, 'instances')

        for uuid in instances:
            self.logger.debug("Fetching %s %s submission" % (uuid, form_id))
            form_str = u'%(formId)s[@version=null and @uiVersion=null]/'\
                u'%(formId)s[@key=%(instanceId)s]' % {
                    'formId': form_id,
                    'instanceId': uuid
                }
            instance_path = os.path.join(path, uuid.replace(':', ''),
                                         'submission.xml')
            if not default_storage.exists(instance_path):
                if self._get_response(self.download_submission_url,
                                      params={'formId': form_str}):
                    instance_res = self._current_response
                    content = instance_res.content.strip()
                    default_storage.save(instance_path, ContentFile(content))
                else:
                    continue
            else:
                instance_res = default_storage.open(instance_path)
                content = instance_res.read()

            try:
                instance_doc = clean_and_parse_xml(content)
            except ExpatError:
                continue

            media_path = os.path.join(path, uuid.replace(':', ''))
            self.download_media_files(instance_doc, media_path)
            self.logger.debug("Fetched %s %s submission" % (form_id, uuid))

        if xml_doc.getElementsByTagName('resumptionCursor'):
            rs_node = xml_doc.getElementsByTagName('resumptionCursor')[0]
            cursor = rs_node.childNodes[0].nodeValue

            if self.resumption_cursor != cursor:
                self.resumption_cursor = cursor
                self.download_instances(form_id, cursor)
Example #3
0
 def download_xforms(self, include_instances=False):
     # fetch formList
     response = requests.get(self.form_list_url, auth=self.auth)
     self.logger.debug('Successfull fetched %s.' % self.form_list_url)
     xml_doc = clean_and_parse_xml(response.content)
     forms = []
     for childNode in xml_doc.childNodes:
         if childNode.nodeName == 'xforms':
             for xformNode in childNode.childNodes:
                 if xformNode.nodeName == 'xform':
                     form_id = xformNode.getElementsByTagName('formID')[0]
                     id_string = form_id.childNodes[0].nodeValue
                     form_name = xformNode.getElementsByTagName('name')[0]
                     name = form_name.childNodes[0].nodeValue
                     if name.startswith('Crowd/'):
                         # skip crowdforms: very formhub specific
                         continue
                     d = xformNode.getElementsByTagName('downloadUrl')[0]
                     download_url = d.childNodes[0].nodeValue
                     m = xformNode.getElementsByTagName('manifestUrl')[0]
                     manifest_url = m.childNodes[0].nodeValue
                     forms.append((id_string, download_url, manifest_url))
     # download each xform
     if forms:
         for id_string, download_url, manifest_url in forms:
             form_path = os.path.join(self.forms_path, id_string,
                                      '%s.xml' % id_string)
             if not default_storage.exists(form_path):
                 form_res = requests.get(download_url, auth=self.auth)
                 content = ContentFile(form_res.content.strip())
                 default_storage.save(form_path, content)
             else:
                 form_res = default_storage.open(form_path)
                 content = form_res.read()
             self.logger.debug("Fetched %s." % download_url)
             manifest_res = requests.get(manifest_url, auth=self.auth)
             try:
                 manifest_doc = clean_and_parse_xml(manifest_res.content)
             except ExpatError:
                 continue
             manifest_path = os.path.join(self.forms_path, id_string,
                                          'form-media')
             self.logger.debug("Downloading media files for %s" % id_string)
             self.download_media_files(manifest_doc, manifest_path)
             if include_instances:
                 self.logger.debug("Downloading submissions for %s" %
                                   id_string)
                 self.download_instances(id_string)
                 self.logger.debug("Done downloading submissions for %s" %
                                   id_string)
Example #4
0
def check_custom_form_validation(xml, request, username):
    TAG_TO_PARSE = '_Tubewell_ID'
    FORM_ID_TO_CHECK = str('tubewell_arsenic_level')
    tubewell_id = 0
    form_id = None
    valid = False
    FormXMLTree = clean_and_parse_xml(xml)
    collection = FormXMLTree.documentElement
    if collection.hasAttribute("id"):
        form_id = collection.getAttribute("id")
        #print "Root element : %s " % collection.getAttribute("id")
    if form_id != FORM_ID_TO_CHECK:
        return True
    all_Tag_to_parse = collection.getElementsByTagName(
        "group_arsenic_level_group")
    for ids in all_Tag_to_parse:
        tubewell_id = ids.getElementsByTagName(TAG_TO_PARSE)[0]
        tubewell_id = tubewell_id.childNodes[0].data
        #print "Tubewell_ID: %s" % tubewell_id
    cursor = connection.cursor()
    registration_query = "SELECT (json->>'Tubewell_ID') AS identification FROM logger_instance WHERE xform_id=18"
    cursor.execute(registration_query)
    fetchVal = cursor.fetchall()

    for each in fetchVal:
        tmpval = int(each[0])
        # print 'tmpval ' + tmpval
        if tmpval == int(tubewell_id):
            # print 'each for: '+ each[0]
            valid = True
    #print 'fetchVal: '+fetchVal
    #print 'valid : '+ str(valid)
    return valid
Example #5
0
def inject_instanceid(xml_str, uuid):
    if get_uuid_from_xml(xml_str) is None:
        xml = clean_and_parse_xml(xml_str)
        children = xml.childNodes
        if children.length == 0:
            raise ValueError(_("XML string must have a survey element."))

        # check if we have a meta tag
        survey_node = children.item(0)
        meta_tags = [
            n for n in survey_node.childNodes
            if n.nodeType == Node.ELEMENT_NODE
            and n.tagName.lower() == "meta"]
        if len(meta_tags) == 0:
            meta_tag = xml.createElement("meta")
            xml.documentElement.appendChild(meta_tag)
        else:
            meta_tag = meta_tags[0]

        # check if we have an instanceID tag
        uuid_tags = [
            n for n in meta_tag.childNodes
            if n.nodeType == Node.ELEMENT_NODE
            and n.tagName == "instanceID"]
        if len(uuid_tags) == 0:
            uuid_tag = xml.createElement("instanceID")
            meta_tag.appendChild(uuid_tag)
        else:
            uuid_tag = uuid_tags[0]
        # insert meta and instanceID
        text_node = xml.createTextNode(u"uuid:%s" % uuid)
        uuid_tag.appendChild(text_node)
        return xml.toxml()
    return xml_str
Example #6
0
def inject_instanceid(xml_str, uuid):
    if get_uuid_from_xml(xml_str) is None:
        xml = clean_and_parse_xml(xml_str)
        children = xml.childNodes
        if children.length == 0:
            raise ValueError(_("XML string must have a survey element."))

        # check if we have a meta tag
        survey_node = children.item(0)
        meta_tags = [
            n for n in survey_node.childNodes
            if n.nodeType == Node.ELEMENT_NODE and n.tagName.lower() == "meta"
        ]
        if len(meta_tags) == 0:
            meta_tag = xml.createElement("meta")
            xml.documentElement.appendChild(meta_tag)
        else:
            meta_tag = meta_tags[0]

        # check if we have an instanceID tag
        uuid_tags = [
            n for n in meta_tag.childNodes
            if n.nodeType == Node.ELEMENT_NODE and n.tagName == "instanceID"
        ]
        if len(uuid_tags) == 0:
            uuid_tag = xml.createElement("instanceID")
            meta_tag.appendChild(uuid_tag)
        else:
            uuid_tag = uuid_tags[0]
        # insert meta and instanceID
        text_node = xml.createTextNode(u"uuid:%s" % uuid)
        uuid_tag.appendChild(text_node)
        return xml.toxml()
    return xml_str
 def test_edited_submission(self):
     """
     Test submissions that have been edited
     """
     xml_submission_file_path = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "..",
         "fixtures",
         "tutorial",
         "instances",
         "tutorial_2012-06-27_11-27-53_w_uuid.xml",
     )
     num_instances_history = InstanceHistory.objects.count()
     num_instances = Instance.objects.count()
     query_args = {
         "username": self.user.username,
         "id_string": self.xform.id_string,
         "query": "{}",
         "fields": "[]",
         "sort": "[]",
         "count": True,
     }
     cursor = ParsedInstance.query_mongo(**query_args)
     num_mongo_instances = cursor[0]["count"]
     # make first submission
     self._make_submission(xml_submission_file_path)
     self.assertEqual(self.response.status_code, 201)
     self.assertEqual(Instance.objects.count(), num_instances + 1)
     # no new record in instances history
     self.assertEqual(InstanceHistory.objects.count(), num_instances_history)
     # check count of mongo instances after first submission
     cursor = ParsedInstance.query_mongo(**query_args)
     self.assertEqual(cursor[0]["count"], num_mongo_instances + 1)
     # edited submission
     xml_submission_file_path = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "..",
         "fixtures",
         "tutorial",
         "instances",
         "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml",
     )
     self._make_submission(xml_submission_file_path)
     self.assertEqual(self.response.status_code, 201)
     # we must have the same number of instances
     self.assertEqual(Instance.objects.count(), num_instances + 1)
     # should be a new record in instances history
     self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 1)
     cursor = ParsedInstance.query_mongo(**query_args)
     self.assertEqual(cursor[0]["count"], num_mongo_instances + 1)
     # make sure we edited the mongo db record and NOT added a new row
     query_args["count"] = False
     cursor = ParsedInstance.query_mongo(**query_args)
     record = cursor[0]
     with open(xml_submission_file_path, "r") as f:
         xml_str = f.read()
     xml_str = clean_and_parse_xml(xml_str).toxml()
     edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0]
     self.assertEqual(record["name"], edited_name)
 def download_xforms(self, include_instances=False):
     # fetch formList
     response = requests.get(self.form_list_url, auth=self.auth)
     self.logger.debug("Successfull fetched %s." % self.form_list_url)
     xml_doc = clean_and_parse_xml(response.content)
     forms = []
     for childNode in xml_doc.childNodes:
         if childNode.nodeName == "xforms":
             for xformNode in childNode.childNodes:
                 if xformNode.nodeName == "xform":
                     form_id = xformNode.getElementsByTagName("formID")[0]
                     id_string = form_id.childNodes[0].nodeValue
                     form_name = xformNode.getElementsByTagName("name")[0]
                     name = form_name.childNodes[0].nodeValue
                     if name.startswith("Crowd/"):
                         # skip crowdforms: very formhub specific
                         continue
                     d = xformNode.getElementsByTagName("downloadUrl")[0]
                     download_url = d.childNodes[0].nodeValue
                     m = xformNode.getElementsByTagName("manifestUrl")[0]
                     manifest_url = m.childNodes[0].nodeValue
                     forms.append((id_string, download_url, manifest_url))
     # download each xform
     if forms:
         for id_string, download_url, manifest_url in forms:
             form_path = os.path.join(self.forms_path, id_string, "%s.xml" % id_string)
             if not default_storage.exists(form_path):
                 form_res = requests.get(download_url, auth=self.auth)
                 content = ContentFile(form_res.content.strip())
                 default_storage.save(form_path, content)
             else:
                 form_res = default_storage.open(form_path)
                 content = form_res.read()
             self.logger.debug("Fetched %s." % download_url)
             manifest_res = requests.get(manifest_url, auth=self.auth)
             try:
                 manifest_doc = clean_and_parse_xml(manifest_res.content)
             except ExpatError:
                 continue
             manifest_path = os.path.join(self.forms_path, id_string, "form-media")
             self.logger.debug("Downloading media files for %s" % id_string)
             self.download_media_files(manifest_doc, manifest_path)
             if include_instances:
                 self.logger.debug("Downloading submissions for %s" % id_string)
                 self.download_instances(id_string)
                 self.logger.debug("Done downloading submissions for %s" % id_string)
Example #9
0
def get_case_id_string_from_xml_str(xml_str):
    xml_obj = clean_and_parse_xml(xml_str)
    try:
        case_id = xml_obj.getElementsByTagName("case_id")[0].firstChild.data
    except:
        case_id = None

    return case_id
    def test_edited_submission(self):
        """
        Test submissions that have been edited
        """
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid.xml"
        )
        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'username': self.user.username,
            'id_string': self.xform.id_string,
            'query': '{}',
            'fields': '[]',
            'sort': '[]',
            'count': True
        }

        cursor = ParsedInstance.query_mongo(**query_args)
        num_mongo_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # no new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history)
        # check count of mongo instances after first submission
        cursor = ParsedInstance.query_mongo(**query_args)
        self.assertEqual(cursor[0]['count'], num_mongo_instances + 1)
        # edited submission
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml"
        )
        client = DigestClient()
        client.set_authorization('bob', 'bob', 'Digest')
        self._make_submission(xml_submission_file_path, client=client)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history + 1)
        cursor = ParsedInstance.query_mongo(**query_args)
        self.assertEqual(cursor[0]['count'], num_mongo_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = ParsedInstance.query_mongo(**query_args)
        record = cursor[0]
        with open(xml_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
Example #11
0
def call_parave_ai_reg_api(xml, request, username, user):
    FormXMLTree = clean_and_parse_xml(xml)
    collection = FormXMLTree.documentElement
    if collection.hasAttribute("id"):
        form_id = collection.getAttribute("id")
        print form_id
    if form_id == "paravet_ai_technitian_reg":
        mobile = collection.getElementsByTagName(
            "mobile")[0].__dict__['childNodes'][0].data
        paravet_name = collection.getElementsByTagName(
            "name")[0].__dict__['childNodes'][0].data
        occupation = collection.getElementsByTagName(
            "occupation")[0].__dict__['childNodes'][0].data
        print mobile
        #print paravet_name
        #print occupation
        # 1=para,farmer=3,ai=2
        if occupation == '1':
            _occupation = 'Paravet'
        elif occupation == '2':
            _occupation = 'AI Technicians'
        elif occupation == '3':
            _occupation = 'Farmer'
        else:
            _occupation = ''
        views_api.register_as_paravet_ai(paravet_name, mobile, _occupation,
                                         user.id)

    if form_id == "farmer_registration":
        password = views_api.id_generator()
        #password = '******'
        mobile = collection.getElementsByTagName(
            "mobile")[0].__dict__['childNodes'][0].data
        farmer_name = collection.getElementsByTagName(
            "name")[0].__dict__['childNodes'][0].data
        occupation = 'Farmer'
        #print occupation
        submitted_data = {}
        submitted_data['username'] = mobile
        #user = User.objects.filter(username=data['phone']).first()
        # password = id_generator()
        #password = '******'
        # when login
        submitted_data['contact_number'] = mobile
        submitted_data['first_name'] = farmer_name

        submitted_data['password'] = password
        submitted_data['password_repeat'] = password
        submitted_data['organisation_name'] = 397

        user_form = UserForm(data=submitted_data)
        profile_form = UserProfileForm(data=submitted_data)
        views_api.save_user_details(user_form, profile_form, submitted_data,
                                    farmer_name, mobile, occupation, user.id)

    return 0
Example #12
0
    def test_uuid_injection_in_cascading_select(self):
        """
        Test that the uuid is injected in the right instance node for
        forms with a cascading select
        """
        pre_count = XForm.objects.count()
        xls_path = os.path.join(self.this_directory, "fixtures",
                                "cascading_selects",
                                "new_cascading_select.xls")
        file_name, file_ext = os.path.splitext(os.path.split(xls_path)[1])
        self.response = TestBase._publish_xls_file(self, xls_path)
        post_count = XForm.objects.count()
        self.assertEqual(post_count, pre_count + 1)
        xform = XForm.objects.latest('date_created')

        # check that the uuid is within the main instance/
        # the one without an id attribute
        xml = clean_and_parse_xml(xform.xml)

        # check for instance nodes that are direct children of the model node
        model_node = xml.getElementsByTagName("model")[0]
        instance_nodes = [
            node for node in model_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE and node.tagName.lower() ==
            "instance" and not node.hasAttribute("id")
        ]
        self.assertEqual(len(instance_nodes), 1)
        instance_node = instance_nodes[0]

        # get the first element whose id attribute is equal to our form's
        # id_string
        form_nodes = [
            node for node in instance_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE
            and node.getAttribute("id") == xform.id_string
        ]
        form_node = form_nodes[0]

        # find the formhub node that has a uuid child node
        formhub_nodes = form_node.getElementsByTagName("formhub")
        self.assertEqual(len(formhub_nodes), 1)
        uuid_nodes = formhub_nodes[0].getElementsByTagName("uuid")
        self.assertEqual(len(uuid_nodes), 1)

        # check for the calculate bind
        calculate_bind_nodes = [
            node for node in model_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE and node.tagName == "bind"
            and node.getAttribute("nodeset") == "/%s/formhub/uuid" %
            xform.id_string
        ]
        self.assertEqual(len(calculate_bind_nodes), 1)
        calculate_bind_node = calculate_bind_nodes[0]
        self.assertEqual(calculate_bind_node.getAttribute("calculate"),
                         "'%s'" % xform.uuid)
    def test_edited_submission(self):
        """
        Test submissions that have been edited
        """
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml")
        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'username': self.user.username,
            'id_string': self.xform.id_string,
            'query': '{}',
            'fields': '[]',
            'sort': '[]',
            'count': True
        }

        cursor = ParsedInstance.query_mongo(**query_args)
        num_mongo_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # no new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history)
        # check count of mongo instances after first submission
        cursor = ParsedInstance.query_mongo(**query_args)
        self.assertEqual(cursor[0]['count'], num_mongo_instances + 1)
        # edited submission
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml")
        client = DigestClient()
        client.set_authorization('bob', 'bob', 'Digest')
        self._make_submission(xml_submission_file_path, client=client)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history + 1)
        cursor = ParsedInstance.query_mongo(**query_args)
        self.assertEqual(cursor[0]['count'], num_mongo_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = ParsedInstance.query_mongo(**query_args)
        record = cursor[0]
        with open(xml_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(r"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
 def download_instances(self, form_id, cursor=0, num_entries=100):
     response = requests.get(
         self.submission_list_url,
         auth=self.auth,
         params={"formId": form_id, "numEntries": num_entries, "cursor": cursor},
     )
     self.logger.debug("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor))
     try:
         xml_doc = clean_and_parse_xml(response.content)
     except ExpatError:
         return
     instances = self.get_instances_uuids(xml_doc)
     path = os.path.join(self.forms_path, form_id, "instances")
     for uuid in instances:
         self.logger.debug("Fetching %s %s submission" % (uuid, form_id))
         form_str = u"%(formId)s[@version=null and @uiVersion=null]/" u"%(formId)s[@key=%(instanceId)s]" % {
             "formId": form_id,
             "instanceId": uuid,
         }
         instance_path = os.path.join(path, uuid.replace(":", ""), "submission.xml")
         if not default_storage.exists(instance_path):
             instance_res = requests.get(self.download_submission_url, auth=self.auth, params={"formId": form_str})
             content = instance_res.content.strip()
             default_storage.save(instance_path, ContentFile(content))
         else:
             instance_res = default_storage.open(instance_path)
             content = instance_res.read()
         try:
             instance_doc = clean_and_parse_xml(content)
         except ExpatError:
             continue
         media_path = os.path.join(path, uuid.replace(":", ""))
         self.download_media_files(instance_doc, media_path)
         self.logger.debug("Fetched %s %s submission" % (form_id, uuid))
     if xml_doc.getElementsByTagName("resumptionCursor"):
         rs_node = xml_doc.getElementsByTagName("resumptionCursor")[0]
         cursor = rs_node.childNodes[0].nodeValue
         if self.resumption_cursor != cursor:
             self.resumption_cursor = cursor
             self.download_instances(form_id, cursor)
Example #15
0
 def test_xml_repeated_nodes_to_dict(self):
     xml_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             "../fixtures/repeated_nodes.xml")
     json_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_nodes_expected_results.json")
     with open(xml_file) as file:
         xml_dict = _xml_node_to_dict(clean_and_parse_xml(file.read()))
         self.assertTrue(xml_dict['#document']['RW_OUNIS_2016']['S2A'])
         self.assertEqual(
             3, len(xml_dict['#document']['RW_OUNIS_2016']['S2A']))
         with open(json_file) as file:
             self.assertEqual(json.loads(file.read()), xml_dict)
Example #16
0
    def _get_form_list(self, xml_text):
        xml_doc = clean_and_parse_xml(xml_text)
        forms = []

        for childNode in xml_doc.childNodes:
            if childNode.nodeName == 'xforms':
                for xformNode in childNode.childNodes:
                    if xformNode.nodeName == 'xform':
                        id_string = node_value(xformNode, 'formID')
                        download_url = node_value(xformNode, 'downloadUrl')
                        manifest_url = node_value(xformNode, 'manifestUrl')
                        forms.append((id_string, download_url, manifest_url))

        return forms
Example #17
0
    def download_manifest(self, manifest_url, id_string):
        if self._get_response(manifest_url):
            manifest_res = self._current_response

            try:
                manifest_doc = clean_and_parse_xml(manifest_res.content)
            except ExpatError:
                return

            manifest_path = os.path.join(
                self.forms_path, id_string, 'form-media')
            self.logger.debug("Downloading media files for %s" % id_string)

            self.download_media_files(manifest_doc, manifest_path)
Example #18
0
    def _get_form_list(self, xml_text):
        xml_doc = clean_and_parse_xml(xml_text)
        forms = []

        for childNode in xml_doc.childNodes:
            if childNode.nodeName == 'xforms':
                for xformNode in childNode.childNodes:
                    if xformNode.nodeName == 'xform':
                        id_string = node_value(xformNode, 'formID')
                        download_url = node_value(xformNode, 'downloadUrl')
                        manifest_url = node_value(xformNode, 'manifestUrl')
                        forms.append((id_string, download_url, manifest_url))

        return forms
Example #19
0
    def download_manifest(self, manifest_url, id_string):
        if self._get_response(manifest_url):
            manifest_res = self._current_response

            try:
                manifest_doc = clean_and_parse_xml(manifest_res.content)
            except ExpatError:
                return

            manifest_path = os.path.join(
                self.forms_path, id_string, 'form-media')
            self.logger.debug("Downloading media files for %s" % id_string)

            self.download_media_files(manifest_doc, manifest_path)
Example #20
0
    def test_uuid_injection_in_cascading_select(self):
        """Test that the uuid is injected in the right instance node for
        forms with a cascading select"""
        pre_count = XForm.objects.count()
        xls_path = os.path.join(
            self.this_directory, "fixtures", "cascading_selects",
            "new_cascading_select.xls")
        file_name, file_ext = os.path.splitext(os.path.split(xls_path)[1])
        self.response = TestBase._publish_xls_file(self, xls_path)
        post_count = XForm.objects.count()
        self.assertEqual(post_count, pre_count + 1)
        xform = XForm.objects.latest('date_created')

        # check that the uuid is within the main instance/
        # the one without an id attribute
        xml = clean_and_parse_xml(xform.xml)

        # check for instance nodes that are direct children of the model node
        model_node = xml.getElementsByTagName("model")[0]
        instance_nodes = [node for node in model_node.childNodes if
                          node.nodeType == Node.ELEMENT_NODE and
                          node.tagName.lower() == "instance" and
                          not node.hasAttribute("id")]
        self.assertEqual(len(instance_nodes), 1)
        instance_node = instance_nodes[0]

        # get the first element whose id attribute is equal to our form's
        # id_string
        form_nodes = [node for node in instance_node.childNodes if
                      node.nodeType == Node.ELEMENT_NODE and
                      node.getAttribute("id") == xform.id_string]
        form_node = form_nodes[0]

        # find the formhub node that has a uuid child node
        formhub_nodes = form_node.getElementsByTagName("formhub")
        self.assertEqual(len(formhub_nodes), 1)
        uuid_nodes = formhub_nodes[0].getElementsByTagName("uuid")
        self.assertEqual(len(uuid_nodes), 1)

        # check for the calculate bind
        calculate_bind_nodes = [node for node in model_node.childNodes if
                                node.nodeType == Node.ELEMENT_NODE and
                                node.tagName == "bind" and
                                node.getAttribute("nodeset") ==
                                "/%s/formhub/uuid" % file_name]
        self.assertEqual(len(calculate_bind_nodes), 1)
        calculate_bind_node = calculate_bind_nodes[0]
        self.assertEqual(
            calculate_bind_node.getAttribute("calculate"), "'%s'" % xform.uuid)
Example #21
0
def is_exist_farmer_paravet_ait(xml, request, username, user):
    flag = 0
    FormXMLTree = clean_and_parse_xml(xml)
    collection = FormXMLTree.documentElement
    if collection.hasAttribute("id"):
        form_id = collection.getAttribute("id")
        print form_id
    if form_id == "farmer_registration":
        mobile = collection.getElementsByTagName(
            "mobile")[0].__dict__['childNodes'][0].data
        if views_api.check_duplicate_farmer(mobile) == 0:
            flag = 0
        else:
            flag = 1
    return flag
Example #22
0
 def test_xml_repeated_group_to_dict(self):
     xml_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_group/repeated_group.xml")
     json_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_group/repeated_group.json")
     with open(xml_file) as file:
         dict_ = _xml_node_to_dict(clean_and_parse_xml(file.read()))
         self.assertTrue(dict_['#document']['form']['question_group'])
         self.assertEqual(2,
                          len(dict_['#document']['form']['question_group']))
         with open(json_file) as jfile:
             import json
             self.assertEqual(jfile.read(), json.dumps(dict_))
Example #23
0
 def test_xml_repeated_nodes_to_dict(self):
     xml_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_nodes.xml"
     )
     json_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_nodes_expected_results.json"
     )
     with open(xml_file) as file:
         xml_dict = _xml_node_to_dict(clean_and_parse_xml(file.read()))
         self.assertTrue(xml_dict['#document']['RW_OUNIS_2016']['S2A'])
         self.assertEqual(3, len(
             xml_dict['#document']['RW_OUNIS_2016']['S2A']))
         with open(json_file) as file:
             self.assertEqual(json.loads(file.read()), xml_dict)
Example #24
0
 def test_xml_repeated_group_to_dict(self):
     xml_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_group/repeated_group.xml"
     )
     json_file = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "../fixtures/repeated_group/repeated_group.json"
     )
     with open(xml_file) as file:
         dict_ = _xml_node_to_dict(clean_and_parse_xml(file.read()))
         self.assertTrue(dict_['#document']['form']['question_group'])
         self.assertEqual(2, len(dict_['#document']['form']['question_group']))
         with open(json_file) as jfile:
             import json
             self.assertEqual(jfile.read(), json.dumps(dict_))
 def _upload_instance(self, xml_file, instance_dir_path, files):
     xml_doc = clean_and_parse_xml(xml_file.read())
     xml = StringIO()
     de_node = xml_doc.documentElement
     for node in de_node.firstChild.childNodes:
         xml.write(node.toxml())
     new_xml_file = ContentFile(xml.getvalue())
     new_xml_file.content_type = "text/xml"
     xml.close()
     attachments = []
     for attach in de_node.getElementsByTagName("mediaFile"):
         filename_node = attach.getElementsByTagName("filename")
         filename = filename_node[0].childNodes[0].nodeValue
         if filename in files:
             file_obj = default_storage.open(os.path.join(instance_dir_path, filename))
             mimetype, encoding = mimetypes.guess_type(file_obj.name)
             media_obj = django_file(file_obj, "media_files[]", mimetype)
             attachments.append(media_obj)
     create_instance(self.user.username, new_xml_file, attachments)
Example #26
0
def send_push_noti_after_profile_update(xml):
    FormXMLTree = clean_and_parse_xml(xml)
    collection = FormXMLTree.documentElement
    if collection.hasAttribute("id"):
        form_id = collection.getAttribute("id")
        print form_id
    if form_id == "farmer_profile_update":
        mobile = collection.getElementsByTagName(
            "mobile")[0].__dict__['childNodes'][0].data
        views.send_push_message(mobile, 5, 'Profile update',
                                'Your profile has been updated as Farmer', '',
                                mobile, '')
    if form_id == "paravet_at_tech_profile_update":
        mobile = collection.getElementsByTagName(
            "mobile")[0].__dict__['childNodes'][0].data
        views.send_push_message(mobile, 5, 'Profile update',
                                'Your profile has been updated as AI/Paravet',
                                '', mobile, '')
    print 'push notificatiob ended*************************************'
Example #27
0
def get_id_string_from_xml_str(xml_str):
    xml_obj = clean_and_parse_xml(xml_str)
    root_node = xml_obj.documentElement
    id_string = root_node.getAttribute(u"id")

    if len(id_string) == 0:
        # may be hidden in submission/data/id_string
        elems = root_node.getElementsByTagName('data')

        for data in elems:
            for child in data.childNodes:
                id_string = data.childNodes[0].getAttribute('id')

                if len(id_string) > 0:
                    break

            if len(id_string) > 0:
                break

    return id_string
Example #28
0
 def _upload_instance(self, xml_file, instance_dir_path, files):
     xml_doc = clean_and_parse_xml(xml_file.read())
     xml = StringIO()
     de_node = xml_doc.documentElement
     for node in de_node.firstChild.childNodes:
         xml.write(node.toxml())
     new_xml_file = ContentFile(xml.getvalue())
     new_xml_file.content_type = 'text/xml'
     xml.close()
     attachments = []
     for attach in de_node.getElementsByTagName('mediaFile'):
         filename_node = attach.getElementsByTagName('filename')
         filename = filename_node[0].childNodes[0].nodeValue
         if filename in files:
             file_obj = default_storage.open(
                 os.path.join(instance_dir_path, filename))
             mimetype, encoding = mimetypes.guess_type(file_obj.name)
             media_obj = django_file(file_obj, 'media_files[]', mimetype)
             attachments.append(media_obj)
     create_instance(self.user.username, new_xml_file, attachments)
Example #29
0
def get_id_string_from_xml_str(xml_str):
    xml_obj = clean_and_parse_xml(xml_str)
    root_node = xml_obj.documentElement
    id_string = root_node.getAttribute(u"id")

    if len(id_string) == 0:
        # may be hidden in submission/data/id_string
        elems = root_node.getElementsByTagName('data')

        for data in elems:
            for child in data.childNodes:
                id_string = data.childNodes[0].getAttribute('id')

                if len(id_string) > 0:
                    break

            if len(id_string) > 0:
                break

    return id_string
Example #30
0
    def retrieve(self, request, *args, **kwargs):
        self.object = self.get_object()

        xml_obj = clean_and_parse_xml(self.object.xml)
        submission_xml_root_node = xml_obj.documentElement
        submission_xml_root_node.setAttribute('instanceID',
                                              u'uuid:%s' % self.object.uuid)
        submission_xml_root_node.setAttribute(
            'submissionDate', self.object.date_created.isoformat())
        data = {
            'submission_data':
            submission_xml_root_node.toxml(),
            'media_files':
            Attachment.objects.filter(instance=self.object),
            'host':
            request.build_absolute_uri().replace(request.get_full_path(), '')
        }

        return Response(data,
                        headers=get_openrosa_headers(request, location=False),
                        template_name='downloadSubmission.xml')
Example #31
0
    def test_edited_submission_require_auth(self):
        """
        Test submissions that have been edited
        """
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml")
        # require authentication
        self.user.profile.require_auth = True
        self.user.profile.save()

        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'xform': self.xform,
            'query': '{}',
            'fields': '[]',
            'count': True
        }
        cursor = ParsedInstance.query_data(**query_args)
        num_data_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)

        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # no new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history)
        # check count of mongo instances after first submission
        cursor = ParsedInstance.query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)

        # create a new user
        alice = self._create_user('alice', 'alice')
        UserProfile.objects.create(user=alice)
        auth = DigestAuth('alice', 'alice')

        # edited submission
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml")
        self._make_submission(xml_submission_file_path, auth=auth)
        self.assertEqual(self.response.status_code, 403)

        # assign report perms to user
        assign_perm('report_xform', alice, self.xform)
        assign_perm('logger.change_xform', alice, self.xform)

        self._make_submission(xml_submission_file_path, auth=auth)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history + 1)
        cursor = ParsedInstance.query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = ParsedInstance.query_data(**query_args)
        record = cursor[0]
        with open(xml_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
Example #32
0
    def test_edited_submission(self):
        """
        Test submissions that have been edited
        """

        # Delete all previous instance history objects
        InstanceHistory.objects.all().delete()

        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml")
        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'xform': self.xform,
            'query': '{}',
            'fields': '[]',
            'count': True
        }

        cursor = [r for r in query_data(**query_args)]
        num_data_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)

        # Take initial instance from DB
        initial_instance = self.xform.instances.first()

        # check that '_last_edited' key is not in the json
        self.assertIsNone(initial_instance.json.get(LAST_EDITED))

        # no new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history)
        # check count of mongo instances after first submission
        cursor = query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # edited submission
        xml_edit_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml")
        client = DigestClient()
        client.set_authorization('bob', 'bob', 'Digest')
        with catch_signal(process_submission) as handler:
            self._make_submission(xml_edit_submission_file_path, client=client)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history + 1)

        instance_history_1 = InstanceHistory.objects.first()
        edited_instance = self.xform.instances.first()

        self.assertDictEqual(initial_instance.get_dict(),
                             instance_history_1.get_dict())
        handler.assert_called_once_with(instance=edited_instance,
                                        sender=Instance,
                                        signal=ANY)

        self.assertNotEqual(edited_instance.uuid, instance_history_1.uuid)

        # check that instance history's submission_date is equal to instance's
        # date_created - last_edited by default is null for an instance
        self.assertEquals(edited_instance.date_created,
                          instance_history_1.submission_date)
        # check that '_last_edited' key is not in the json
        self.assertIn(LAST_EDITED, edited_instance.json)

        cursor = query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = query_data(**query_args)
        record = cursor[0]
        with open(xml_edit_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
        instance_before_second_edit = edited_instance
        xml_edit_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "..", "fixtures",
            "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited_again.xml")
        self._make_submission(xml_edit_submission_file_path)
        cursor = query_data(**query_args)
        record = cursor[0]
        edited_instance = self.xform.instances.first()
        instance_history_2 = InstanceHistory.objects.last()
        self.assertEquals(instance_before_second_edit.last_edited,
                          instance_history_2.submission_date)
        # check that '_last_edited' key is not in the json
        self.assertIn(LAST_EDITED, edited_instance.json)
        self.assertEqual(record['name'], 'Tom and Jerry')
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history + 2)
        # submitting original submission is treated as a duplicate
        # does not add a new record
        # does not change data
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 202)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        self.assertEqual(InstanceHistory.objects.count(),
                         num_instances_history + 2)
Example #33
0
def get_id_string_from_xml_str(xml_str):
    xml_obj = clean_and_parse_xml(xml_str)
    root_node = xml_obj.documentElement

    return root_node.getAttribute(u"id")
Example #34
0
    def _set_uuid_in_xml(self, file_name=None):
        """
        Add bind to automatically set UUID node in XML.
        """
        if not file_name:
            file_name = self.file_name()
        file_name, file_ext = os.path.splitext(file_name)

        doc = clean_and_parse_xml(self.xml)
        model_nodes = doc.getElementsByTagName("model")
        if len(model_nodes) != 1:
            raise Exception(u"xml contains multiple model nodes")

        model_node = model_nodes[0]
        instance_nodes = [node for node in model_node.childNodes if
                          node.nodeType == Node.ELEMENT_NODE and
                          node.tagName.lower() == "instance" and
                          not node.hasAttribute("id")]

        if len(instance_nodes) != 1:
            raise Exception(u"Multiple instance nodes without the id "
                            u"attribute, can't tell which is the main one")

        instance_node = instance_nodes[0]

        # get the first child whose id attribute matches our id_string
        survey_nodes = [node for node in instance_node.childNodes
                        if node.nodeType == Node.ELEMENT_NODE and
                        (node.tagName == file_name or
                         node.attributes.get('id'))]

        if len(survey_nodes) != 1:
            raise Exception(
                u"Multiple survey nodes with the id '%s'" % self.id_string)

        survey_node = survey_nodes[0]
        formhub_nodes = [n for n in survey_node.childNodes
                         if n.nodeType == Node.ELEMENT_NODE and
                         n.tagName == "formhub"]

        if len(formhub_nodes) > 1:
            raise Exception(
                u"Multiple formhub nodes within main instance node")
        elif len(formhub_nodes) == 1:
            formhub_node = formhub_nodes[0]
        else:
            formhub_node = survey_node.insertBefore(
                doc.createElement("formhub"), survey_node.firstChild)

        uuid_nodes = [node for node in formhub_node.childNodes if
                      node.nodeType == Node.ELEMENT_NODE and
                      node.tagName == "uuid"]

        if len(uuid_nodes) == 0:
            formhub_node.appendChild(doc.createElement("uuid"))
        if len(formhub_nodes) == 0:
            # append the calculate bind node
            calculate_node = doc.createElement("bind")
            calculate_node.setAttribute(
                "nodeset", "/%s/formhub/uuid" % file_name)
            calculate_node.setAttribute("type", "string")
            calculate_node.setAttribute("calculate", "'%s'" % self.uuid)
            model_node.appendChild(calculate_node)

        self.xml = doc.toprettyxml(indent="  ", encoding='utf-8')
        # hack
        # http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-\
        # and-silly-whitespace/
        text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
        output_re = re.compile('\n.*(<output.*>)\n(  )*')
        prettyXml = text_re.sub('>\g<1></', self.xml)
        inlineOutput = output_re.sub('\g<1>', prettyXml)
        inlineOutput = re.compile('<label>\s*\n*\s*\n*\s*</label>').sub(
            '<label></label>', inlineOutput)
        self.xml = inlineOutput
    def test_edited_submission_require_auth(self):
        """
        Test submissions that have been edited
        """
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid.xml"
        )
        # require authentication
        self.user.profile.require_auth = True
        self.user.profile.save()

        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'xform': self.xform,
            'query': '{}',
            'fields': '[]',
            'count': True
        }
        cursor = ParsedInstance.query_data(**query_args)
        num_data_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)

        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # no new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history)
        # check count of mongo instances after first submission
        cursor = ParsedInstance.query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)

        # create a new user
        alice = self._create_user('alice', 'alice')
        UserProfile.objects.create(user=alice)
        auth = DigestAuth('alice', 'alice')

        # edited submission
        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml"
        )
        self._make_submission(xml_submission_file_path, auth=auth)
        self.assertEqual(self.response.status_code, 403)

        # assign report perms to user
        assign_perm('report_xform', alice, self.xform)
        assign_perm('logger.change_xform', alice, self.xform)

        self._make_submission(xml_submission_file_path, auth=auth)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history + 1)
        cursor = ParsedInstance.query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = ParsedInstance.query_data(**query_args)
        record = cursor[0]
        with open(xml_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
Example #36
0
    def test_edited_submission(self):
        """
        Test submissions that have been edited
        """

        # Delete all previous instance history objects
        InstanceHistory.objects.all().delete()

        xml_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid.xml"
        )
        num_instances_history = InstanceHistory.objects.count()
        num_instances = Instance.objects.count()
        query_args = {
            'xform': self.xform,
            'query': '{}',
            'fields': '[]',
            'count': True
        }

        cursor = [r for r in query_data(**query_args)]
        num_data_instances = cursor[0]['count']
        # make first submission
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 201)
        self.assertEqual(Instance.objects.count(), num_instances + 1)

        # Take initial instance from DB
        initial_instance = self.xform.instances.first()

        # check that '_last_edited' key is not in the json
        self.assertIsNone(initial_instance.json.get(LAST_EDITED))

        # no new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history)
        # check count of mongo instances after first submission
        cursor = query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # edited submission
        xml_edit_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml"
        )
        client = DigestClient()
        client.set_authorization('bob', 'bob', 'Digest')
        with catch_signal(process_submission) as handler:
            self._make_submission(xml_edit_submission_file_path, client=client)
        self.assertEqual(self.response.status_code, 201)
        # we must have the same number of instances
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        # should be a new record in instances history
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history + 1)

        instance_history_1 = InstanceHistory.objects.first()
        edited_instance = self.xform.instances.first()

        self.assertDictEqual(initial_instance.get_dict(),
                             instance_history_1.get_dict())
        handler.assert_called_once_with(instance=edited_instance,
                                        sender=Instance, signal=ANY)

        self.assertNotEqual(edited_instance.uuid, instance_history_1.uuid)

        # check that instance history's submission_date is equal to instance's
        # date_created - last_edited by default is null for an instance
        self.assertEquals(edited_instance.date_created,
                          instance_history_1.submission_date)
        # check that '_last_edited' key is not in the json
        self.assertIn(LAST_EDITED, edited_instance.json)

        cursor = query_data(**query_args)
        self.assertEqual(cursor[0]['count'], num_data_instances + 1)
        # make sure we edited the mongo db record and NOT added a new row
        query_args['count'] = False
        cursor = query_data(**query_args)
        record = cursor[0]
        with open(xml_edit_submission_file_path, "r") as f:
            xml_str = f.read()
        xml_str = clean_and_parse_xml(xml_str).toxml()
        edited_name = re.match(r"^.+?<name>(.+?)</name>", xml_str).groups()[0]
        self.assertEqual(record['name'], edited_name)
        instance_before_second_edit = edited_instance
        xml_edit_submission_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "..", "fixtures", "tutorial", "instances",
            "tutorial_2012-06-27_11-27-53_w_uuid_edited_again.xml"
        )
        self._make_submission(xml_edit_submission_file_path)
        cursor = query_data(**query_args)
        record = cursor[0]
        edited_instance = self.xform.instances.first()
        instance_history_2 = InstanceHistory.objects.last()
        self.assertEquals(instance_before_second_edit.last_edited,
                          instance_history_2.submission_date)
        # check that '_last_edited' key is not in the json
        self.assertIn(LAST_EDITED, edited_instance.json)
        self.assertEqual(record['name'], 'Tom and Jerry')
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history + 2)
        # submitting original submission is treated as a duplicate
        # does not add a new record
        # does not change data
        self._make_submission(xml_submission_file_path)
        self.assertEqual(self.response.status_code, 202)
        self.assertEqual(Instance.objects.count(), num_instances + 1)
        self.assertEqual(
            InstanceHistory.objects.count(), num_instances_history + 2)
Example #37
0
    def _set_uuid_in_xml(self, file_name=None):
        """
        Add bind to automatically set UUID node in XML.
        """
        if not file_name:
            file_name = self.file_name()
        file_name, file_ext = os.path.splitext(file_name)

        doc = clean_and_parse_xml(self.xml)
        model_nodes = doc.getElementsByTagName("model")
        if len(model_nodes) != 1:
            raise Exception(u"xml contains multiple model nodes")

        model_node = model_nodes[0]
        instance_nodes = [
            node for node in model_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE and
            node.tagName.lower() == "instance" and not node.hasAttribute("id")
        ]

        if len(instance_nodes) != 1:
            raise Exception(u"Multiple instance nodes without the id "
                            u"attribute, can't tell which is the main one")

        instance_node = instance_nodes[0]

        # get the first child whose id attribute matches our id_string
        survey_nodes = [
            node for node in instance_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE and
            (node.tagName == file_name or node.attributes.get('id'))
        ]

        if len(survey_nodes) != 1:
            raise Exception(
                u"Multiple survey nodes with the id '%s'" % self.id_string)

        survey_node = survey_nodes[0]
        formhub_nodes = [
            n for n in survey_node.childNodes
            if n.nodeType == Node.ELEMENT_NODE and n.tagName == "formhub"
        ]

        if len(formhub_nodes) > 1:
            raise Exception(
                u"Multiple formhub nodes within main instance node")
        elif len(formhub_nodes) == 1:
            formhub_node = formhub_nodes[0]
        else:
            formhub_node = survey_node.insertBefore(
                doc.createElement("formhub"), survey_node.firstChild)

        uuid_nodes = [
            node for node in formhub_node.childNodes
            if node.nodeType == Node.ELEMENT_NODE and node.tagName == "uuid"
        ]

        if len(uuid_nodes) == 0:
            formhub_node.appendChild(doc.createElement("uuid"))
        if len(formhub_nodes) == 0:
            # append the calculate bind node
            calculate_node = doc.createElement("bind")
            calculate_node.setAttribute(
                "nodeset", "/%s/formhub/uuid" % survey_node.tagName)
            calculate_node.setAttribute("type", "string")
            calculate_node.setAttribute("calculate", "'%s'" % self.uuid)
            model_node.appendChild(calculate_node)

        self.xml = doc.toprettyxml(indent="  ", encoding='utf-8')
        # hack
        # http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-\
        # and-silly-whitespace/
        text_re = re.compile('(>)\n\s*(\s[^<>\s].*?)\n\s*(\s</)', re.DOTALL)
        output_re = re.compile('\n.*(<output.*>)\n(  )*')
        pretty_xml = text_re.sub(lambda m: ''.join(m.group(1, 2, 3)),
                                 self.xml.decode('utf-8'))
        inline_output = output_re.sub('\g<1>', pretty_xml)
        inline_output = re.compile('<label>\s*\n*\s*\n*\s*</label>').sub(
            '<label></label>', inline_output)
        self.xml = inline_output
Example #38
0
def get_id_string_from_xml_str(xml_str):
    xml_obj = clean_and_parse_xml(xml_str)
    root_node = xml_obj.documentElement

    return root_node.getAttribute(u"id")