Ejemplo n.º 1
0
 def submit_at_hour(hour):
     st_xml = """
     <?xml version='1.0' ?><start_time id="start_time"><start_time>2012-01-11T%d:00:00.000+00</start_time></start_time>
     """.strip() % hour
     try:
         create_instance(self.user.username, TempFileProxy(st_xml), [])
     except DuplicateInstance:
         pass
Ejemplo n.º 2
0
 def submit_at_hour(hour):
     st_xml = """
     <?xml version='1.0' ?><start_time id="start_time"><start_time>2012-01-11T%d:00:00.000</start_time></start_time>
     """.strip() % hour
     try:
         create_instance(self.user.username, TempFileProxy(st_xml), [])
     except DuplicateInstance:
         pass
Ejemplo n.º 3
0
def restore_backup_from_path(dir_path, username, status):
    """
    Only restores xml submissions, media files are assumed to still be in
    storage and will be retrieved by the filename stored within the submission
    """
    num_instances = 0
    num_restored = 0
    for dir_path, dir_names, file_names in os.walk(dir_path):
        for file_name in file_names:
            # check if its a valid xml instance
            xml_instance_path = os.path.join(dir_path, file_name)
            num_instances += 1
            xml_file = django_file(xml_instance_path, field_name="xml_file", content_type="text/xml")
            media_files = []
            date_created = None
            try:
                date_created = _date_created_from_filename(file_name)
            except ValueError as e:
                sys.stderr.write("Couldn't determine date created from filename: '%s'\n" % file_name)
            else:
                sys.stdout.write("Creating instance from '%s'\n" % file_name)
                try:
                    instance = create_instance(username, xml_file, media_files, date_created_override=date_created)
                    num_restored += 1
                except Exception as e:
                    sys.stderr.write("Couldn't restote %s, create instance said: %s\n" % (file_name, e))
    return num_instances, num_restored
Ejemplo n.º 4
0
def generate_instance(username, xml_file, media_files, uuid=None):
    """ Process an XForm submission as if done via HTTP

        :param IO xml_file: file-like object containing XML XForm
        :param string username: username of the Form's owner
        :param list media_files: a list of UploadedFile objects
        :param string uuid: an optionnal uuid for the instance.

        :returns a (status, message) tuple. """

    try:
        instance = create_instance(username, xml_file, media_files, uuid=uuid)
    except InstanceInvalidUserError:
        return {"code": SMS_SUBMISSION_REFUSED, "text": _(u"Username or ID required.")}
    except IsNotCrowdformError:
        return {"code": SMS_SUBMISSION_REFUSED, "text": _(u"Sorry but the crowd form you " u"submitted to is closed.")}
    except InstanceEmptyError:
        return {"code": SMS_INTERNAL_ERROR, "text": _(u"Received empty submission. " u"No instance was created")}
    except FormInactiveError:
        return {"code": SMS_SUBMISSION_REFUSED, "text": _(u"Form is not active")}
    except XForm.DoesNotExist:
        return {"code": SMS_SUBMISSION_REFUSED, "text": _(u"Form does not exist on this account")}
    except ExpatError:
        return {"code": SMS_INTERNAL_ERROR, "text": _(u"Improperly formatted XML.")}
    except DuplicateInstance:
        return {"code": SMS_SUBMISSION_REFUSED, "text": _(u"Duplicate submission")}

    if instance is None:
        return {"code": SMS_INTERNAL_ERROR, "text": _(u"Unable to create submission.")}

    user = User.objects.get(username=username)

    audit = {"xform": instance.xform.id_string}
    audit_log(
        Actions.SUBMISSION_CREATED,
        user,
        instance.xform.user,
        _("Created submission on form %(id_string)s.") % {"id_string": instance.xform.id_string},
        audit,
        HttpRequest(),
    )

    xml_file.close()
    if len(media_files):
        [_file.close() for _file in media_files]

    return {
        "code": SMS_SUBMISSION_ACCEPTED,
        "text": _(u"[SUCCESS] Your submission has been accepted."),
        "id": get_sms_instance_id(instance),
    }
