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

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 "updatecommand.h"
0021 
0022 #include <Akonadi/ItemFetchJob>
0023 #include <Akonadi/ItemFetchScope>
0024 #include <Akonadi/ItemModifyJob>
0025 
0026 #include <qfile.h>
0027 
0028 #include <iostream>
0029 
0030 #include "collectionresolvejob.h"
0031 #include "commandfactory.h"
0032 
0033 using namespace Akonadi;
0034 
0035 DEFINE_COMMAND("update", UpdateCommand, I18N_NOOP("Update an item's payload from a file"));
0036 
0037 UpdateCommand::UpdateCommand(QObject *parent)
0038     : AbstractCommand(parent),
0039       mFile(nullptr)
0040 {
0041 }
0042 
0043 UpdateCommand::~UpdateCommand()
0044 {
0045     delete mFile;
0046 }
0047 
0048 void UpdateCommand::setupCommandOptions(QCommandLineParser *parser)
0049 {
0050     addOptionsOption(parser);
0051     addDryRunOption(parser);
0052 
0053     parser->addPositionalArgument("item", i18nc("@info:shell", "The item to update, an ID or Akonadi URL"));
0054     parser->addPositionalArgument("file", i18nc("@info:shell", "File to update the item from"));
0055 }
0056 
0057 int UpdateCommand::initCommand(QCommandLineParser *parser)
0058 {
0059     const QStringList args = parser->positionalArguments();
0060     if (!checkArgCount(args, 1, i18nc("@info:shell", "No item specified"))) return InvalidUsage;
0061     if (!checkArgCount(args, 2, i18nc("@info:shell", "No file specified"))) return InvalidUsage;
0062 
0063     if (!getCommonOptions(parser)) return InvalidUsage;
0064 
0065     mItemArg = args.at(0);
0066     mFileArg = args.at(1);
0067 
0068     return NoError;
0069 }
0070 
0071 void UpdateCommand::start()
0072 {
0073     if (!allowDangerousOperation()) {
0074         emit finished(RuntimeError);
0075     }
0076 
0077     Item item = CollectionResolveJob::parseItem(mItemArg, true);
0078     if (!item.isValid()) {
0079         emit finished(RuntimeError);
0080         return;
0081     }
0082 
0083     if (!QFile::exists(mFileArg)) {
0084         emit error(i18nc("@info:shell", "File ‘%1’ does not exist", mFileArg));
0085         emit finished(RuntimeError);
0086         return;
0087     }
0088 
0089     // TODO: report strerror(errno), then above is superfluous
0090     mFile = new QFile(mFileArg);
0091     if (!mFile->open(QIODevice::ReadOnly)) {
0092         emit error(i18nc("@info:shell", "File ‘%1’ cannot be read", mFileArg));
0093         emit finished(RuntimeError);
0094         delete mFile;
0095         mFile = nullptr;
0096         return;
0097     }
0098 
0099     ItemFetchJob *job = new ItemFetchJob(item, this);
0100     job->fetchScope().setFetchModificationTime(false);
0101     job->fetchScope().fetchAllAttributes(false);
0102     connect(job, &KJob::result, this, &UpdateCommand::onItemFetched);
0103 }
0104 
0105 void UpdateCommand::onItemFetched(KJob *job)
0106 {
0107     if (!checkJobResult(job)) return;
0108     ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job);
0109     Q_ASSERT(fetchJob != nullptr);
0110 
0111     Item::List items = fetchJob->items();
0112     if (items.count() < 1) {
0113         emit error(i18nc("@info:shell", "No result returned for item '%1'", job->property("arg").toString()));
0114         emit finished(RuntimeError);
0115         return;
0116     }
0117 
0118     if (!isDryRun()) {
0119         Item item = items.first();
0120         QByteArray data = mFile->readAll();
0121         item.setPayloadFromData(data);
0122         ItemModifyJob *modifyJob = new ItemModifyJob(item, this);
0123         connect(modifyJob, &KJob::result, this, &UpdateCommand::onItemUpdated);
0124     } else {
0125         onItemUpdated(job);
0126     }
0127 }
0128 
0129 void UpdateCommand::onItemUpdated(KJob *job)
0130 {
0131     if (!checkJobResult(job)) return;
0132     std::cout << qPrintable(i18nc("@info:shell", "Item updated successfully")) << std::endl;
0133     emit finished(NoError);
0134 }