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

0001 /**
0002  * \file ExportCsv.qml
0003  * Export all tags of all files to 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 columnSet = {}
0029     var rows = []
0030     var selectedFramesV1 = null
0031     var selectedFramesV2 = null
0032     var selectedFramesV3 = null
0033 
0034     /**
0035      * Get list of frame names which are selected in frame table.
0036      * @param tagNr Frame.Tag_1, Frame.Tag_2, or Frame.Tag_3
0037      * @return selected frame names, null if all frames are selected.
0038      */
0039     function getSelectedFrames(tagNr) {
0040       var checked = []
0041       var frameModel = app.tag(tagNr).frameModel
0042       var numRows = frameModel.rowCount()
0043       for (var row = 0; row < numRows; ++row) {
0044         var name = script.getRoleData(frameModel, row, "name")
0045         if (script.getRoleData(frameModel, row, "checkState") === Qt.Checked) {
0046           checked.push(name)
0047         }
0048       }
0049       return checked.length < numRows ? checked : null
0050     }
0051 
0052     /**
0053      * Remove all frames from tags which are not included in @a selectedFrames.
0054      * @param tags object with frame names as keys
0055      * @param selectedFrames array with keys which will not be removed,
0056      * if null, nothing will be removed
0057      */
0058     function removeUnselectedFrames(tags, selectedFrames) {
0059       if (selectedFrames) {
0060         for (var name in tags) {
0061           if (tags.hasOwnProperty(name)) {
0062             if (!selectedFrames.includes(name)) {
0063               delete tags[name]
0064             }
0065           }
0066         }
0067       }
0068     }
0069 
0070     function doWork() {
0071       var tags
0072       var prop
0073       if (app.selectionInfo.tag(Frame.Tag_2).tagFormat) {
0074         tags = app.getAllFrames(tagv2)
0075         removeUnselectedFrames(tags, selectedFramesV2)
0076       }
0077       if (app.selectionInfo.tag(Frame.Tag_1).tagFormat) {
0078         var tagsV1 = app.getAllFrames(tagv1)
0079         removeUnselectedFrames(tagsV1, selectedFramesV1)
0080         if (typeof tags === "undefined") {
0081           tags = {}
0082         }
0083         for (prop in tagsV1) {
0084           tags["v1" + prop] = tagsV1[prop]
0085         }
0086       }
0087       if (app.selectionInfo.tag(Frame.Tag_3).tagFormat) {
0088         var tagsV3 = app.getAllFrames(Frame.TagV3)
0089         removeUnselectedFrames(tagsV3, selectedFramesV3)
0090         if (typeof tags === "undefined") {
0091           tags = {}
0092         }
0093         for (prop in tagsV3) {
0094           tags["v3" + prop] = tagsV3[prop]
0095         }
0096       }
0097       if (tags) {
0098         // Feel free to add additional columns, but you may have to exclude
0099         // them in ImportCsv.qml too.
0100         // tags["Duration"] = app.selectionInfo.formatString(Frame.Tag_2, "%{duration}")
0101         // tags["Bitrate"] = app.selectionInfo.formatString(Frame.Tag_2, "%{bitrate}")
0102         // tags["Mode"] = app.selectionInfo.formatString(Frame.Tag_2, "%{mode}")
0103         // tags["Codec"] = app.selectionInfo.formatString(Frame.Tag_2, "%{codec}")
0104         // tags["Directory"] = app.selectionInfo.formatString(Frame.Tag_2, "%{dirname}")
0105         // tags["File"] = app.selectionInfo.formatString(Frame.Tag_2, "%{file}")
0106         rows.push(tags)
0107         for (prop in tags) {
0108           columnSet[prop] = null
0109         }
0110         tags["File Path"] = app.selectionInfo.filePath
0111       }
0112 
0113       if (!app.nextFile()) {
0114         var columns = []
0115         for (prop in columnSet) {
0116           columns.push(prop)
0117         }
0118         columns.sort()
0119         columns.unshift("File Path")
0120 
0121         var numRows = rows.length
0122         var numColumns = columns.length
0123         var columnNr, rowNr
0124         var txt = ""
0125         for (columnNr = 0; columnNr < numColumns; ++columnNr) {
0126           if (columnNr > 0) {
0127             txt += "\t"
0128           }
0129           txt += columns[columnNr]
0130         }
0131         txt += "\n"
0132         for (rowNr = 0; rowNr < numRows; ++rowNr) {
0133           var row = rows[rowNr]
0134           for (columnNr = 0; columnNr < numColumns; ++columnNr) {
0135             var value = row[columns[columnNr]]
0136             if (typeof value === "undefined") {
0137               value = ""
0138             } else {
0139               if (value.indexOf("\n") !== -1) {
0140                 value = '"' + value.replace(/"/g, '""').replace(/\r\n/g, "\n") +
0141                         '"'
0142               }
0143               value = value.replace(/\t/g, " ")
0144             }
0145             if (columnNr > 0) {
0146               txt += "\t"
0147             }
0148             txt += value
0149           }
0150           txt += "\n"
0151         }
0152         var exportPath = getArguments()[0]
0153         if (!exportPath) {
0154           exportPath = app.selectFileName(
0155             "Export", app.dirName + "/export.csv",
0156             "CSV files (*.csv);;All files (*)", true)
0157           if (!exportPath) {
0158             Qt.quit()
0159             return
0160           }
0161         }
0162         if (script.writeFile(exportPath, txt)) {
0163           console.log("Exported tags of %1 files to %2".
0164                       arg(numRows).arg(exportPath))
0165         } else {
0166           console.log("Failed to write", exportPath)
0167         }
0168         Qt.quit()
0169       } else {
0170         setTimeout(doWork, 1)
0171       }
0172     }
0173 
0174     function startWork() {
0175       selectedFramesV1 = getSelectedFrames(Frame.Tag_1)
0176       selectedFramesV2 = getSelectedFrames(Frame.Tag_2)
0177       selectedFramesV3 = getSelectedFrames(Frame.Tag_3)
0178 
0179       app.expandFileListFinished.disconnect(startWork)
0180       console.log("Reading tags")
0181       app.firstFile()
0182       doWork()
0183     }
0184 
0185     if (!isStandalone() && app.hasGui()) {
0186       console.log("Expanding file list")
0187       app.expandFileListFinished.connect(startWork)
0188       app.requestExpandFileList()
0189     } else {
0190       startWork()
0191     }
0192   }
0193 }