See More

/* * Project Name : Visual Python * Description : GUI-based Python code generator * File Name : File.js * Author : Black Logic * Note : Apps > File * License : GNU GPLv3 with Visual Python special exception * Date : 2021. 11. 18 * Change Date : */ //============================================================================ // [CLASS] File //============================================================================ define([ __VP_TEXT_LOADER__('vp_base/html/m_apps/file.html'), // INTEGRATION: unified version of text loader __VP_CSS_LOADER__('vp_base/css/m_apps/file'), // INTEGRATION: unified version of css loader 'vp_base/js/com/com_String', 'vp_base/js/com/com_util', 'vp_base/js/com/com_Const', 'vp_base/js/com/component/PopupComponent', 'vp_base/js/com/com_generatorV2', 'vp_base/data/m_library/pandasLibrary', 'vp_base/js/com/component/FileNavigation', 'vp_base/js/com/component/SuggestInput' ], function(fileHtml, fileCss, com_String, com_util, com_Const, PopupComponent , pdGen, pandasLibrary, FileNavigation, SuggestInput) { /** * File */ class File extends PopupComponent { _init() { super._init(); /** Write codes executed before rendering */ this.config.dataview = false; this.config.sizeLevel = 2; this.config.checkModules = ['pd']; this.fileExtensions = { 'csv': ['csv', 'tsv', 'txt'], 'excel': ['xlsx', 'xls'], 'json': ['json'], 'pickle': [], 'sas': [], // xport or sas7bdat 'spss': [], 'parquet': ['parquet'] } this.package = { input: [ { name: 'vp_fileioType' }, { name: 'vp_pageDom'} ] } // INTEGRATED: integrate data source from raw.github // if (vpConfig.extensionType === 'notebook') { // this.dataPath = window.location.origin + com_Const.DATA_PATH + "sample_csv/"; // } else if (vpConfig.extensionType === 'colab' || vpConfig.extensionType === 'lab') { // // this.dataPath = com_Const.DATA_PATH + "sample_csv/"; // this.dataPath = 'https://raw.githubusercontent.com/visualpython/visualpython/main/data/sample_csv/'; // } if (vpConfig.extensionType === 'lite') { this.dataPath = '/drive/data/'; } else { this.dataPath = 'https://raw.githubusercontent.com/visualpython/visualpython/main/visualpython/data/sample_csv/'; } this.state = { fileType: 'csv', fileExtension: ['csv'], selectedFile: '', selectedPath: '', vp_fileioType: 'Read', vp_pageDom: '', userOption: '', ...this.state } this.fileResultState = { pathInputId : this.wrapSelector('#vp_fileRead #i0'), fileInputId : this.wrapSelector('#vp_fileRead #fileName') }; this.fileState = { 'Read': { fileTypeId: { 'csv': 'pd_readCsv', 'excel': 'pd_readExcel', 'json': 'pd_readJson', 'pickle': 'pd_readPickle', 'sas': 'pd_readSas', 'spss': 'pd_readSpss', 'parquet':'pd_readParquet' }, selectedType: 'csv', package: null, fileResultState: { pathInputId : this.wrapSelector('#vp_fileRead #i0'), fileInputId : this.wrapSelector('#vp_fileRead #fileName') } }, 'Write': { fileTypeId: { 'csv': 'pd_toCsv', 'excel': 'pd_toExcel', 'json': 'pd_toJson', 'pickle': 'pd_toPickle', 'parquet':'pd_toParquet' }, selectedType: 'csv', package: null, fileResultState: { pathInputId : this.wrapSelector('#vp_fileWrite #i1'), fileInputId : this.wrapSelector('#vp_fileWrite #fileName') } }, // 'Sample': { // library: 'pandas', // code: "${vp_sampleReturn} = pd.read_csv('" + this.dataPath + "${vp_sampleFile}'${v})", // input: [ // { // name:'vp_sampleFile', // label: 'Sample Data', // component: 'option_select', // options: [ // 'iris.csv', 'titanic.csv', 'fish.csv', 'campusRecruitment.csv', // 'houseData_500.csv', 'economic_index.csv', 'tips.csv' // ], // options_label: [ // 'iris', 'titanic', 'fish', 'campusRecruitment', // 'houseData_500', 'economic index', 'tips' // ] // } // ], // output: [ // { // name:'vp_sampleReturn', // type:'var', // label:'Allocate to', // required: true // } // ] // } "Sample": { "library": "pandas", "code": "${vp_sampleReturn} = pd.read_csv('" + this.dataPath + "${vp_sampleFile}')", "options": [ { "name": "vp_sampleFile", "label": "Sample Data", "required": true, "component": [ "option_select" ], "options": [ "iris.csv", "titanic.csv", "fish.csv", "campusRecruitment.csv", "houseData_500.csv", "economic_index.csv", "tips.csv" ], "options_label": [ "iris", "titanic", "fish", "campusRecruitment", "houseData_500", "economic index", "tips" ] }, { "name": "vp_sampleReturn", "label": "Allocate to", "component": [ "data_select" ], "output": true, "required": true, "value": 'vp_df' } ] } } } _unbindEvent() { super._unbindEvent(); $(document).off('change', this.wrapSelector('#fileReadAs')); } _bindEvent() { super._bindEvent(); /** Implement binding events */ var that = this; $(this.wrapSelector('#vp_fileioType')).on('change', function() { var pageType = $(this).val(); that.state['vp_fileioType'] = pageType; $(that.wrapSelector('.vp-fileio-box')).hide(); $(that.wrapSelector('#vp_file' + pageType)).show(); if (pageType === 'Read' && that.fileState[pageType].selectedType === 'spss') { // show install button that.showInstallButton(); // show install note below File type selection $(`

