diff --git a/kpa-thumbnailtool/ThumbnailCacheConverter.cpp b/kpa-thumbnailtool/ThumbnailCacheConverter.cpp index df4a5dd0..6e0410da 100644 --- a/kpa-thumbnailtool/ThumbnailCacheConverter.cpp +++ b/kpa-thumbnailtool/ThumbnailCacheConverter.cpp @@ -1,73 +1,75 @@ /* Copyright (C) 2020 The KPhotoAlbum development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ThumbnailCacheConverter.h" #include "Logging.h" +#include #include #include -#include #include #include +#include -int KPAThumbnailTool::convertV5ToV4Cache(const QString &indexFilename) +int KPAThumbnailTool::convertV5ToV4Cache(const QString &indexFilename, QTextStream &err) { QFile indexFile { indexFilename }; if (!indexFile.open(QIODevice::ReadOnly)) { - qCWarning(MainLog) << "Could not open thumbnailindex file!"; - qCWarning(MainLog) << "Aborting..."; + err << i18nc("@info:shell", "Could not open thumbnailindex file!\n"); + err << i18nc("@info:shell", "Thumbnailindex was not changed.\n"); return 1; } QDataStream stream { &indexFile }; int version; stream >> version; if (version != 5) { - qCWarning(MainLog) << "Thumbnailindex is not a version 5 file!"; - qCWarning(MainLog) << "Aborting..."; + err << i18nc("@info:shell", "Thumbnailindex is not a version 5 file!\n"); + err << i18nc("@info:shell", "Thumbnailindex was not changed.\n"); return 1; } // skip dimensions stream.skipRawData(sizeof(int)); QTemporaryFile newIndexFile; if (!newIndexFile.open()) { - qCWarning(MainLog) << "Could not open temporary file for writing!"; - qCWarning(MainLog) << "Aborting..."; + err << i18nc("@info:shell", "Could not open temporary file for writing!\n"); + err << i18nc("@info:shell", "Thumbnailindex was not changed.\n"); return 1; } QDataStream newStream { &newIndexFile }; constexpr int v4FileVersion = 4; newStream << v4FileVersion; int numBytes = 0; char buf[256]; do { numBytes = stream.readRawData(buf, 256); newStream.writeRawData(buf, numBytes); } while (numBytes != 0); if (!indexFile.rename(QString::fromUtf8("%1.bak").arg(indexFilename))) { - qCWarning(MainLog) << "Could not back up thumbnailindex file!"; - qCWarning(MainLog) << "Aborting..."; + err << i18nc("@info:shell", "Could not back up thumbnailindex file!\n"); + err << i18nc("@info:shell", "Thumbnailindex was not changed.\n"); return 1; } if (!newIndexFile.copy(indexFilename)) { - qCWarning(MainLog) << "Could not emplace new thumbnailindex file!" << newIndexFile.errorString(); + err << i18nc("@info:shell", "Could not copy temporary thumbnailindex file to final location!\n"); + err << i18nc("@info:shell", "Error message was: %1\n", newIndexFile.errorString()); return 1; } return 0; } // vi:expandtab:tabstop=4 shiftwidth=4: diff --git a/kpa-thumbnailtool/ThumbnailCacheConverter.h b/kpa-thumbnailtool/ThumbnailCacheConverter.h index 7daeebc8..23716c2e 100644 --- a/kpa-thumbnailtool/ThumbnailCacheConverter.h +++ b/kpa-thumbnailtool/ThumbnailCacheConverter.h @@ -1,41 +1,43 @@ /* Copyright (C) 2020 The KPhotoAlbum development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPA_THUMBNAILTOOL_THUMBNAILCACHECONVERTER_H #define KPA_THUMBNAILTOOL_THUMBNAILCACHECONVERTER_H class QString; +class QTextStream; namespace KPAThumbnailTool { /** * @brief Convert a version 5 ThumbnailCache index file to version 4. * This function does not use the ThumbnailCache code at all, * but just reads the file and converts the header accordingly. * * This way, code in ThumbnailCache is not bloated by a niche-usecase. * * @param indexFilename + * @param err an output stream for error messages * @return 0 on success, 1 otherwise. */ -int convertV5ToV4Cache(const QString &indexFilename); +int convertV5ToV4Cache(const QString &indexFilename, QTextStream &err); } #endif // vi:expandtab:tabstop=4 shiftwidth=4: diff --git a/kpa-thumbnailtool/main.cpp b/kpa-thumbnailtool/main.cpp index e04d44a6..e656ea5d 100644 --- a/kpa-thumbnailtool/main.cpp +++ b/kpa-thumbnailtool/main.cpp @@ -1,151 +1,152 @@ /* Copyright (C) 2020 The KPhotoAlbum development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "Logging.h" #include "ThumbnailCacheConverter.h" #include "version.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KPAThumbnailTool; -void checkConflictingOptions(const QCommandLineParser &parser, const QCommandLineOption &opt1, const QCommandLineOption &opt2) +void checkConflictingOptions(const QCommandLineParser &parser, const QCommandLineOption &opt1, const QCommandLineOption &opt2, QTextStream &err) { if (parser.isSet(opt1) && parser.isSet(opt2)) { - qWarning() << "Conflicting commandline options: " << opt1.names().first() << "," << opt2.names().first(); + err << i18nc("@info:shell", "Conflicting commandline options: %1 and %2!\n", opt1.names().first(), opt2.names().first()); exit(1); } } int main(int argc, char **argv) { KLocalizedString::setApplicationDomain("kphotoalbum"); QCoreApplication app(argc, argv); KAboutData aboutData( QStringLiteral("kpa-thumbnailtool"), //component name i18n("KPhotoAlbum Thumbnail Tool"), // display name QStringLiteral(KPA_VERSION), i18n("Tool for inspecting and editing the KPhotoAlbum thumbnail cache"), // short description KAboutLicense::GPL, i18n("Copyright (C) 2020 The KPhotoAlbum Development Team"), // copyright statement QString(), // other text QStringLiteral("https://www.kphotoalbum.org") // homepage ); aboutData.setOrganizationDomain("kde.org"); // maintainer is expected to be the first entry // Note: I like to sort by name, grouped by active/inactive; // Jesper gets ranked with the active authors for obvious reasons aboutData.addAuthor(i18n("Johannes Zarl-Zierl"), i18n("Development, Maintainer"), QStringLiteral("johannes@zarl-zierl.at")); aboutData.addAuthor(i18n("Robert Krawitz"), i18n("Development, Optimization"), QStringLiteral("rlk@alum.mit.edu")); aboutData.addAuthor(i18n("Tobias Leupold"), i18n("Development, Releases, Website"), QStringLiteral("tobias.leupold@gmx.de")); aboutData.addAuthor(i18n("Jesper K. Pedersen"), i18n("Former Maintainer, Project Creator"), QStringLiteral("blackie@kde.org")); // not currently active: aboutData.addAuthor(i18n("Hassan Ibraheem"), QString(), QStringLiteral("hasan.ibraheem@gmail.com")); aboutData.addAuthor(i18n("Jan Kundrát"), QString(), QStringLiteral("jkt@gentoo.org")); aboutData.addAuthor(i18n("Andreas Neustifter"), QString(), QStringLiteral("andreas.neustifter@gmail.com")); aboutData.addAuthor(i18n("Tuomas Suutari"), QString(), QStringLiteral("thsuut@utu.fi")); aboutData.addAuthor(i18n("Miika Turkia"), QString(), QStringLiteral("miika.turkia@gmail.com")); aboutData.addAuthor(i18n("Henner Zeller"), QString(), QStringLiteral("h.zeller@acm.org")); // initialize the commandline parser QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption infoOption { QString::fromUtf8("info"), i18nc("@info:shell", "Print information about thumbnail cache.") }; parser.addOption(infoOption); QCommandLineOption convertV5ToV4Option { QString::fromUtf8("convertV5ToV4"), i18nc("@info:shell", "Convert thumbnailindex to format suitable for KPhotoAlbum >= 4.3.") }; parser.addOption(convertV5ToV4Option); QCommandLineOption verifyOption { QString::fromUtf8("verify"), i18nc("@info:shell", "Verify thumbnail cache consistency.") }; parser.addOption(verifyOption); parser.addPositionalArgument(QString::fromUtf8("imageDir"), i18nc("@info:shell", "The directory containing the .thumbnail directory.")); KAboutData::setApplicationData(aboutData); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); QTextStream console { stdout }; + QTextStream err { stderr }; - checkConflictingOptions(parser, convertV5ToV4Option, infoOption); - checkConflictingOptions(parser, convertV5ToV4Option, verifyOption); + checkConflictingOptions(parser, convertV5ToV4Option, infoOption, err); + checkConflictingOptions(parser, convertV5ToV4Option, verifyOption, err); const auto args = parser.positionalArguments(); if (args.empty()) { - qWarning("Missing argument!"); + err << i18nc("@info:shell", "Missing argument!\n"); return 1; } const auto imageDir = QDir { args.first() }; if (!imageDir.exists()) { - qWarning("Not a directory!"); + err << i18nc("@info:shell", "%1 is not a directory!\n", args.first()); return 1; } if (parser.isSet(convertV5ToV4Option)) { const QString indexFile = imageDir.absoluteFilePath(QString::fromUtf8(".thumbnails/thumbnailindex")); - return convertV5ToV4Cache(indexFile); + return convertV5ToV4Cache(indexFile, err); } int returnValue = 0; DB::DummyUIDelegate uiDelegate; Settings::SettingsData::setup(imageDir.path(), uiDelegate); const auto thumbnailDir = imageDir.absoluteFilePath(ImageManager::defaultThumbnailDirectory()); const ImageManager::ThumbnailCache cache { thumbnailDir }; if (parser.isSet(infoOption)) { console << i18nc("@info:shell", "Thumbnail cache directory: %1\n", thumbnailDir); console << i18nc("@info:shell", "Thumbnailindex file version: %1\n", cache.actualFileVersion()); console << i18nc("@info:shell", "Maximum supported thumbnailindex file version: %1\n", cache.preferredFileVersion()); console << i18nc("@info:shell", "Thumbnail storage size: %1\n", cache.thumbnailSize()); if (cache.actualFileVersion() < 5) { console << i18nc("@info:shell", "Note: Thumbnail storage size is defined in the configuration file prior to v5.\n"); } } if (parser.isSet(verifyOption)) { const auto incorrectDimensions = cache.findIncorrectlySizedThumbnails(); if (incorrectDimensions.isEmpty()) { console << i18nc("@info:shell", "No inconsistencies found.\n"); } else { returnValue = 1; console << i18nc("@info:shell This line is printed before a list of file names.", "The following thumbnails appear to have incorrect sizes:\n"); for (const auto &filename : incorrectDimensions) { console << filename.absolute() << "\n"; } } } return returnValue; // so far, we don't need an event loop: //// immediately quit the event loop: //QTimer::singleShot(0, &app, &QCoreApplication::quit); //return QCoreApplication::exec(); } // vi:expandtab:tabstop=4 shiftwidth=4: