ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

storage.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "backends/cloud/storage.h"
00024 #include "backends/cloud/downloadrequest.h"
00025 #include "backends/cloud/folderdownloadrequest.h"
00026 #include "backends/cloud/savessyncrequest.h"
00027 #include "backends/networking/curl/connectionmanager.h"
00028 #include "common/debug.h"
00029 #include "common/file.h"
00030 #include <common/translation.h>
00031 #include "common/osd_message_queue.h"
00032 
00033 namespace Cloud {
00034 
00035 Storage::Storage():
00036     _runningRequestsCount(0), _savesSyncRequest(nullptr), _syncRestartRequestsed(false),
00037     _downloadFolderRequest(nullptr), _isEnabled(false) {}
00038 
00039 Storage::~Storage() {}
00040 
00041 bool Storage::isEnabled() const {
00042     return _isEnabled;
00043 }
00044 
00045 void Storage::enable() {
00046     _isEnabled = true;
00047 }
00048 
00049 Networking::ErrorCallback Storage::getErrorPrintingCallback() {
00050     return new Common::Callback<Storage, Networking::ErrorResponse>(this, &Storage::printErrorResponse);
00051 }
00052 
00053 void Storage::printErrorResponse(Networking::ErrorResponse error) {
00054     debug(9, "Storage: error response (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode);
00055     debug(9, "%s", error.response.c_str());
00056 }
00057 
00058 Networking::Request *Storage::addRequest(Networking::Request *request) {
00059     _runningRequestsMutex.lock();
00060     ++_runningRequestsCount;
00061     if (_runningRequestsCount == 1)
00062         debug(9, "Storage is working now");
00063     _runningRequestsMutex.unlock();
00064     return ConnMan.addRequest(request, new Common::Callback<Storage, Networking::Request *>(this, &Storage::requestFinishedCallback));
00065 }
00066 
00067 void Storage::requestFinishedCallback(Networking::Request *invalidRequestPointer) {
00068     bool restartSync = false;
00069 
00070     _runningRequestsMutex.lock();
00071     if (invalidRequestPointer == _savesSyncRequest)
00072         _savesSyncRequest = nullptr;
00073     --_runningRequestsCount;
00074     if (_syncRestartRequestsed)
00075         restartSync = true;
00076     if (_runningRequestsCount == 0 && !restartSync)
00077         debug(9, "Storage is not working now");
00078     _runningRequestsMutex.unlock();
00079 
00080     if (restartSync)
00081         syncSaves(nullptr, nullptr);
00082 }
00083 
00084 Networking::Request *Storage::upload(Common::String remotePath, Common::String localPath, UploadCallback callback, Networking::ErrorCallback errorCallback) {
00085     if (!errorCallback) errorCallback = getErrorPrintingCallback();
00086 
00087     Common::File *f = new Common::File();
00088     if (!f->open(localPath)) {
00089         warning("Storage: unable to open file to upload from");
00090         if (errorCallback)
00091             (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "", -1));
00092         delete errorCallback;
00093         delete callback;
00094         delete f;
00095         return nullptr;
00096     }
00097 
00098     return upload(remotePath, f, callback, errorCallback);
00099 }
00100 
00101 bool Storage::uploadStreamSupported() {
00102     return true;
00103 }
00104 
00105 Networking::Request *Storage::streamFile(Common::String path, Networking::NetworkReadStreamCallback callback, Networking::ErrorCallback errorCallback) {
00106     //most Storages use paths instead of ids, so this should work
00107     return streamFileById(path, callback, errorCallback);
00108 }
00109 
00110 Networking::Request *Storage::download(Common::String remotePath, Common::String localPath, BoolCallback callback, Networking::ErrorCallback errorCallback) {
00111     //most Storages use paths instead of ids, so this should work
00112     return downloadById(remotePath, localPath, callback, errorCallback);
00113 }
00114 
00115 Networking::Request *Storage::downloadById(Common::String remoteId, Common::String localPath, BoolCallback callback, Networking::ErrorCallback errorCallback) {
00116     if (!errorCallback) errorCallback = getErrorPrintingCallback();
00117 
00118     Common::DumpFile *f = new Common::DumpFile();
00119     if (!f->open(localPath, true)) {
00120         warning("Storage: unable to open file to download into");
00121         if (errorCallback) (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "", -1));
00122         delete errorCallback;
00123         delete callback;
00124         delete f;
00125         return nullptr;
00126     }
00127 
00128     return addRequest(new DownloadRequest(this, callback, errorCallback, remoteId, f));
00129 }
00130 
00131 Networking::Request *Storage::downloadFolder(Common::String remotePath, Common::String localPath, FileArrayCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00132     if (!_isEnabled) {
00133         warning("Storage::downloadFolder: cannot be run while Storage is disabled");
00134         if (errorCallback)
00135             (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "Storage is disabled.", -1));
00136         return nullptr;
00137     }
00138     if (!errorCallback)
00139         errorCallback = getErrorPrintingCallback();
00140     return addRequest(new FolderDownloadRequest(this, callback, errorCallback, remotePath, localPath, recursive));
00141 }
00142 
00143 SavesSyncRequest *Storage::syncSaves(BoolCallback callback, Networking::ErrorCallback errorCallback) {
00144     _runningRequestsMutex.lock();
00145     if (!_isEnabled) {
00146         warning("Storage::syncSaves: cannot be run while Storage is disabled");
00147         if (errorCallback)
00148             (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "Storage is disabled.", -1));
00149         _runningRequestsMutex.unlock();
00150         return nullptr;
00151     }
00152     if (_savesSyncRequest) {
00153         warning("Storage::syncSaves: there is a sync in progress already");
00154         _syncRestartRequestsed = true;
00155         _runningRequestsMutex.unlock();
00156         return _savesSyncRequest;
00157     }
00158     if (!callback)
00159         callback = new Common::Callback<Storage, BoolResponse>(this, &Storage::savesSyncDefaultCallback);
00160     if (!errorCallback)
00161         errorCallback = new Common::Callback<Storage, Networking::ErrorResponse>(this, &Storage::savesSyncDefaultErrorCallback);
00162     _savesSyncRequest = new SavesSyncRequest(this, callback, errorCallback);
00163     _syncRestartRequestsed = false;
00164     _runningRequestsMutex.unlock();
00165     return (SavesSyncRequest *)addRequest(_savesSyncRequest); //who knows what that ConnMan could return in the future
00166 }
00167 
00168 bool Storage::isWorking() {
00169     _runningRequestsMutex.lock();
00170     bool working = _runningRequestsCount > 0;
00171     _runningRequestsMutex.unlock();
00172     return working;
00173 }
00174 
00176 
00177 bool Storage::isSyncing() {
00178     _runningRequestsMutex.lock();
00179     bool syncing = _savesSyncRequest != nullptr;
00180     _runningRequestsMutex.unlock();
00181     return syncing;
00182 }
00183 
00184 double Storage::getSyncDownloadingProgress() {
00185     double result = 1;
00186     _runningRequestsMutex.lock();
00187     if (_savesSyncRequest)
00188         result = _savesSyncRequest->getDownloadingProgress();
00189     _runningRequestsMutex.unlock();
00190     return result;
00191 }
00192 
00193 double Storage::getSyncProgress() {
00194     double result = 1;
00195     _runningRequestsMutex.lock();
00196     if (_savesSyncRequest)
00197         result = _savesSyncRequest->getProgress();
00198     _runningRequestsMutex.unlock();
00199     return result;
00200 }
00201 
00202 Common::Array<Common::String> Storage::getSyncingFiles() {
00203     Common::Array<Common::String> result;
00204     _runningRequestsMutex.lock();
00205     if (_savesSyncRequest)
00206         result = _savesSyncRequest->getFilesToDownload();
00207     _runningRequestsMutex.unlock();
00208     return result;
00209 }
00210 
00211 void Storage::cancelSync() {
00212     _runningRequestsMutex.lock();
00213     if (_savesSyncRequest)
00214         _savesSyncRequest->finish();
00215     _runningRequestsMutex.unlock();
00216 }
00217 
00218 void Storage::setSyncTarget(GUI::CommandReceiver *target) {
00219     _runningRequestsMutex.lock();
00220     if (_savesSyncRequest)
00221         _savesSyncRequest->setTarget(target);
00222     _runningRequestsMutex.unlock();
00223 }
00224 
00225 void Storage::savesSyncDefaultCallback(BoolResponse response) {
00226     _runningRequestsMutex.lock();
00227     _savesSyncRequest = nullptr;
00228     _runningRequestsMutex.unlock();
00229 
00230     if (!response.value)
00231         warning("SavesSyncRequest called success callback with `false` argument");
00232 }
00233 
00234 void Storage::savesSyncDefaultErrorCallback(Networking::ErrorResponse error) {
00235     _runningRequestsMutex.lock();
00236     _savesSyncRequest = nullptr;
00237     _runningRequestsMutex.unlock();
00238 
00239     printErrorResponse(error);
00240 
00241     if (error.interrupted)
00242         Common::OSDMessageQueue::instance().addMessage(_("Saved games sync was cancelled."));
00243     else
00244         Common::OSDMessageQueue::instance().addMessage(_("Saved games sync failed.\nCheck your Internet connection."));
00245 }
00246 
00248 
00249 bool Storage::startDownload(Common::String remotePath, Common::String localPath) {
00250     _runningRequestsMutex.lock();
00251     if (_downloadFolderRequest) {
00252         warning("Storage::startDownload: there is a download in progress already");
00253         _runningRequestsMutex.unlock();
00254         return false;
00255     }
00256     _downloadFolderRequest = (FolderDownloadRequest *)downloadFolder(
00257         remotePath, localPath,
00258         new Common::Callback<Storage, FileArrayResponse>(this, &Storage::directoryDownloadedCallback),
00259         new Common::Callback<Storage, Networking::ErrorResponse>(this, &Storage::directoryDownloadedErrorCallback),
00260         true
00261     );
00262     _runningRequestsMutex.unlock();
00263     return true;
00264 }
00265 
00266 void Storage::cancelDownload() {
00267     _runningRequestsMutex.lock();
00268     if (_downloadFolderRequest)
00269         _downloadFolderRequest->finish();
00270     _runningRequestsMutex.unlock();
00271 }
00272 
00273 void Storage::setDownloadTarget(GUI::CommandReceiver *target) {
00274     _runningRequestsMutex.lock();
00275     if (_downloadFolderRequest)
00276         _downloadFolderRequest->setTarget(target);
00277     _runningRequestsMutex.unlock();
00278 }
00279 
00280 bool Storage::isDownloading() {
00281     _runningRequestsMutex.lock();
00282     bool syncing = _downloadFolderRequest != nullptr;
00283     _runningRequestsMutex.unlock();
00284     return syncing;
00285 }
00286 
00287 double Storage::getDownloadingProgress() {
00288     double result = 1;
00289     _runningRequestsMutex.lock();
00290     if (_downloadFolderRequest)
00291         result = _downloadFolderRequest->getProgress();
00292     _runningRequestsMutex.unlock();
00293     return result;
00294 }
00295 
00296 uint64 Storage::getDownloadBytesNumber() {
00297     uint64 result = 0;
00298     _runningRequestsMutex.lock();
00299     if (_downloadFolderRequest)
00300         result = _downloadFolderRequest->getDownloadedBytes();
00301     _runningRequestsMutex.unlock();
00302     return result;
00303 }
00304 
00305 uint64 Storage::getDownloadTotalBytesNumber() {
00306     uint64 result = 0;
00307     _runningRequestsMutex.lock();
00308     if (_downloadFolderRequest)
00309         result = _downloadFolderRequest->getTotalBytesToDownload();
00310     _runningRequestsMutex.unlock();
00311     return result;
00312 }
00313 
00314 uint64 Storage::getDownloadSpeed() {
00315     uint64 result = 0;
00316     _runningRequestsMutex.lock();
00317     if (_downloadFolderRequest)
00318         result = _downloadFolderRequest->getDownloadSpeed();
00319     _runningRequestsMutex.unlock();
00320     return result;
00321 }
00322 
00323 Common::String Storage::getDownloadRemoteDirectory() {
00324     Common::String result = "";
00325     _runningRequestsMutex.lock();
00326     if (_downloadFolderRequest)
00327         result = _downloadFolderRequest->getRemotePath();
00328     _runningRequestsMutex.unlock();
00329     return result;
00330 }
00331 
00332 Common::String Storage::getDownloadLocalDirectory() {
00333     Common::String result = "";
00334     _runningRequestsMutex.lock();
00335     if (_downloadFolderRequest)
00336         result = _downloadFolderRequest->getLocalPath();
00337     _runningRequestsMutex.unlock();
00338     return result;
00339 }
00340 
00341 void Storage::directoryDownloadedCallback(FileArrayResponse response) {
00342     _runningRequestsMutex.lock();
00343     _downloadFolderRequest = nullptr;
00344     _runningRequestsMutex.unlock();
00345 
00346     Common::String message;
00347     if (response.value.size()) {
00348         message = Common::String::format(_("Download complete.\nFailed to download %u files."), response.value.size());
00349     } else {
00350         message = _("Download complete.");
00351     }
00352     Common::OSDMessageQueue::instance().addMessage(message.c_str());
00353 }
00354 
00355 void Storage::directoryDownloadedErrorCallback(Networking::ErrorResponse error) {
00356     _runningRequestsMutex.lock();
00357     _downloadFolderRequest = nullptr;
00358     _runningRequestsMutex.unlock();
00359 
00360     Common::OSDMessageQueue::instance().addMessage(_("Download failed."));
00361 }
00362 
00363 } // End of namespace Cloud


Generated on Sat Jul 4 2020 05:01:07 for ResidualVM by doxygen 1.7.1
curved edge   curved edge