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 }