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