简体   繁体   English

MTurk如何在提交任务时将文件上传到S3

[英]MTurk how to upload file to S3 when task is submitted

I am trying to create a task on Amazon MTurk, where the workers would collect some data and upload a single file when they are ready & submit the task.我正在尝试在 Amazon MTurk 上创建一个任务,工作人员将在其中收集一些数据并在准备好并提交任务时上传单个文件。 When the task is submitted, I want to upload the file to my linked S3 bucket - which is mostly based on this tutorial .提交任务后,我想将文件上传到我链接的 S3 存储桶 - 这主要基于本教程

However, the file is sometimes uploaded successfully, and sometimes not.但是,文件有时上传成功,有时不成功。 Since the S3.upload function is asynchronous, it looks like the task submission is sometimes completed before the file upload is completed.由于S3.upload函数是异步的,看起来任务提交有时会在文件上传完成之前完成。 I am a javascript newbie: I tried to make this happen synchronously, but it still doesn't work properly.我是一个javascript新手:我试图让这同步发生,但它仍然无法正常工作。 Here is my javascript code:这是我的javascript代码:

<script>
    let config = {
        region: 'xxx',
        pool: 'xxx',
        bucket: 'xxx'
    }
    
    AWS.config.region = config.region;
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: config.pool,
    });
    
    var s3 = new AWS.S3({
        apiVersion: '2006-03-01',
        params: {Bucket: config.bucket},
    });
  
    start_upload = function (event) {
        $("#status").text("Uploading...");
    
        let file = $("#file").prop('files')[0];
        if (file === null || file === undefined) {
            alert("You must upload a file before submitting.");
            $("#status").text("");
            return false;
        }
    
        console.log('Filename: ' + file.name);
    
        let workerId = turkGetParam('workerId');
        let fileKey = '${food_name}' + '/' + workerId + '-' + file.name;
    
        return upload_to_s3(file, fileKey);
    };
  
    upload_to_s3 = async (file, fileKey) => {
        const params = {
            Key: fileKey,
            Body: file,
            ContentType: file.type,
            ACL: 'bucket-owner-full-control'
        };
    
        try {
            console.log("Starting upload...");
            const data = await s3.upload(params).promise();
            console.log("Done uploading file");
            $("#status").text("Success.");
            return true;
        } catch (err) {
            console.log("Error uploading data. ", err);
            alert("Failed to upload, please try again. If the problem persists, contact the Requester.");
            $("#status").text("");
            return false;
        }
    }
  
    // Validate and upload file on submit
    window.onload = function() {document.getElementById('submitButton').setAttribute('onclick', 'return start_upload()'); }
</script>

Here is the relevant part of the layout of this task (HIT):这是此任务 (HIT) 布局的相关部分: 在此处输入图片说明

How can I make sure that the file upload is completed before the task is completed?如何在任务完成前确保文件上传完成? I saw that I can overwrite the default submit button added by MTurk, but I would prefer not doing that if possible.我看到我可以覆盖 MTurk 添加的默认提交按钮,但如果可能的话,我宁愿不这样做。

I've found the problem: S3#upload returns a ManagedUpload object, but it doesn't mean that the file upload is completed.我发现了问题: S3#upload返回了一个ManagedUpload对象,但这并不意味着文件上传完成。 I am now using promises and in the callback I submit the form manually.我现在正在使用承诺,并在回调中手动提交表单。 Note that the form is provided by MTurk by default.请注意,该表单默认由 MTurk 提​​供。 I just find it by its ID and invoke the submit function manually.我只是通过它的 ID 找到它并手动调用submit功能。

For reference, here is the working code:作为参考,这里是工作代码:

<script>
    let config = {
        region: 'xxx',
        pool: 'xxx',
        bucket: 'xxx'
    }
    
    AWS.config.region = config.region;
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: config.pool,
    });
    
    var s3 = new AWS.S3({
        apiVersion: '2006-03-01',
        params: {Bucket: config.bucket},
    });
    
    start_upload = function (event) {
        $("#status").text("Uploading, please wait...");
    
        let file = $("#file").prop('files')[0];
        if (file === null || file === undefined) {
            alert("You must choose a file before submitting.");
            $("#status").text("");
            return false;
        }
    
        let workerId = turkGetParam('workerId');
        let fileKey = '${food_name}' + '/' + workerId + '-' + file.name;
    
        upload_to_s3(file, fileKey);
        
        return false;
    };
  
    upload_to_s3 = (file, fileKey) => {
        const params = {
            Key: fileKey,
            Body: file,
            ContentType: file.type,
            ACL: 'bucket-owner-full-control'
        };
    
        let promise = s3.upload(params).promise();
        promise.then( (data) => {
            console.log("Upload completed");
            $("#status").text("Success.");
            
            const form = document.getElementById('mturk_form');
            form.submit();
        }, (err) => {
            console.log("Upload failed!!!", err);
            alert("Failed to upload, please try again. If the problem persists, contact the Requester.");
            $("#status").text("");
        } );
    }
  
    // Validate and upload file on submit
    window.onload = function() {document.getElementById('submitButton').setAttribute('onclick', 'return start_upload()'); }
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM