Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/dvwebloader.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
<link type="text/css" rel="stylesheet" href="css/dvwebloader.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/core.js"></script>
<script src="js/fileupload2.js"></script>
<script type="module" src="js/fileupload2.js"></script>
</head>
<body>
<main>
<div>
<img id='logo' alt='Site Logo'>
<h1>Folder Upload</h1>
<h1><span id="title-text">Folder Upload</span></h1>
<div id='help'>
<a href='https://github.com/gdcc/dvwebloader/wiki' target='_blank'>Help/Tutorial</a>
<a href='https://github.com/gdcc/dvwebloader/wiki' target='_blank'><span id="help-tutorial-text">Help/Tutorial</span></a>
</div>
</div>
<hr class='solid'>

<div id="top">
<label for='files' class='button'>Select a Directory<input type="file" id="files" name="files[]" multiple webkitdirectory style="display: none" /></label>
<label for='files' class='button'><span id="select-dir-text">Select a Directory</span><input type="file" id="files" name="files[]" multiple webkitdirectory style="display: none" /></label>
<div id='messages'></div>
</div>
<div id="filelist"></div>
<div id="credit">
<a href='https://github.com/gdcc/dvwebloader' target='_blank'>DVWebloader v0.2</a>, development sponsored by UiT/DataverseNO
<a href='https://github.com/gdcc/dvwebloader' target='_blank'>DVWebloader v0.2</a><span id="sponsor-text">, development sponsored by UiT/DataverseNO</span>
</div>
<script>
var input = document
Expand Down
70 changes: 40 additions & 30 deletions src/js/fileupload2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import getLocalizedString from './lang.js';

