Libkdav2

davcollectioncreatejob.cpp
1 /*
2  Copyright (c) 2010 Grégory Oestreicher <[email protected]>
3  Copyright (c) 2018 Rémi Nicole <[email protected]>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 #include "davcollectioncreatejob.h"
21 
22 #include "davcollectionfetchjob.h"
23 #include "davcollectionmodifyjob.h"
24 #include "daverror.h"
25 #include "davjob.h"
26 #include "davmanager.h"
27 
28 #include <QColor>
29 #include <QMetaEnum>
30 
31 using namespace KDAV2;
32 
34  : DavJobBase(parent), mCollection(collection), mRedirectCount(0)
35 {
36 }
37 
39 {
40  auto protocol = mCollection.url().protocol();
41  switch (protocol) {
42  case CalDav:
43  // This is a calendar, use the MKCALENDAR request
44  createCalendar();
45  break;
46  case CardDav:
47  // This is an addressbook, use the extended MKCOL request
48  createAddressbook();
49  break;
50  default: {
51  // This is a normal collection
52  auto job = DavManager::self()->createMkColJob(collectionUrl());
53  connect(job, &DavJob::result, this, &DavCollectionCreateJob::collectionCreated);
54  }
55  }
56 }
57 
59 {
60  return mCollection;
61 }
62 
63 QUrl DavCollectionCreateJob::collectionUrl() const
64 {
65  return mCollection.url().url();
66 }
67 
68 void DavCollectionCreateJob::collectionCreated(KJob *job)
69 {
70  auto storedJob = static_cast<DavJob*>(job);
71 
72  if (storedJob->error()) {
73  setErrorFromJob(storedJob, ERR_COLLECTIONCREATE);
74  emitResult();
75  return;
76  }
77 
78  DavCollectionModifyJob *modifyJob =
79  new DavCollectionModifyJob(DavUrl(storedJob->url(), mCollection.url().protocol()), this);
80 
81  modifyJob->setProperty(QStringLiteral("displayname"), mCollection.displayName());
82 
83  connect(modifyJob, &DavCollectionFetchJob::result, this, &DavCollectionCreateJob::collectionModified);
84  modifyJob->start();
85 }
86 
87 void DavCollectionCreateJob::collectionModified(KJob *job)
88 {
89  if (job->error()) {
90  setError(ERR_PROBLEM_WITH_REQUEST);
91  setErrorTextFromDavError();
92  emitResult();
93  return;
94  }
95 
96  DavCollectionFetchJob *fetchJob = new DavCollectionFetchJob(mCollection, this);
97  connect(fetchJob, &DavCollectionFetchJob::result, this, &DavCollectionCreateJob::collectionRefreshed);
98  fetchJob->start();
99 }
100 
101 void DavCollectionCreateJob::collectionRefreshed(KJob *job)
102 {
103  if (job->error()) {
104  setError(ERR_PROBLEM_WITH_REQUEST);
105  setErrorTextFromDavError();
106  emitResult();
107  return;
108  }
109 
111  mCollection = fetchJob->collection();
112 
113  emitResult();
114 }
115 
116 void DavCollectionCreateJob::createCalendar()
117 {
118  // clang-format off
119  /* Create a query like this:
120  *
121  * <C:mkcalendar xmlns:D='DAV:'xmlns:C='urn:ietf:params:xml:ns:caldav' xmlns:ICAL="http://apple.com/ns/ical/">
122  * <D:set>
123  * <D:prop>
124  * <D:displayname>Test Calendar</D:displayname>
125  * <ICAL:calendar-color>#24b0a3ff</ICAL:calendar-color>
126  * <C:supported-calendar-component-set>
127  * <C:comp name="VEVENT"/>
128  * <C:comp name="VJOURNAL"/>
129  * <C:comp name="VTODO"/>
130  * </C:supported-calendar-component-set>
131  * </D:prop>
132  * </D:set>
133  * </C:mkcalendar>
134  */
135  // clang-format on
136 
137  QDomDocument document;
138 
139  auto mkcalElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("mkcalendar"));
140  document.appendChild(mkcalElement);
141  auto setElement = mkcalElement.appendChild(
142  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("set")));
143  auto propElement =
144  setElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")));
145 
146  if (!mCollection.displayName().isEmpty()) {
147  auto displayNameElement = propElement.appendChild(
148  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname")));
149  displayNameElement.appendChild(document.createTextNode(mCollection.displayName()));
150  }
151 
152  if (mCollection.color().isValid()) {
153  auto colorElement = propElement.appendChild(document.createElementNS(
154  QStringLiteral("http://apple.com/ns/ical/"), QStringLiteral("calendar-color")));
155  colorElement.appendChild(document.createTextNode(mCollection.color().name() + "FF"));
156  }
157 
158  auto compSetElement = propElement.appendChild(document.createElementNS(
159  QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("supported-calendar-component-set")));
160 
161  auto supportedComp = mCollection.contentTypes();
162 
163  if (supportedComp.testFlag(DavCollection::Events)) {
164  auto compElement = document.createElementNS(
165  QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp"));
166  compElement.setAttribute(QStringLiteral("name"), QStringLiteral("VEVENT"));
167  compSetElement.appendChild(compElement);
168  }
169 
170  if (supportedComp.testFlag(DavCollection::Todos)) {
171  auto compElement = document.createElementNS(
172  QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp"));
173  compElement.setAttribute(QStringLiteral("name"), QStringLiteral("VTODO"));
174  compSetElement.appendChild(compElement);
175  }
176 
177  if (supportedComp.testFlag(DavCollection::FreeBusy)) {
178  auto compElement = document.createElementNS(
179  QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp"));
180  compElement.setAttribute(QStringLiteral("name"), QStringLiteral("VFREEBUSY"));
181  compSetElement.appendChild(compElement);
182  }
183 
184  if (supportedComp.testFlag(DavCollection::Journal)) {
185  auto compElement = document.createElementNS(
186  QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp"));
187  compElement.setAttribute(QStringLiteral("name"), QStringLiteral("VJOURNAL"));
188  compSetElement.appendChild(compElement);
189  }
190 
191  auto job = DavManager::self()->createMkCalendarJob(collectionUrl(), document);
192  // Skip the modification
193  connect(job, &DavJob::result, this, &DavCollectionCreateJob::collectionModified);
194 }
195 
196 void DavCollectionCreateJob::createAddressbook()
197 {
198  // clang-format off
199  /* Create a query like this:
200  *
201  * <D:mkcol xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
202  * <D:set>
203  * <D:prop>
204  * <D:resourcetype>
205  * <D:collection/>
206  * <C:addressbook/>
207  * </D:resourcetype>
208  * <D:displayname>Lisa's Contacts</D:displayname>
209  * </D:prop>
210  * </D:set>
211  * </D:mkcol>
212  */
213  // clang-format on
214 
215  QDomDocument document;
216 
217  auto mkcolElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("mkcol"));
218  document.appendChild(mkcolElement);
219  auto setElement = mkcolElement.appendChild(
220  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("set")));
221  auto propElement =
222  setElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")));
223 
224  auto resourceTypeElement = propElement.appendChild(
225  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype")));
226 
227  resourceTypeElement.appendChild(
228  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("collection")));
229 
230  resourceTypeElement.appendChild(document.createElementNS(
231  QStringLiteral("urn:ietf:params:xml:ns:carddav"), QStringLiteral("addressbook")));
232 
233  if (!mCollection.displayName().isEmpty()) {
234  auto displayNameElement = propElement.appendChild(
235  document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname")));
236  displayNameElement.appendChild(document.createTextNode(mCollection.displayName()));
237  }
238 
239  auto job = DavManager::self()->createMkColJob(collectionUrl(), document);
240  // Skip the modification
241  connect(job, &DavJob::result, this, &DavCollectionCreateJob::collectionModified);
242 }
QUrl url() const
Returns the url that identifies the DAV object.
Definition: davurl.cpp:41
DavUrl url() const
Returns the url that identifies the collection.
A helper class to store information about DAV collection.
Definition: davcollection.h:49
void emitResult()
QDomNode appendChild(const QDomNode &newChild)
QString name() const const
static DavManager * self()
Returns the global instance of the DAV manager.
Definition: davmanager.cpp:52
base class for the jobs used by the resource.
Definition: davjobbase.h:37
void setError(int errorCode)
void setProperty(const QString &property, const QString &value, const QString &ns=QString())
Sets the property that shall be modified by the job.
DavJob * createMkColJob(const QUrl &url)
Returns a preconfigured DAV MKCOL job.
Definition: davmanager.cpp:119
QDomElement createElementNS(const QString &nsURI, const QString &qName)
void start() override
Starts the job.
A helper class to combine url and protocol of a DAV url.
Definition: davurl.h:35
DavCollection collection() const
Returns the fetched collection including current etag information.
The collection can contain todo DAV resources.
Definition: davcollection.h:62
void setAttribute(const QString &name, const QString &value)
bool isEmpty() const const
The collection can contain free/busy information.
Definition: davcollection.h:64
A job that fetches a DAV collection from the DAV server.
DavCollectionCreateJob(const DavCollection &collection, QObject *parent=nullptr)
Creates a new dav collection create job.
The collection can contain journal DAV resources.
Definition: davcollection.h:65
QString displayName() const
Returns the display name of the collection.
A job that modifies a DAV collection.
QColor color() const
Return the color of the collection, or an empty string if none was provided by the backend...
QDomText createTextNode(const QString &value)
void start() override
Starts the job.
Protocol protocol() const
Returns the DAV protocol dialect that is used to retrieve the DAV object.
Definition: davurl.cpp:51
DavJob * createMkCalendarJob(const QUrl &url, const QDomDocument &document)
Returns a preconfigured DAV MKCALENDAR job.
Definition: davmanager.cpp:133
DavCollection collection() const
Returns the created DAV item including the correct identifier url and current etag information...
The collection can contain event DAV resources.
Definition: davcollection.h:61
void result(KJob *job)
void setErrorFromJob(DavJob *, ErrorNumber jobErrorCode=ERR_PROBLEM_WITH_REQUEST)
Set the error of this job from a failed DavJob (executed by this job).
Definition: davjobbase.cpp:99
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
bool isValid() const const
ContentTypes contentTypes() const
Returns the possible content types of the collection.
int error() const
void start() override
Starts the job.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jan 27 2022 23:10:33 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.