9#include "fileabstractuploadjob.h"
13#include <QNetworkReply>
14#include <QNetworkRequest>
16#include <QCryptographicHash>
19#include <QMimeDatabase>
24using namespace KGAPI2::Drive;
26class Q_DECL_HIDDEN FileAbstractUploadJob::Private
29 Private(FileAbstractUploadJob *parent);
31 QByteArray buildMultipart(
const QString &filePath,
const FilePtr &metaData, QString &boundary);
32 QByteArray
readFile(
const QString &filePath, QString &contentType);
34 void _k_uploadProgress(qint64 bytesSent, qint64 totalBytes);
36 int originalFilesCount = 0;
37 QMap<QString, FilePtr> files;
39 QMap<QString, FilePtr> uploadedFiles;
41 File::SerializationOptions serializationOptions = File::NoOptions;
44 FileAbstractUploadJob *
const q;
47FileAbstractUploadJob::Private::Private(FileAbstractUploadJob *parent)
56 qCWarning(KGAPIDebug) <<
"Failed to access" << filePath;
61 const QMimeDatabase db;
63 contentType = mime.
name();
64 qCDebug(KGAPIDebug) <<
"Determined content type" << contentType <<
"for" << filePath;
68 QByteArray output = file.readAll();
75QByteArray FileAbstractUploadJob::Private::buildMultipart(
const QString &filePath,
const FilePtr &metaData, QString &boundary)
77 QString fileContentType = metaData->mimeType();
78 QByteArray fileContent;
80 fileContent =
readFile(filePath, fileContentType);
85 qCDebug(KGAPIDebug) <<
"Setting content type" << fileContentType <<
"for" << filePath;
89 QFileInfo finfo(filePath);
93 body +=
"--" + boundary.
toLatin1() +
'\n';
94 body +=
"Content-Type: application/json; charset=UTF-8\n";
96 body += File::toJSON(metaData, q->serializationOptions());
99 body +=
"--" + boundary.
toLatin1() +
'\n';
100 body +=
"Content-Type: " + fileContentType.
toLatin1() +
'\n';
104 body +=
"--" + boundary.
toLatin1() +
"--";
109void FileAbstractUploadJob::Private::processNext()
111 if (files.isEmpty()) {
116 const QString filePath = files.cbegin().key();
118 qCWarning(KGAPIDebug) << filePath <<
"is not a valid file path";
123 const FilePtr metaData = files.take(filePath);
126 if (filePath.
startsWith(QLatin1StringView(
"?="))) {
127 url = q->createUrl(QString(), metaData);
129 url = q->createUrl(filePath, metaData);
133 QUrlQuery
query(url);
139 query.removeQueryItem(QStringLiteral(
"uploadType"));
141 query.addQueryItem(QStringLiteral(
"uploadType"), QStringLiteral(
"media"));
143 rawData =
readFile(filePath, contentType);
149 }
else if (!filePath.
startsWith(QLatin1StringView(
"?="))) {
150 query.addQueryItem(QStringLiteral(
"uploadType"), QStringLiteral(
"multipart"));
153 rawData = buildMultipart(filePath, metaData, boundary);
155 contentType = QStringLiteral(
"multipart/related; boundary=%1").
arg(boundary);
161 rawData = File::toJSON(metaData, q->serializationOptions());
162 contentType = QStringLiteral(
"application/json");
167 QNetworkRequest request(url);
172 q->enqueueRequest(request, rawData, contentType);
175void FileAbstractUploadJob::Private::_k_uploadProgress(qint64 bytesSent, qint64 totalBytes)
180 int processedParts = (originalFilesCount - files.count() - 1) * 100;
181 int currentFileParts = 100.0 * ((qreal)bytesSent / (qreal)totalBytes);
183 q->emitProgress(processedParts + currentFileParts, originalFilesCount * 100);
186FileAbstractUploadJob::FileAbstractUploadJob(
const FilePtr &metadata,
const AccountPtr &
account,
QObject *
parent)
188 , d(new Private(this))
190 d->files.insert(QStringLiteral(
"?=0"), metadata);
191 d->originalFilesCount = 1;
194FileAbstractUploadJob::FileAbstractUploadJob(
const FilesList &metadata,
const AccountPtr &account,
QObject *parent)
195 : FileAbstractDataJob(account, parent)
196 , d(new Private(this))
199 for (
const FilePtr &file : metadata) {
200 d->files.insert(QStringLiteral(
"?=%1").arg(i), file);
203 d->originalFilesCount = d->files.count();
206FileAbstractUploadJob::FileAbstractUploadJob(
const QString &filePath,
const AccountPtr &account,
QObject *parent)
207 : FileAbstractDataJob(account, parent)
208 , d(new Private(this))
210 d->files.insert(filePath, FilePtr());
211 d->originalFilesCount = 1;
214FileAbstractUploadJob::FileAbstractUploadJob(
const QString &filePath,
const FilePtr &metaData,
const AccountPtr &account,
QObject *parent)
215 : FileAbstractDataJob(account, parent)
216 , d(new Private(this))
218 d->files.insert(filePath, metaData);
219 d->originalFilesCount = 1;
222FileAbstractUploadJob::FileAbstractUploadJob(
const QStringList &filePaths,
const AccountPtr &account,
QObject *parent)
223 : FileAbstractDataJob(account, parent)
224 , d(new Private(this))
226 for (
const QString &filePath : filePaths) {
227 d->files.insert(filePath, FilePtr());
229 d->originalFilesCount = d->files.count();
233 : FileAbstractDataJob(account, parent)
234 , d(new Private(this))
237 d->originalFilesCount = d->files.
count();
240FileAbstractUploadJob::~FileAbstractUploadJob()
245void FileAbstractUploadJob::start()
250QMap<QString, FilePtr> FileAbstractUploadJob::files()
const
252 return d->uploadedFiles;
255void FileAbstractUploadJob::dispatchRequest(QNetworkAccessManager *accessManager,
256 const QNetworkRequest &request,
257 const QByteArray &data,
258 const QString &contentType)
260 Q_UNUSED(contentType)
262 QNetworkReply *reply = dispatch(accessManager, request, data);
265 d->_k_uploadProgress(bytesSent, totalBytes);
269void FileAbstractUploadJob::handleReply(
const QNetworkReply *reply,
const QByteArray &rawData)
272 ContentType ct = Utils::stringToContentType(contentType);
273 if (ct == KGAPI2::JSON) {
274 const QNetworkRequest request = reply->
request();
277 FilePtr file = File::fromJSON(rawData);
279 d->uploadedFiles.insert(filePath, file);
290void FileAbstractUploadJob::setSerializationOptions(File::SerializationOptions options)
292 d->serializationOptions = options;
295File::SerializationOptions FileAbstractUploadJob::serializationOptions()
const
297 return d->serializationOptions;
300#include "moc_fileabstractuploadjob.cpp"
void setErrorString(const QString &errorString)
Set job error description to errorString.
AccountPtr account() const
Returns account used to authenticate requests.
virtual void emitFinished()
Emits Job::finished() signal.
void setError(KGAPI2::Error error)
Set job error to error.
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
A job to fetch a single map tile described by a StaticMapUrl.
@ InvalidResponse
LibKGAPI error - Google returned invalid response.
bool readFile(const QString &sourceUrl, QString &sourceCode)
bool isEmpty() const const
qsizetype length() const const
QByteArray toHex(char separator) const const
QByteArray hash(QByteArrayView data, Algorithm method)
bool exists() const const
size_type count() const const
QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const const
QNetworkRequest request() const const
void uploadProgress(qint64 bytesSent, qint64 bytesTotal)
QVariant attribute(Attribute code, const QVariant &defaultValue) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isNull() const const
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toLatin1() const const
void setQuery(const QString &query, ParsingMode mode)
QString toString() const const