Baloo

tools/balooctl/main.cpp
1/*
2 SPDX-FileCopyrightText: 2012-2015 Vishesh Handa <me@vhanda.in>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6
7#include <QCoreApplication>
8#include <QCommandLineParser>
9#include <QFile>
10
11#include <KAboutData>
12#include <KLocalizedString>
13#include <KFormat>
14#include <QProcess>
15#include <QTextStream>
16#include <QFileInfo>
17#include <QLocale>
18
19#include <QDBusConnection>
20#include <QDBusConnectionInterface>
21
22#include "global.h"
23#include "database.h"
24#include "transaction.h"
25#include "databasesize.h"
26#include "config.h"
27
28#include "indexer.h"
29#include "indexerconfig.h"
30#include "idutils.h"
31#include "fileindexerconfig.h"
32#include "monitorcommand.h"
33#include "schedulerinterface.h"
34#include "maininterface.h"
35#include "indexerstate.h"
36#include "configcommand.h"
37#include "statuscommand.h"
38
39#include "clearcommand.h"
40#include "indexcommand.h"
41
42using namespace Baloo;
43
44void start()
45{
46 const QString exe = QStringLiteral(KDE_INSTALL_FULL_LIBEXECDIR_KF "/baloo_file");
48}
49
50int main(int argc, char* argv[])
51{
52 QCoreApplication app(argc, argv);
53
54 KAboutData aboutData(QStringLiteral("baloo"), i18n("balooctl"), QStringLiteral(PROJECT_VERSION));
55 aboutData.addAuthor(i18n("Vishesh Handa"), QString(), QStringLiteral("vhanda@kde.org"));
56
58
59 QCommandLineParser parser;
60 parser.addPositionalArgument(QStringLiteral("command"), i18n("The command to execute"));
61
62 parser.addPositionalArgument(QStringLiteral("status"), i18n("Print the status of the indexer"));
63 parser.addPositionalArgument(QStringLiteral("enable"), i18n("Enable the file indexer"));
64 parser.addPositionalArgument(QStringLiteral("disable"), i18n("Disable the file indexer"));
65 parser.addPositionalArgument(QStringLiteral("purge"), i18n("Remove the index database"));
66 parser.addPositionalArgument(QStringLiteral("suspend"), i18n("Suspend the file indexer"));
67 parser.addPositionalArgument(QStringLiteral("resume"), i18n("Resume the file indexer"));
68 parser.addPositionalArgument(QStringLiteral("check"), i18n("Check for any unindexed files and index them"));
69 parser.addPositionalArgument(QStringLiteral("index"), i18n("Index the specified files"));
70 parser.addPositionalArgument(QStringLiteral("clear"), i18n("Forget the specified files"));
71 parser.addPositionalArgument(QStringLiteral("config"), i18n("Modify the Baloo configuration"));
72 parser.addPositionalArgument(QStringLiteral("monitor"), i18n("Monitor the file indexer"));
73 parser.addPositionalArgument(QStringLiteral("indexSize"), i18n("Display the disk space used by index"));
74 parser.addPositionalArgument(QStringLiteral("failed"), i18n("Display files which could not be indexed"));
75
76 QString statusFormatDescription = i18nc("Format to use for status command, %1|%2|%3 are option values, %4 is a CLI command",
77 "Output format <%1|%2|%3>.\nThe default format is \"%1\".\nOnly applies to \"%4\"",
78 QStringLiteral("multiline"),
79 QStringLiteral("json"),
80 QStringLiteral("simple"),
81 QStringLiteral("balooctl status <file>"));
82
83 parser.addOption({{QStringLiteral("f"), QStringLiteral("format")}, statusFormatDescription, i18n("format"), QStringLiteral("multiline")});
84
85 parser.addVersionOption();
86 parser.addHelpOption();
87
88 parser.process(app);
89 if (parser.positionalArguments().isEmpty()) {
90 parser.showHelp(1);
91 }
92
93 QTextStream out(stdout);
94
95 QString command = parser.positionalArguments().first();
96
97 org::kde::baloo::main mainInterface(QStringLiteral("org.kde.baloo"),
98 QStringLiteral("/"),
100
101 org::kde::baloo::scheduler schedulerinterface(QStringLiteral("org.kde.baloo"),
102 QStringLiteral("/scheduler"),
104
105 // Deal with the various balooctl commands:
106
107 if (command == QLatin1String("config")) {
108 ConfigCommand command;
109 return command.exec(parser);
110 }
111
112 if (command == QLatin1String("status")) {
113 StatusCommand commandStatus;
114 return commandStatus.exec(parser);
115 }
116
117 if (command == QLatin1String("enable") || command == QLatin1String("disable")) {
118 bool isEnabled = false;
119 if (command == QLatin1String("enable")) {
120 isEnabled = true;
121 }
122 else if (command == QLatin1String("disable")) {
123 isEnabled = false;
124 }
125
126 IndexerConfig cfg;
127 cfg.setFileIndexingEnabled(isEnabled);
128
129 if (isEnabled) {
130 bool running = mainInterface.isValid();
131 if (running) {
132 out << "File Indexer already running\n";
133 } else {
134 out << "Enabling and starting the File Indexer\n";
135 start();
136 }
137 } else {
138 out << "Disabling and stopping the File Indexer\n";
139
140 mainInterface.quit();
141 }
142
143 return 0;
144 }
145
146 if (command == QLatin1String("purge")) {
147 bool running = mainInterface.isValid();
148
149 if (running) {
150 mainInterface.quit();
151 out << "Stopping the File Indexer ...";
152 for (int i = 5 * 60; i; --i) {
154 if (!mainInterface.isValid()) {
155 break;
156 }
157 out << "." << Qt::flush;
158 QThread::msleep(200);
159 }
160 if (!mainInterface.isValid()) {
161 out << " - done\n";
162 } else {
163 out << " - failed to stop!\n";
164 return 1;
165 }
166 }
167
168 const QString path = fileIndexDbPath() + QStringLiteral("/index");
169 QFile(path).remove();
170 out << "Deleted the index database\n";
171
172 if (running) {
173 start();
174 out << "Restarting the File Indexer\n";
175 }
176
177 return 0;
178 }
179
180 if (command == QLatin1String("suspend")) {
181 schedulerinterface.suspend();
182 out << "File Indexer suspended\n";
183 return 0;
184 }
185
186 if (command == QLatin1String("resume")) {
187 schedulerinterface.resume();
188 out << "File Indexer resumed\n";
189 return 0;
190 }
191
192 if (command == QLatin1String("check")) {
193 schedulerinterface.checkUnindexedFiles();
194 out << "Started search for unindexed files\n";
195 return 0;
196 }
197
198 if (command == QLatin1String("index")) {
199 IndexCommand commandIndex;
200 return commandIndex.exec(parser);
201 }
202
203 if (command == QLatin1String("clear")) {
204 ClearCommand commandClear;
205 return commandClear.exec(parser);
206 }
207
208 if (command == QLatin1String("failed")) {
209 Database *db = globalDatabaseInstance();
210 if (!db->open(Database::ReadOnlyDatabase)) {
211 out << "Baloo Index could not be opened\n";
212 return 1;
213 }
214
215 Transaction tr(db, Transaction::ReadOnly);
216
217 const quint64 limit = 128;
218 const QVector<quint64> failedIds = tr.failedIds(limit);
219 if (failedIds.isEmpty()) {
220 out << "All Files were indexed successfully\n";
221 return 0;
222 }
223
224 out << "The following files could not be indexed:\n";
225 for (auto id : failedIds) {
226 out << tr.documentUrl(id) << '\n';
227 }
228 if (failedIds.size() == limit) {
229 out << "... list truncated\n";
230 }
231 return 0;
232 }
233
234 if (command == QLatin1String("indexSize")) {
235 Database *db = globalDatabaseInstance();
236 if (!db->open(Database::ReadOnlyDatabase)) {
237 out << "Baloo Index could not be opened\n";
238 return 1;
239 }
240
241 DatabaseSize size;
242 {
243 Transaction tr(db, Transaction::ReadOnly);
244 size = tr.dbSize();
245 }
246 uint totalDataSize = size.expectedSize;
247
248 KFormat format(QLocale::system());
249 auto prFunc = [&](const QString& name, uint size) {
250 out.setFieldWidth(20);
251 out << name;
252 out.setFieldWidth(0);
253 out << ":";
254 out.setFieldWidth(15);
255 out << format.formatByteSize(size, 2);
256 out.setFieldWidth(10);
257 out << QString::number((100.0 * size / totalDataSize), 'f', 3);
258 out.setFieldWidth(0);
259 out << " %\n";
260 };
261
262 out << "File Size: " << format.formatByteSize(size.actualSize, 2) << "\n";
263 out << "Used: " << format.formatByteSize(totalDataSize, 2) << "\n\n";
264 prFunc(QStringLiteral("PostingDB"), size.postingDb);
265 prFunc(QStringLiteral("PositionDB"), size.positionDb);
266 prFunc(QStringLiteral("DocTerms"), size.docTerms);
267 prFunc(QStringLiteral("DocFilenameTerms"), size.docFilenameTerms);
268 prFunc(QStringLiteral("DocXattrTerms"), size.docXattrTerms);
269 prFunc(QStringLiteral("IdTree"), size.idTree);
270 prFunc(QStringLiteral("IdFileName"), size.idFilename);
271 prFunc(QStringLiteral("DocTime"), size.docTime);
272 prFunc(QStringLiteral("DocData"), size.docData);
273 prFunc(QStringLiteral("ContentIndexingDB"), size.contentIndexingIds);
274 prFunc(QStringLiteral("FailedIdsDB"), size.failedIds);
275 prFunc(QStringLiteral("MTimeDB"), size.mtimeDb);
276
277 return 0;
278 }
279
280 if (command == QLatin1String("monitor")) {
281 MonitorCommand mon;
282 return mon.exec(parser);
283 }
284
285 /*
286 TODO: Make separate executable
287 if (command == QLatin1String("checkDb")) {
288 Database *db = globalDatabaseInstance();
289 if (!db->open(Database::ReadOnlyDatabase)) {
290 out << "Baloo Index could not be opened\n";
291 return 1;
292 }
293
294 Transaction tr(db, Transaction::ReadOnly);
295 tr.checkPostingDbinTermsDb();
296 tr.checkTermsDbinPostingDb();
297 out << "Checking file paths .. "<< '\n';
298 tr.checkFsTree();
299 return 0;
300 }
301 */
302
303 parser.showHelp(1);
304 return 0;
305}
This class allows it to access the current config, to read and modify it.
static void setApplicationData(const KAboutData &aboutData)
Q_SCRIPTABLE QString start(QString train="")
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Implements storage for docIds without any associated data Instantiated for:
Definition coding.cpp:11
QString path(const QString &relativePath)
QString name(StandardAction id)
QCommandLineOption addHelpOption()
bool addOption(const QCommandLineOption &option)
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
QCommandLineOption addVersionOption()
QStringList positionalArguments() const const
void process(const QCoreApplication &app)
void showHelp(int exitCode)
void processEvents(QEventLoop::ProcessEventsFlags flags)
QDBusConnection sessionBus()
bool remove()
T & first()
bool isEmpty() const const
QLocale system()
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
QString number(double n, char format, int precision)
QTextStream & flush(QTextStream &stream)
void msleep(unsigned long msecs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:56:58 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.