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 }