Ejemplo n.º 5
0
 def callback(xform_fs):
     """
     This callback is passed an instance of a XFormInstanceFS.
     See xform_fs.py for more info.
     """
     xml_file = django_file(xform_fs.path,
                            field_name="xml_file",
                            content_type="text/xml")
     images = [django_file(jpg, field_name="image",
                     content_type="image/jpeg") for jpg in xform_fs.photos]
     # TODO: if an instance has been submitted make sure all the
     # files are in the database.
     # there shouldn't be any instances with a submitted status in the
     instance = create_instance(user.username, xml_file, images, status)
     # close the files
     xml_file.close()
     for i in images: i.close()
     if instance:
         return 1
     else:
         return 0
Ejemplo n.º 6
0
def import_instance(path_to_instance_folder, status, user):
    xml_files = glob.glob( os.path.join(path_to_instance_folder, "*.xml") )
    if len(xml_files)<1: return
    if len(xml_files)>1: raise Exception(_("Too many XML files."))
    xml_file = django_file(xml_files[0],
                           field_name="xml_file",
                           content_type="text/xml")
    images = []
    for jpg in glob.glob(os.path.join(path_to_instance_folder, "*.jpg")):
        image_file = django_file(jpg,
                                 field_name="image",
                                 content_type="image/jpeg")
        images.append(image_file)
    # todo: if an instance has been submitted make sure all the
    # files are in the database.
    # there shouldn't be any instances with a submitted status in the
    instance = create_instance(user.username, xml_file, images, status)
    # close the files
    xml_file.close()
    for i in images: i.close()
    return instance
Ejemplo n.º 7
0
 def callback(xform_fs):
     """
     This callback is passed an instance of a XFormInstanceFS.
     See xform_fs.py for more info.
     """
     xml_file = django_file(xform_fs.path,
         field_name="xml_file",
         content_type="text/xml")
     images = [django_file(jpg, field_name="image",
         content_type="image/jpeg") for jpg in xform_fs.photos]
     # TODO: if an instance has been submitted make sure all the
     # files are in the database.
     # there shouldn't be any instances with a submitted status in the
     instance = create_instance(user.username, xml_file, images, status)
     # close the files
     xml_file.close()
     for i in images:
         i.close()
     if instance:
         return 1
     else:
         return 0
Ejemplo n.º 8
0
def import_instance(path_to_instance_folder, status, user):
    xml_files = glob.glob(os.path.join(path_to_instance_folder, "*.xml"))
    if len(xml_files) < 1: return
    if len(xml_files) > 1: raise Exception("Too many XML files.")
    xml_file = django_file(xml_files[0],
                           field_name="xml_file",
                           content_type="text/xml")
    images = []
    for jpg in glob.glob(os.path.join(path_to_instance_folder, "*.jpg")):
        image_file = django_file(jpg,
                                 field_name="image",
                                 content_type="image/jpeg")
        images.append(image_file)
    # todo: if an instance has been submitted make sure all the
    # files are in the database.
    # there shouldn't be any instances with a submitted status in the
    instance = create_instance(user.username, xml_file, images, status)
    # close the files
    xml_file.close()
    for i in images:
        i.close()
    return instance
Ejemplo n.º 9
0
def restore_backup_from_path(dir_path, username, status):
    """
    Only restores xml submissions, media files are assumed to still be in
    storage and will be retrieved by the filename stored within the submission
    """
    num_instances = 0
    num_restored = 0
    for dir_path, dir_names, file_names in os.walk(dir_path):
        for file_name in file_names:
            # check if its a valid xml instance
            xml_instance_path = os.path.join(dir_path, file_name)
            num_instances += 1
            xml_file = django_file(xml_instance_path,
                                   field_name="xml_file",
                                   content_type="text/xml")
            media_files = []
            date_created = None
            try:
                date_created = _date_created_from_filename(file_name)
            except ValueError as e:
                sys.stderr.write(
                    "Couldn't determine date created from filename: '%s'\n" %
                    file_name)
            else:
                sys.stdout.write("Creating instance from '%s'\n" % file_name)
                try:
                    instance = create_instance(
                        username,
                        xml_file,
                        media_files,
                        date_created_override=date_created)
                    num_restored += 1
                except Exception as e:
                    sys.stderr.write(
                        "Could not restore %s, create instance said: %s\n" %
                        (file_name, e))
    return num_instances, num_restored
