Warning, /multimedia/kid3/src/qml/script/ImportCsv.qml is written in an unsupported language. File is not indexed.

0001 /**
0002  * \file ImportCsv.qml
0003  * Import all tags of all files from a CSV file.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 06 Mar 2015
0008  *
0009  * Copyright (C) 2015-2021  Urs Fleisch
0010  *
0011  * This program is free software; you can redistribute it and/or modify
0012  * it under the terms of the GNU Lesser General Public License as published by
0013  * the Free Software Foundation; version 3.
0014  *
0015  * This program is distributed in the hope that it will be useful,
0016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  * GNU Lesser General Public License for more details.
0019  *
0020  * You should have received a copy of the GNU Lesser General Public License
0021  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  */
0023 
0024 import Kid3 1.0
0025 
0026 Kid3Script {
0027   onRun: {
0028     var rows, names, files = {}
0029     var numRowsImported = 0
0030     var round = 0
0031 
0032     function unquoteColumns(columns) {
0033       for (var i = 0; i < columns.length; ++i) {
0034         var val = columns[i]
0035         if (val.length >= 2 &&
0036             val[0] === '"' && val[val.length - 1] === '"') {
0037           val = val.substr(1, val.length - 2).replace(/""/g, '"')
0038           columns[i] = val
0039         }
0040       }
0041       return columns
0042     }
0043 
0044     function readCsvFile(filePath) {
0045       var filePathCol = -1
0046       var lines = ("" + script.readFile(filePath)).split(/[\r\n]+/)
0047       for (var i = 0; i < lines.length; ++i) {
0048         var line = lines[i]
0049         if (line.length > 0) {
0050           var columns = unquoteColumns(line.split("\t"))
0051           if (i > 0) {
0052             if (columns.length < names.length && i + 1 < lines.length) {
0053               // The line does not contain all columns, check for continuation.
0054               var lastColumn = columns[columns.length - 1]
0055               if (lastColumn.length > 1 && lastColumn[0] === '"' &&
0056                   lastColumn[lastColumn.length - 1] !== '"') {
0057                 for (var consumed = 0, extendedLine = line;
0058                      i + 1 + consumed < lines.length &&
0059                      columns.length < names.length;
0060                      ++consumed) {
0061                   extendedLine += "\n"
0062                   extendedLine += lines[i + 1 + consumed]
0063                   columns = unquoteColumns(extendedLine.split("\t"))
0064                 }
0065                 if (columns.length === names.length) {
0066                   // Continuation OK, apply changes.
0067                   lines[i] = extendedLine
0068                   lines.splice(i + 1, consumed)
0069                 } else {
0070                   columns = unquoteColumns(line.split("\t"))
0071                 }
0072               }
0073             }
0074             if (filePathCol >= 0 && filePathCol < columns.length) {
0075               files[columns[filePathCol]] = i - 1
0076             }
0077             rows.push(columns)
0078           } else {
0079             names = columns
0080             filePathCol = names.indexOf("File Path")
0081             rows = []
0082           }
0083         }
0084       }
0085     }
0086 
0087     function doWork() {
0088       var rowNr
0089       if (files) {
0090         var filePath = app.selectionInfo.filePath
0091         rowNr = files[filePath]
0092       } else {
0093         rowNr = numRowsImported
0094       }
0095 
0096       if (typeof rowNr !== "undefined" && rowNr >= 0 && rowNr < rows.length) {
0097         var row = rows[rowNr]
0098         for (var i = 0; i < row.length && i < names.length; ++i) {
0099           var frameName = names[i]
0100           var frameValue = row[i]
0101           if (frameName !== "File Path" && frameName !== "Duration" &&
0102               frameValue !== "") {
0103             frameValue = frameValue.replace(/\\n/g, "\n").replace(/\\r/g, "\r").
0104                                     replace(/\\t/g, "\t")
0105             if (frameName.substr(0, 2) === "v1") {
0106               frameName = frameName.substr(2)
0107               app.setFrame(tagv1, frameName, frameValue)
0108             } else if (frameName.substr(0, 2) === "v3") {
0109               frameName = frameName.substr(2)
0110               app.setFrame(Frame.TagV3, frameName, frameValue)
0111             } else {
0112               app.setFrame(tagv2, frameName, frameValue)
0113             }
0114           }
0115         }
0116         ++numRowsImported
0117       } else if (filePath) {
0118         console.log("No data for " + filePath)
0119       }
0120       if (!app.nextFile()) {
0121         console.log("Imported tags for %1 files".arg(numRowsImported))
0122         if (isStandalone()) {
0123           // Save the changes if the script is started stand-alone, not from Kid3.
0124           app.saveDirectory()
0125         } else if (numRowsImported === 0 && round === 0) {
0126           console.log("No files found, importing unconditionally.")
0127           files = undefined
0128           ++round;
0129           app.firstFile()
0130           doWork()
0131         }
0132         Qt.quit()
0133       } else {
0134         setTimeout(doWork, 1)
0135       }
0136     }
0137 
0138     function startWork() {
0139       app.expandFileListFinished.disconnect(startWork)
0140       console.log("Setting tags")
0141       app.firstFile()
0142       doWork()
0143     }
0144 
0145     var importPath = getArguments()[0]
0146     if (!importPath) {
0147       importPath = app.selectFileName(
0148         "Import", app.dirName, "CSV files (*.csv);;All files (*)", false)
0149       if (!importPath) {
0150         Qt.quit()
0151         return
0152       }
0153     }
0154     readCsvFile(importPath)
0155     if (rows && rows.length > 0 && names && names.length > 1) {
0156       console.log("Read tags for %1 files from %2".
0157                   arg(rows.length).arg(importPath))
0158       if (Object.keys(files).length === 0) {
0159         console.log("No File Path column found, importing unconditionally.")
0160         files = undefined
0161       }
0162 
0163       if (!isStandalone() && app.hasGui()) {
0164         console.log("Expanding file list")
0165         app.expandFileListFinished.connect(startWork)
0166         app.requestExpandFileList()
0167       } else {
0168         startWork()
0169       }
0170     } else {
0171       console.log("No data found in %1".arg(importPath))
0172     }
0173   }
0174 }