1 /*
2 * This file is part of LibKGAPI library
3 *
4 * SPDX-FileCopyrightText: 2013 Daniel Vrátil <dvratil@redhat.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8 #include "filecopyjob.h"
9 #include "account.h"
10 #include "driveservice.h"
11 #include "file.h"
12 #include "utils.h"
13
14 #include <QNetworkReply>
15 #include <QNetworkRequest>
16
17
18 using namespace KGAPI2;
19 using namespace KGAPI2::Drive;
20
21 class Q_DECL_HIDDEN FileCopyJob::Private
22 {
23 public:
24 Private(FileCopyJob *parent);
25 void processNext();
26
27 QMap<QString, FilePtr > files;
28
29 QList<FilePtr> copies;
30
31 private:
32 FileCopyJob *const q;
33 };
34
Private(FileCopyJob * parent)35 FileCopyJob::Private::Private(FileCopyJob *parent):
36 q(parent)
37 {
38 }
39
processNext()40 void FileCopyJob::Private::processNext()
41 {
42 if (files.isEmpty()) {
43 q->emitFinished();
44 return;
45 }
46
47 const QString fileId = files.cbegin().key();
48 const FilePtr file = files.take(fileId);
49
50 QUrl url = DriveService::copyFileUrl(fileId);
51 q->updateUrl(url);
52
53 QNetworkRequest request(url);
54
55 const QByteArray rawData = File::toJSON(file);
56
57 q->enqueueRequest(request, rawData, QStringLiteral("application/json"));
58 }
59
FileCopyJob(const QString & sourceFileId,const FilePtr & destinationFile,const AccountPtr & account,QObject * parent)60 FileCopyJob::FileCopyJob(const QString &sourceFileId,
61 const FilePtr &destinationFile,
62 const AccountPtr &account,
63 QObject *parent):
64 FileAbstractDataJob(account, parent),
65 d(new Private(this))
66 {
67 d->files.insert(sourceFileId, destinationFile);
68 }
69
FileCopyJob(const FilePtr & sourceFile,const FilePtr & destinationFile,const AccountPtr & account,QObject * parent)70 FileCopyJob::FileCopyJob(const FilePtr &sourceFile,
71 const FilePtr &destinationFile,
72 const AccountPtr &account,
73 QObject *parent):
74 FileAbstractDataJob(account, parent),
75 d(new Private(this))
76 {
77 d->files.insert(sourceFile->id(), destinationFile);
78 }
79
FileCopyJob(const QMap<QString,FilePtr> & files,const AccountPtr & account,QObject * parent)80 FileCopyJob::FileCopyJob(const QMap< QString, FilePtr > &files,
81 const AccountPtr &account,
82 QObject *parent):
83 FileAbstractDataJob(account, parent),
84 d(new Private(this))
85 {
86 d->files = files;
87 }
88
FileCopyJob(const QMap<FilePtr,FilePtr> & files,const AccountPtr & account,QObject * parent)89 FileCopyJob::FileCopyJob(const QMap< FilePtr, FilePtr > &files,
90 const AccountPtr &account,
91 QObject *parent):
92 FileAbstractDataJob(account, parent),
93 d(new Private(this))
94 {
95 QMap<FilePtr, FilePtr>::ConstIterator iter = files.constBegin();
96 QMap<FilePtr, FilePtr>::ConstIterator iterEnd = files.constEnd();
97 for (; iter != iterEnd; ++iter) {
98 d->files.insert(iter.key()->id(), iter.value());
99 }
100 }
101
~FileCopyJob()102 FileCopyJob::~FileCopyJob()
103 {
104 delete d;
105 }
106
files() const107 FilesList FileCopyJob::files() const
108 {
109 return d->copies;
110 }
111
start()112 void FileCopyJob::start()
113 {
114 d->processNext();
115 }
116
dispatchRequest(QNetworkAccessManager * accessManager,const QNetworkRequest & request,const QByteArray & data,const QString & contentType)117 void FileCopyJob::dispatchRequest(QNetworkAccessManager *accessManager,
118 const QNetworkRequest &request,
119 const QByteArray &data,
120 const QString &contentType)
121 {
122 QNetworkRequest r = request;
123 r.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
124
125 accessManager->post(r, data);
126 }
127
128
handleReply(const QNetworkReply * reply,const QByteArray & rawData)129 void FileCopyJob::handleReply(const QNetworkReply *reply,
130 const QByteArray &rawData)
131 {
132 const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
133 ContentType ct = Utils::stringToContentType(contentType);
134 if (ct == KGAPI2::JSON) {
135 d->copies << File::fromJSON(rawData);
136 } else {
137 setError(KGAPI2::InvalidResponse);
138 setErrorString(tr("Invalid response content type"));
139 emitFinished();
140 return;
141 }
142
143 // Enqueue next item or finish
144 d->processNext();
145 }
146
147
148