Ejemplo n.º 10
0
def submission(request, username=None):
    if username and username.lower() != 'crowdforms':
        formlist_user = get_object_or_404(User, username=username.lower())
        profile, created = \
            UserProfile.objects.get_or_create(user=formlist_user)

        if profile.require_auth:
            authenticator = HttpDigestAuthenticator()
            if not authenticator.authenticate(request):
                return authenticator.build_challenge_response()
    if request.method == 'HEAD':
        response = OpenRosaResponse(status=204)
        if username:
            response['Location'] = request.build_absolute_uri().replace(
                request.get_full_path(), '/%s/submission' % username)
        else:
            response['Location'] = request.build_absolute_uri().replace(
                request.get_full_path(), '/submission')
        return response
    context = RequestContext(request)
    xml_file_list = []
    media_files = []
    html_response = False
    # request.FILES is a django.utils.datastructures.MultiValueDict
    # for each key we have a list of values
    try:
        xml_file_list = request.FILES.pop("xml_submission_file", [])
        if len(xml_file_list) != 1:
            return OpenRosaResponseBadRequest(
                _(u"There should be a single XML submission file."))
        # save this XML file and media files as attachments
        media_files = request.FILES.values()

        # get uuid from post request
        uuid = request.POST.get('uuid')
        # response as html if posting with a UUID
        if not username and uuid:
            html_response = True
        try:
            instance = create_instance(username,
                                       xml_file_list[0],
                                       media_files,
                                       uuid=uuid,
                                       request=request)
        except InstanceInvalidUserError:
            return OpenRosaResponseBadRequest(_(u"Username or ID required."))
        except IsNotCrowdformError:
            return OpenRosaResponseNotAllowed(
                _(u"Sorry but the crowd form you submitted to is closed."))
        except InstanceEmptyError:
            return OpenRosaResponseBadRequest(
                _(u"Received empty submission. No instance was created"))
        except FormInactiveError:
            return OpenRosaResponseNotAllowed(_(u"Form is not active"))
        except XForm.DoesNotExist:
            return OpenRosaResponseNotFound(
                _(u"Form does not exist on this account"))
        except ExpatError:
            return OpenRosaResponseBadRequest(_(u"Improperly formatted XML."))
        except DuplicateInstance:
            response = OpenRosaResponse(_(u"Duplicate submission"))
            response.status_code = 202
            response['Location'] = request.build_absolute_uri(request.path)
            return response
        except PermissionDenied, e:
            return OpenRosaResponseNotAllowed(e.message)
        except Exception, e:
            raise
Ejemplo n.º 11
0
def submission(request, username=None):
    context = RequestContext(request)
    xml_file_list = []
    media_files = []
    html_response = False
    # request.FILES is a django.utils.datastructures.MultiValueDict
    # for each key we have a list of values
    try:
        xml_file_list = request.FILES.pop("xml_submission_file", [])
        if len(xml_file_list) != 1:
            return HttpResponseBadRequest(
                _(u"There should be a single XML submission file.")
            )
        # save this XML file and media files as attachments
        media_files = request.FILES.values()

        # get uuid from post request
        uuid = request.POST.get('uuid')
        # response as html if posting with a UUID
        if not username and uuid:
            html_response = True
        try:
            instance = create_instance(
                username,
                xml_file_list[0],
                media_files,
                uuid=uuid
            )
        except InstanceInvalidUserError:
            return HttpResponseBadRequest(_(u"Username or ID required."))
        except IsNotCrowdformError:
            return HttpResponseNotAllowed(
                _(u"Sorry but the crowd form you submitted to is closed.")
            )
        except InstanceEmptyError:
            return HttpResponseBadRequest(
                _(u"Received empty submission. No instance was created")
            )
        except FormInactiveError:
            return HttpResponseNotAllowed(_(u"Form is not active"))
        except XForm.DoesNotExist:
            return HttpResponseNotFound(
                _(u"Form does not exist on this account")
            )
        except ExpatError:
            return HttpResponseBadRequest(_(u"Improperly formatted XML."))
        except DuplicateInstance:
            response = HttpResponse(_(u"Duplicate submission"))
            response.status_code = 202
            response['Location'] = request.build_absolute_uri(request.path)
            return response

        if instance is None:
            return HttpResponseBadRequest(_(u"Unable to create submission."))

        # ODK needs two things for a form to be considered successful
        # 1) the status code needs to be 201 (created)
        # 2) The location header needs to be set to the host it posted to
        if html_response:
            context.username = instance.user.username
            context.id_string = instance.xform.id_string
            context.domain = Site.objects.get(id=settings.SITE_ID).domain
            response = render_to_response("submission.html",
                                          context_instance=context)
        else:
            response = HttpResponse()
        response.status_code = 201
        response['Location'] = request.build_absolute_uri(request.path)
        return response
    except IOError as e:
        if 'request data read error' in unicode(e):
            return HttpResponseBadRequest(_(u"File transfer interruption."))
        else:
            raise
    finally:
        if len(xml_file_list):
            [_file.close() for _file in xml_file_list]
        if len(media_files):
            [_file.close() for _file in media_files]
