Newer
Older
/********************************************************************************************
* *
* Copyright (C) 2017 Armin Felder, Dennis Beier *
* This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>. *
* *
* RocketChatMobileEngine is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* RocketChatMobileEngine is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************************/
FileUploader::FileUploader( QObject *parent, RocketChatServerData *pServer, const QUrl &pUri, const QString &pChannelId ): QObject( parent ),
mUri( pUri ), mChannelId( pChannelId ), mServer( pServer )
auto file = QSharedPointer<QFile>::create( pUri.toLocalFile() );
if ( file->open( QIODevice::ReadOnly ) ) {
mDump = file->readAll();
this->mSize = mDump.size();
qDebug() << "read file with bytes:" << file->size();
if ( !this->mSize ) {
file->close();
QMimeDatabase db;
mType = db.mimeTypeForFile( pUri.fileName() );
}
} else {
qWarning() << file->errorString();
void FileUploader::upload( const std::function<void( void )> &pCleanup )
{
this->mCleanUp = pCleanup;
DdpCallback success = [ & ]( QJsonObject response, MeteorDDP * ddp ) {
onUfsCreated( response );
};
DdpCallback errorFunc = [ & ]( QJsonObject response, MeteorDDP * ddp ) {
Q_UNUSED( ddp );
if ( response.contains( "error" ) ) {
if ( errorObject.contains( "message" ) ) {
emit error( message );
}
}
};
QSharedPointer<DDPUfsCreateRequest> request(
new DDPUfsCreateRequest( mChannelId, mUri.fileName(), mDump.size(), mType.name(), success )
);
request->setError( errorFunc );
if ( !mErrorStatus ) {
mServer->sendDdprequest( request, true );
QMutexLocker locker( &mLock );
if ( mPartialRequests.empty() ) {
if ( pResponse.contains( "result" ) ) {
if ( result.contains( "url" ) && result.contains( "token" ) && result.contains( "fileId" ) ) {
QString url = result["url"].toString();
mToken = result["token"].toString();
qDebug() << result.keys();
qDebug() << result["fileId"].toString();
QString fileId = result["fileId"].toString();
this->mFileId = fileId;
int pos = 0;
int arrsize = mSize;
int sizeInArray = 100000;
emit ufsCreated( fileId );
int chunkNum = arrsize / sizeInArray;
chunkNum += ( arrsize % sizeInArray ) ? 1 : 0;
qDebug() << "creating partials: " << chunkNum << "of bytes:" << mSize;
if ( mSize == 0 ) {
bool cancel = mCanceled;
RestRequestCallback nextOne = [ = ]( QNetworkReply *, QJsonObject data, RestApi * ) {
Q_UNUSED( data );
QMutexLocker locker( &mLock );
if ( cancel ) {
nextRequest();
}
};
for ( int i = 0; i < chunkNum; i++ ) {
qDebug() << "creating partials nr " << chunkNum;
QByteArray chunk = mDump.mid( pos, sizeInArray );
double progress = ( 1.0 / chunkNum ) * ( i + 1 );
QString completePath = url + "&progress=" + QString::number( progress );
auto partial = QSharedPointer<RestFileUploadRequest>::create( completePath, mToken, chunk );
partial->setProgress( progress );
qDebug() << "creating partial " << chunkNum << ":" << progress << "size:" << chunk.size();;
partial->setSuccess( nextOne );
mPartialRequests.append( partial );
pos += chunk.size();
}
auto lastRequest = mPartialRequests.last();
lastRequest->setSuccess( [ = ]( QNetworkReply * reply, QJsonObject data, RestApi * ) {
onUploadCompleted( data );
} );
auto request = mPartialRequests.first();
mServer->sendApiRequest( request, true );
void FileUploader::onUploadCompleted( const QJsonObject &pResponse )
Q_UNUSED( pResponse );
int major = std::get<0>( RocketChatServerConfig::serverVersion );
int minor = std::get<1>( RocketChatServerConfig::serverVersion );
int patch = std::get<2>( RocketChatServerConfig::serverVersion );
if ( major != -1 && minor != -1 && patch != -1 ) {
if ( major >= 0 && minor > 60 ) {
store = QStringLiteral( "Uploads" );
}
}
QJsonArray params = {mFileId, store, mToken};
DdpCallback success2 = [ = ]( QJsonObject pResponse, MeteorDDP * pDdp ) {
if ( pResponse.contains( "result" ) ) {
QJsonObject result = pResponse["result"].toObject();
QJsonArray params2 = {mChannelId, QJsonValue::Null, result};
DdpCallback success3 = [ = ]( QJsonObject pResponse, MeteorDDP * pDdp ) {
Q_UNUSED( pResponse );
Q_UNUSED( pDdp );
qDebug() << "send file message response";
mCleanUp();
};
auto request3 = QSharedPointer<DDPMethodRequest>::create( "sendFileMessage", params2, success3 );
mServer->sendDdprequest( request3, true );
auto request = QSharedPointer<DDPMethodRequest>::create( QStringLiteral( "ufsComplete" ), params, success2 );
mServer->sendDdprequest( request, true );
qDebug() << "file upload ready";
}
void FileUploader::nextRequest()
{
mPartialRequests.pop_front();
auto request = mPartialRequests.first();
double diff = request->getProgress() - progress;
uint now = QDateTime::currentDateTime().toTime_t();
if( diff >= 0.05 && now - lastUpdate){
progress = request->getProgress();
qDebug() << "progress is "<< progress;
emit progressChanged( progress );
mServer->sendApiRequest( request, true );
}
}
QString FileUploader::getFileId() const
{
return mFileId;
}