Baloo

configcommand.cpp
1 /*
2  This file is part of the KDE Baloo project.
3  SPDX-FileCopyrightText: 2015 Vishesh Handa <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7 
8 #include "configcommand.h"
9 #include "indexerconfig.h"
10 
11 #include <QDir>
12 #include <QTextStream>
13 #include <QFileInfo>
14 
15 #include <KLocalizedString>
16 
17 using namespace Baloo;
18 
19 /*
20  * TODO: remove code duplication, we are performing similar operations
21  * for excludeFolders, includeFolders and excludeFilters just using different
22  * setters/getters. Figure out a way to unify the code while still keeping it
23  * readable.
24  */
25 
26 namespace
27 {
28 QString normalizeTrailingSlashes(QString&& path)
29 {
30  while (path.endsWith(QLatin1Char('/'))) {
31  path.chop(1);
32  }
33  path += QLatin1Char('/');
34  return path;
35 }
36 }
37 
38 QString ConfigCommand::command()
39 {
40  return QStringLiteral("config");
41 }
42 
43 QString ConfigCommand::description()
44 {
45  return i18n("Manipulate the Baloo configuration");
46 }
47 
48 int ConfigCommand::exec(const QCommandLineParser& parser)
49 {
50  QStringList args = parser.positionalArguments();
51  args.removeFirst();
52 
53  QTextStream out(stdout);
54 
55  auto printCommand = [&out](const QString& command, const QString& description) {
56  out << " ";
57  out.setFieldWidth(25);
58  out.setFieldAlignment(QTextStream::AlignLeft);
59  out << command;
60  out.setFieldWidth(0);
61  out.setFieldAlignment(QTextStream::AlignLeft);
62  out << description << '\n';
63  };
64 
65  const QString command = args.isEmpty() ? QStringLiteral("help") : args.takeFirst();
66  if (command == QLatin1String("help")) {
67  // Show help
68  out << i18n("The config command can be used to manipulate the Baloo Configuration\n");
69  out << i18n("Usage: balooctl config <command>\n\n");
70  out << i18n("Possible Commands:\n");
71 
72  printCommand(QStringLiteral("add"), i18n("Add a value to config parameter"));
73  printCommand(QStringLiteral("rm | remove"), i18n("Remove a value from a config parameter"));
74  printCommand(QStringLiteral("list | ls | show"), i18n("Show the value of a config parameter"));
75  printCommand(QStringLiteral("set"), i18n("Set the value of a config parameter"));
76  printCommand(QStringLiteral("help"), i18n("Display this help menu"));
77  return 0;
78  }
79 
80  if (command == QLatin1String("list") || command == QLatin1String("ls") || command == QLatin1String("show")) {
81  if (args.isEmpty()) {
82  out << i18n("The following configuration options may be listed:\n\n");
83 
84  printCommand(QStringLiteral("hidden"), i18n("Controls if Baloo indexes hidden files and folders"));
85  printCommand(QStringLiteral("contentIndexing"), i18n("Controls if Baloo indexes file content"));
86  printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes"));
87  printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index"));
88  printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files"));
89  printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files"));
90  return 0;
91  }
92 
94  QString value = args.takeFirst();
95  if (value.compare(QLatin1String("hidden"), Qt::CaseInsensitive) == 0) {
96  if (config.indexHidden()) {
97  out << "yes\n";
98  } else {
99  out << "no\n";
100  }
101 
102  return 0;
103  }
104 
105  if (value.compare(QStringLiteral("contentIndexing"), Qt::CaseInsensitive) == 0) {
106  if (config.onlyBasicIndexing()) {
107  out << "no\n";
108  } else {
109  out << "yes\n";
110  }
111 
112  return 0;
113  }
114 
115  auto printList = [&out](const QStringList& list) {
116  for (const QString& item: list) {
117  out << item << '\n';
118  }
119  };
120 
121  if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) {
122  printList(config.includeFolders());
123  return 0;
124  }
125 
126  if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) {
127  printList(config.excludeFolders());
128  return 0;
129  }
130 
131  if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) {
132  printList(config.excludeFilters());
133  return 0;
134  }
135 
136  if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) {
137  printList(config.excludeMimetypes());
138  return 0;
139  }
140 
141  out << i18n("Config parameter could not be found\n");
142  return 1;
143  }
144 
145  if (command == QLatin1String("rm") || command == QLatin1String("remove")) {
146  if (args.isEmpty()) {
147  out << i18n("The following configuration options may be modified:\n\n");
148 
149  printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes"));
150  printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index"));
151  printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files"));
152  printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files"));
153  return 0;
154  }
155 
157  QString value = args.takeFirst();
158  if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) {
159  if (args.isEmpty()) {
160  out << i18n("A folder must be provided\n");
161  return 1;
162  }
163 
164  QString path = args.takeFirst().replace(QStringLiteral("$HOME"), QDir::homePath());
165  path = normalizeTrailingSlashes(std::move(path));
166  QStringList folders = config.includeFolders();
167  if (!folders.contains(path)) {
168  out << i18n("%1 is not in the list of include folders", path) << '\n';
169  return 1;
170  }
171 
172  folders.removeAll(path);
173  config.setIncludeFolders(folders);
174 
175  return 0;
176  }
177 
178  if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) {
179  if (args.isEmpty()) {
180  out << i18n("A folder must be provided\n");
181  return 1;
182  }
183 
184  QString path = args.takeFirst().replace(QStringLiteral("$HOME"), QDir::homePath());
185  path = normalizeTrailingSlashes(std::move(path));
186  QStringList folders = config.excludeFolders();
187  if (!folders.contains(path)) {
188  out << i18n("%1 is not in the list of exclude folders", path) << '\n';
189  return 1;
190  }
191 
192  folders.removeAll(path);
193  config.setExcludeFolders(folders);
194 
195  return 0;
196  }
197 
198  if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) {
199  if (args.isEmpty()) {
200  out << i18n("A filter must be provided\n");
201  return 1;
202  }
203 
204  QStringList filters = config.excludeFilters();
205  if (!filters.contains(args.first())) {
206  out << i18n("%1 is not in list of exclude filters", args.first()) << '\n';
207  return 1;
208  }
209 
210  filters.removeAll(args.first());
211  config.setExcludeFilters(filters);
212  return 0;
213  }
214 
215  if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) {
216  if (args.isEmpty()) {
217  out << i18n("A mimetype must be provided\n");
218  return 1;
219  }
220 
221  QStringList mimetypes = config.excludeMimetypes();
222  if (!mimetypes.contains(args.first())) {
223  out << i18n("%1 is not in list of exclude mimetypes", args.first()) << '\n';
224  return 1;
225  }
226 
227  mimetypes.removeAll(args.first());
228  config.setExcludeMimetypes(mimetypes);
229  return 0;
230  }
231 
232  out << i18n("Config parameter could not be found\n");
233  return 1;
234  }
235 
236  if (command == QLatin1String("add")) {
237  if (args.isEmpty()) {
238  out << i18n("The following configuration options may be modified:\n\n");
239 
240  printCommand(QStringLiteral("includeFolders"), i18n("The list of folders which Baloo indexes"));
241  printCommand(QStringLiteral("excludeFolders"), i18n("The list of folders which Baloo will never index"));
242  printCommand(QStringLiteral("excludeFilters"), i18n("The list of filters which are used to exclude files"));
243  printCommand(QStringLiteral("excludeMimetypes"), i18n("The list of mimetypes which are used to exclude files"));
244  return 0;
245  }
246 
248  QString value = args.takeFirst();
249  if (value.compare(QLatin1String("includeFolders"), Qt::CaseInsensitive) == 0) {
250  if (args.isEmpty()) {
251  out << i18n("A folder must be provided\n");
252  return 1;
253  }
254 
255  auto fileInfo = QFileInfo(args.takeFirst());
256  if (!fileInfo.exists()) {
257  out << i18n("Path does not exist\n");
258  return 1;
259  }
260 
261  if (!fileInfo.isDir()) {
262  out << i18n("Path is not a directory\n");
263  return 1;
264  }
265 
266  auto path = normalizeTrailingSlashes(fileInfo.absoluteFilePath());
267  QStringList folders = config.includeFolders();
268  if (folders.contains(path)) {
269  out << i18n("%1 is already in the list of include folders", path) << '\n';
270  return 1;
271  }
272 
273  if (config.excludeFolders().contains(path)) {
274  out << i18n("%1 is in the list of exclude folders", path) << '\n';
275  return 1;
276  }
277 
278  folders.append(path);
279  config.setIncludeFolders(folders);
280 
281  return 0;
282  }
283 
284  if (value.compare(QLatin1String("excludeFolders"), Qt::CaseInsensitive) == 0) {
285  if (args.isEmpty()) {
286  out << i18n("A folder must be provided\n");
287  return 1;
288  }
289 
290  auto fileInfo = QFileInfo(args.takeFirst());
291  if (!fileInfo.exists()) {
292  out << i18n("Path does not exist\n");
293  return 1;
294  }
295 
296  if (!fileInfo.isDir()) {
297  out << i18n("Path is not a directory\n");
298  return 1;
299  }
300 
301  auto path = normalizeTrailingSlashes(fileInfo.absoluteFilePath());
302  QStringList folders = config.excludeFolders();
303  if (folders.contains(path)) {
304  out << i18n("%1 is already in the list of exclude folders", path) << '\n';
305  return 1;
306  }
307 
308  if (config.includeFolders().contains(path)) {
309  out << i18n("%1 is in the list of exclude folders", path) << '\n';
310  return 1;
311  }
312 
313  folders.append(path);
314  config.setExcludeFolders(folders);
315 
316  return 0;
317  }
318 
319  if (value.compare(QStringLiteral("excludeFilters"), Qt::CaseInsensitive) == 0) {
320  if (args.empty()) {
321  out << i18n("A filter must be provided\n");
322  return 1;
323  }
324 
325  QStringList filters = config.excludeFilters();
326  if (filters.contains(args.first())) {
327  out << i18n("Exclude filter is already in the list\n");
328  return 1;
329  }
330 
331  filters.append(args.first());
332  config.setExcludeFilters(filters);
333 
334  return 0;
335  }
336 
337  if (value.compare(QStringLiteral("excludeMimetypes"), Qt::CaseInsensitive) == 0) {
338  if (args.empty()) {
339  out << i18n("A mimetype must be provided\n");
340  return 1;
341  }
342 
343  QStringList mimetypes = config.excludeMimetypes();
344  if (mimetypes.contains(args.first())) {
345  out << i18n("Exclude mimetype is already in the list\n");
346  return 1;
347  }
348 
349  mimetypes.append(args.first());
350  config.setExcludeMimetypes(mimetypes);
351 
352  return 0;
353  }
354 
355  out << i18n("Config parameter could not be found\n");
356  return 1;
357  }
358 
359  if (command == QLatin1String("set")) {
360  if (args.isEmpty()) {
361  out << i18n("The following configuration options may be modified:\n\n");
362 
363  printCommand(QStringLiteral("hidden"), i18n("Controls if Baloo indexes hidden files and folders"));
364  printCommand(QStringLiteral("contentIndexing"), i18n("Controls if Baloo indexes file content"));
365  return 0;
366  }
367 
369  QString configParam = args.takeFirst();
370 
371  if (configParam == QLatin1String("hidden")) {
372  if (args.isEmpty()) {
373  out << i18n("A value must be provided\n");
374  return 1;
375  }
376 
377  QString value = args.takeFirst();
378  if (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0
379  || value.compare(QLatin1String("y"), Qt::CaseInsensitive) == 0
380  || value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0
381  || value.compare(QLatin1String("1")) == 0) {
382  config.setIndexHidden(true);
383  return 0;
384  }
385 
386  if (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0
387  || value.compare(QLatin1String("n"), Qt::CaseInsensitive) == 0
388  || value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0
389  || value.compare(QLatin1String("0")) == 0) {
390  config.setIndexHidden(false);
391  return 0;
392  }
393 
394  out << i18n("Invalid value\n");
395  return 1;
396  }
397 
398  if (configParam.compare(QStringLiteral("contentIndexing"), Qt::CaseInsensitive) == 0) {
399  if (args.isEmpty()) {
400  out << i18n("A value must be provided\n");
401  return 1;
402  }
403 
404  QString value = args.takeFirst();
405  if (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0
406  || value.compare(QLatin1String("y"), Qt::CaseInsensitive) == 0
407  || value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0
408  || value.compare(QLatin1String("1")) == 0) {
409  config.setOnlyBasicIndexing(false);
410  return 0;
411  }
412 
413  if (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0
414  || value.compare(QLatin1String("n"), Qt::CaseInsensitive) == 0
415  || value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0
416  || value.compare(QLatin1String("0")) == 0) {
417  config.setOnlyBasicIndexing(true);
418  return 0;
419  }
420 
421  out << i18n("Invalid value\n");
422  return 1;
423  }
424 
425  out << i18n("Config parameter could not be found\n");
426  return 1;
427  }
428 
429  return 0;
430 }
void append(const T &value)
T & first()
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
CaseInsensitive
int removeAll(const T &value)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void chop(int n)
QStringList positionalArguments() const const
QString homePath()
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
bool empty() const const
QString i18n(const char *text, const TYPE &arg...)
T takeFirst()
Implements storage for docIds without any associated data Instantiated for:
Definition: coding.cpp:11
void removeFirst()
bool isEmpty() const const
KSharedConfigPtr config()
QString path(const QString &relativePath)
int compare(const QString &other, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Nov 29 2023 03:56:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.