Пример #1
0
 def test_xform_delete_cascades_mongo_instances(self):
     initial_mongo_count = ParsedInstance.query_mongo(
         self.user.username,
         self.xform.id_string,
         '{}',
         '[]',
         '{}',
         count=True)[0]["count"]
     # submit instance
     for i in range(len(self.surveys)):
         self._submit_transport_instance(i)
     # check mongo record exists
     mongo_count = ParsedInstance.query_mongo(self.user.username,
                                              self.xform.id_string,
                                              '{}',
                                              '[]',
                                              '{}',
                                              count=True)[0]["count"]
     self.assertEqual(mongo_count, initial_mongo_count + len(self.surveys))
     # delete form
     xform_delete_url = reverse(delete_xform,
                                kwargs={
                                    'username': self.user.username,
                                    'id_string': self.xform.id_string
                                })
     self.client.post(xform_delete_url)
     mongo_count = ParsedInstance.query_mongo(self.user.username,
                                              self.xform.id_string,
                                              '{}',
                                              '[]',
                                              '{}',
                                              count=True)[0]["count"]
     self.assertEqual(mongo_count, initial_mongo_count)
Пример #2
0
 def test_deleted_submission_not_in_export(self):
     self._publish_transportation_form()
     initial_count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     self._submit_transport_instance(0)
     self._submit_transport_instance(1)
     count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     self.assertEqual(count, initial_count+2)
     # get id of second submission
     instance_id = Instance.objects.filter(
         xform=self.xform).order_by('id').reverse()[0].id
     delete_url = reverse(
         delete_data, kwargs={"username": self.user.username,
                              "id_string": self.xform.id_string})
     params = {'id': instance_id}
     self.client.post(delete_url, params)
     count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     self.assertEqual(count, initial_count + 1)
     # create the export
     csv_export_url = reverse(
         'csv_export', kwargs={"username": self.user.username,
                             "id_string":self.xform.id_string})
     response = self.client.get(csv_export_url)
     self.assertEqual(response.status_code, 200)
     f = StringIO.StringIO(response.content)
     csv_reader = csv.reader(f)
     num_rows = len([row for row in csv_reader])
     f.close()
     # number of rows == 2 i.e. initial_count + header plus one row
     self.assertEqual(num_rows, initial_count + 2)
Пример #3
0
def api(request, username=None, id_string=None):
    '''
    Returns all results as JSON.  If a parameter string is passed,
    it takes the 'query' parameter, converts this string to a dictionary, an
    that is then used as a MongoDB query string.

    NOTE: only a specific set of operators are allow, currently $or and $and.
    Please send a request if you'd like another operator to be enabled.

    NOTE: Your query must be valid JSON, double check it here,
    http://json.parser.online.fr/

    E.g. api?query='{"last_name": "Smith"}'
    '''
    xform, owner = check_and_set_user_and_form(username, id_string, request)
    if not xform:
        return HttpResponseForbidden('Not shared.')
    try:
        args = {"username": username, "id_string": id_string, "query": request.GET.get('query'),
                "fields": request.GET.get('fields'), "sort": request.GET.get('sort')}
        if 'start' in request.GET:
            args["start"] = int(request.GET.get('start'))
        if 'limit' in request.GET:
            args["limit"] = int(request.GET.get('limit'))
        if 'count' in request.GET:
            args["count"] = True if int(request.GET.get('count')) > 0 else False
        cursor = ParsedInstance.query_mongo(**args)
    except ValueError, e:
        return HttpResponseBadRequest(e.message)
