diff options
Diffstat (limited to 'uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html')
-rw-r--r-- | uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html b/uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html new file mode 100644 index 0000000..07c240f --- /dev/null +++ b/uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html @@ -0,0 +1,276 @@ +{%extends "base.html"%} +{%from "flash_messages.html" import flash_all_messages%} +{%from "upload_progress_indicator.html" import upload_progress_indicator%} + +{%block title%}Upload R/qtl2 Bundle{%endblock%} + +{%block contents%} +{%macro rqtl2_file_help()%} +<span class="form-text text-muted"> + <p> + Provide a valid R/qtl2 zip file here. In particular, ensure your zip bundle + contains exactly one control file and the corresponding files mentioned in + the control file. + </p> + <p> + The control file can be either a YAML or JSON file. <em>ALL</em> other data + files in the zip bundle should be CSV files. + </p> + <p>See the + <a href="https://kbroman.org/qtl2/assets/vignettes/input_files.html" + target="_blank"> + R/qtl2 file format specifications + </a> + for more details. + </p> +</span> +{%endmacro%} +{{upload_progress_indicator()}} + +<div id="resumable-file-display-template" + class="panel panel-info" + style="display: none"> + <div class="panel-heading"></div> + <div class="panel-body"></div> +</div> + + +<h2 class="heading">Upload R/qtl2 Bundle</h2> + +<div id="resumable-drop-area" + style="display:none;background:#eeeeee;min-height:12em;border-radius:0.5em;padding:1em;"> + <p> + <a id="resumable-browse-button" href="#" + class="btn btn-info">Browse</a> + </p> + <p class="form-text text-muted"> + You can drag and drop your file here, or click the browse button. + Click on the file to remove it. + </p> + {{rqtl2_file_help()}} + <div id="resumable-selected-files" + style="display:flex;flex-direction:row;flex-wrap: wrap;justify-content:space-around;gap:10px 20px;"></div> + <div id="resumable-class-buttons" style="text-align: right;"> + <button id="resumable-upload-button" + class="btn btn-primary" + style="display: none">start upload</button> + <button id="resumable-cancel-upload-button" + class="btn btn-danger" + style="display: none">cancel upload</button> + </div> + <div id="resumable-progress-bar" class="progress" style="display: none"> + <div class="progress-bar" + role="progress-bar" + aria-valuenow="60" + aria-valuemin="0" + aria-valuemax="100" + style="width: 0%;"> + Uploading: 60% + </div> + </div> +</div> + +<form id="frm-upload-rqtl2-bundle" + action="{{url_for('upload.rqtl2.upload_rqtl2_bundle', + species_id=species.SpeciesId, + population_id=population.InbredSetId)}}" + method="POST" + enctype="multipart/form-data" + data-resumable-target="{{url_for( + 'upload.rqtl2.upload_rqtl2_bundle_chunked_post', + species_id=species.SpeciesId, + population_id=population.InbredSetId)}}"> + <input type="hidden" name="species_id" value="{{species.SpeciesId}}" /> + <input type="hidden" name="population_id" + value="{{population.InbredSetId}}" /> + + {{flash_all_messages()}} + + <div class="form-group"> + <legend class="heading">file upload</legend> + <label for="file-rqtl2-bundle" class="form-label">R/qtl2 bundle</label> + <input type="file" id="file-rqtl2-bundle" name="rqtl2_bundle_file" + accept="application/zip, .zip" + required="required" + class="form-control" /> + {{rqtl2_file_help()}} + </div> + + <button type="submit" + class="btn btn-primary" + data-toggle="modal" + data-target="#upload-progress-indicator">upload R/qtl2 bundle</button> +</form> + +{%endblock%} + +{%block javascript%} +<script src="{{url_for('base.node_modules', + filename='resumablejs/resumable.js')}}"></script> +<script type="text/javascript" src="/static/js/upload_progress.js"></script> +<script type="text/javascript"> + function readBinaryFile(file) { + return new Promise((resolve, reject) => { + var _reader = new FileReader(); + _reader.onload = (event) => {resolve(_reader.result);}; + _reader.readAsArrayBuffer(file); + }); + } + + function computeFileChecksum(file) { + return readBinaryFile(file) + .then((content) => { + return window.crypto.subtle.digest( + "SHA-256", new Uint8Array(content)); + }).then((digest) => { + return Uint8ArrayToHex(new Uint8Array(digest)) + }); + } + + function Uint8ArrayToHex(arr) { + var toHex = (val) => { + _hex = val.toString(16); + if(_hex.length < 2) { + return "0" + val; + } + return _hex; + }; + _hexstr = "" + arr.forEach((val) => {_hexstr += toHex(val)}); + return _hexstr + } + + var r = Resumable({ + target: $("#frm-upload-rqtl2-bundle").attr("data-resumable-target"), + fileType: ["zip"], + maxFiles: 1, + forceChunkSize: true, + generateUniqueIdentifier: (file, event) => { + return computeFileChecksum(file).then((checksum) => { + var _relativePath = (file.webkitRelativePath + || file.relativePath + || file.fileName + || file.name); + return checksum + "-" + _relativePath.replace( + /[^a-zA-Z0-9_-]/img, ""); + }); + } + }); + + if(r.support) { + //Hide form and display drag&drop UI + $("#frm-upload-rqtl2-bundle").css("display", "none"); + $("#resumable-drop-area").css("display", "block"); + + // Define UI elements for browse and drag&drop + r.assignDrop(document.getElementById("resumable-drop-area")); + r.assignBrowse(document.getElementById("resumable-browse-button")); + + // Event handlers + + function display_files(files) { + displayArea = $("#resumable-selected-files") + displayArea.empty(); + files.forEach((file) => { + var displayElement = $( + "#resumable-file-display-template").clone(); + displayElement.removeAttr("id"); + displayElement.css("display", ""); + displayElement.find(".panel-heading").text(file.fileName); + list = $("<ul></ul>"); + list.append($("<li><strong>Name</strong>: " + + (file.name + || file.fileName + || file.relativePath + || file.webkitRelativePath) + + "</li>")); + list.append($("<li><strong>Size</strong>: " + + (file.size / (1024*1024)).toFixed(2) + + " MB</li>")); + list.append($("<li><strong>Unique Identifier</strong>: " + + file.uniqueIdentifier + "</li>")); + list.append($("<li><strong>Mime</strong>: " + + file.file.type + + "</li>")); + displayElement.find(".panel-body").append(list); + displayElement.appendTo("#resumable-selected-files"); + }); + } + + r.on("filesAdded", function(files) { + display_files(files); + $("#resumable-upload-button").css("display", ""); + $("#resumable-upload-button").on("click", (event) => { + r.upload(); + }); + }); + + r.on("uploadStart", (event) => { + $("#resumable-upload-button").css("display", "none"); + $("#resumable-cancel-upload-button").css("display", ""); + $("#resumable-cancel-upload-button").on("click", (event) => { + r.files.forEach((file) => { + if(file.isUploading()) { + file.abort(); + } + }); + $("#resumable-cancel-upload-button").css("display", "none"); + $("#resumable-upload-button").on("click", (event) => { + r.files.forEach((file) => {file.retry();}); + }); + $("#resumable-upload-button").css("display", ""); + }); + }); + + r.on("progress", () => { + var progress = (r.progress() * 100).toFixed(2); + var pbar = $("#resumable-progress-bar > .progress-bar"); + $("#resumable-progress-bar").css("display", ""); + pbar.css("width", progress+"%"); + pbar.attr("aria-valuenow", progress); + pbar.text("Uploading: " + progress + "%"); + }) + + r.on("fileSuccess", (file, message) => { + if(message != "OK") { + var uri = (window.location.protocol + + "//" + + window.location.host + + message); + window.location.replace(uri); + } + }); + + r.on("error", (message, file) => { + filename = (file.webkitRelativePath + || file.relativePath + || file.fileName + || file.name); + jsonmsg = JSON.parse(message); + alert("There was an error while uploading your file '" + + filename + + "'. The error message was:\n\n\t" + + jsonmsg.error + + " (" + + jsonmsg.statuscode + + "): " + jsonmsg.message); + }) + } else { + setup_upload_handlers( + "frm-upload-rqtl2-bundle", make_data_uploader( + function (form) { + var formdata = new FormData(); + formdata.append( + "species_id", + form.querySelector('input[name="species_id"]').value); + formdata.append( + "population_id", + form.querySelector('input[name="population_id"]').value); + formdata.append( + "rqtl2_bundle_file", + form.querySelector("#file-rqtl2-bundle").files[0]); + return formdata; + })); + } +</script> +{%endblock%} |