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


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