Ejemplo n.º 12
0
     return HttpResponseBadRequest(
         "There should be a single XML submission file."
         )
 # save this XML file and media files as attachments
 media_files = request.FILES.values()
 if not username:
     uuid = request.POST.get('uuid')
     if not uuid:
         return HttpResponseBadRequest("Username or ID required.")
     show_options = True
     xform = XForm.objects.get(uuid=uuid)
     username = xform.user.username
 try:
     instance = create_instance(
             username,
             xml_file_list[0],
             media_files
             )
 except InstanceEmptyError:
     return HttpResponseBadRequest('Received empty submission. No instance was created')
 except FormInactiveError:
     return HttpResponseNotAllowed('Form is not active')
 except XForm.DoesNotExist:
     return HttpResponseNotFound('Form does not exist on this account')
 if instance == None:
     return HttpResponseBadRequest("Unable to create submission.")
 # ODK needs two things for a form to be considered successful
 # 1) the status code needs to be 201 (created)
 # 2) The location header needs to be set to the host it posted to
 if show_options:
     context.username = instance.user.username
Ejemplo n.º 13
0
def submission(request, username=None):
    if username and username.lower() != 'crowdforms':
        formlist_user = get_object_or_404(User, username=username.lower())
        profile, created = \
            UserProfile.objects.get_or_create(user=formlist_user)

        if profile.require_auth:
            authenticator = HttpDigestAuthenticator()
            if not authenticator.authenticate(request):
                return authenticator.build_challenge_response()
    if request.method == 'HEAD':
        response = OpenRosaResponse(status=204)
        if username:
            response['Location'] = request.build_absolute_uri().replace(
                request.get_full_path(), '/%s/submission' % username)
        else:
            response['Location'] = request.build_absolute_uri().replace(
                request.get_full_path(), '/submission')
        return response
    context = RequestContext(request)
    xml_file_list = []
    media_files = []
    html_response = False
    # request.FILES is a django.utils.datastructures.MultiValueDict
    # for each key we have a list of values
    try:
        xml_file_list = request.FILES.pop("xml_submission_file", [])
        if len(xml_file_list) != 1:
            return OpenRosaResponseBadRequest(
                _(u"There should be a single XML submission file.")
            )
        # save this XML file and media files as attachments
        media_files = request.FILES.values()

        # get uuid from post request
        uuid = request.POST.get('uuid')
        # response as html if posting with a UUID
        if not username and uuid:
            html_response = True
        try:
            instance = create_instance(
                username, xml_file_list[0], media_files,
                uuid=uuid, request=request
            )
        except InstanceInvalidUserError:
            return OpenRosaResponseBadRequest(_(u"Username or ID required."))
        except IsNotCrowdformError:
            return OpenRosaResponseNotAllowed(
                _(u"Sorry but the crowd form you submitted to is closed.")
            )
        except InstanceEmptyError:
            return OpenRosaResponseBadRequest(
                _(u"Received empty submission. No instance was created")
            )
        except FormInactiveError:
            return OpenRosaResponseNotAllowed(_(u"Form is not active"))
        except XForm.DoesNotExist:
            return OpenRosaResponseNotFound(
                _(u"Form does not exist on this account")
            )
        except ExpatError:
            return OpenRosaResponseBadRequest(_(u"Improperly formatted XML."))
        except DuplicateInstance:
            response = OpenRosaResponse(_(u"Duplicate submission"))
            response.status_code = 202
            response['Location'] = request.build_absolute_uri(request.path)
            return response
        except PermissionDenied, e:
            return OpenRosaResponseNotAllowed(e.message)
        except Exception, e:
            raise
