File indexing completed on 2024-05-12 05:22:19

0001 /*
0002  * This file is part of LibKGAPI library
0003  *
0004  * SPDX-FileCopyrightText: 2020 David Barchiesi <david@barchie.si>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #pragma once
0010 
0011 #include "account.h"
0012 #include "file.h"
0013 #include "fileabstractdatajob.h"
0014 #include "kgapidrive_export.h"
0015 
0016 namespace KGAPI2
0017 {
0018 
0019 namespace Drive
0020 {
0021 
0022 /**
0023  * @headerfile fileabstractresumablejob.h
0024  *
0025  * @brief Abstract superclass for KGAPI2::Drive::File create or modify jobs
0026  * that use chunked uploading of the file's content.
0027  *
0028  * The Job starts an upload session and data is written in chunks. When the
0029  * Job is out of chunks to write it will emit the @p readyWrite() signal and
0030  * expect new data to be written via @p write().
0031  *
0032  * Writing 0 bytes will indicate that the File has been completely transferred
0033  * and the Job will close the upload session.
0034  *
0035  * @see <a href="https://developers.google.com/drive/api/v2/manage-uploads#resumable">Perform a resumable upload</a>
0036  * @see readyWrite, write
0037  *
0038  * @author David Barchiesi <david@barchie.si>
0039  * @since 20.12
0040  */
0041 class KGAPIDRIVE_EXPORT FileAbstractResumableJob : public KGAPI2::Drive::FileAbstractDataJob
0042 {
0043     Q_OBJECT
0044 
0045 public:
0046     /**
0047      * @brief Constructs a job that will upload an Untitled file in the
0048      * users root folder.
0049      *
0050      * @param account Account to authenticate the request
0051      * @param parent
0052      */
0053     explicit FileAbstractResumableJob(const AccountPtr &account, QObject *parent = nullptr);
0054 
0055     /**
0056      * @brief Constructs a job that will upload a file with its metadata.
0057      *
0058      * @param metadata File metadata to upload
0059      * @param account Account to authenticate the request
0060      * @param parent
0061      */
0062     explicit FileAbstractResumableJob(const FilePtr &metadata, const AccountPtr &account, QObject *parent = nullptr);
0063 
0064     /**
0065      * @brief Constructs a job that will upload an Untitled file in the
0066      * users root folder with data contained in device.
0067      *
0068      * @param device Open device to read from
0069      * @param account Account to authenticate the request
0070      * @param parent
0071      */
0072     explicit FileAbstractResumableJob(QIODevice *device, const AccountPtr &account, QObject *parent = nullptr);
0073 
0074     /**
0075      * @brief Constructs a job that will upload a file with its metadata
0076      * with data contained in device.
0077      *
0078      * @param device Open device to read from
0079      * @param metadata File metadata to upload
0080      * @param account Account to authenticate the request
0081      * @param parent
0082      */
0083     explicit FileAbstractResumableJob(QIODevice *device, const FilePtr &metadata, const AccountPtr &account, QObject *parent = nullptr);
0084 
0085     /**
0086      * @brief Destructor
0087      */
0088     ~FileAbstractResumableJob() override;
0089 
0090     /**
0091      * @brief Returns metadata supplied at Job creation or retrieved on
0092      * Job completion.
0093      */
0094     FilePtr metadata() const;
0095 
0096     /**
0097      * @brief Sets the total upload size and is required for progress reporting
0098      * via the Job::progress() signal.
0099      */
0100     void setUploadSize(int size);
0101 
0102     /**
0103      * @brief This function writes all the bytes in \p data to the upload session.
0104      *
0105      * The write operation splits written data in chunks that will be
0106      * subsequently uploaded in the session.
0107      *
0108      * Writing an empty \p data will signal the Job that it can complete as no
0109      * more data will be written.
0110      *
0111      * When more data is required the readyWrite() signal is emitted.
0112      *
0113      * @see readyWrite
0114      *
0115      * @param data the data to write
0116      */
0117     void write(const QByteArray &data);
0118 
0119 protected:
0120     /**
0121      * @brief KGAPI2::Job::start implementation
0122      */
0123     void start() override;
0124 
0125     /**
0126      * @brief KGAPI2::Job::handleReply implementation
0127      *
0128      * @param reply
0129      * @param rawData
0130      */
0131     void handleReply(const QNetworkReply *reply, const QByteArray &rawData) override;
0132 
0133     /**
0134      * @brief KGAPI2::Job::dispatchRequest implementation
0135      *
0136      * @param accessManager
0137      * @param request
0138      * @param data
0139      * @param contentType
0140      */
0141     void dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) override;
0142 
0143     /**
0144      * @brief Emit readyWrite() signal
0145      */
0146     void emitReadyWrite();
0147 
0148     /**
0149      * @brief Generates url that will be used during upload session start.
0150      */
0151     virtual QUrl createUrl() = 0;
0152 
0153 Q_SIGNALS:
0154 
0155     /**
0156      * @brief Emitted when @p job requires more data to proceed. Bytes should
0157      * be written via write(). When connecting to this signal always use a
0158      * synchronous connection type like Qt::DirectConnection.
0159      *
0160      * Subclasses should never ever emit this signal directly.
0161      *
0162      * @param job The job that requires data
0163      * @sa readyWrite()
0164      *
0165      * @note Connecting via Qt::QueuedConnection or any other asynchronous connection
0166      * type will potentially crash the job or end it prematurely. Use Qt::DirectConnection
0167      *
0168      * @see write
0169      */
0170     void readyWrite(KGAPI2::Drive::FileAbstractResumableJob *job);
0171 
0172 private:
0173     class Private;
0174     QScopedPointer<Private> d;
0175     friend class Private;
0176 
0177     Q_PRIVATE_SLOT(d, void _k_uploadProgress(qint64 uploadedBytes, qint64 totalBytes))
0178 };
0179 
0180 } // namespace Drive
0181 
0182 } // namespace KGAPI2