File indexing completed on 2024-05-12 05:46:52
0001 /****************************************************************************** 0002 * Copyright 2013 Sebastian Kügler <sebas@kde.org> * 0003 * Copyright 2014 Alex Richardson <arichardson.kde@gmail.com> * 0004 * * 0005 * This library is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU Lesser General Public * 0007 * * 0008 * License as published by the Free Software Foundation; either * 0009 * version 2.1 of the License, or (at your option) version 3, or any * 0010 * later version accepted by the membership of KDE e.V. (or its * 0011 * successor approved by the membership of KDE e.V.), which shall * 0012 * act as a proxy defined in Section 6 of version 3 of the license. * 0013 * * 0014 * This library is distributed in the hope that it will be useful, * 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0017 * Lesser General Public License for more details. * 0018 * * 0019 * You should have received a copy of the GNU Lesser General Public * 0020 * License along with this library. If not, see * 0021 * <http://www.gnu.org/licenses/>. * 0022 * * 0023 ******************************************************************************/ 0024 0025 #include "desktoptojson.h" 0026 #include "../lib/plugin/desktopfileparser_p.h" 0027 0028 0029 #include <QFile> 0030 #include <QFileInfo> 0031 #include <QJsonDocument> 0032 #include <QJsonObject> 0033 #include <QJsonArray> 0034 0035 DesktopToJson::DesktopToJson(QCommandLineParser *parser, const QCommandLineOption &i, 0036 const QCommandLineOption &o, const QCommandLineOption &v, 0037 const QCommandLineOption &c, const QCommandLineOption &s) 0038 : m_parser(parser), 0039 input(i), 0040 output(o), 0041 verbose(v), 0042 compat(c), 0043 serviceTypesOption(s) 0044 { 0045 } 0046 0047 bool DesktopFileParser::s_verbose = false; 0048 bool DesktopFileParser::s_compatibilityMode = false; 0049 0050 0051 int DesktopToJson::runMain() 0052 { 0053 if (!m_parser->isSet(input)) { 0054 m_parser->showHelp(1); 0055 return 1; 0056 } 0057 if (m_parser->isSet(verbose)) { 0058 DesktopFileParser::s_verbose = true; 0059 } 0060 if (m_parser->isSet(compat)) { 0061 DesktopFileParser::s_compatibilityMode = true; 0062 } 0063 if (!resolveFiles()) { 0064 qCCritical(DESKTOPPARSER) << "Failed to resolve filenames" << m_inFile << m_outFile << endl; 0065 return 1; 0066 } 0067 0068 #pragma message("TODO: make it an error if one of the service type files is invalid or not found") 0069 const QStringList serviceTypes = m_parser->values(serviceTypesOption); 0070 return convert(m_inFile, m_outFile, serviceTypes) ? EXIT_SUCCESS : EXIT_FAILURE; 0071 } 0072 0073 bool DesktopToJson::resolveFiles() 0074 { 0075 if (m_parser->isSet(input)) { 0076 m_inFile = m_parser->value(input); 0077 const QFileInfo fi(m_inFile); 0078 if (!fi.exists()) { 0079 qCCritical(DESKTOPPARSER) << "File not found: " << m_inFile << endl; 0080 return false; 0081 } 0082 if (!fi.isAbsolute()) { 0083 m_inFile = fi.absoluteFilePath(); 0084 } 0085 } 0086 0087 if (m_parser->isSet(output)) { 0088 m_outFile = m_parser->value(output); 0089 } else if (!m_inFile.isEmpty()) { 0090 m_outFile = m_inFile; 0091 m_outFile.replace(QStringLiteral(".desktop"), QStringLiteral(".json")); 0092 } 0093 0094 return m_inFile != m_outFile && !m_inFile.isEmpty() && !m_outFile.isEmpty(); 0095 } 0096 0097 void DesktopFileParser::convertToCompatibilityJson(const QString &key, const QString &value, QJsonObject &json, int lineNr) 0098 { 0099 // XXX: Hidden=true doesn't make sense with json plugins since the metadata is inside the .so 0100 static const QStringList boolkeys = QStringList { 0101 QStringLiteral("Hidden"), 0102 QStringLiteral("X-KDE-PluginInfo-EnabledByDefault"), 0103 }; 0104 static const QStringList stringlistkeys = QStringList { 0105 QStringLiteral("X-KDE-ServiceTypes"), 0106 QStringLiteral("X-KDE-PluginInfo-Depends"), 0107 }; 0108 if (boolkeys.contains(key)) { 0109 // should only be lower case, but be tolerant here 0110 if (value.toLower() == QLatin1String("true")) { 0111 json[key] = true; 0112 } else { 0113 if (value.toLower() != QLatin1String("false")) { 0114 qCWarning(DESKTOPPARSER).nospace() << "Expected boolean value for key \"" << key 0115 << "\" at line " << lineNr << "but got \"" << value << "\" instead."; 0116 } 0117 json[key] = false; 0118 } 0119 } else if (stringlistkeys.contains(key)) { 0120 json[key] = QJsonArray::fromStringList(DesktopFileParser::deserializeList(value)); 0121 } else { 0122 json[key] = value; 0123 } 0124 } 0125 0126 bool DesktopToJson::convert(const QString &src, const QString &dest, const QStringList& serviceTypes) 0127 { 0128 0129 QJsonObject json; 0130 DesktopFileParser::convert(src, serviceTypes, json, nullptr); 0131 0132 if (DesktopFileParser::s_compatibilityMode) { 0133 Q_ASSERT(json.value(QStringLiteral("KPlugin")).toObject().isEmpty()); 0134 json.remove(QStringLiteral("KPlugin")); 0135 } 0136 QJsonDocument jdoc; 0137 jdoc.setObject(json); 0138 0139 QFile file(dest); 0140 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { 0141 qCCritical(DESKTOPPARSER) << "Failed to open " << dest << endl; 0142 return false; 0143 } 0144 0145 file.write(jdoc.toJson()); 0146 qCDebug(DESKTOPPARSER) << "Generated " << dest << endl; 0147 return true; 0148 }