Пример #4
0
def delete_data(request, username=None, id_string=None):
    xform, owner = check_and_set_user_and_form(username, id_string, request)
    if not xform:
        return HttpResponseForbidden(_(u'Not shared.'))
    try:
        args = {"username": username, "id_string": id_string,
                "query": request.GET.get('query'),
                "fields": request.GET.get('fields'),
                "sort": request.GET.get('sort')}

        if 'limit' in request.GET:
            args["limit"] = int(request.GET.get('limit'))
        cursor = ParsedInstance.query_mongo(**args)
    except ValueError as e:
        return HttpResponseBadRequest(e)

    today = datetime.today().strftime('%Y-%m-%dT%H:%M:%S')
    ParsedInstance.edit_mongo(
        args['query'], '{ "$set": {"_deleted_at": "%s" }}' % today)

    records = list(record for record in cursor)
    response_text = simplejson.dumps(records)
    if 'callback' in request.GET and request.GET.get('callback') != '':
        callback = request.GET.get('callback')
        response_text = ("%s(%s)" % (callback, response_text))
    return HttpResponse(response_text, mimetype='application/json')
Пример #5
0
def api(request, username=None, id_string=None):
    """
    Returns all results as JSON.  If a parameter string is passed,
    it takes the 'query' parameter, converts this string to a dictionary, an
    that is then used as a MongoDB query string.

    NOTE: only a specific set of operators are allow, currently $or and $and.
    Please send a request if you'd like another operator to be enabled.

    NOTE: Your query must be valid JSON, double check it here,
    http://json.parser.online.fr/

    E.g. api?query='{"last_name": "Smith"}'
    """
    xform, owner = check_and_set_user_and_form(username, id_string, request)
    if not xform:
        return HttpResponseForbidden("Not shared.")
    try:
        args = {
            "username": username,
            "id_string": id_string,
            "query": request.GET.get("query"),
            "fields": request.GET.get("fields"),
            "sort": request.GET.get("sort"),
        }
        if "start" in request.GET:
            args["start"] = int(request.GET.get("start"))
        if "limit" in request.GET:
            args["limit"] = int(request.GET.get("limit"))
        if "count" in request.GET:
            args["count"] = True if int(request.GET.get("count")) > 0 else False
        cursor = ParsedInstance.query_mongo(**args)
    except ValueError, e:
        return HttpResponseBadRequest(e.message)
Пример #6
0
 def test_edited_submissions_in_exports(self):
     self._publish_transportation_form()
     initial_count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     instance_name = 'transport_2011-07-25_19-05-36'
     path = os.path.join(
         'main', 'tests', 'fixtures', 'transportation', 'instances_w_uuid',
         instance_name, instance_name + '.xml')
     self._make_submission(path)
     count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     self.assertEqual(count, initial_count+1)
     instance = Instance.objects.filter(
         xform=self.xform).order_by('id').reverse()[0]
     # make edited submission - simulating what enketo would return
     instance_name = 'transport_2011-07-25_19-05-36-edited'
     path = os.path.join(
         'main', 'tests', 'fixtures', 'transportation', 'instances_w_uuid',
         instance_name, instance_name + '.xml')
     self._make_submission(path)
     count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]['count']
     self.assertEqual(count, initial_count+1)
     # create the export
     csv_export_url = reverse(
         'csv_export', kwargs={"username": self.user.username,
                             "id_string":self.xform.id_string})
     response = self.client.get(csv_export_url)
     self.assertEqual(response.status_code, 200)
     f = StringIO.StringIO(response.content)
     csv_reader = csv.DictReader(f)
     data = [row for row in csv_reader]
     f.close()
     num_rows = len(data)
     # number of rows == initial_count + 1
     self.assertEqual(num_rows, initial_count + 1)
     key ='transport/loop_over_transport_types_frequency/ambulance/frequency_to_referral_facility'
     self.assertEqual(data[initial_count][key], "monthly")
Пример #7
0
 def _get_form_data(self, xform, **kwargs):
     margs = {
         'username': xform.user.username,
         'id_string': xform.id_string,
         'query': kwargs.get('query', None),
         'fields': kwargs.get('fields', None),
         'sort': kwargs.get('sort', None)
     }
     # TODO: Possibly add "url" field to all data records
     cursor = ParsedInstance.query_mongo(**margs)
     records = list(record for record in cursor)
     return records