`).insertAfter($(that.wrapSelector('#fileType')).closest('tr')); } else { that.hideInstallButton(); $(that.wrapSelector('.vp-spss-note')).remove(); } //set fileExtensions that.fileResultState = { ...that.fileState[pageType].fileResultState }; }); // fileReadAs change Event, Use PyArrow $(document).on('change', this.wrapSelector('#fileReadAs'), function() { let isChecked = $(this).prop('checked'); var fileioType = that.state.vp_fileioType; var prefix = '#vp_file' + fileioType + ' '; var selectedType = that.fileState[fileioType]['selectedType']; var fileioTypePrefix = fileioType.toLowerCase(); if(fileioTypePrefix == 'write'){ fileioTypePrefix = "to"; } let fileId = that.fileState[fileioType].fileTypeId[selectedType]; if (isChecked) { // pyArrow fileId = "pa_" + fileioTypePrefix + selectedType[0].toUpperCase() + selectedType.slice(1); // that.fileState[fileioType].fileTypeId[that.state.fileExtension] = "pa_" + fileioTypePrefix + selectedFileFormat[0].toUpperCase() + selectedFileFormat.slice(1); $(that.wrapSelector(prefix + '#vp_optionBox')).closest('.vp-accordian-container').hide(); } else { // pandas // that.fileState[fileioType].fileTypeId[that.state.fileExtension] = "pd_" + fileioTypePrefix + selectedFileFormat[0].toUpperCase() + selectedFileFormat.slice(1); if (that.state.fileType != 'parquet'){ // parquet has no options area $(that.wrapSelector(prefix + '#vp_optionBox')).closest('.vp-accordian-container').show(); } } let pdLib = pandasLibrary.PANDAS_FUNCTION; let thisPkg = JSON.parse(JSON.stringify(pdLib[fileId])); that.fileState[fileioType].package = thisPkg; }); } _bindEventByType(pageType) { var that = this; var prefix = '#vp_file' + pageType + ' '; var fileioTypePrefix = pageType.toLowerCase(); if(fileioTypePrefix == 'write'){ fileioTypePrefix = "to"; } // select file type $(this.wrapSelector(prefix + '#fileType')).change(function() { var fileType = $(this).val(); that.fileState[pageType].selectedType = fileType; // reload that.renderPage(pageType); that._bindEventByType(pageType); }); // open file navigation $(this.wrapSelector(prefix + '#vp_openFileNavigationBtn')).click(function() { let type = 'save'; if (pageType == 'Read') { type = 'open'; } let extensionList = []; if (that.state.fileExtension && that.state.fileExtension.length > 0) { extensionList = that.state.fileExtension; } let fileNavi = new FileNavigation({ type: type, extensions: extensionList, finish: function(filesPath, status, error) { let {file, path} = filesPath[0]; that.state.selectedFile = file; that.state.selectedPath = path; // set text $(that.fileResultState.fileInputId).val(file); $(that.fileResultState.pathInputId).val(path); } }); fileNavi.open(); }); } saveState() { var pageType = $(this.wrapSelector('#vp_fileioType')).val(); // save input state $(this.wrapSelector('#vp_file' + pageType + ' input')).each(function () { this.defaultValue = this.value; }); // save checkbox state $(this.wrapSelector('#vp_file' + pageType + ' input[type="checkbox"]')).each(function () { if (this.checked) { this.setAttribute("checked", true); } else { this.removeAttribute("checked"); } }); // save select state $(this.wrapSelector('#vp_file' + pageType + ' select > option')).each(function () { if (this.selected) { this.setAttribute("selected", true); } else { this.removeAttribute("selected"); } }); var pageDom = $(this.wrapSelector('#vp_file' + pageType)).html(); this.state['vp_pageDom'] = pageDom; } loadStateAfterRender() { var pageType = this.state['vp_fileioType']; var pageDom = this.state['vp_pageDom']; // load pageDom $(this.wrapSelector('#vp_file' + pageType)).html(pageDom); // set page type $(this.wrapSelector('#vp_fileioType')).val(pageType); // show loaded page $(this.wrapSelector('.vp-fileio-box')).hide(); $(this.wrapSelector('#vp_file' + pageType)).show(); //set fileResultState this.fileResultState = { ...this.fileState[pageType].fileResultState }; // bind event by page type this._bindEventByType(pageType); } templateForBody() { /** Implement generating template */ let page = $(fileHtml); // Removed dataselector for Allocation input // let allocateSelector = new DataSelector({ // pageThis: this, id: 'vp_sampleReturn', placeholder: 'Variable name', value: 'vp_df' // }); // $(page).find('#vp_sampleReturn').replaceWith(allocateSelector.toTagString()); return page; } renderPage(pageType) { var that = this; var prefix = '#vp_file' + pageType + ' '; // clear $(this.wrapSelector(prefix + '#vp_inputOutputBox table tbody')).html(''); $(this.wrapSelector(prefix + '#vp_optionBox table tbody')).html(''); var fileTypeObj = this.fileState[pageType]['fileTypeId']; var selectedType = this.fileState[pageType]['selectedType']; let fileId = fileTypeObj[selectedType]; let pdLib = pandasLibrary.PANDAS_FUNCTION; let thisPkg = JSON.parse(JSON.stringify(pdLib[fileId])); this.fileState[pageType].package = thisPkg; this.state.fileExtension = that.fileExtensions[selectedType]; this.fileResultState = { ...this.fileState[pageType].fileResultState }; if (selectedType == 'pickle' || selectedType == 'parquet') { // hide additional option box $(this.wrapSelector(prefix + '#vp_optionBox')).closest('.vp-accordian-container').hide(); } else { $(this.wrapSelector(prefix + '#vp_optionBox')).closest('.vp-accordian-container').show(); } if (pageType == 'Write') { if (selectedType == 'json') { this.fileResultState.pathInputId = this.wrapSelector(prefix + '#path_or_buf'); } if (selectedType == 'pickle' || selectedType == 'parquet') { this.fileResultState.pathInputId = this.wrapSelector(prefix + '#path'); } } // render interface // pdGen.vp_showInterfaceOnPage(this.wrapSelector('#vp_file' + pageType), thisPkg); // pdGen.vp_showInterfaceOnPage(this.wrapSelector('#vp_file' + pageType), thisPkg); pdGen.vp_showInterfaceOnPage(this, thisPkg, this.state, parent=('#vp_file' + pageType)); // pyarrow can r/w parquet, csv and only read json. if ((pageType == 'Read' && selectedType == 'json') || selectedType == 'parquet'|| selectedType == 'csv') { // add checkbox 'Use PyArrow', next to File Type $(this.wrapSelector(prefix + '#vp_inputOutputBox table tbody')).prepend( $('').append($(``)) .append($(' ')) ); } else { $(this.wrapSelector(prefix + '#vp_inputOutputBox table tbody')).prepend( $('').append($(``)) .append($(' ')) ); } // prepend file type selector var fileTypeList = Object.keys(fileTypeObj); fileTypeList.forEach(type => { $(this.wrapSelector(prefix + '#fileType')).append( $(``) ); }); // prepend user option let hasAllocateTo = $(this.wrapSelector(prefix + '#o0')).length > 0; if (hasAllocateTo) { $(this.wrapSelector(prefix + '#o0')).closest('tr').after( $('').append($(``)) .append($('')) ) } else { $(this.wrapSelector(prefix + '#vp_inputOutputBox table tbody')).append( $('').append($(``)) .append($('')) ) } $(this.wrapSelector(prefix + '#fileType')).val(selectedType); // add file navigation button if (pageType == 'Write') { if (selectedType == 'json') { $(prefix + '#path_or_buf').parent().html( com_util.formatString('
' , 'vp-file-browser-button') ); } else if (selectedType == 'pickle' || selectedType == 'parquet') { $(prefix + '#path').parent().html( com_util.formatString('
' , 'vp-file-browser-button') ); } else { $(this.fileState[pageType]['fileResultState']['pathInputId']).parent().html( com_util.formatString('
' , 'i1' , 'vp-file-browser-button') ); } } else { $(this.fileState[pageType]['fileResultState']['pathInputId']).parent().html( com_util.formatString('
' , 'i0' , 'vp-file-browser-button') ); } if (pageType === 'Read' && selectedType === 'spss') { // show install button this.showInstallButton(); // show install note below File type selection $(` `).insertAfter($(this.wrapSelector('#fileType')).closest('tr')); } else { this.hideInstallButton(); } // encoding suggest input $(this.wrapSelector('#encoding')).replaceWith(function() { // encoding list : utf8 cp949 ascii var encodingList = ['utf8', 'cp949', 'ascii']; var suggestInput = new SuggestInput(); suggestInput.setComponentID('encoding'); suggestInput.addClass('vp-input vp-state'); suggestInput.setSuggestList(function() { return encodingList; }); suggestInput.setPlaceholder('encoding option'); return suggestInput.toTagString(); }); // separator suggest input $(this.wrapSelector('#sep')).replaceWith(function() { // separator list : var sepList = [',', '|', '\\t', '\\n', ':', ';', '-', '_', '&', '/', '\\']; var suggestInput = new SuggestInput(); suggestInput.setComponentID('sep'); suggestInput.addClass('vp-input vp-state'); suggestInput.setSuggestList(function() { return sepList; }); suggestInput.setPlaceholder('Input separator'); return suggestInput.toTagString(); }); } render() { super.render(); this.renderPage('Read'); this.renderPage('Write'); // initialize fileResultState this.fileResultState = { ...this.fileState['Read'].fileResultState }; if (this.state.vp_pageDom && this.state.vp_pageDom != '') { this.loadStateAfterRender(); } this._bindEventByType('Read'); this._bindEventByType('Write'); } generateInstallCode() { return [ '!pip install pyreadstat' ]; } generateCode() { var pageType = $(this.wrapSelector('#vp_fileioType')).val(); var sbCode = new com_String; this.saveState(); var prefix = '#vp_file' + pageType + ' '; var userOption = new com_String(); var userOptValue = $(this.wrapSelector(prefix + '#userOption')).val(); if (userOptValue != '') { userOption.appendFormat(', {0}', userOptValue); } if (pageType == 'Sample') { // sample csv code // var result = pdGen.vp_codeGenerator(this.uuid + ' #vp_fileSample', { ...this.fileState[pageType] }, userOption.toString()); var result = pdGen.vp_codeGenerator(this, { ...this.fileState[pageType] }, this.state, userOption.toString(), parent='#vp_fileSample'); sbCode.append(result); } else if (pageType == 'Read') { var thisPkg = JSON.parse(JSON.stringify(this.fileState[pageType].package)); thisPkg.options.push({ name: 'fileType', type: 'var' }); // var result = pdGen.vp_codeGenerator(this.uuid + ' #vp_fileRead', thisPkg, userOption.toString()); var result = pdGen.vp_codeGenerator(this, thisPkg, this.state, userOption.toString(), parent='#vp_fileRead'); sbCode.append(result); } else if (pageType == 'Write') { var thisPkg = JSON.parse(JSON.stringify(this.fileState[pageType].package)); thisPkg.options.push({ name: 'fileType', type: 'var' }); // var result = pdGen.vp_codeGenerator(this.uuid + ' #vp_fileWrite', thisPkg, userOption.toString()); var result = pdGen.vp_codeGenerator(this, thisPkg, this.state, userOption.toString(), parent='#vp_fileWrite'); sbCode.append(result); } return sbCode.toString(); } } return File; });