Ejemplo n.º 14
0
 def submit_simple_yes():
     create_instance(self.user.username, TempFileProxy("""
         <?xml version='1.0' ?><yes_or_no id="yes_or_no"><yesno>Yes</yesno></yes_or_no>
         """.strip()), [])
Ejemplo n.º 15
0
 def submit_simple_yes():
     create_instance(
         self.user.username,
         TempFileProxy("""
         <?xml version='1.0' ?><yes_or_no id="yes_or_no"><yesno>Yes</yesno></yes_or_no>
         """.strip()), [])
Ejemplo n.º 16
0
def generate_instance(username, xml_file, media_files, uuid=None):
    ''' Process an XForm submission as if done via HTTP

        :param IO xml_file: file-like object containing XML XForm
        :param string username: username of the Form's owner
        :param list media_files: a list of UploadedFile objects
        :param string uuid: an optionnal uuid for the instance.

        :returns a (status, message) tuple. '''

    try:
        instance = create_instance(username, xml_file, media_files, uuid=uuid)
    except InstanceInvalidUserError:
        return {
            'code': SMS_SUBMISSION_REFUSED,
            'text': _(u"Username or ID required.")
        }
    except IsNotCrowdformError:
        return {
            'code': SMS_SUBMISSION_REFUSED,
            'text': _(u"Sorry but the crowd form you "
                      u"submitted to is closed.")
        }
    except InstanceEmptyError:
        return {
            'code': SMS_INTERNAL_ERROR,
            'text': _(u"Received empty submission. "
                      u"No instance was created")
        }
    except FormInactiveError:
        return {
            'code': SMS_SUBMISSION_REFUSED,
            'text': _(u"Form is not active")
        }
    except XForm.DoesNotExist:
        return {
            'code': SMS_SUBMISSION_REFUSED,
            'text': _(u"Form does not exist on this account")
        }
    except ExpatError:
        return {
            'code': SMS_INTERNAL_ERROR,
            'text': _(u"Improperly formatted XML.")
        }
    except DuplicateInstance:
        return {
            'code': SMS_SUBMISSION_REFUSED,
            'text': _(u"Duplicate submission")
        }

    if instance is None:
        return {
            'code': SMS_INTERNAL_ERROR,
            'text': _(u"Unable to create submission.")
        }

    user = User.objects.get(username=username)

    audit = {"xform": instance.xform.id_string}
    audit_log(
        Actions.SUBMISSION_CREATED, user, instance.xform.user,
        _("Created submission on form %(id_string)s.") %
        {"id_string": instance.xform.id_string}, audit, HttpRequest())

    xml_file.close()
    if len(media_files):
        [_file.close() for _file in media_files]

    return {
        'code': SMS_SUBMISSION_ACCEPTED,
        'text': _(u"[SUCCESS] Your submission has been accepted."),
        'id': get_sms_instance_id(instance)
    }
Ejemplo n.º 17
0
     else:
         raise
 if len(xml_file_list) != 1:
     return HttpResponseBadRequest(
         "There should be a single XML submission file.")
 # save this XML file and media files as attachments
 media_files = request.FILES.values()
 if not username:
     uuid = request.POST.get('uuid')
     if not uuid:
         return HttpResponseBadRequest("Username or ID required.")
     show_options = True
     xform = XForm.objects.get(uuid=uuid)
     username = xform.user.username
 try:
     instance = create_instance(username, xml_file_list[0], media_files)
 except InstanceEmptyError:
     return HttpResponseBadRequest(
         'Received empty submission. No instance was created')
 except FormInactiveError:
     return HttpResponseNotAllowed('Form is not active')
 if instance == None:
     return HttpResponseBadRequest("Unable to create submission.")
 # ODK needs two things for a form to be considered successful
 # 1) the status code needs to be 201 (created)
 # 2) The location header needs to be set to the host it posted to
 if show_options:
     context.username = instance.user.username
     context.id_string = instance.xform.id_string
     context.domain = Site.objects.get(id=settings.SITE_ID).domain
     response = render_to_response("submission.html",