File indexing completed on 2024-04-28 03:51:53
0001 /* 0002 This file is part of the KDE Baloo project. 0003 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "configcommand.h" 0009 #include "indexerconfig.h" 0010 0011 #include <QDir> 0012 #include <QTextStream> 0013 #include <QFileInfo> 0014 0015 #include <KLocalizedString> 0016 0017 using namespace Baloo; 0018 0019 /* 0020 * TODO: remove code duplication, we are performing similar operations 0021 * for excludeFolders, includeFolders and excludeFilters just using different 0022 * setters/getters. Figure out a way to unify the code while still keeping it 0023 * readable. 0024 */ 0025 0026 namespace 0027 { 0028 QString normalizeTrailingSlashes(QString&& path) 0029 { 0030 while (path.endsWith(QLatin1Char('/'))) { 0031 path.chop(1); 0032 } 0033 path += QLatin1Char('/'); 0034 return path; 0035 } 0036 } 0037 0038 QString ConfigCommand::command() 0039 { 0040 return QStringLiteral("config"); 0041 } 0042 0043 QString ConfigCommand::description() 0044 { 0045 return i18n("Manipulate the Baloo configuration"); 0046 } 0047 0048 int ConfigCommand::exec(const QCommandLineParser& parser) 0049 { 0050 QStringList args = parser.positionalArguments(); 0051 args.removeFirst(); 0052 0053 QTextStream out(stdout); 0054 0055 auto printCommand = [&out](const QString& command, const QString& description) { 0056 out << " "; 0057 out.setFieldWidth(25); 0058 out.setFieldAlignment(QTextStream::AlignLeft); 0059 out << command; 0060 out.setFieldWidth(0); 0061 out.setFieldAlignment(QTextStream::AlignLeft); 0062 out << description << '\n'; 0063 }; 0064 0065 const QString command = args.isEmpty() ? QStringLiteral("help") : args.takeFirst(); 0066 if (command == QLatin1String("help")) { 0067 // Show help 0068 out << i18n("The config command can be used to manipulate the Baloo Configuration\n"); 0069 out << i18n("Usage: balooctl config <command>\n\n"); 0070 out << i18n("Possible Commands:\n"); 0071 0072 printCommand(QStringLiteral("add"), i18n("Add a value to config parameter")); 0073 printCommand(QStringLiteral("rm | remove"), i18n("Remove a value from a config parameter")); 0074 printCommand(QStringLiteral("list | ls | show"), i18n("Show the value of a config parameter")); 0075 printCommand(QStringLiteral("set"), i18n("Set the value of a config parameter")); 0076 printCommand(QStringLiteral("help"), i18n("Display this help menu")); 0077 return 0; 0078 } 0079 0080 if (command == QLatin1String("list") || command == QLatin1String("ls") || command == QLatin1String("show")) { 0081 if (args.isEmpty()) { 0082 out << i18n("The following configuration options may be listed:\n\n"); 0083 0084 printCommand(QStringLiteral("hidden"), i18n("Controls if Baloo indexes hidden files and folders")); 0085 printCommand(QStringLiteral("contentIndexing"), i18n("Controls if Baloo indexes file content")); 0086 printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes")); 0087 printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index")); 0088 printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files")); 0089 printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files")); 0090 return 0; 0091 } 0092 0093 IndexerConfig config; 0094 QString value = args.takeFirst(); 0095 if (value.compare(QLatin1String("hidden"), Qt::CaseInsensitive) == 0) { 0096 if (config.indexHidden()) { 0097 out << "yes\n"; 0098 } else { 0099 out << "no\n"; 0100 } 0101 0102 return 0; 0103 } 0104 0105 if (value.compare(QStringLiteral("contentIndexing"), Qt::CaseInsensitive) == 0) { 0106 if (config.onlyBasicIndexing()) { 0107 out << "no\n"; 0108 } else { 0109 out << "yes\n"; 0110 } 0111 0112 return 0; 0113 } 0114 0115 auto printList = [&out](const QStringList& list) { 0116 for (const QString& item: list) { 0117 out << item << '\n'; 0118 } 0119 }; 0120 0121 if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) { 0122 printList(config.includeFolders()); 0123 return 0; 0124 } 0125 0126 if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) { 0127 printList(config.excludeFolders()); 0128 return 0; 0129 } 0130 0131 if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) { 0132 printList(config.excludeFilters()); 0133 return 0; 0134 } 0135 0136 if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) { 0137 printList(config.excludeMimetypes()); 0138 return 0; 0139 } 0140 0141 out << i18n("Config parameter could not be found\n"); 0142 return 1; 0143 } 0144 0145 if (command == QLatin1String("rm") || command == QLatin1String("remove")) { 0146 if (args.isEmpty()) { 0147 out << i18n("The following configuration options may be modified:\n\n"); 0148 0149 printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes")); 0150 printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index")); 0151 printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files")); 0152 printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files")); 0153 return 0; 0154 } 0155 0156 IndexerConfig config; 0157 QString value = args.takeFirst(); 0158 if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) { 0159 if (args.isEmpty()) { 0160 out << i18n("A folder must be provided\n"); 0161 return 1; 0162 } 0163 0164 QString path = args.takeFirst().replace(QStringLiteral("$HOME"), QDir::homePath()); 0165 path = normalizeTrailingSlashes(std::move(path)); 0166 QStringList folders = config.includeFolders(); 0167 if (!folders.contains(path)) { 0168 out << i18n("%1 is not in the list of include folders", path) << '\n'; 0169 return 1; 0170 } 0171 0172 folders.removeAll(path); 0173 config.setIncludeFolders(folders); 0174 0175 return 0; 0176 } 0177 0178 if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) { 0179 if (args.isEmpty()) { 0180 out << i18n("A folder must be provided\n"); 0181 return 1; 0182 } 0183 0184 QString path = args.takeFirst().replace(QStringLiteral("$HOME"), QDir::homePath()); 0185 path = normalizeTrailingSlashes(std::move(path)); 0186 QStringList folders = config.excludeFolders(); 0187 if (!folders.contains(path)) { 0188 out << i18n("%1 is not in the list of exclude folders", path) << '\n'; 0189 return 1; 0190 } 0191 0192 folders.removeAll(path); 0193 config.setExcludeFolders(folders); 0194 0195 return 0; 0196 } 0197 0198 if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) { 0199 if (args.isEmpty()) { 0200 out << i18n("A filter must be provided\n"); 0201 return 1; 0202 } 0203 0204 QStringList filters = config.excludeFilters(); 0205 if (!filters.contains(args.first())) { 0206 out << i18n("%1 is not in list of exclude filters", args.first()) << '\n'; 0207 return 1; 0208 } 0209 0210 filters.removeAll(args.first()); 0211 config.setExcludeFilters(filters); 0212 return 0; 0213 } 0214 0215 if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) { 0216 if (args.isEmpty()) { 0217 out << i18n("A mimetype must be provided\n"); 0218 return 1; 0219 } 0220 0221 QStringList mimetypes = config.excludeMimetypes(); 0222 if (!mimetypes.contains(args.first())) { 0223 out << i18n("%1 is not in list of exclude mimetypes", args.first()) << '\n'; 0224 return 1; 0225 } 0226 0227 mimetypes.removeAll(args.first()); 0228 config.setExcludeMimetypes(mimetypes); 0229 return 0; 0230 } 0231 0232 out << i18n("Config parameter could not be found\n"); 0233 return 1; 0234 } 0235 0236 if (command == QLatin1String("add")) { 0237 if (args.isEmpty()) { 0238 out << i18n("The following configuration options may be modified:\n\n"); 0239 0240 printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes")); 0241 printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index")); 0242 printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files")); 0243 printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files")); 0244 return 0; 0245 } 0246 0247 IndexerConfig config; 0248 QString value = args.takeFirst(); 0249 if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) { 0250 if (args.isEmpty()) { 0251 out << i18n("A folder must be provided\n"); 0252 return 1; 0253 } 0254 0255 auto fileInfo = QFileInfo(args.takeFirst()); 0256 if (!fileInfo.exists()) { 0257 out << i18n("Path does not exist\n"); 0258 return 1; 0259 } 0260 0261 if (!fileInfo.isDir()) { 0262 out << i18n("Path is not a directory\n"); 0263 return 1; 0264 } 0265 0266 auto path = normalizeTrailingSlashes(fileInfo.absoluteFilePath()); 0267 QStringList folders = config.includeFolders(); 0268 if (folders.contains(path)) { 0269 out << i18n("%1 is already in the list of include folders", path) << '\n'; 0270 return 1; 0271 } 0272 0273 if (config.excludeFolders().contains(path)) { 0274 out << i18n("%1 is in the list of exclude folders", path) << '\n'; 0275 return 1; 0276 } 0277 0278 folders.append(path); 0279 config.setIncludeFolders(folders); 0280 0281 return 0; 0282 } 0283 0284 if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) { 0285 if (args.isEmpty()) { 0286 out << i18n("A folder must be provided\n"); 0287 return 1; 0288 } 0289 0290 auto fileInfo = QFileInfo(args.takeFirst()); 0291 if (!fileInfo.exists()) { 0292 out << i18n("Path does not exist\n"); 0293 return 1; 0294 } 0295 0296 if (!fileInfo.isDir()) { 0297 out << i18n("Path is not a directory\n"); 0298 return 1; 0299 } 0300 0301 auto path = normalizeTrailingSlashes(fileInfo.absoluteFilePath()); 0302 QStringList folders = config.excludeFolders(); 0303 if (folders.contains(path)) { 0304 out << i18n("%1 is already in the list of exclude folders", path) << '\n'; 0305 return 1; 0306 } 0307 0308 if (config.includeFolders().contains(path)) { 0309 out << i18n("%1 is in the list of exclude folders", path) << '\n'; 0310 return 1; 0311 } 0312 0313 folders.append(path); 0314 config.setExcludeFolders(folders); 0315 0316 return 0; 0317 } 0318 0319 if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) { 0320 if (args.empty()) { 0321 out << i18n("A filter must be provided\n"); 0322 return 1; 0323 } 0324 0325 QStringList filters = config.excludeFilters(); 0326 if (filters.contains(args.first())) { 0327 out << i18n("Exclude filter is already in the list\n"); 0328 return 1; 0329 } 0330 0331 filters.append(args.first()); 0332 config.setExcludeFilters(filters); 0333 0334 return 0; 0335 } 0336 0337 if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) { 0338 if (args.empty()) { 0339 out << i18n("A mimetype must be provided\n"); 0340 return 1; 0341 } 0342 0343 QStringList mimetypes = config.excludeMimetypes(); 0344 if (mimetypes.contains(args.first())) { 0345 out << i18n("Exclude mimetype is already in the list\n"); 0346 return 1; 0347 } 0348 0349 mimetypes.append(args.first()); 0350 config.setExcludeMimetypes(mimetypes); 0351 0352 return 0; 0353 } 0354 0355 out << i18n("Config parameter could not be found\n"); 0356 return 1; 0357 } 0358 0359 if (command == QLatin1String("set")) { 0360 if (args.isEmpty()) { 0361 out << i18n("The following configuration options may be modified:\n\n"); 0362 0363 printCommand(QStringLiteral("hidden"), i18n("Controls if Baloo indexes hidden files and folders")); 0364 printCommand(QStringLiteral("contentIndexing"), i18n("Controls if Baloo indexes file content")); 0365 return 0; 0366 } 0367 0368 IndexerConfig config; 0369 QString configParam = args.takeFirst(); 0370 0371 if (configParam == QLatin1String("hidden")) { 0372 if (args.isEmpty()) { 0373 out << i18n("A value must be provided\n"); 0374 return 1; 0375 } 0376 0377 QString value = args.takeFirst(); 0378 if (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0 0379 || value.compare(QLatin1String("y"), Qt::CaseInsensitive) == 0 0380 || value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0 0381 || value.compare(QLatin1String("1")) == 0) { 0382 config.setIndexHidden(true); 0383 return 0; 0384 } 0385 0386 if (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0 0387 || value.compare(QLatin1String("n"), Qt::CaseInsensitive) == 0 0388 || value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0 0389 || value.compare(QLatin1String("0")) == 0) { 0390 config.setIndexHidden(false); 0391 return 0; 0392 } 0393 0394 out << i18n("Invalid value\n"); 0395 return 1; 0396 } 0397 0398 if (configParam.compare(QStringLiteral("contentIndexing"), Qt::CaseInsensitive) == 0) { 0399 if (args.isEmpty()) { 0400 out << i18n("A value must be provided\n"); 0401 return 1; 0402 } 0403 0404 QString value = args.takeFirst(); 0405 if (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0 0406 || value.compare(QLatin1String("y"), Qt::CaseInsensitive) == 0 0407 || value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0 0408 || value.compare(QLatin1String("1")) == 0) { 0409 config.setOnlyBasicIndexing(false); 0410 return 0; 0411 } 0412 0413 if (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0 0414 || value.compare(QLatin1String("n"), Qt::CaseInsensitive) == 0 0415 || value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0 0416 || value.compare(QLatin1String("0")) == 0) { 0417 config.setOnlyBasicIndexing(true); 0418 return 0; 0419 } 0420 0421 out << i18n("Invalid value\n"); 0422 return 1; 0423 } 0424 0425 out << i18n("Config parameter could not be found\n"); 0426 return 1; 0427 } 0428 0429 return 0; 0430 }