Пример #8
0
 def _get_form_data(self, xform, **kwargs):
     margs = {
         'username': xform.user.username,
         'id_string': xform.id_string,
         'query': kwargs.get('query', None),
         'fields': kwargs.get('fields', None),
         'sort': kwargs.get('sort', None)
     }
     # TODO: Possibly add "url" field to all data records
     cursor = ParsedInstance.query_mongo(**margs)
     records = list(record for record in cursor)
     return records
Пример #9
0
 def test_xform_delete_cascades_mongo_instances(self):
     initial_mongo_count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]["count"]
     # submit instance
     for i in range(len(self.surveys)):
         self._submit_transport_instance(i)
     # check mongo record exists
     mongo_count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]["count"]
     self.assertEqual(mongo_count, initial_mongo_count + len(self.surveys))
     # delete form
     xform_delete_url = reverse(delete_xform, kwargs={
         'username': self.user.username,
         'id_string': self.xform.id_string
     })
     self.client.post(xform_delete_url)
     mongo_count = ParsedInstance.query_mongo(
         self.user.username, self.xform.id_string, '{}', '[]', '{}',
         count=True)[0]["count"]
     self.assertEqual(mongo_count, initial_mongo_count)
Пример #10
0
def delete_data(request, username=None, id_string=None):
    query = request.POST.get('query', None)
    if query is None:
        return HttpResponseBadRequest(_(u"Invalid query parameter"))

    try:
        simplejson.loads(query)
    except ValueError:
        return HttpResponseBadRequest(_(u"Invalid query parameter"))

    xform, owner = check_and_set_user_and_form(username, id_string, request)
    response_text = u''
    if not xform:
        return HttpResponseForbidden(_(u'Not shared.'))
    try:
        query_args = {
            "username": username, "id_string": id_string,
            "query": query,
            "fields": request.POST.get('fields', None),
            "sort": request.POST.get('sort', None),
            "limit": 1
        }

        if 'limit' in request.GET:
            query_args["limit"] = int(request.GET.get('limit'))
        cursor = ParsedInstance.query_mongo(**query_args)
    except ValueError as e:
        return HttpResponseBadRequest(e)
    else:
        records = list(record for record in cursor)
        if records.__len__():
            for record in records:
                Instance.delete_by_uuid(
                    username, id_string, uuid=record['_uuid'])
                audit = {
                    'xform': xform.id_string
                }
                audit_log(Actions.SUBMISSION_DELETED, request.user, owner,
                    _("Deleted submission with id '%(record_id)s' on '%(id_string)s'.") %\
                    {
                        'id_string': xform.id_string,
                        'record_id': record['_id']
                    }, audit, request)
            response_text = simplejson.dumps(records)
    if 'callback' in request.GET and request.GET.get('callback') != '':
        callback = request.GET.get('callback')
        response_text = ("%s(%s)" % (callback, response_text))
    return HttpResponse(response_text, mimetype='application/json')
Пример #11
0
def api(request, username=None, id_string=None):
    """
    Returns all results as JSON.  If a parameter string is passed,
    it takes the 'query' parameter, converts this string to a dictionary, an
    that is then used as a MongoDB query string.

    NOTE: only a specific set of operators are allow, currently $or and $and.
    Please send a request if you'd like another operator to be enabled.

    NOTE: Your query must be valid JSON, double check it here,
    http://json.parser.online.fr/

    E.g. api?query='{"last_name": "Smith"}'
    """
    if request.method == "OPTIONS":
        response = HttpResponse()
        add_cors_headers(response)
        return response
    helper_auth_helper(request)
    helper_auth_helper(request)
    xform, owner = check_and_set_user_and_form(username, id_string, request)

    if not xform:
        return HttpResponseForbidden(_(u'Not shared.'))

    try:
        args = {
            'username': username,
            'id_string': id_string,
            'query': request.GET.get('query'),
            'fields': request.GET.get('fields'),
            'sort': request.GET.get('sort')
        }
        if 'start' in request.GET:
            args["start"] = int(request.GET.get('start'))
        if 'limit' in request.GET:
            args["limit"] = int(request.GET.get('limit'))
        if 'count' in request.GET:
            args["count"] = True if int(request.GET.get('count')) > 0\
                else False
        cursor = ParsedInstance.query_mongo(**args)
    except ValueError, e:
        return HttpResponseBadRequest(e.__str__())
