Best JavaScript code snippet using wpt
CSV.js
Source:CSV.js
1/// <reference path="../_references.js" />2/*3 Copyright (C) 2020 LESERT Aymeric - aymeric.lesert@concilium-lesert.fr4 This program is free software; you can redistribute it and/or modify5 it under the terms of the GNU General Public License as published by6 the Free Software Foundation; either version 2 of the License, or7 (at your option) any later version.8 This program is distributed in the hope that it will be useful,9 but WITHOUT ANY WARRANTY; without even the implied warranty of10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11 GNU General Public License for more details.12 You should have received a copy of the GNU General Public License along13 with this program; if not, write to the Free Software Foundation, Inc.,14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.15*/16class CSV extends LoggerBaseObject {17 /**18 * @returns {string} identifier of the current csv file19 */20 get Name() {21 return this._name;22 }23 /**24 * @returns {string} charset of the file25 */26 get Charset() {27 return this._charset;28 }29 /**30 * @returns {string} separator between 2 fields31 */32 get Separator() {33 return this._separator;34 }35 /**36 * @returns {integer} number of rows into the CSV37 */38 get RowCount() {39 return this._rowCount;40 }41 /**42 * @returns {integer} current row number into the file43 */44 get RowCurrent() {45 return this._rowNumber;46 }47 /**48 * @returns {integer} number of rows added into the database49 */50 get RowAdded() {51 return this._rowAdded;52 }53 /**54 * @returns {integer} number of rows updated into the database55 */56 get RowUpdated() {57 return this._rowUpdated;58 }59 /**60 * @returns {integer} number of rows delted into the database61 */62 get RowDeleted() {63 return this._rowDeleted;64 }65 /**66 * @returns {boolean} indicates if csv must delete all lines not imported67 */68 get WillDeleteRows() {69 return this._willDeletedRows;70 }71 /**72 * Add a new line into the CSV file73 * @param {any} table table name of the property74 */75 addRow( table ) {76 this._row.push( { _table: table === undefined || table === null ? null : table } );77 this._rowCount++;78 this._rowNumber++;79 }80 /**81 * Add a list of headers attached to the table on depends on the content of the record82 * @param {any} table columns for a given table83 * @param {any} record record containing the columns84 */85 addHeaderRecord( table, record ) {86 let addTableName = this._tablesByOrder.length > 1;87 // Add attributes88 for ( let attr in record ) {89 if ( attr.startsWith( "_" ) || attr === "Id" )90 continue;91 let ignore = attr === "CustomerId" || attr.startsWith( "Copy" );92 if ( !ignore && record._list !== null && record._list !== undefined && record._list.column === attr )93 ignore = true;94 table[attr] = { table: table._table, attribut: attr, label: ( addTableName ? ( table._table + "." ) : "" ) + attr, list: table._list, ignore: ignore };95 this._headers.push( table[attr] );96 }97 // Add sub lists98 if ( record._subLists === null || record._subLists === undefined )99 return;100 for ( let subListId in record._subLists ) {101 let subList = record._subLists[subListId];102 if ( subList === null || subList === undefined || !subList.composition )103 continue;104 table[subListId] = { table: table._table, attribut: subListId, label: ( addTableName ? ( table._table + "." ) : "" ) + subListId, list: table._list, ignore: false };105 this._headers.push( table[subListId] );106 }107 }108 /**109 * Add a list of headers110 * @param {any} table table name of the property111 * @param {any} list reference on the list ot use to show a column112 */113 writeHeaderFromList( table, list ) {114 if ( list === null || list === undefined )115 return;116 let currentTable = { _table: table, _list: list === null || list === undefined ? null : list };117 this._tablesByName[table] = currentTable;118 this._tablesByOrder.push( currentTable );119 // Add headers of the main record120 this.addHeaderRecord( currentTable, list.NewItem );121 }122 /**123 * Add a new value into the CSV file124 * @param {any} table table name of the property125 * @param {any} record record to show into the csv file126 * @param {any} list reference on the list ot use to show a column127 */128 writeRecordFromList( table, record, list ) {129 if ( record === null || record === undefined )130 return;131 this._row[this._rowCount - 1][table] = record === null || record === undefined ? null : record;132 let currentTable = this._tablesByName[table];133 if ( currentTable !== undefined ) {134 for ( let attr in record ) {135 if ( currentTable[attr] === null || currentTable[attr] === undefined || currentTable[attr].ignore )136 continue;137 /* TODO: Handle export into CSV an attached file ?138 if ( typeof record[attr] === "string" && record[attr].startsWith( "data:image/" ) )139 currentTable[attr].ignore = true; */140 }141 return;142 }143 if ( ( list === null || list === undefined ) && record._list !== undefined && record._list !== null )144 list = record._list;145 currentTable = { _table: table, _list: list === null || list === undefined ? null : list };146 this._tablesByName[table] = currentTable;147 this._tablesByOrder.push( currentTable );148 // Add headers of the current record149 this.addHeaderRecord( currentTable, record );150 }151 /**152 * Add the content of a list and its sublists into the csv file153 * @param {any} list list to add into the csv file154 * @param {any} withAssociation clone also all sublists (composition or not)155 * @param {Function} fnProgress function to call to notify the progression of the building CSV156 */157 writeFromList( list, withAssociation, fnProgress ) {158 if ( list === null || list === undefined )159 return;160 withAssociation = withAssociation !== null && withAssociation !== undefined && withAssociation === true;161 function handleRead( csv, list, headers ) {162 return function ( record ) {163 csv.addRow( list.Table );164 for ( let id in headers )165 csv.writeRecordFromList( headers[id].list.Table, headers[id].record, headers[id].list );166 csv.writeRecordFromList( list.Table, record, list );167 if ( record._subLists === null || record._subLists === undefined )168 return;169 headers.push( { list: list, record: record } );170 for ( let subListId in record._subLists ) {171 let subList = record._subLists[subListId];172 if ( subList === null || subList === undefined || !subList.composition && !withAssociation )173 continue;174 let listToAdd = record[subListId];175 for ( let id in listToAdd )176 handleRead( csv, subList.list, headers )( listToAdd[id] );177 }178 headers.pop();179 };180 }181 this._row = [];182 this._rowCount = 0;183 this._rowNumber = 0;184 this.writeHeaderFromList( list.Table, list );185 list.each( handleRead( this, list, [] ) );186 }187 /**188 * Convert the CSV data into a file189 * @param {Array} headers list of headers to add into the CSV file (null or undefined, set the default column)190 * @param {Function} fnProgress function to call to notify the progression of the building CSV191 * @returns {Blob} a blob describing the CSV file to download192 */193 toBlob( headers, fnProgress ) {194 let i = 0;195 let j = 0;196 let k = 0;197 let l = 0;198 let matrix = [];199 let previousRow = null;200 let currentRow = [];201 let file = "";202 this.info( "Building CSV file ..." );203 // Header204 if ( !Array.isArray(headers) ) {205 for ( i = 0; i < this._headers.length; i++ )206 if ( !this._headers[i].ignore )207 currentRow.push( this._headers[i].label );208 } else {209 for ( i = 0; i < this._headers.length; i++ ) {210 let exist = false;211 if ( this._headers[i].ignore )212 continue;213 for ( j = 0; j < headers.length && !exist; j++ ) {214 if ( headers[j] === this._headers[i].label ) {215 exist = true;216 } else if ( Array.isArray( headers[j] ) && headers[j][0] === this._headers[i].label ) {217 exist = true;218 if ( typeof headers[j][1] === 'string' )219 this._headers[i].label = headers[j][1];220 }221 }222 this._headers[i].ignore = !exist;223 if ( exist )224 currentRow.push( this._headers[i].label );225 }226 }227 matrix.push( currentRow );228 // Data229 if ( fnProgress )230 fnProgress( 0, 2 * this._row.length );231 for ( i = 0, k = 1; i < this._row.length; i++ ) {232 let sameRow = true;233 let line = this._row[i];234 previousRow = currentRow;235 currentRow = [];236 for ( j = 0, l = 0; j < this._headers.length; j++ ) {237 let header = this._headers[j];238 if ( header.ignore )239 continue;240 if ( header.table === null && header.attribut === "line" ) {241 currentRow.push( k );242 l++;243 continue;244 }245 if ( header.table === null && header.attribut === "table" ) {246 currentRow.push( line._table );247 l++;248 continue;249 }250 if ( header === null || header === undefined ) {251 if ( previousRow[l] !== null && previousRow[l] !== undefined )252 sameRow = false;253 currentRow.push( null );254 l++;255 continue;256 }257 let record = line[header.table];258 if ( record === null || record === undefined ) {259 if ( previousRow[l] !== null && previousRow[l] !== undefined )260 sameRow = false;261 currentRow.push( null );262 l++;263 continue;264 }265 let value = null;266 if ( header.list === null )267 value = record[header.attribut];268 else269 value = header.list.getAttributCSV( record, header.attribut );270 if ( previousRow[l] !== value )271 sameRow = false;272 currentRow.push( value );273 l++;274 }275 // Add the line if the current line is different than the previous one276 if ( !sameRow ) {277 matrix.push( currentRow );278 k++;279 }280 if ( fnProgress )281 fnProgress();282 }283 if ( fnProgress )284 fnProgress( this._row.length, this._row.length + matrix.length);285 // Convert matrix to string286 file = this._charset.toLowerCase() === "utf-8" ? "\ufeff" : "";287 for ( i = 0; i < matrix.length; i++ ) {288 currentRow = matrix[i];289 for ( j = 0; j < currentRow.length; j++ ) {290 file += String.convertCSV( currentRow[j], this._separator );291 if ( j < currentRow.length - 1 )292 file += this._separator;293 }294 file += "\n";295 if ( fnProgress )296 fnProgress();297 }298 this.info( "CSV file built" );299 return new Blob( [file], { encoding: this.Charset, type: 'text/csv;charset=' + this.Charset } )300 }301 /**302 * Convert the CSV data into a file (using generator function)303 * @param {List.List} list list of items to export304 * @param {Array} headers list of headers to add into the CSV file (null or undefined, set the default column)305 * @yield {any} status of a progress bar306 */307 *toBlobFromList( list, headers ) {308 this._blob = null;309 this.info( "Building CSV file from a list ..." );310 yield GUI.Box.Progress.Status( 0, 1, Helper.Label( "MSG_EXPORT_WRITING", this.Name ) );311 // Getting the list of items312 let items = list.getList();313 // Progress bar314 this.info( "Exporting " + items.length + " lines into the CSV file ..." );315 yield GUI.Box.Progress.Status( 0, items.length + 1 );316 // Build the blob content317 let file = this._charset.toLowerCase() === "utf-8" ? "\ufeff" : "";318 // Set the header file319 let firstHeader = false;320 for ( let header of headers ) {321 if ( firstHeader )322 file += this._separator;323 firstHeader = true;324 if ( Array.isArray( header ) ) {325 file += String.convertCSV( header[1], this._separator );326 } else {327 file += String.convertCSV( header, this._separator );328 }329 }330 file += "\n";331 yield GUI.Box.Progress.Status();332 // Set data into the CSV file333 for ( let item of Array.toIterable( items ) ) {334 let firstHeader = false;335 for ( let header of headers ) {336 let attribute = Array.isArray( header ) ? header[0] : header;337 if ( firstHeader )338 file += this._separator;339 firstHeader = true;340 file += String.convertCSV( list.getAttributCSV( item, attribute ), this._separator );341 }342 file += "\n";343 yield GUI.Box.Progress.Status();344 }345 this.info( "CSV file built" );346 this._blob = new Blob( [file], { encoding: this.Charset, type: 'text/csv;charset=' + this.Charset } )347 }348 /**349 * Retrieve the last blob generated350 */351 get Blob() {352 return this._blob;353 }354 /**355 * Check if the filename is in the list of files of csv356 * @param {string} filename name of the csv file concerned by this header357 */358 hasFile( filename ) {359 for ( let file of this._files ) {360 if ( file.name === filename )361 return true;362 }363 return false;364 }365 /**366 * Check if the name is the name of a header of the CSV file367 * @param {string} name name of the header to check368 * @param {string} filename name of the csv file concerned by this header369 */370 hasHeader( name, filename ) {371 if ( this._files.length === 0 )372 return false;373 if ( filename === null || filename === undefined )374 return this._files[0].headersByName[name] !== undefined;375 for ( let file of this._files ) {376 if ( file.name !== filename )377 continue;378 return file.headersByName[name] !== undefined;379 }380 return false;381 }382 /**383 * Execute a function on each row into the CSV file384 * @param {List.List} list list referencing the target content of the CSV file385 * @param {Errors} errors function to call to notify the progression of the parsing CSV386 * @param {any} labelPreloading label to write on preloading the content387 * @param {any} labelChecking label to write on checking the content388 * @param {any} labelImporting label to write on importing the content389 * @param {any} labelDeleting label to write on importing the content390 * @param {boolean} checking true if the checking part must be done391 * @param {boolean} importing true if the importing part must be done392 * @param {boolean} deleting true if the data to delete must be deleted393 * @param {array} files list of files to load after the main file (complete data within others files)394 * @yield {any} status of a progress bar395 */396 *toList( list, errors, labelPreloading, labelChecking, labelImporting, labelDeleting, checking, importing, deleting, files ) {397 let firstName = this._name;398 let rowCountTotal = 0;399 let columnsByOrder = [], columnsByName = {};400 // Initialize the loading csv files401 this._row = [];402 this._rowCount = 0;403 this._rowNumber = 0;404 checking = checking === null || checking === undefined || checking === true;405 importing = importing === null || importing === undefined || importing === true;406 deleting = deleting !== null && deleting !== undefined && deleting === true;407 this._willDeletedRows = deleting;408 if ( checking ) {409 this._rowAdded = 0;410 this._rowUpdated = 0;411 this._rowDeleted = 0;412 }413 // Build the list of contents into csv files414 this._files = [{415 name: this._name,416 content: this._content,417 startIndex: 0,418 size: 0,419 firstRow: 0,420 headers: [],421 headersByName: {},422 rowCount: 0423 }];424 if ( files !== null && files !== undefined && Array.isArray( files ) && files.length > 0 ) {425 for ( let file of Array.toIterable( files ) )426 this._files.push( {427 name: file.name,428 content: file.csv === null || file.csv === undefined || String.isEmptyOrWhiteSpaces( file.csv._content ) ? "" : file.csv._content,429 startIndex: 0,430 size: 0,431 firstRow: 0,432 headers: [],433 headersByName: {},434 rowCount: 0435 } );436 }437 try {438 // Step 1 - Read the headers into the CSV files and check if headers are corrects439 yield GUI.Box.Progress.Status( 0, this._files.length, labelPreloading );440 for ( let file of this._files ) {441 this._name = file.name;442 // Initialize the reading of the CSV file443 if ( String.isEmptyOrWhiteSpaces( file.content ) ) {444 errors.addGlobal( "ERR_CSV_FILE_MISSING", [file.name] );445 continue;446 }447 // Step 1 - Read the header into the CSV file448 file.size = file.content.length;449 // Has the file UTF-8 format ?450 file.startIndex = 0;451 if ( file.content[0] === "\ufeff" )452 file.startIndex++;453 if ( file.content.length > 2 && file.content[0].charCodeAt() === 239 && file.content[1].charCodeAt() === 187 && file.content[2].charCodeAt() === 191 )454 file.startIndex += 3;455 let i, j = 0, openBracelet = false;456 for ( i = file.startIndex; i < file.size && file.content[i] !== '\n' && file.content[i] !== '\r'; i++ ) {457 let c = file.content[i];458 if ( c === '"' ) {459 openBracelet = !openBracelet;460 } else if ( c === '\\' ) {461 if ( i < file.size )462 i++;463 } else if ( c === this._separator && !openBracelet ) {464 // read the header name465 let headerName = String.cleanupCSV( file.content.substring( file.startIndex, i ) );466 // check if the header is unique467 if ( file.headersByName[headerName] !== undefined )468 errors.addGlobal( "ERR_CSV_HEADERDOUBLE", [headerName, j, file.name] );469 file.headers.push( headerName );470 file.headersByName[headerName] = j;471 file.startIndex = i + 1;472 j++;473 }474 }475 // if the end of line is not reached ...476 let headerName = String.cleanupCSV( file.content.substring( file.startIndex, i ) );477 // check if the header is unique478 if ( file.headersByName[headerName] !== undefined )479 errors.addGlobal( "ERR_CSV_HEADERDOUBLE", [headerName, j, file.name] );480 file.headers.push( headerName );481 file.headersByName[headerName] = j;482 // Goto the first line483 for ( ; i <= file.size && ( file.content[i] === '\n' || file.content[i] === '\r' || file.content[i] === undefined ); i++ ) {484 if ( file.content[i] === '\n' )485 file.firstRow++;486 }487 file.startIndex = i;488 file.rowCount = file.content.count( '\n' );489 rowCountTotal += file.rowCount - file.firstRow;490 yield GUI.Box.Progress.Status();491 }492 if ( errors.HasError ) {493 this._files = [];494 return null;495 }496 // Start the reading CSV file497 this._name = firstName;498 if ( !list.startCSV( this, errors ) ) {499 if ( !errors.HasError )500 errors.addGlobal( "CSV_ABORTED" );501 this._files = [];502 return null;503 }504 // Step 2 - Preloading files only if several files must be read505 if ( Array.isArray( files ) ) {506 yield GUI.Box.Progress.Status( 0, rowCountTotal);507 let stopReading = false;508 for ( let file of this._files ) {509 // Set the current file510 this._name = file.name;511 this._rowNumber = file.firstRow;512 this._rowCount = file.rowCount;513 columnsByOrder = [];514 columnsByName = {};515 if ( !list.startPreloadingCSV( this, errors ) ) {516 stopReading = true;517 break;518 }519 // Parse the csv file and preload each line520 let errorLine = new Errors();521 let startIndex = file.startIndex;522 for ( let i = startIndex, j = 0, openBracelet = false; i <= file.size && !stopReading; i++ ) {523 let c = i === file.size ? '\n' : file.content[i];524 if ( c === '"' ) {525 openBracelet = !openBracelet;526 } else if ( c === '\\' ) {527 i++;528 } else if ( c === this._separator && !openBracelet ) {529 // read the current value530 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );531 columnsByOrder[j] = value;532 columnsByName[file.headers[j]] = value;533 j++;534 startIndex = i + 1;535 } else if ( c === '\n' || c === '\r' ) {536 // read the last value537 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );538 columnsByOrder[j] = value;539 columnsByName[file.headers[j]] = value;540 j++;541 // go to the next line (not empty)542 for ( ; i < file.size && ( file.content[i] === '\n' || file.content[i] === '\r' ); i++ ) {543 if ( file.content[i] === '\n' ) {544 this._rowNumber++;545 yield GUI.Box.Progress.Status();546 }547 }548 startIndex = i;549 if ( i < file.size ) i--;550 // preload the line551 if ( j !== file.headers.length ) {552 errorLine.addGlobal( "ERR_CSV_COLUMN_MISSING", [j, file.headers.length] );553 } else if ( !list.preloadRecordFromCSV( this, columnsByOrder, columnsByName, errorLine ) ) {554 stopReading = true;555 }556 if ( errorLine.HasFatal )557 stopReading = true;558 if ( errorLine.HasError ) {559 errors.addError( Language.Manager.Instance.interpolation( "ERR_LINE", [file.name, this.RowCurrent] ), errorLine );560 errorLine = new Errors();561 }562 // start a new line563 j = 0;564 openBracelet = false;565 }566 }567 stopReading = !list.endPreloadingCSV( this, errors ) || stopReading;568 if ( stopReading && !errors.HasError )569 errors.addGlobal( "CSV_ABORTED" );570 if ( stopReading )571 break;572 }573 if ( errors.HasError ) {574 this._name = firstName;575 list.endCSV( this, errors );576 this._files = [];577 return null;578 }579 }580 // Step 3 - Parse the CSV file and check if data are correct (only for the main file ... preloading file must have compose all files)581 this._name = firstName;582 columnsByOrder = [];583 columnsByName = {};584 if ( checking ) {585 let file = this._files[0];586 this._rowNumber = file.firstRow;587 this._rowCount = file.rowCount;588 yield GUI.Box.Progress.Status( this.RowCurrent, this.RowCount, labelChecking );589 if ( !list.startCheckingCSV( this, errors ) ) {590 list.endCSV( this, errors );591 if ( !errors.HasError )592 errors.addGlobal( "CSV_ABORTED" );593 this._files = [];594 return null;595 }596 // Parse the csv file and check each line597 let stopReading = false;598 let errorLine = new Errors();599 let startIndex = file.startIndex;600 for ( let i = startIndex, j = 0, openBracelet = false; i <= file.size && !stopReading; i++ ) {601 let c = i === file.size ? '\n' : file.content[i];602 if ( c === '"' ) {603 openBracelet = !openBracelet;604 } else if ( c === '\\' ) {605 i++;606 } else if ( c === this._separator && !openBracelet ) {607 // read the current value608 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );609 columnsByOrder[j] = value;610 columnsByName[file.headers[j]] = value;611 j++;612 startIndex = i + 1;613 } else if ( c === '\n' || c === '\r' ) {614 // read the last value615 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );616 columnsByOrder[j] = value;617 columnsByName[file.headers[j]] = value;618 j++;619 // go to the next line (not empty)620 for ( ; i < file.size && ( file.content[i] === '\n' || file.content[i] === '\r' ); i++ ) {621 if ( file.content[i] === '\n' ) {622 this._rowNumber++;623 yield GUI.Box.Progress.Status();624 }625 }626 startIndex = i;627 if ( i < file.size ) i--;628 // check if the line is completed and check the content of the line629 if ( j !== file.headers.length ) {630 errorLine.addGlobal( "ERR_CSV_COLUMN_MISSING", [j, file.headers.length] );631 } else if ( !list.checkRecordFromCSV( this, columnsByOrder, columnsByName, errorLine ) ) {632 stopReading = true;633 }634 // Retrieve the record and add or update data into the table635 if ( !stopReading && !errorLine.HasError ) {636 let record = list.getRecordFromCSV( this, columnsByOrder, columnsByName, errorLine );637 if ( record !== null && !errorLine.HasError ) {638 if ( record.oldItem === null && record.newItem !== null ) {639 // Add a new line into the database640 this._rowAdded++;641 } else if ( record.oldItem !== null && record.newItem !== null ) {642 // Update an existing line into the database only if they are different643 if ( !DSRecord.IsEqual( record.oldItem, record.newItem ) )644 this._rowUpdated++;645 }646 }647 }648 if ( errorLine.HasFatal )649 stopReading = true;650 if ( errorLine.HasError ) {651 errors.addError( Language.Manager.Instance.interpolation( "ERR_LINE", [file.name, this.RowCurrent] ), errorLine );652 errorLine = new Errors();653 }654 // start a new line655 j = 0;656 openBracelet = false;657 }658 }659 stopReading = !list.endCheckingCSV( this, errors ) || stopReading;660 if ( stopReading && !errors.HasError )661 errors.addGlobal( "CSV_ABORTED" );662 if ( errors.HasError ) {663 list.endCSV( this, errors );664 this._files = [];665 return null;666 }667 this._rowDeleted = list.getRowToDeleteCSV( this );668 }669 // Step 3 - update data into the list or in the database670 if ( importing ) {671 let file = this._files[0];672 this._rowNumber = file.firstRow;673 this._rowCount = file.rowCount;674 yield GUI.Box.Progress.Status( this.RowCurrent, this.RowCount, labelImporting );675 if ( !list.startImportingCSV( this, errors ) ) {676 list.endCSV( this, errors );677 if ( !errors.HasError )678 errors.addGlobal( "CSV_ABORTED" );679 this._files = [];680 return null;681 }682 // Parse the csv file and update each line683 this._rowAdded = 0;684 this._rowUpdated = 0;685 this._rowDeleted = 0;686 let stopReading = false;687 let errorLine = new Errors();688 let startIndex = file.startIndex;689 for ( let i = startIndex, j = 0, openBracelet = false; i <= file.size && !stopReading; i++ ) {690 let c = i === file.size ? '\n' : file.content[i];691 if ( c === '"' ) {692 openBracelet = !openBracelet;693 } else if ( c === '\\' ) {694 i++;695 } else if ( c === this._separator && !openBracelet ) {696 // read the current value697 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );698 columnsByOrder[j] = value;699 columnsByName[file.headers[j]] = value;700 j++;701 startIndex = i + 1;702 } else if ( c === '\n' || c === '\r' ) {703 // read the last value704 let value = String.cleanupCSV( file.content.substring( startIndex, i ) );705 columnsByOrder[j] = value;706 columnsByName[file.headers[j]] = value;707 j++;708 // go to the next line (not empty)709 for ( ; i < file.size && ( file.content[i] === '\n' || file.content[i] === '\r' ); i++ ) {710 if ( file.content[i] === '\n' ) {711 this._rowNumber++;712 yield GUI.Box.Progress.Status();713 }714 }715 startIndex = i;716 if ( i < file.size ) i--;717 // Update the record and add or update data into the table718 let record = list.getRecordFromCSV( this, columnsByOrder, columnsByName, errorLine );719 if ( record !== null && !errorLine.HasError ) {720 if ( record.oldItem === null && record.newItem !== null ) {721 // Add a new line into the database722 list.addItemCSV( this, record.newItem, errorLine, true, true );723 this._rowAdded++;724 } else if ( record.oldItem !== null && record.newItem !== null ) {725 // Update an existing line into the database only if they are different726 if ( !DSRecord.IsEqual( record.oldItem, record.newItem ) ) {727 list.updateItemCSV( this, list.getId( record.oldItem ), record.oldItem, record.newItem, errorLine, true, true );728 this._rowUpdated++;729 }730 }731 }732 if ( errorLine.HasFatal )733 stopReading = true;734 if ( errorLine.HasError ) {735 errors.addError( Language.Manager.Instance.interpolation( "ERR_LINE", [file.name, this.RowCurrent] ), errorLine );736 errorLine = new Errors();737 }738 // start a new line739 j = 0;740 openBracelet = false;741 }742 }743 // Step 4 - Deleting all lines to delete744 if ( deleting && !stopReading && !errors.HasError ) {745 // Getting the list of records to delete746 yield GUI.Box.Progress.Status( 0, 1, labelDeleting );747 let itemsToDelete = list.getItemsToDeleteCSV( this, errors );748 yield GUI.Box.Progress.Status();749 // Delete records750 if ( !errors.HasError && itemsToDelete.length > 0 ) {751 yield GUI.Box.Progress.Status( 0, itemsToDelete.length, labelDeleting );752 for ( let i = 0; i < itemsToDelete.length; i++ ) {753 let record = itemsToDelete[i];754 list.deleteItemCSV( this, list.getId( record ), record, errors, false );755 if ( errors.HasFatal )756 break;757 yield GUI.Box.Progress.Status();758 }759 }760 if ( errors.HasError )761 stopReading = true;762 }763 // Step 5 - Updating all temporary keys764 if ( !stopReading && !errors.HasError ) {765 // Getting the list of records to update766 yield GUI.Box.Progress.Status( 0, 1, labelImporting );767 let itemsToUpdate = list.getItemsToPostUpdateCSV( this, errors );768 yield GUI.Box.Progress.Status();769 // Update records770 if ( !errors.HasError && itemsToUpdate.length > 0 ) {771 yield GUI.Box.Progress.Status( 0, itemsToUpdate.length, labelImporting );772 for ( let i = 0; i < itemsToUpdate.length; i++ ) {773 let oldRecord = itemsToUpdate[i][0];774 let newRecord = itemsToUpdate[i][1];775 list.updateItemCSV( this, list.getId( oldRecord ), oldRecord, newRecord, errors, true, true );776 if ( errors.HasFatal )777 break;778 yield GUI.Box.Progress.Status();779 }780 }781 if ( errors.HasError )782 stopReading = true;783 }784 // Close the importing data785 stopReading = !list.endImportingCSV( this, errors ) || stopReading;786 if ( stopReading && !errors.HasError )787 errors.addGlobal( "CSV_ABORTED" );788 if ( errors.HasError ) {789 list.endCSV( this, errors );790 this._files = [];791 return null;792 }793 this._rowDeleted = list.getRowToDeleteCSV( this );794 }795 if ( !deleting )796 this._rowNumber = 0;797 list.endCSV( this, errors );798 } catch ( e ) {799 errors.addFatal( "ERR_CSV_UNEXPECTED", this.Name );800 this.exception( "Unable to load data due to an unexpected error", e );801 }802 this._name = firstName;803 this._files = [];804 return null;805 }806 /**807 * Duplicate the content of the CSV file808 * @param {any} name name of the CSV component809 */810 copy( name ) {811 return new CSV( name, this, this._separator, this._charset );812 }813 /**814 * Constructor815 * @param {string} name name of the CSV component816 * @param {any} content content to decode as a CSV file (or a CSV instance)817 * @param {string} separator string describing the separator between 2 columns818 * @param {string} charset string describing the charset of the target file819 */820 constructor( name, content, separator, charset ) {821 super( "CSV" + ( name ? ( "." + name ) : "" ) );822 this._name = String.isEmptyOrWhiteSpaces( name ) ? "" : name;823 if ( content instanceof CSV )824 this._content = content._content;825 else826 this._content = ( String.isEmptyOrWhiteSpaces( content ) && !( typeof content === 'string' ) ) ? null : content;827 this._charset = String.isEmptyOrWhiteSpaces( charset ) ? "utf-8" : charset;828 this._separator = String.isEmptyOrWhiteSpaces( separator ) ? ";" : separator;829 this._blob = null;830 this._row = [];831 this._rowCount = 0;832 this._rowNumber = 0;833 this._rowAdded = 0;834 this._rowUpdated = 0;835 this._rowDeleted = 0;836 this._willDeletedRows = false;837 this._tablesByOrder = [];838 this._tablesByName = {};839 this._headers = [];840 this._headers.push( { table: null, attribut: "line", label: "line", list: null, ignore: false } );841 this._headers.push( { table: null, attribut: "table", label: "table", list: null, ignore: false } );842 this._files = [];843 }...
vorleserModule.js
Source:vorleserModule.js
1/**2 * Created by wassi on 27.12.13.3 */4var identifier= "sound/vorleser";5var soundAccess = require('../../hardware/soundAccess');6var sharedResources = require('../../services/sharedResources');7var event = require('../../services/eventbus');8var fs = require('fs');9var settingsManager = require('../../services/settings');10var _index = 0;11//milliseconds to rewind on start12var startOffset = -5000;13var _basedir = 'audiobooks/';14var settings = {15 dir: 'test',16 file: '1.mp3',17 position: 0,18 maxVolume:100,19 lowVolume: 50,20 readTime: 5000,21 fadeOutTime : 500022};23//store initial settings in DB24settingsManager.init(settings,identifier);25var _volume = settings.maxVolume;26var running = false;27var player = null;28var startTime;29var positionAtStart = 0;30var read = function(){31 var files = fs.readdirSync(_basedir + settings.dir);32 positionAtStart = Math.max(0, settings.position+startOffset);33 startTime = Date.now();34 files.sort();35 //console.log(files);36 _index = files.indexOf(settings.file);37 if(_index==-1){38 settings.file = files[0];39 settings.position = 0;40 _index = 0;41 }42 //reduce volume after 10 minutes43 player = soundAccess.play(_basedir + settings.dir + '/' + settings.file);44 player.seek(settings.position);45 player.play();46 player.volume(_volume);47 //read next file, when current file finished48 player.on('exit',function(){49 _index++;50 if(_index<files.length){51 settings.position = 0;52 settings.file = files[_index];53 read();54 }55 });56 stopReading = null;57 reduceVolume();58};59var stopReading;60var reduceReading;61var reduceVolume=function(){62 reduceReading = setTimeout(function(){63 _volume = settings.lowVolume;64 player.volume(_volume);65 //Stop reading after one minute66 stopReading = setTimeout(function(){67 stop();68 },settings.fadeOutTime);69 event.emitter.once('movement.primary',function(){70 if(!player) return;71 //console.log('TEST');72 settings.position = positionAtStart + Date.now()-startTime;73 //update position74 exports.setSettings(settings);75 clearTimeout(stopReading);76 _volume = settings.maxVolume;77 player.volume(_volume);78 reduceVolume();79 });80 },settings.readTime);81};82var stop=function(){83 if(player){84 player.stop();85 player = null;86 settings.position = positionAtStart + Date.now()-startTime;87 }88 clearTimeout(stopReading);89 clearTimeout(reduceReading);90 exports.setSettings(settings);//auto save on closing91 running = false;92};93var soundControl = {94 start:function(){95 soundAccess.turnOn();96 _volume = settings.maxVolume;97 read();98 running = true;99 },100 stop:function(){101 soundAccess.turnOff()102 stop();103 },104 isProcessRunning: function(){105 return running;106 }107};108exports.stop = function(){109 soundControl.stop();110};111/*var loadSettings = function(){112 settingsManager.load(settings,identifier);113};*/114var saveSettings = function(s){115 settingsManager.save(s,identifier,settings);116};117exports.launch = function(){118 sharedResources.sound.run(soundControl);119};120exports.getIdentifier = function(){121 return {name:"Vorleser",identifier:identifier};122};123exports.setSettings = function(s){124 saveSettings(s);125};126exports.getSettings = function(){127 return settings;...
useTextToSpeech.ts
Source:useTextToSpeech.ts
...26 speech.pitch = pitch || 0.8;27 speech.rate = rate || 1;28 speech.volume = volume || 1;29 speech.text = text;30 stopReading();31 window.speechSynthesis.speak(speech);32 };33 return { readText, stopReading };34};...
Using AI Code Generation
1var wpt = require('wpt');2var fs = require('fs');3var config = require('./config.json');4var wpt = new WebPageTest('www.webpagetest.org', config.apiKey);5var testId = '160430_7E_1d6';6wpt.stopReading(testId, function(err, data) {7 if (err) {8 console.log(err);9 } else {10 console.log(data);11 }12});
Using AI Code Generation
1var wpt = require('wpt');2var wptClient = new wpt('your wpt API key');3wptClient.stopReading('testId',function(err,data){4 console.log(data);5});6var wpt = require('wpt');7var wptClient = new wpt('your wpt API key');8wptClient.stopReading('testId',function(err,data){9 console.log(data);10});11var wpt = require('wpt');12var wptClient = new wpt('your wpt API key');13wptClient.stopReading('testId',function(err,data){14 console.log(data);15});16var wpt = require('wpt');17var wptClient = new wpt('your wpt API key');18wptClient.stopReading('testId',function(err,data){19 console.log(data);20});21var wpt = require('wpt');22var wptClient = new wpt('your wpt API key');23wptClient.stopReading('testId',function(err,data){24 console.log(data);25});26var wpt = require('wpt');27var wptClient = new wpt('your wpt API key');28wptClient.stopReading('testId',function(err,data){29 console.log(data);30});31var wpt = require('wpt');32var wptClient = new wpt('your wpt API key');33wptClient.stopReading('testId',function(err,data){34 console.log(data);35});36var wpt = require('wpt');37var wptClient = new wpt('your wpt API key');38wptClient.stopReading('testId',function(err,data){39 console.log(data);40});41var wpt = require('wpt');42var wptClient = new wpt('your wpt API key');43wptClient.stopReading('testId',function(err,data){44 console.log(data);45});
Using AI Code Generation
1var wptoolkit = require('wptoolkit');2wptoolkit.stopReading(function(err, data) {3 console.log(data);4});5getBatteryStatus(callback)6var wptoolkit = require('wptoolkit');7wptoolkit.getBatteryStatus(function(err, data) {8 console.log(data);9});10getDeviceVersion(callback)11var wptoolkit = require('wptoolkit');12wptoolkit.getDeviceVersion(function(err, data) {13 console.log(data);14});15getDeviceInformation(callback)16var wptoolkit = require('wptoolkit');17wptoolkit.getDeviceInformation(function(err, data) {18 console.log(data);19});20getDeviceSerial(callback)21var wptoolkit = require('wptoolkit');22wptoolkit.getDeviceSerial(function(err, data) {23 console.log(data);24});25getDeviceTime(callback)26var wptoolkit = require('wptoolkit');27wptoolkit.getDeviceTime(function(err, data) {28 console.log(data);29});30setDeviceTime(callback)31var wptoolkit = require('wptoolkit');32wptoolkit.setDeviceTime(function(err, data) {
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!