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

0001 /*
0002     Copyright (C) 2012  Kevin Krammer <krammer@kde.org>
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 "createcommand.h"
0020 
0021 #include "collectionresolvejob.h"
0022 #include "collectionpathjob.h"
0023 #include "errorreporter.h"
0024 
0025 #include <Akonadi/Collection>
0026 #include <Akonadi/CollectionCreateJob>
0027 #include <Akonadi/CollectionFetchJob>
0028 
0029 #include <iostream>
0030 
0031 #include "commandfactory.h"
0032 
0033 using namespace Akonadi;
0034 
0035 DEFINE_COMMAND("create", CreateCommand, I18N_NOOP("Create a new collection"));
0036 
0037 CreateCommand::CreateCommand(QObject *parent)
0038     : AbstractCommand(parent)
0039 {
0040 }
0041 
0042 void CreateCommand::start()
0043 {
0044     connect(resolveJob(), &KJob::result, this, &CreateCommand::onTargetFetched);
0045     resolveJob()->start();
0046 }
0047 
0048 void CreateCommand::setupCommandOptions(QCommandLineParser *parser)
0049 {
0050     addOptionsOption(parser);
0051     parser->addOption(QCommandLineOption((QStringList() << "p" << "parent"), i18n("Parent collection to create in"), i18n("collection")));
0052     addDryRunOption(parser);
0053 
0054     parser->addPositionalArgument("collection", i18nc("@info:shell", "The collection to create, either as a path or a name (with a parent specified)"));
0055 }
0056 
0057 int CreateCommand::initCommand(QCommandLineParser *parser)
0058 {
0059     const QStringList args = parser->positionalArguments();
0060     if (!checkArgCount(args, 1, i18nc("@info:shell", "Missing collection argument"))) return InvalidUsage;
0061 
0062     if (!getCommonOptions(parser)) return InvalidUsage;
0063 
0064     const QString collectionArg = args.first();
0065     if (parser->isSet("parent")) {
0066         // A parent collection is specified.  That must already exist,
0067         // and the new collection must be a plain name (not containing
0068         // any '/'es).
0069 
0070         if (collectionArg.contains(QLatin1Char('/'))) {
0071             emit error(i18nc("@info:shell", "Collection argument (with parent) cannot be a path"));
0072             return InvalidUsage;
0073         }
0074 
0075         mNewCollectionName = collectionArg;
0076         mParentCollection = parser->value("parent");
0077     } else {
0078         // No parent collection is specified.  The new collection name
0079         // is the last part of the specified argument, and the remainder
0080         // is taken as the parent collection which must already exist.
0081         // Note that this means that an argument like "33/newname" is
0082         // acceptable, where the number is resolved as a collection ID.
0083         // Even something like "akonadi://?collection=33/newname" is
0084         // acceptable.
0085 
0086         int i = collectionArg.lastIndexOf(QLatin1Char('/'));
0087         if (i == -1) {
0088             emit error(i18nc("@info:shell", "Collection argument (without parent) must be a path"));
0089             return InvalidUsage;
0090         }
0091 
0092         mNewCollectionName = collectionArg.mid(i+1);
0093         mParentCollection = collectionArg.left(i);
0094     }
0095 
0096     if (mNewCollectionName.isEmpty()) {
0097         emitErrorSeeHelp(i18nc("@info:shell", "New collection name not specified"));
0098         return InvalidUsage;
0099     }
0100 
0101     if (!getResolveJob(mParentCollection)) return InvalidUsage;
0102 
0103     return NoError;
0104 }
0105 
0106 void CreateCommand::onTargetFetched(KJob *job)
0107 {
0108     if (!checkJobResult(job, i18nc("@info:shell",
0109                                    "Cannot fetch parent collection '%1', %2",
0110                                    mParentCollection,
0111                                    job->errorString()))) return;
0112     CollectionResolveJob *res = resolveJob();
0113     Q_ASSERT(job == res);
0114     Akonadi::Collection parentCollection = res->collection();
0115     Q_ASSERT(parentCollection.isValid());
0116 
0117     // Warning for bug 319513
0118     if ((mNewCollectionName == "cur") || (mNewCollectionName == "new") || (mNewCollectionName == "tmp")) {
0119         QString parentResource = parentCollection.resource();
0120         if (parentResource.startsWith(QLatin1String("akonadi_maildir_resource"))) {
0121             ErrorReporter::warning(i18n("Creating a maildir folder named '%1' may not work",
0122                                         mNewCollectionName));
0123         }
0124     }
0125 
0126     Akonadi::Collection newCollection;
0127     newCollection.setParentCollection(parentCollection);
0128     newCollection.setName(mNewCollectionName);
0129     newCollection.setContentMimeTypes(parentCollection.contentMimeTypes());
0130     if (!isDryRun()) {
0131         CollectionCreateJob *createJob = new CollectionCreateJob(newCollection);
0132         connect(createJob, &KJob::result, this, &CreateCommand::onCollectionCreated);
0133     } else {
0134         emit finished(NoError);
0135     }
0136 }
0137 
0138 void CreateCommand::onCollectionCreated(KJob *job)
0139 {
0140     if (!checkJobResult(job, i18n("Error creating collection '%1' under '%2', %3",
0141                                   mNewCollectionName,
0142                                   resolveJob()->formattedCollectionName(),
0143                                   job->errorString()))) return;
0144     CollectionCreateJob *createJob = qobject_cast<CollectionCreateJob *>(job);
0145     Q_ASSERT(createJob != nullptr);
0146 
0147     CollectionPathJob *pathJob = new CollectionPathJob(createJob->collection());
0148     connect(pathJob, &KJob::result, this, &CreateCommand::onPathFetched);
0149     pathJob->start();
0150 }
0151 
0152 void CreateCommand::onPathFetched(KJob *job)
0153 {
0154     if (!checkJobResult(job, i18n("Error getting path of new collection, %1", job->errorString()))) return;
0155     CollectionPathJob *pathJob = qobject_cast<CollectionPathJob *>(job);
0156     Q_ASSERT(pathJob != nullptr);
0157 
0158     std::cout << qPrintable(i18n("Created new collection '%1'", pathJob->formattedCollectionPath()))
0159               << std::endl;
0160 
0161     emit finished(NoError);
0162 }