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

cloudmanager.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/cloudmanager.h"
00024 #include "backends/cloud/box/boxstorage.h"
00025 #include "backends/cloud/dropbox/dropboxstorage.h"
00026 #include "backends/cloud/onedrive/onedrivestorage.h"
00027 #include "backends/cloud/googledrive/googledrivestorage.h"
00028 #include "common/translation.h"
00029 #include "common/config-manager.h"
00030 #include "common/str.h"
00031 #ifdef USE_SDL_NET
00032 #include "backends/networking/sdl_net/localwebserver.h"
00033 #endif
00034 
00035 namespace Common {
00036 
00037 DECLARE_SINGLETON(Cloud::CloudManager);
00038 
00039 }
00040 
00041 namespace Cloud {
00042 
00043 const char *const CloudManager::kStoragePrefix = "storage_";
00044 
00045 CloudManager::CloudManager() : _currentStorageIndex(0), _activeStorage(nullptr) {}
00046 
00047 CloudManager::~CloudManager() {
00048     g_system->getEventManager()->getEventDispatcher()->unregisterSource(this);
00049 
00050     delete _activeStorage;
00051     freeStorages();
00052 }
00053 
00054 Common::String CloudManager::getStorageConfigName(uint32 index) const {
00055     switch (index) {
00056     case kStorageNoneId: return "<none>";
00057     case kStorageDropboxId: return "Dropbox";
00058     case kStorageOneDriveId: return "OneDrive";
00059     case kStorageGoogleDriveId: return "GoogleDrive";
00060     case kStorageBoxId: return "Box";
00061     }
00062     assert(false); // Unhandled StorageID value
00063     return "";
00064 }
00065 
00066 void CloudManager::loadStorage() {
00067     switch (_currentStorageIndex) {
00068     case kStorageDropboxId:
00069         _activeStorage = Dropbox::DropboxStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00070         break;
00071     case kStorageOneDriveId:
00072         _activeStorage = OneDrive::OneDriveStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00073         break;
00074     case kStorageGoogleDriveId:
00075         _activeStorage = GoogleDrive::GoogleDriveStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00076         break;
00077     case kStorageBoxId:
00078         _activeStorage = Box::BoxStorage::loadFromConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00079         break;
00080     default:
00081         _activeStorage = nullptr;
00082     }
00083 
00084     if (!_activeStorage) {
00085         _currentStorageIndex = kStorageNoneId;
00086     }
00087 }
00088 
00089 void CloudManager::init() {
00090     //init configs structs
00091     for (uint32 i = 0; i < kStorageTotal; ++i) {
00092         Common::String name = getStorageConfigName(i);
00093         StorageConfig config;
00094         config.name = _(name);
00095         config.username = "";
00096         config.lastSyncDate = "";
00097         config.usedBytes = 0;
00098         if (ConfMan.hasKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain))
00099             config.username = ConfMan.get(kStoragePrefix + name + "_username", ConfMan.kCloudDomain);
00100         if (ConfMan.hasKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain))
00101             config.lastSyncDate = ConfMan.get(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain);
00102         if (ConfMan.hasKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain))
00103             config.usedBytes = ConfMan.get(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain).asUint64();
00104         _storages.push_back(config);
00105     }
00106 
00107     //load an active storage if there is any
00108     _currentStorageIndex = kStorageNoneId;
00109     if (ConfMan.hasKey("current_storage", ConfMan.kCloudDomain))
00110         _currentStorageIndex = ConfMan.getInt("current_storage", ConfMan.kCloudDomain);
00111 
00112     loadStorage();
00113 
00114     g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
00115 }
00116 
00117 void CloudManager::save() {
00118     for (uint32 i = 0; i < _storages.size(); ++i) {
00119         if (i == kStorageNoneId)
00120             continue;
00121         Common::String name = getStorageConfigName(i);
00122         ConfMan.set(kStoragePrefix + name + "_username", _storages[i].username, ConfMan.kCloudDomain);
00123         ConfMan.set(kStoragePrefix + name + "_lastSync", _storages[i].lastSyncDate, ConfMan.kCloudDomain);
00124         ConfMan.set(kStoragePrefix + name + "_usedBytes", Common::String::format("%lu", _storages[i].usedBytes), ConfMan.kCloudDomain);
00125     }
00126 
00127     ConfMan.set("current_storage", Common::String::format("%u", _currentStorageIndex), ConfMan.kCloudDomain);
00128     if (_activeStorage)
00129         _activeStorage->saveConfig(kStoragePrefix + getStorageConfigName(_currentStorageIndex) + "_");
00130     ConfMan.flushToDisk();
00131 }
00132 
00133 void CloudManager::replaceStorage(Storage *storage, uint32 index) {
00134     freeStorages();
00135     if (!storage)
00136         error("CloudManager::replaceStorage: NULL storage passed");
00137     if (index >= kStorageTotal)
00138         error("CloudManager::replaceStorage: invalid index passed");
00139     if (_activeStorage != nullptr && _activeStorage->isWorking()) {
00140         warning("CloudManager::replaceStorage: replacing Storage while the other is working");
00141         if (_activeStorage->isDownloading())
00142             _activeStorage->cancelDownload();
00143         if (_activeStorage->isSyncing())
00144             _activeStorage->cancelSync();
00145         removeStorage(_activeStorage);
00146     } else {
00147         delete _activeStorage;
00148     }
00149     _activeStorage = storage;
00150     _currentStorageIndex = index;
00151     if (_storages[index].username == "") {
00152         // options' Cloud tab believes Storage is connected once it has non-empty username
00153         _storages[index].username = _("<syncing...>");
00154         _storages[index].lastSyncDate = _("<right now>");
00155         _storages[index].usedBytes = 0;
00156     }
00157     save();
00158 
00159     //do what should be done on first Storage connect
00160     if (_activeStorage) {
00161         _activeStorage->info(nullptr, nullptr); //automatically calls setStorageUsername()
00162     }
00163 }
00164 
00165 void CloudManager::removeStorage(Storage *storage) {
00166     // can't just delete it as it's mostly likely the one who calls the method
00167     // it would be freed on freeStorages() call (on next Storage connect or replace)
00168     _storagesToRemove.push_back(storage);
00169 }
00170 
00171 void CloudManager::freeStorages() {
00172     for (uint32 i = 0; i < _storagesToRemove.size(); ++i)
00173         delete _storagesToRemove[i];
00174     _storagesToRemove.clear();
00175 }
00176 
00177 void CloudManager::passNoStorageConnected(Networking::ErrorCallback errorCallback) const {
00178     if (errorCallback == nullptr)
00179         return;
00180     (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "No Storage connected!", -1));
00181 }
00182 
00183 Storage *CloudManager::getCurrentStorage() const {
00184     return _activeStorage;
00185 }
00186 
00187 uint32 CloudManager::getStorageIndex() const {
00188     return _currentStorageIndex;
00189 }
00190 
00191 Common::StringArray CloudManager::listStorages() const {
00192     Common::StringArray result;
00193     for (uint32 i = 0; i < _storages.size(); ++i) {
00194         result.push_back(_storages[i].name);
00195     }
00196     return result;
00197 }
00198 
00199 bool CloudManager::switchStorage(uint32 index) {
00200     if (index >= _storages.size()) {
00201         warning("CloudManager::switchStorage: invalid index passed");
00202         return false;
00203     }
00204 
00205     Storage *storage = getCurrentStorage();
00206     if (storage && storage->isWorking()) {
00207         warning("CloudManager::switchStorage: another storage is working now");
00208         return false;
00209     }
00210 
00211     _currentStorageIndex = index;
00212     loadStorage();
00213     save();
00214     return true;
00215 }
00216 
00217 Common::String CloudManager::getStorageUsername(uint32 index) {
00218     if (index >= _storages.size())
00219         return "";
00220     return _storages[index].username;
00221 }
00222 
00223 uint64 CloudManager::getStorageUsedSpace(uint32 index) {
00224     if (index >= _storages.size())
00225         return 0;
00226     return _storages[index].usedBytes;
00227 }
00228 
00229 Common::String CloudManager::getStorageLastSync(uint32 index) {
00230     if (index >= _storages.size())
00231         return "";
00232     if (index == _currentStorageIndex && isSyncing())
00233         return "";
00234     return _storages[index].lastSyncDate;
00235 }
00236 
00237 void CloudManager::setStorageUsername(uint32 index, Common::String name) {
00238     if (index >= _storages.size())
00239         return;
00240     _storages[index].username = name;
00241     save();
00242 }
00243 
00244 void CloudManager::setStorageUsedSpace(uint32 index, uint64 used) {
00245     if (index >= _storages.size())
00246         return;
00247     _storages[index].usedBytes = used;
00248     save();
00249 }
00250 
00251 void CloudManager::setStorageLastSync(uint32 index, Common::String date) {
00252     if (index >= _storages.size())
00253         return;
00254     _storages[index].lastSyncDate = date;
00255     save();
00256 }
00257 
00258 void CloudManager::connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb) {
00259     freeStorages();
00260 
00261     switch (index) {
00262     case kStorageDropboxId:
00263         new Dropbox::DropboxStorage(code, cb);
00264         break;
00265     case kStorageOneDriveId:
00266         new OneDrive::OneDriveStorage(code, cb);
00267         break;
00268     case kStorageGoogleDriveId:
00269         new GoogleDrive::GoogleDriveStorage(code, cb);
00270         break;
00271     case kStorageBoxId:
00272         new Box::BoxStorage(code, cb);
00273         break;
00274     }
00275     // in these constructors Storages request token using the passed code
00276     // when the token is received, they call replaceStorage()
00277     // or removeStorage(), if some error occurred
00278     // thus, no memory leak happens
00279 }
00280 
00281 void CloudManager::disconnectStorage(uint32 index) {
00282     if (index >= kStorageTotal)
00283         error("CloudManager::disconnectStorage: invalid index passed");
00284 
00285     Common::String name = getStorageConfigName(index);
00286     switch (index) {
00287     case kStorageDropboxId:
00288         Dropbox::DropboxStorage::removeFromConfig(kStoragePrefix + name + "_");
00289         break;
00290     case kStorageOneDriveId:
00291         OneDrive::OneDriveStorage::removeFromConfig(kStoragePrefix + name + "_");
00292         break;
00293     case kStorageGoogleDriveId:
00294         GoogleDrive::GoogleDriveStorage::removeFromConfig(kStoragePrefix + name + "_");
00295         break;
00296     case kStorageBoxId:
00297         Box::BoxStorage::removeFromConfig(kStoragePrefix + name + "_");
00298         break;
00299     }
00300 
00301     switchStorage(kStorageNoneId);
00302 
00303     ConfMan.removeKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain);
00304     ConfMan.removeKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain);
00305     ConfMan.removeKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain);
00306 
00307     StorageConfig config;
00308     config.name = _(name);
00309     config.username = "";
00310     config.lastSyncDate = "";
00311     config.usedBytes = 0;
00312 
00313     _storages[index] = config;
00314 }
00315 
00316 
00317 Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00318     Storage *storage = getCurrentStorage();
00319     if (storage) {
00320         return storage->listDirectory(path, callback, errorCallback, recursive);
00321     } else {
00322         passNoStorageConnected(errorCallback);
00323         delete callback;
00324         delete errorCallback;
00325     }
00326     return nullptr;
00327 }
00328 
00329 Networking::Request *CloudManager::downloadFolder(Common::String remotePath, Common::String localPath, Storage::FileArrayCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00330     Storage *storage = getCurrentStorage();
00331     if (storage) {
00332         return storage->downloadFolder(remotePath, localPath, callback, errorCallback, recursive);
00333     } else {
00334         passNoStorageConnected(errorCallback);
00335         delete callback;
00336         delete errorCallback;
00337     }
00338     return nullptr;
00339 }
00340 
00341 Networking::Request *CloudManager::info(Storage::StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
00342     Storage *storage = getCurrentStorage();
00343     if (storage) {
00344         return storage->info(callback, errorCallback);
00345     } else {
00346         passNoStorageConnected(errorCallback);
00347         delete callback;
00348         delete errorCallback;
00349     }
00350     return nullptr;
00351 }
00352 
00353 Common::String CloudManager::savesDirectoryPath() {
00354     Storage *storage = getCurrentStorage();
00355     if (storage)
00356         return storage->savesDirectoryPath();
00357     return "";
00358 }
00359 
00360 bool CloudManager::canSyncFilename(const Common::String &filename) const {
00361     if (filename == "" || filename[0] == '.')
00362         return false;
00363 
00364     return true;
00365 }
00366 
00367 bool CloudManager::isStorageEnabled() const {
00368     Storage *storage = getCurrentStorage();
00369     if (storage)
00370         return storage->isEnabled();
00371     return false;
00372 }
00373 
00374 void CloudManager::enableStorage() {
00375     Storage *storage = getCurrentStorage();
00376     if (storage) {
00377         storage->enable();
00378         save();
00379     }
00380 }
00381 
00382 SavesSyncRequest *CloudManager::syncSaves(Storage::BoolCallback callback, Networking::ErrorCallback errorCallback) {
00383     Storage *storage = getCurrentStorage();
00384     if (storage) {
00385         setStorageLastSync(_currentStorageIndex, "???"); //TODO get the date
00386         return storage->syncSaves(callback, errorCallback);
00387     } else {
00388         passNoStorageConnected(errorCallback);
00389         delete callback;
00390         delete errorCallback;
00391     }
00392     return nullptr;
00393 }
00394 
00395 bool CloudManager::isWorking() const {
00396     Storage *storage = getCurrentStorage();
00397     if (storage)
00398         return storage->isWorking();
00399     return false;
00400 }
00401 
00403 
00404 bool CloudManager::isSyncing() const {
00405     Storage *storage = getCurrentStorage();
00406     if (storage)
00407         return storage->isSyncing();
00408     return false;
00409 }
00410 
00411 double CloudManager::getSyncDownloadingProgress() const {
00412     Storage *storage = getCurrentStorage();
00413     if (storage)
00414         return storage->getSyncDownloadingProgress();
00415     return 1;
00416 }
00417 
00418 double CloudManager::getSyncProgress() const {
00419     Storage *storage = getCurrentStorage();
00420     if (storage)
00421         return storage->getSyncProgress();
00422     return 1;
00423 }
00424 
00425 Common::Array<Common::String> CloudManager::getSyncingFiles() const {
00426     Storage *storage = getCurrentStorage();
00427     if (storage)
00428         return storage->getSyncingFiles();
00429     return Common::Array<Common::String>();
00430 }
00431 
00432 void CloudManager::cancelSync() const {
00433     Storage *storage = getCurrentStorage();
00434     if (storage)
00435         storage->cancelSync();
00436 }
00437 
00438 void CloudManager::setSyncTarget(GUI::CommandReceiver *target) const {
00439     Storage *storage = getCurrentStorage();
00440     if (storage)
00441         storage->setSyncTarget(target);
00442 }
00443 
00444 void CloudManager::showCloudDisabledIcon() {
00445     _icon.show(CloudIcon::kDisabled, 3000);
00446 }
00447 
00449 
00450 bool CloudManager::startDownload(Common::String remotePath, Common::String localPath) const {
00451     Storage *storage = getCurrentStorage();
00452     if (storage)
00453         return storage->startDownload(remotePath, localPath);
00454     return false;
00455 }
00456 
00457 void CloudManager::cancelDownload() const {
00458     Storage *storage = getCurrentStorage();
00459     if (storage)
00460         storage->cancelDownload();
00461 }
00462 
00463 void CloudManager::setDownloadTarget(GUI::CommandReceiver *target) const {
00464     Storage *storage = getCurrentStorage();
00465     if (storage)
00466         storage->setDownloadTarget(target);
00467 }
00468 
00469 bool CloudManager::isDownloading() const {
00470     Storage *storage = getCurrentStorage();
00471     if (storage)
00472         return storage->isDownloading();
00473     return false;
00474 }
00475 
00476 double CloudManager::getDownloadingProgress() const {
00477     Storage *storage = getCurrentStorage();
00478     if (storage)
00479         return storage->getDownloadingProgress();
00480     return 1;
00481 }
00482 
00483 uint64 CloudManager::getDownloadBytesNumber() const {
00484     Storage *storage = getCurrentStorage();
00485     if (storage)
00486         return storage->getDownloadBytesNumber();
00487     return 0;
00488 }
00489 
00490 uint64 CloudManager::getDownloadTotalBytesNumber() const {
00491     Storage *storage = getCurrentStorage();
00492     if (storage)
00493         return storage->getDownloadTotalBytesNumber();
00494     return 0;
00495 }
00496 
00497 uint64 CloudManager::getDownloadSpeed() const {
00498     Storage *storage = getCurrentStorage();
00499     if (storage)
00500         return storage->getDownloadSpeed();
00501     return 0;
00502 }
00503 
00504 Common::String CloudManager::getDownloadRemoteDirectory() const {
00505     Storage *storage = getCurrentStorage();
00506     if (storage)
00507         return storage->getDownloadRemoteDirectory();
00508     return "";
00509 }
00510 
00511 Common::String CloudManager::getDownloadLocalDirectory() const {
00512     Storage *storage = getCurrentStorage();
00513     if (storage)
00514         return storage->getDownloadLocalDirectory();
00515     return "";
00516 }
00517 
00518 bool CloudManager::pollEvent(Common::Event &event) {
00519     if (_icon.needsUpdate()) {
00520         if (_icon.getShownType() != CloudIcon::kDisabled) {
00521             if (isWorking()) {
00522                 _icon.show(CloudIcon::kSyncing);
00523             } else {
00524                 _icon.show(CloudIcon::kNone);
00525             }
00526         }
00527 
00528         _icon.update();
00529     }
00530 
00531     return false;
00532 }
00533 
00534 } // End of namespace Cloud


Generated on Sat Apr 4 2020 05:00:24 for ResidualVM by doxygen 1.7.1
curved edge   curved edge