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

0001 /*
0002  * Copyright (C) 2014  Bhaskar Kandiyal <bkandiyal@gmail.com>
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 
0020 #include "deletecommand.h"
0021 
0022 #include <Akonadi/Item>
0023 #include <Akonadi/ItemDeleteJob>
0024 #include <Akonadi/ItemFetchJob>
0025 #include <Akonadi/CollectionDeleteJob>
0026 #include <Akonadi/CollectionPathResolver>
0027 
0028 #include <klocalizedstring.h>
0029 
0030 #include <qurl.h>
0031 
0032 #include <iostream>
0033 
0034 #include "commandfactory.h"
0035 #include "collectionresolvejob.h"
0036 
0037 
0038 using namespace Akonadi;
0039 
0040 DEFINE_COMMAND("delete", DeleteCommand, I18N_NOOP("Delete a collection or an item"));
0041 
0042 DeleteCommand::DeleteCommand(QObject *parent)
0043     : AbstractCommand(parent),
0044       mDeleteJob(nullptr)
0045 {
0046 }
0047 
0048 void DeleteCommand::setupCommandOptions(QCommandLineParser *parser)
0049 {
0050     addOptionsOption(parser);
0051     addCollectionItemOptions(parser);
0052     addDryRunOption(parser);
0053 
0054     parser->addPositionalArgument("entity", i18nc("@info:shell", "The collection or item"));
0055 }
0056 
0057 int DeleteCommand::initCommand(QCommandLineParser *parser)
0058 {
0059     const QStringList args = parser->positionalArguments();
0060     if (!checkArgCount(args, 1, i18nc("@info:shell", "Missing collection/item argument"))) return InvalidUsage;
0061 
0062     if (!getCommonOptions(parser)) return InvalidUsage;
0063 
0064     mEntityArg = args.first();
0065     if (!getResolveJob(mEntityArg)) return InvalidUsage;
0066 
0067     return NoError;
0068 }
0069 
0070 void DeleteCommand::start()
0071 {
0072     if (!allowDangerousOperation()) {
0073         emit finished(RuntimeError);
0074     }
0075 
0076     if (wantItem()) {
0077         fetchItems();
0078     } else {
0079         connect(resolveJob(), &KJob::result, this, &DeleteCommand::onBaseFetched);
0080         resolveJob()->start();
0081     }
0082 }
0083 
0084 void DeleteCommand::onBaseFetched(KJob *job)
0085 {
0086     CollectionResolveJob *res = resolveJob();
0087     Q_ASSERT(job == res);
0088 
0089     if (job->error() != 0) {
0090         if (job->error() == CollectionPathResolver::Unknown) {
0091             if (!wantCollection()) {
0092                 fetchItems();
0093                 return;
0094             }
0095         }
0096 
0097         emit error(job->errorString());
0098         emit finished(RuntimeError);
0099         return;
0100     }
0101 
0102     if (res->collection() == Collection::root()) {
0103         emit error(i18nc("@info:shell", "Cannot delete the root collection"));
0104         emit finished(RuntimeError);
0105         return;
0106     }
0107 
0108     if (!isDryRun()) {
0109         mDeleteJob = new CollectionDeleteJob(res->collection(), this);
0110         connect(mDeleteJob, &KJob::result, this, &DeleteCommand::onCollectionDeleted);
0111     } else {
0112         onCollectionDeleted(job);
0113     }
0114 }
0115 
0116 void DeleteCommand::onCollectionDeleted(KJob *job)
0117 {
0118     if (!checkJobResult(job)) return;
0119     std::cout << i18n("Collection deleted successfully").toLocal8Bit().constData() << std::endl;
0120     emit finished(NoError);
0121 }
0122 
0123 void DeleteCommand::fetchItems()
0124 {
0125     Item item = CollectionResolveJob::parseItem(mEntityArg);
0126     if (!item.isValid()) {
0127         emit error(i18nc("@info:shell", "Invalid item/collection syntax '%1'", mEntityArg));
0128         emit finished(RuntimeError);
0129         return;
0130     }
0131 
0132     if (!isDryRun()) {
0133         ItemDeleteJob *deleteJob = new ItemDeleteJob(item, this);
0134         connect(deleteJob, &KJob::result, this, &DeleteCommand::onItemsDeleted);
0135     } else {
0136         ItemFetchJob *fetchJob = new ItemFetchJob(item, this);
0137         connect(fetchJob, &KJob::result, this, &DeleteCommand::onItemsFetched);
0138     }
0139 }
0140 
0141 void DeleteCommand::onItemsFetched(KJob *job)
0142 {
0143     if (!checkJobResult(job)) return;
0144     ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job);
0145     Q_ASSERT(fetchJob != nullptr);
0146 
0147     Item::List items = fetchJob->items();
0148     if (items.count() < 0) {
0149         emit error(i18nc("@info:shell", "Cannot find '%1' as a collection or item", mEntityArg));
0150         emit finished(RuntimeError);
0151         return;
0152     }
0153 
0154     emit finished(NoError);
0155 }
0156 
0157 void DeleteCommand::onItemsDeleted(KJob *job)
0158 {
0159     if (!checkJobResult(job)) return;
0160     std::cout << i18n("Item deleted successfully").toLocal8Bit().constData() << std::endl;
0161     emit finished(NoError);
0162 }