KDAV

davitemsfetchjob.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Grégory Oestreicher <greg@kamago.net>
3
4 Based on DavItemsListJob:
5 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "davitemsfetchjob.h"
11#include "davjobbase_p.h"
12
13#include "daverror.h"
14#include "davmanager_p.h"
15#include "davmultigetprotocol_p.h"
16#include "utils_p.h"
17
18#include <KIO/DavJob>
19#include <KIO/Job>
20
21using namespace KDAV;
22
23namespace KDAV
24{
25class DavItemsFetchJobPrivate : public DavJobBasePrivate
26{
27public:
28 void davJobFinished(KJob *job);
29
30 DavUrl mCollectionUrl;
31 QStringList mUrls;
33};
34}
35
36DavItemsFetchJob::DavItemsFetchJob(const DavUrl &collectionUrl, const QStringList &urls, QObject *parent)
37 : DavJobBase(new DavItemsFetchJobPrivate, parent)
38{
40 d->mCollectionUrl = collectionUrl;
41 d->mUrls = urls;
42}
43
45{
47 const DavMultigetProtocol *protocol = dynamic_cast<const DavMultigetProtocol *>(DavManager::davProtocol(d->mCollectionUrl.protocol()));
48 if (!protocol) {
49 setError(ERR_NO_MULTIGET);
50 d->setErrorTextFromDavError();
51 emitResult();
52 return;
53 }
54
55 const QDomDocument report = protocol->itemsReportQuery(d->mUrls)->buildQuery();
56 KIO::DavJob *job = DavManager::self()->createReportJob(d->mCollectionUrl.url(), report.toString(), QStringLiteral("0"));
57 job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true"));
58 connect(job, &KIO::DavJob::result, this, [d](KJob *job) {
59 d->davJobFinished(job);
60 });
61}
62
64{
65 Q_D(const DavItemsFetchJob);
66 DavItem::List values;
67 values.reserve(d->mItems.size());
68 for (const auto &value : std::as_const(d->mItems)) {
69 values << value;
70 }
71 return values;
72}
73
75{
76 Q_D(const DavItemsFetchJob);
77 return d->mItems.value(url);
78}
79
80void DavItemsFetchJobPrivate::davJobFinished(KJob *job)
81{
82 KIO::DavJob *davJob = qobject_cast<KIO::DavJob *>(job);
83 const QString responseCodeStr = davJob->queryMetaData(QStringLiteral("responsecode"));
84 const int responseCode = responseCodeStr.isEmpty() ? 0 : responseCodeStr.toInt();
85
86 // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx
87 if (davJob->error() || (responseCode >= 400 && responseCode < 600)) {
88 setLatestResponseCode(responseCode);
89 setError(ERR_PROBLEM_WITH_REQUEST);
90 setJobErrorText(davJob->errorText());
91 setJobError(davJob->error());
92 setErrorTextFromDavError();
93
94 emitResult();
95 return;
96 }
97
98 const DavMultigetProtocol *protocol = static_cast<const DavMultigetProtocol *>(DavManager::davProtocol(mCollectionUrl.protocol()));
99
100 QDomDocument document;
101 document.setContent(davJob->responseData(), QDomDocument::ParseOption::UseNamespaceProcessing);
102 const QDomElement documentElement = document.documentElement();
103
104 QDomElement responseElement = Utils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response"));
105
106 while (!responseElement.isNull()) {
107 QDomElement propstatElement = Utils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("propstat"));
108
109 if (propstatElement.isNull()) {
110 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
111 continue;
112 }
113
114 // Check for errors
115 const QDomElement statusElement = Utils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("status"));
116 if (!statusElement.text().contains(QLatin1String("200"))) {
117 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
118 continue;
119 }
120
121 const QDomElement propElement = Utils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop"));
122
123 DavItem item;
124
125 // extract path
126 const QDomElement hrefElement = Utils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("href"));
127 const QString href = hrefElement.text();
128
129 QUrl url = davJob->url();
130 if (href.startsWith(QLatin1Char('/'))) {
131 // href is only a path, use request url to complete
132 url.setPath(href, QUrl::TolerantMode);
133 } else {
134 // href is a complete url
135 url = QUrl::fromUserInput(href);
136 }
137
138 auto _url = url;
139 _url.setUserInfo(mCollectionUrl.url().userInfo());
140 item.setUrl(DavUrl(_url, mCollectionUrl.protocol()));
141
142 // extract ETag
143 const QDomElement getetagElement = Utils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("getetag"));
144 item.setEtag(getetagElement.text());
145
146 // extract content
147 const QDomElement dataElement = Utils::firstChildElementNS(propElement, protocol->responseNamespace(), protocol->dataTagName());
148
149 if (dataElement.isNull()) {
150 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
151 continue;
152 }
153
154 const QByteArray data = dataElement.firstChild().toText().data().toUtf8();
155 if (data.isEmpty()) {
156 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
157 continue;
158 }
159
160 item.setData(data);
161
162 mItems.insert(item.url().toDisplayString(), item);
163 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
164 }
165
166 emitResult();
167}
168
169#include "moc_davitemsfetchjob.cpp"
A helper class to store information about DAV resources.
Definition davitem.h:39
DavUrl url() const
Returns the URL that identifies the item.
Definition davitem.cpp:47
void setEtag(const QString &etag)
Sets the etag of the item.
Definition davitem.cpp:72
void setUrl(const DavUrl &url)
Sets the url that identifies the item.
Definition davitem.cpp:42
void setData(const QByteArray &data)
Sets the raw content data of the item.
Definition davitem.cpp:62
A job that fetches a list of items from a DAV server using a MULTIGET query.
DavItem item(const QString &url) const
Return the item found at url.
DavItemsFetchJob(const DavUrl &collectionUrl, const QStringList &urls, QObject *parent=nullptr)
Creates a new items fetch job.
void start() override
Starts the job.
DavItem::List items() const
Returns the list of fetched items.
base class for the jobs used by the resource.
Definition davjobbase.h:27
A helper class to combine URL and protocol of a DAV URL.
Definition davurl.h:27
QUrl url() const
Returns the URL that identifies the DAV object.
Definition davurl.cpp:45
Protocol protocol() const
Returns the DAV protocol dialect that is used to retrieve the DAV object.
Definition davurl.cpp:55
QString toDisplayString() const
Returns the URL in a user-friendly way without login information.
Definition davurl.cpp:60
QByteArray responseData() const
void addMetaData(const QMap< QString, QString > &values)
QString queryMetaData(const QString &key)
const QUrl & url() const
void emitResult()
int error() const
void result(KJob *job)
void setError(int errorCode)
QString errorText() const
The KDAV namespace.
bool isEmpty() const const
QDomElement documentElement() const const
ParseResult setContent(QAnyStringView text, ParseOptions options)
QString text() const const
bool isNull() const const
void reserve(qsizetype size)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
TolerantMode
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
void setPath(const QString &path, ParsingMode mode)
void setUserInfo(const QString &userInfo, ParsingMode mode)
QString userInfo(ComponentFormattingOptions options) const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.