Baloo

tools/experimental/baloodb/main.cpp
1/*
2 SPDX-FileCopyrightText: 2018 Michael Heidelbach <heidelbach@web.de>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6
7#include "global.h"
8#include "experimental/databasesanitizer.h"
9
10#include <KAboutData>
11#include <KLocalizedString>
12
13#include <QCoreApplication>
14#include <QCommandLineOption>
15#include <QCommandLineParser>
16#include <QStandardPaths>
17#include <QTextStream>
18#include <QList>
19#include <QElapsedTimer>
20
21using namespace Baloo;
22
23struct Command {
24 const QString name;
25 const QString description;
26 const QStringList args;
27 const QStringList options;
28};
29
30const auto options = QList<QCommandLineOption>{
32 QStringList{QStringLiteral("i"), QStringLiteral("device-id")},
33 i18n("Filter by device id."
34 "\n0 (default) does not filter and everything is printed."
35 "\nPositive numbers are including filters printing only the mentioned device id."
36 "\nNegative numbers are excluding filters printing everything but the mentioned device id."
37 "\nMay be given multiple times."),
38 i18n("integer"),
39 nullptr
40 },
42 QStringList{QStringLiteral("m"), QStringLiteral("missing-only")},
43 i18n("List only inaccessible entries.\nOnly applies to \"%1\"", QStringLiteral("list"))
44 },
46 QStringList{QStringLiteral("u"), QStringLiteral("mounted-only")},
47 i18n("Act only on item on mounted devices")
48 },
50 QStringList{QStringLiteral("D"), QStringLiteral("dry-run")},
51 i18n("Print results of a cleaning operation, but do not change anything."
52 "\nOnly applies to \"%1\" command", QStringLiteral("clean"))
53 }
54};
55
56const auto commands = std::vector<Command>{
57 Command{
58 QStringLiteral("list"),
59 i18n("List database contents. Use a regular expression as argument to filter output"),
61 QStringLiteral("pattern")
62 },
64 QStringLiteral("missing-only"),
65 QStringLiteral("device-id")
66 }
67 },
68 Command{
69 QStringLiteral("devices"),
70 i18n("List devices"),
72 QStringList{QStringLiteral("missing-only")}
73 },
74 /*TODO:
75 Command{
76 QStringLiteral("check"),
77 i18n("Check database contents. "
78 "Beware this may take very long to execute"),
79 QStringList{},
80 QStringList{}
81 },
82 */
83 Command{
84 QStringLiteral("clean"),
85 i18n("Remove stale database entries"),
87 QStringLiteral("pattern")
88 },
90 QStringLiteral("dry-run"),
91 QStringLiteral("device-id"),
92 QStringLiteral("mounted-only")
93 }
94 }
95};
96
97const QStringList allowedCommands()
98{
99 QStringList names;
100 for (const auto& c : commands) {
101 names.append(c.name);
102 }
103 return names;
104}
105const QStringList getOptions(const QString& name)
106{
107 for (const auto& c : commands) {
108 if (c.name == name) {
109 return c.options;
110 }
111 }
112 return QStringList();
113}
114QString createDescription()
115{
117 for (const auto& c: commands) {
118 auto options = getOptions(c.name);
119 const QString optionStr = options.isEmpty()
120 ? QString()
121 : QStringLiteral(" [--%1]").arg(options.join(QLatin1String("] [--")));
122
124 if (!c.args.isEmpty() ) {
125 argumentStr = QStringLiteral(" [%1]").arg(c.args.join(QStringLiteral("] [")));
126 }
127
128 const QString commandStr = QStringLiteral("%1%2%3")
129 .arg(c.name)
130 .arg(optionStr)
131 .arg(argumentStr);
132
133 const QString str = QStringLiteral("%1 %2")
134 .arg(commandStr, -58)
135 .arg(c.description);
136
138 }
140 return i18n("\n\nCommands:\n %1", allCommandsStr);
141}
142
143int main(int argc, char* argv[])
144{
146 KAboutData aboutData(QStringLiteral("baloodb"),
147 i18n("Baloo Database Sanitizer"),
149 i18n("The Baloo Database Lister & Sanitizer"),
151 i18n("(c) 2018, Michael Heidelbach"));
152 aboutData.addAuthor(i18n("Michael Heidelbach"), i18n("Maintainer"), QStringLiteral("ottwolt@gmail.com"));
154
156 parser.addOptions(options);
157 parser.addPositionalArgument(QStringLiteral("command"),
158 i18n("The command to execute"),
159 allowedCommands().join(QLatin1Char('|'))
160 );
161 parser.addPositionalArgument(QStringLiteral("pattern"),
162 i18nc("Command", "A regular expression applied to the URL of database items"
163 "\nExample: %1"
164 , "baloodb list '^/media/videos/series'"
165 )
166 );
167 const QString warnExperiment = QStringLiteral(
168 "===\nPlease note: This is an experimental tool. Command line switches or their meaning may change.\n===");
169
170 parser.setApplicationDescription(warnExperiment + createDescription());
171 parser.addVersionOption();
172 parser.addHelpOption();
173
174 parser.process(app);
175 if (parser.positionalArguments().isEmpty()) {
176 qDebug() << "No command";
177 parser.showHelp(1);
178 }
179
180 auto args = parser.positionalArguments();
181 auto command = args.at(0);
182 args.removeFirst();
183
184 if(!allowedCommands().contains(command)) {
185 qDebug() << "Unknown command" << command;
186 parser.showHelp(1);
187 }
188
189 const auto optNames = parser.optionNames();
190 const auto allowedOptions = getOptions(command);
191
193 for (const auto& dev : parser.values(QStringLiteral("device-id"))) {
194 deviceIds.append(dev.toInt());
195 }
197 parser.isSet(QStringLiteral("missing-only"))
198 ? DatabaseSanitizer::IgnoreAvailable
199 : DatabaseSanitizer::IgnoreNone
200 ) | (
201 parser.isSet(QStringLiteral("mounted-only"))
202 ? DatabaseSanitizer::IgnoreUnmounted
203 : DatabaseSanitizer::IgnoreNone
204 );
205 const QString pattern = args.isEmpty()
206 ? QString()
207 : args.at(0);
209 ? nullptr
210 : new QRegularExpression{pattern});
211
212 auto db = globalDatabaseInstance();
215 timer.start();
216
217 if (command == QLatin1String("list")) {
218 if (!db->open(Database::ReadOnlyDatabase)) {
219 err << i18n("Baloo Index could not be opened") << endl;
220 return 1;
221 }
222 DatabaseSanitizer san(db, Transaction::ReadOnly);
223 err << i18n("Listing database contents...") << endl;
224 san.printList(deviceIds, accessFilter, urlFilter);
225 } else if (command == QLatin1String("devices")) {
226 if (!db->open(Database::ReadOnlyDatabase)) {
227 err << i18n("Baloo Index could not be opened") << endl;
228 return 1;
229 }
230 DatabaseSanitizer san(db, Transaction::ReadOnly);
231 err << i18n("Listing database contents...") << endl;
232 san.printDevices(deviceIds, accessFilter);
233
234 } else if (command == QLatin1String("clean")) {
235 auto dbMode = Database::ReadWriteDatabase;
236 if (!db->open(dbMode)) {
237 err << i18n("Baloo Index could not be opened") << endl;
238 return 1;
239 }
240 DatabaseSanitizer san(db, Transaction::ReadWrite);
241 err << i18n("Removing stale database contents...") << endl;
242 san.removeStaleEntries(deviceIds, accessFilter, parser.isSet(QStringLiteral("dry-run")), urlFilter);
243
244 } else if (command == QLatin1String("check")) {
245 parser.showHelp(1);
246 /* TODO: After check methods are improved
247 Database *db = globalDatabaseInstance();
248 if (!db->open(Database::ReadOnlyDatabase)) {
249 err << i18n("Baloo Index could not be opened") << endl;
250 return 1;
251 }
252 Transaction tr(db, Transaction::ReadOnly);
253 err << i18n("Checking file paths ... ") << endl;
254 tr.checkFsTree();
255
256 err << i18n("Checking postings ... ") << endl;
257 tr.checkTermsDbinPostingDb();
258
259 err << i18n("Checking terms ... ") << endl;
260 tr.checkPostingDbinTermsDb();
261 */
262 }
263 err << i18n("Elapsed: %1 secs", timer.nsecsElapsed() / 1000000000.0) << endl;
264
265 return 0;
266}
An Abstract class from which all other balooctl commands can inherit from.
Definition command.h:20
Provide methods to show database problems and sanitize them.
static void setApplicationData(const KAboutData &aboutData)
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
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
bool isEmpty() const const
bool isEmpty() const const
QTextStream & endl(QTextStream &stream)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.