var fileList = [];
var rawFileMap = {};
var toRegisterFileList = [];
Expand All @@ -16,9 +18,7 @@ var UploadState = {
//true indicates direct upload is being used, but cancel may set it back to false at which point direct upload functions should not do further work
var directUploadEnabled = false;
var directUploadReport = true;

var checksumAlgName;

//How many files have started being processed but aren't yet being uploaded
var filesInProgress = 0;
//The # of the current file being processed (total number of files for which upload has at least started)
Expand All @@ -45,6 +45,7 @@ var apiKey;
var existingFiles;
var convertedFileNameMap;
var queryParams;
var dvLocale;

$(document).ready(function() {
queryParams = new URLSearchParams(window.location.search.substring(1));
Expand All @@ -54,8 +55,12 @@ $(document).ready(function() {
datasetPid = queryParams.get("datasetPid");
console.log('PID: ' + datasetPid);
apiKey = queryParams.get("key");
console.log(apiKey);
dvLocale = queryParams.get("dvLocale");
console.log('locale: ' + dvLocale);
directUploadEnabled = true;
addMessage('info', 'Getting Dataset Information...');
initTranslation();
addMessage('info', 'msgGettingDatasetInfo');
fetch(siteUrl + "/api/files/fixityAlgorithm")
.then((response) => {
if (!response.ok) {
Expand Down Expand Up @@ -113,15 +118,14 @@ $(document).ready(function() {
console.log('exists: ' + numExists);
console.log('rawFileMap len: ' + totalFiles);
if (totalFiles === numExists) {
addMessage('info', 'All files already exist in dataset. There\'s nothing to upload.');
addMessage('info', 'msgFilesAlreadyExist');
} else
if (numExists !== 0 && totalFiles > numExists) {
addMessage('info', 'Some files already exist in dataset. Only checked files will be uploaded.');
}
if (numExists !== 0 && totalFiles > numExists) {
addMessage('info', 'msgUploadOnlyCheckedFiles');
}
$('label.button').hide();
};
});

function addIconAndLogo(siteUrl) {
// Add favicon from source Dataverse
$('head')
Expand Down Expand Up @@ -171,16 +175,24 @@ function addIconAndLogo(siteUrl) {
$('#logo').attr('src', siteUrl + '/logos/preview_logo.png');

}
function addMessage(type, text) {
$('#messages').html('').append($('<div/>').addClass(type).text(text));
function initTranslation() {
initSpanTxt('title-text', 'title');
initSpanTxt('select-dir-text', 'selectDir');
initSpanTxt('help-tutorial-text', 'helpTutorial');
initSpanTxt('sponsor-text', 'sponsor');
}
function initSpanTxt(htmlId, key) {
$('#'+htmlId).text(getLocalizedString(dvLocale, key));
}
function addMessage(type, key) {
$('#messages').html('').append($('<div/>').addClass(type).text(getLocalizedString(dvLocale, key)));
}
async function populatePageMetadata(data) {
var mdFields = data.metadataBlocks.citation.fields;
var title = "";
var authors = "";
datasetUrl = data.storageIdentifier;
datasetUrl = siteUrl + '/dataset.xhtml?persistentId=' + datasetPid;
version = queryParams.get("datasetversion");
var datasetUrl = siteUrl + '/dataset.xhtml?persistentId=' + datasetPid;
var version = queryParams.get("datasetversion");
if (version === ":draft") {
version = "DRAFT";
}
Expand All @@ -200,7 +212,7 @@ async function populatePageMetadata(data) {
}
}
}
let mdDiv = $('<div/>').append($('<h2/>').text("Uploading to ").append($('<a/>').prop("href", datasetUrl).prop('target', '_blank').text(title)));
let mdDiv = $('<div/>').append($('<h2/>').text(getLocalizedString(dvLocale, 'uploadingTo')).append($('<a/>').prop("href", datasetUrl).prop('target', '_blank').text(title)));
$('#top').prepend(mdDiv);
}

Expand Down Expand Up @@ -243,7 +255,7 @@ async function retrieveDatasetInfo() {
}
}
$('#files').prop('disabled', false);
addMessage('info', 'Ready. Click Select a Directory. Review the selected files. Start Uploads. (Note - selection dialog will not show files, but they will be shown afterwards on the page.) ');
addMessage('info', 'msgReadyToStart');
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('Failure: ' + jqXHR.status);
Expand Down Expand Up @@ -280,7 +292,7 @@ function setupDirectUpload(enabled) {
var config = { childList: true };
var callback = function(mutations) {
mutations.forEach(function(mutation) {
for (i = 0; i < mutation.addedNodes.length; i++) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
//Add a listener on any replacement file 'select' widget
if (mutation.addedNodes[i].id === 'datasetForm:fileUpload_input') {
fileInput = mutation.addedNodes[i];
Expand Down Expand Up @@ -568,7 +580,6 @@ var fileUpload = class fileUploadClass {
this.state = UploadState.UPLOADED;
console.log('S3 Upload complete for ' + this.file.name + ' : ' + this.storageId);
if (directUploadReport) {

getChecksum(this.file, prog => {
var current = 1 + prog;
$('[upid="' + this.id + '"] progress').attr({
Expand Down Expand Up @@ -663,7 +674,7 @@ function queueFileForDirectUpload(file) {
//startUploads();
if (send) {
if ($('#upload').length === 0) {
$('<button/>').prop('id', 'upload').text('Start Uploads').addClass('button').click(startUploads).appendTo($('#top'));
$('<button/>').prop('id', 'upload').text(getLocalizedString(dvLocale, 'startUpload')).addClass('button').click(startUploads).appendTo($('#top'));
}
}
let fileBlock = $('#filelist>.ui-fileupload-files');
Expand All @@ -689,12 +700,12 @@ function toggleUpload() {
if ($('.ui-fileupload-row').children('input:checked').length !== 0) {
console.log('yes');
if ($('#upload').length === 0) {
$('<button/>').prop('id', 'upload').text('Start Uploads').addClass('button').click(startUploads).insertBefore($('#messages'));
addMessage('info', 'Checked files will be uploaded.');
$('<button/>').prop('id', 'upload').text(getLocalizedString(dvLocale, 'startUpload')).addClass('button').click(startUploads).insertBefore($('#messages'));
addMessage('info', 'msgStartUpload');
}
} else {
$('#upload').remove();
addMessage('info', 'No files to upload. Check some files, or refresh to start over.');
addMessage('info', 'msgNoFile');
}
}

Expand All @@ -721,7 +732,7 @@ async function uploadFileDirectly(urls, storageId, filesize) {
if (directUploadEnabled) {
var upload = null;
//As long as we have the right file size, we're OK
for (i = 0; i < fileList.length; i++) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].file.size == filesize) {
upload = fileList.splice(i, 1)[0];
break;
Expand All @@ -741,13 +752,12 @@ async function uploadFileDirectly(urls, storageId, filesize) {

function removeErrors() {
var errors = document.getElementsByClassName("ui-fileupload-error");
for (i = errors.length - 1; i >= 0; i--) {
for (let i = errors.length - 1; i >= 0; i--) {
errors[i].parentNode.removeChild(errors[i]);
}
}

var observer = null;

// uploadStarted and uploadFinished are not related to direct upload.
// They deal with clearing old errors and watching for new ones and then signaling when all uploads are done
function uploadStarted() {
Expand All @@ -758,7 +768,7 @@ function uploadStarted() {
//Find the upload table body
var files = $('.ui-fileupload-files .ui-fileupload-row');
//Add an id attribute to each entry so we can later match errors with the right entry
for (i = 0; i < files.length; i++) {
for (let i = 0; i < files.length; i++) {
files[i].setAttribute('upid', curId);
curId = curId + 1;
}
Expand All @@ -767,7 +777,7 @@ function uploadStarted() {
var callback = function(mutations) {
//Add an id attribute to all new entries
mutations.forEach(function(mutation) {
for (i = 0; i < mutation.addedNodes.length; i++) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
mutation.addedNodes[i].setAttribute('upid', curId);
curId = curId + 1;
}
Expand Down Expand Up @@ -806,7 +816,7 @@ async function directUploadFinished() {
if (total === numDone) {
// $('button[id$="AllUploadsFinished"]').trigger('click');
console.log("All files in S3");
addMessage('info', 'Uploads to S3 complete. Now registering all files with the dataset. This may take some time for large numbers of files.');
addMessage('info', 'msgUploadCompleteRegistering');
let body = [];
for (let i = 0; i < toRegisterFileList.length; i++) {
let fup = toRegisterFileList[i];
Expand Down Expand Up @@ -844,7 +854,7 @@ async function directUploadFinished() {
processData: false,
success: function(body, statusText, jqXHR) {
console.log("All files sent to " + siteUrl + '/dataset.xhtml?persistentId=doi:' + datasetPid + '&version=DRAFT');
addMessage('success', 'Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.');
addMessage('success', 'msgUploadComplete');
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('Failure: ' + jqXHR.status);
Expand All @@ -861,7 +871,7 @@ async function directUploadFinished() {
} else {
if ((inProgress < 4) && (inProgress < inList)) {
filesInProgress = filesInProgress + 1;
for (i = 0; i < fileList.length; i++) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].state === UploadState.QUEUED) {
fileList[i].startRequestForDirectUploadUrl();
break;
Expand Down Expand Up @@ -934,7 +944,7 @@ async function uploadFailure(jqXHR, upid, filename) {
var textnode = document.createTextNode("Upload unsuccessful (" + status + ": " + statusText + ").");
node.appendChild(textnode);
//Add the error message to the correct row
for (i = 0; i < rows.length; i++) {
for (let i = 0; i < rows.length; i++) {
if (rows[i].getAttribute('upid') === id) {
//Remove any existing error message/only show last error (have seen two error 0 from one network disconnect)
var err = rows[i].getElementsByClassName('ui-fileupload-error');
Expand Down
47 changes: 47 additions & 0 deletions src/js/lang.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const defaultLocale = 'en';
const translations = {
en: {
title: "Folder Upload",
selectDir: "Select a Directory",
helpTutorial: "Help/Tutorial",
sponsor: ", development sponsored by UiT/DataverseNO",
startUpload: "Start Uploads",
uploadingTo: "Uploading to ",
msgGettingDatasetInfo: "Getting Dataset Information...",
msgFilesAlreadyExist: "All files already exist in dataset. There's nothing to upload.",
msgUploadOnlyCheckedFiles: "Some files already exist in dataset. Only checked files will be uploaded.",
msgReadyToStart: "Ready. Click Select a Directory. Review the selected files. Start Uploads. (Note - selection dialog will not show files, but they will be shown afterwards on the page.) ",
msgStartUpload: "Checked files will be uploaded.",
msgNoFile: "No files to upload. Check some files, or refresh to start over.",
msgUploadCompleteRegistering: "Uploads to S3 complete. Now registering all files with the dataset. This may take some time for large numbers of files.",
msgUploadComplete: "Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.",
},
fr: {
title: "Envoi d'un dossier",
selectDir: "Sélectionner un répertoire",
helpTutorial: "Aide/Tutoriel",
sponsor: ", développement sponsorisé par UiT/DataverseNO",
startUpload: "Démarrer les envois",
uploadingTo: "Envoi vers ",
msgGettingDatasetInfo: "Récupération des informations du jeu de données...",
msgFilesAlreadyExist: "Tous les fichiers existent déjà dans le jeu de données. Il n'y a rien à envoyer.",
msgUploadOnlyCheckedFiles: "Certains fichiers existent déjà dans le jeu de données. Seuls les fichiers cochés seront envoyés.",
msgReadyToStart: "Prêt. Cliquez sur Sélectionner un répertoire. Passez en revue les fichiers sélectionnés. Démarrez les envois. (Remarque : la boîte de dialogue de sélection ne montrera pas les fichiers, mais ils seront affichés ensuite sur la page.) ",
msgStartUpload: "Les fichiers cochés seront envoyés.",
msgNoFile: "Aucun fichier à envoyer. Cochez certains fichiers ou rafraîchissez la page pour recommencer.",
msgUploadCompleteRegistering: "Envois vers S3 terminés. Enregistrement de tous les fichiers en cours dans le jeu de données. Cela peut prendre du temps pour un grand nombre de fichiers.",
msgUploadComplete: "Envoi terminé, tous les fichiers sont dans le jeu de données. Fermez cette fenêtre et rafraîchissez la page de votre jeu de données pour voir les fichiers envoyés.",
},
};

export default function getLocalizedString(locale, key) {
if(!locale || !translations[locale]) {
locale = defaultLocale;
console.log('getLocalizedString - locale empty or unknown, using defaultLocale: '+defaultLocale)
}
if (translations[locale] && translations[locale][key]) {
return translations[locale][key];
}
console.log('getLocalizedString - transalation not found with locale: '+locale+' and key:'+key);
return key;
}