File indexing completed on 2024-05-12 05:12:42

0001 /*
0002     Copyright (C) 2013  Jonathan Marten <jjm@keelhaul.me.uk>
0003 
0004     This program is free software; you can redistribute it and/or modify
0005     it under the terms of the GNU General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or
0007     (at your option) any later version.
0008 
0009     This program is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012     GNU General Public License for more details.
0013 
0014     You should have received a copy of the GNU General Public License along
0015     with this program; if not, write to the Free Software Foundation, Inc.,
0016     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0017 */
0018 
0019 #include "showcommand.h"
0020 
0021 #include "collectionresolvejob.h"
0022 
0023 #include <Akonadi/ItemFetchJob>
0024 #include <Akonadi/ItemFetchScope>
0025 #include <KMime/Message>
0026 
0027 #include <iostream>
0028 
0029 #include "commandfactory.h"
0030 #include "errorreporter.h"
0031 
0032 using namespace Akonadi;
0033 
0034 DEFINE_COMMAND("show", ShowCommand, I18N_NOOP("Show the raw payload of an item"));
0035 
0036 ShowCommand::ShowCommand(QObject *parent)
0037     : AbstractCommand(parent)
0038 {
0039 }
0040 
0041 void ShowCommand::setupCommandOptions(QCommandLineParser *parser)
0042 {
0043     parser->addPositionalArgument("item", i18nc("@info:shell", "The items to show"), i18nc("@info:shell", "item..."));
0044     parser->addOption(QCommandLineOption((QStringList() << QStringLiteral("r") << QStringLiteral("raw")), i18nc("@info:shell", "Use raw payload (disables quoted-printable decoding)")));
0045 }
0046 
0047 int ShowCommand::initCommand(QCommandLineParser *parser)
0048 {
0049     const QStringList itemArgs = parser->positionalArguments();
0050     if (!checkArgCount(itemArgs, 1, i18nc("@info:shell", "No items specified"))) return InvalidUsage;
0051 
0052     mRaw = parser->isSet("raw");
0053 
0054     initProcessLoop(itemArgs);
0055     return NoError;
0056 }
0057 
0058 void ShowCommand::start()
0059 {
0060     startProcessLoop("processNextItem");
0061 }
0062 
0063 void ShowCommand::processNextItem()
0064 {
0065     Item item = CollectionResolveJob::parseItem(currentArg(), true);
0066     if (!item.isValid()) {
0067         processNext();
0068         return;
0069     }
0070 
0071     ItemFetchJob *job = new ItemFetchJob(item, this);
0072     job->fetchScope().setFetchModificationTime(false);
0073     job->fetchScope().fetchAllAttributes(false);
0074     job->fetchScope().fetchFullPayload(true);
0075     connect(job, &KJob::result, this, &ShowCommand::onItemFetched);
0076 }
0077 
0078 void ShowCommand::onItemFetched(KJob *job)
0079 {
0080     if (!checkJobResult(job)) {
0081         return;
0082     } else {
0083         ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job);
0084         Q_ASSERT(fetchJob != nullptr);
0085         Item::List items = fetchJob->items();
0086         if (items.isEmpty()) {
0087             emit error(i18nc("@info:shell", "No result returned for item '%1'", currentArg()));
0088         } else {
0089             Akonadi::Item item = items.first();
0090             if (!item.hasPayload()) {
0091                 emit error(i18nc("@info:shell", "Item '%1' has no payload", currentArg()));
0092             } else if (mRaw) {
0093                 std::cout << item.payloadData().constData();    // output the raw payload
0094             } else {
0095                 if (item.hasPayload<KMime::Message::Ptr>()) {
0096                     const KMime::Message::Ptr mail = item.payload<KMime::Message::Ptr>();
0097                     std::cout << qPrintable(mail->head());
0098                     const auto mainPart = mail->mainBodyPart();
0099                     if (mainPart) {
0100                         std::cout << qPrintable(mainPart->decodedText());
0101                     } else {
0102                         ErrorReporter::warning(i18n("Item has no main body part"));
0103                     }
0104                 } else {
0105                     std::cout << qPrintable(QString::fromUtf8(item.payloadData().constData()));
0106                 }
0107             }
0108 
0109             if (!isProcessLoopFinished()) {     // not the last item
0110                 std::cout << "\n";          // blank line to separate
0111             }
0112         }
0113     }
0114 
0115     processNext();
0116 }