diff --git a/l10n/musdb b/l10n/musdb index 9ef4465..a4a3733 160000 --- a/l10n/musdb +++ b/l10n/musdb @@ -1 +1 @@ -Subproject commit 9ef4465d0d13365657430f099d9a4f213604de79 +Subproject commit a4a3733f9a5dcfab2def7bace7fe4517eb00df86 diff --git a/l10n/translation-csvxml b/l10n/translation-csvxml index f4dbfcc..4663b4a 160000 --- a/l10n/translation-csvxml +++ b/l10n/translation-csvxml @@ -1 +1 @@ -Subproject commit f4dbfcc5bf910c360ac7414ecb9d308bbc8abdc1 +Subproject commit 4663b4a5f77f4b417cc93b923f1304d354317203 diff --git a/public/assets/js/csvxmlV2.js b/public/assets/js/csvxmlV2.js index 8f6b830..cc36e80 100644 --- a/public/assets/js/csvxmlV2.js +++ b/public/assets/js/csvxmlV2.js @@ -553,7 +553,8 @@ class CsvxmlPage { uploadFileForValidation(file) { const reader = new FileReader(); - reader.readAsText(file); + let utf8 = true; + reader.readAsText(file, utf8 ? 'UTF-8' : 'CP1251'); let app = this; @@ -563,6 +564,13 @@ class CsvxmlPage { function handleValidation() { + (async function() { + const result = reader.result; + if (utf8 && result.includes('�')) { + window.alert('The file encoding appears to not be UTF-8!\n\nTry exporting the file using the format "CSV (UTF-8)" if you use MS Excel or set the encoding to UTF-8 when exporting through LibreOffice!'); + } + })(); + // On loading success, check if the upload is valid JSON console.log("Read file"); // Validate the file diff --git a/public/assets/js/csvxmlV2.min.js b/public/assets/js/csvxmlV2.min.js index 51ea9bb..5ba5e2a 100644 --- a/public/assets/js/csvxmlV2.min.js +++ b/public/assets/js/csvxmlV2.min.js @@ -8,10 +8,12 @@ console.log(this.toValidate);let lineCounter=1;for(let line of this.toValidate){ lineCounter++;}} checkDuplicateInvNos(){let invNoEncountered=[];let lineCounter=1;for(let line of this.toValidate){if(invNoEncountered.includes(line.inventory_number)){this.errors.duplicateInvNos.push("Duplicate inventory number "+line.inventory_number+" on line "+lineCounter);} invNoEncountered.push(line.inventory_number);lineCounter++;}} -checkDependentColumns(){const headers=Object.keys(this.toValidate[0]);for(let header of headers){if(this.fieldList[header]===undefined||this.fieldList[header].dependsOn===undefined||this.fieldList[header].dependsOn===null)continue;let dependencies=this.fieldList[header].dependsOn;for(let dep of dependencies){if(headers.includes(dep)===false){this.errors.dependentColumns.push("Dependency issue at column "+header+": Corresponding column "+dep+" is missing");}}}} +checkDependentColumns(){const headers=Object.keys(this.toValidate[0]);for(let header of headers){if(this.fieldList[header]===undefined||this.fieldList[header].dependsOn===undefined||this.fieldList[header].dependsOn===null)continue;let dependencies=this.fieldList[header].dependsOn;for(let dep of dependencies){if(headers.includes(dep)===false){this.errors.dependentColumns.push("Dependency issue at column "+header+": Corresponding column "+dep+" is missing");}}} +let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(line[fieldName]==='')continue;const dependencies=this.fieldList[fieldName].dependsOn;if(dependencies===undefined)continue;for(let dependency of dependencies){if(line[dependency]===''){this.errors.dependentColumns.push("Dependency issue at column "+fieldName+": Corresponding column "+dependency+" is empty");}}} +lineCounter++;}} checkControlledLists(){let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(this.fieldList[fieldName]===undefined){console.log("Undefined but requested field "+fieldName);continue;} -let allowedValues=this.fieldList[fieldName].allowedValues;if(allowedValues===undefined||allowedValues===null)continue;if(Object.values(allowedValues).length===0||Object.values(allowedValues).includes(line[fieldName])){continue;} -this.errors.controlledLists.push("Disallowed value used for column "+fieldName+" at line "+lineCounter+" (Allowed values are: "+Object.values(allowedValues).join(", ")+"; current value is "+line[fieldName]+")");} +const allowedValues=this.fieldList[fieldName].allowedValues;if(allowedValues===undefined||allowedValues===null)continue;if(Object.values(allowedValues).length===0||Object.values(allowedValues).includes(line[fieldName])){continue;} +if(line[fieldName]==='')continue;this.errors.controlledLists.push("Disallowed value used for column "+fieldName+" at line "+lineCounter+" (Allowed values are: "+Object.values(allowedValues).join(", ")+"; current value is "+line[fieldName]+")");} lineCounter++;}} checkMainImageResource(){} isValid(){for(let errorClass in this.errors){if(this.errors[errorClass].length!==0)return false;} @@ -34,7 +36,8 @@ static closeDialogueByEscape(e){if(e.keyCode===27){CsvxmlDialogue.closeDialogue( static drawDialogue(contents){let dialogueArea=document.createElement("div");dialogueArea.id="dialogueArea";let dialogue=document.createElement("div");dialogue.id="dialogue";dialogue.appendChild(contents);dialogueArea.appendChild(dialogue);document.body.appendChild(dialogueArea);document.addEventListener('keydown',CsvxmlDialogue.closeDialogueByEscape);return dialogue;}} class CsvxmlPage{fieldList;fieldListFlat;tls;domHelpWrapper;domUploaderWrapper;domMainWrapper;selectedFields;csvBySelectionButton;unsetSelectionButton;constructor(fieldList,tls){this.fieldList=Object.freeze(fieldList);let list={};for(let sectionName in fieldList){list=Object.assign(list,fieldList[sectionName]);} this.fieldListFlat=Object.freeze(list);this.tls=Object.freeze(tls);let domHelpWrapper=document.createElement("div");domHelpWrapper.id="helpSection";this.domHelpWrapper=domHelpWrapper;let domUploaderWrapper=document.createElement("div");domUploaderWrapper.id="uploader";domUploaderWrapper.classList.add("uploader");this.domUploaderWrapper=domUploaderWrapper;let domMainWrapper=document.createElement("main");this.domMainWrapper=domMainWrapper;this.selectedFields=[];} -generateCsv(selectedFields=[]){let line1=[];let line2=[];let line3=[];for(let fieldName in this.fieldListFlat){console.log(fieldName);console.log(selectedFields);if(selectedFields.length!==0&&selectedFields.includes(fieldName)===false)continue;const field=this.fieldListFlat[fieldName];line1.push(fieldName);line2.push(field.name_human_readable);if(field.allowedValues!==undefined){let values=[];for(let key in field.allowedValues)values.push(field.allowedValues[key]);line3.push(values.join(","));} +generateCsv(selectedFields=[]){let line1=[];let line2=[];let line3=[];for(let fieldName in this.fieldListFlat){console.log(fieldName);console.log(selectedFields);if(selectedFields.length!==0&&selectedFields.includes(fieldName)===false)continue;const field=this.fieldListFlat[fieldName];line1.push(fieldName);line2.push(field.name_human_readable);if(field.allowedValues!==undefined){let values=[];for(let key in field.allowedValues){values.push(field.allowedValues[key]);} +line3.push(values.join(","));} else line3.push("");} const csvLine1='"'+line1.join('";"')+'"';const csvLine2='"'+line2.join('";"')+'"';const csvLine3='"'+line3.join('";"')+'"';const toStore=csvLine1+"\n"+csvLine2+"\n"+csvLine3;const triggerLink=document.createElement('a');triggerLink.setAttribute('href','data:text/plain;charset=utf-8,'+encodeURIComponent(toStore));triggerLink.setAttribute('download',"csvxml_museum-digital_template.csv");triggerLink.style.display='none';document.body.appendChild(triggerLink);triggerLink.click();document.body.removeChild(triggerLink);} zipUploadToXml(validator){function runZipping(){let zip=new JSZip();let xmlFiles=validator.generateXml();const serializer=new XMLSerializer();let lineCounter=0;for(let xml of xmlFiles){zip.file(lineCounter+".xml",serializer.serializeToString(xml));lineCounter++;} @@ -45,7 +48,7 @@ generateDialogueCloseButton(){const cancelB=document.createElement("a");cancelB. listValidationErrors(validator){console.log("Listing validation errors");const dialogueContent=document.createElement("div");const headline=document.createElement("h3");headline.textContent=this.tls.validation_errors;headline.appendChild(this.generateDialogueCloseButton());dialogueContent.appendChild(headline);const domErrorsSection=document.createElement("div");for(let errorType in validator.errors){if(validator.errors[errorType].length===0)continue;const ulHl=document.createElement("h4");ulHl.textContent=this.tls['errors_'+errorType]+" ("+validator.errors[errorType].length+")";ulHl.style.cursor="pointer";domErrorsSection.appendChild(ulHl);const ul=document.createElement("ul");for(let error of validator.errors[errorType]){const li=document.createElement("li");li.textContent=error;ul.appendChild(li);} ulHl.addEventListener('click',function(){ul.classList.toggle("minimized");});domErrorsSection.appendChild(ul);} dialogueContent.appendChild(domErrorsSection);const domDlSection=document.createElement("div");const domDlA=document.createElement("span");domDlA.textContent=this.tls.download;domDlA.classList.add("buttonLike");let app=this;domDlA.addEventListener('click',function(){app.zipUploadToXml(validator);});domDlSection.appendChild(domDlA);dialogueContent.appendChild(domDlSection);dialogue=CsvxmlDialogue.drawDialogue(dialogueContent);} -uploadFileForValidation(file){const reader=new FileReader();reader.readAsText(file);let app=this;document.body.classList.add("loading");reader.onload=function(){function handleValidation(){console.log("Read file");let validator=new CsvxmlValidator(app.fieldListFlat,reader.result);document.body.classList.remove("loading");if(validator.isValid()===true){alert("Document is valid. Press ok to download.");app.zipUploadToXml(validator);} +uploadFileForValidation(file){const reader=new FileReader();let utf8=true;reader.readAsText(file,utf8?'UTF-8':'CP1251');let app=this;document.body.classList.add("loading");reader.onload=function(){function handleValidation(){(async function(){const result=reader.result;if(utf8&&result.includes('�')){window.alert('The file encoding appears to not be UTF-8!\n\nTry exporting the file using the format "CSV (UTF-8)" if you use MS Excel or set the encoding to UTF-8 when exporting through LibreOffice!');}})();console.log("Read file");let validator=new CsvxmlValidator(app.fieldListFlat,reader.result);document.body.classList.remove("loading");if(validator.isValid()===true){alert("Document is valid. Press ok to download.");app.zipUploadToXml(validator);} else{console.log("Identified invalid upload document");app.listValidationErrors(validator);}} console.log("Postload papaparse");if(typeof Papa==="undefined"){const loadScript=document.createElement("script");loadScript.setAttribute("src","assets/js/papaparse/papaparse.min.js");loadScript.addEventListener('load',function(){handleValidation();},{passive:true,once:true});document.body.appendChild(loadScript);} else{handleValidation();}};reader.onerror=function(){alert(reader.error);};} diff --git a/public/index.htm b/public/index.htm index 4d1fc25..8d0e9b9 100644 --- a/public/index.htm +++ b/public/index.htm @@ -4,7 +4,7 @@ - + @@ -27,7 +27,7 @@
- +