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 }