Пример #12
0
def edit_data(request, username, id_string, data_id):
    owner = User.objects.get(username=username)
    xform = get_object_or_404(
        XForm, user__username=username, id_string=id_string)
    if not has_edit_permission(xform, owner, request, xform.shared):
        return HttpResponseForbidden(_(u'Not shared.'))
    if not hasattr(settings, 'ENKETO_URL'):
        return HttpResponseRedirect(
            reverse(
                'main.views.show', kwargs={'username': username,
                                           'id_string': id_string}
            )
        )
    try:
        query_args = {
            "username": username, "id_string": id_string,
            "query": '{"_id": %s}' % data_id,
            "fields": None,
            "sort": None,
            "limit": 1
        }

        if 'limit' in request.GET:
            query_args["limit"] = int(request.GET.get('limit'))
        cursor = ParsedInstance.query_mongo(**query_args)
    except ValueError as e:
        return HttpResponseBadRequest(e)
    else:
        records = list(record for record in cursor)
        if records.__len__():
            uuid = records[0]["_uuid"]
            instance = Instance.objects.get(xform=xform, uuid=uuid)

    url = '%sdata/edit_url' % settings.ENKETO_URL
    register_openers()
    response = None
    # see commit 220f2dad0e for tmp file creation
    try:
        formhub_url = "http://%s/" % request.META['HTTP_HOST']
    except:
        formhub_url = "http://formhub.org/"
    injected_xml = inject_instanceid(instance.xml, instance.uuid)
    values = {
        'format': 'json',
        'form_id': xform.id_string,
        'server_url': formhub_url + username,
        'instance': injected_xml,
        'instance_id': instance.uuid,
        'return_url': request.build_absolute_uri(
            reverse(
                'odk_viewer.views.instance',
                kwargs={
                    'username': username,
                    'id_string': id_string}
            ) + "#/" + str(instance.id))
    }
    data, headers = multipart_encode(values)
    headers['User-Agent'] = 'formhub'
    req = urllib2.Request(url, data, headers)
    try:
        response = urllib2.urlopen(req)
        response = json.loads(response.read())
        context = RequestContext(request)
        owner = User.objects.get(username=username)
        context.profile, created = \
            UserProfile.objects.get_or_create(user=owner)
        context.xform = xform
        context.content_user = owner
        context.form_view = True
        if 'edit_url' in response:
            audit = {
                "xform": xform.id_string,
                "data_id": data_id
            }
            audit_log(Actions.SUBMISSION_EDIT_REQUESTED, request.user, owner,
                _("Requested to edit data with id '%(data_id)s' on '%(id_string)s'.") %\
                {
                    'id_string': xform.id_string,
                    'data_id': data_id
                }, audit, request)
            context.enketo = response['edit_url']
            return HttpResponseRedirect(response['edit_url'])
        else:
            json_msg = response['reason']
            """
            return HttpResponse("<script>$('body')</script>")
            """
            context.message = {
                'type': 'alert-error',
                'text': "Enketo error, reason: " + (
                    response['reason'] and "Server not found.")
            }
            messages.add_message(request, messages.WARNING, json_msg)
            return render_to_response("profile.html", context_instance=context)

    except urllib2.URLError:
        # this will happen if we could not connect to enketo
        messages.add_message(
            request, messages.WARNING, _("Enketo error: Unable to open webform url."))
    except ValueError, e:
        messages.add_message(
            request, messages.WARNING, _("Enketo error: enketo replied %s") % e)