2021-04-07 20:44:16 +12:00
|
|
|
from logging import getLogger
|
|
|
|
|
|
|
|
from PyQt5.QtCore import QThread, pyqtSignal, Qt
|
2021-09-14 08:44:59 +12:00
|
|
|
from PyQt5.QtWidgets import QScrollArea, QWidget, QVBoxLayout, QLabel, QPushButton, QMessageBox
|
2021-04-07 20:44:16 +12:00
|
|
|
|
2021-09-07 07:10:18 +12:00
|
|
|
from legendary.core import LegendaryCore
|
|
|
|
from legendary.models.game import SaveGameStatus
|
2021-10-08 07:19:24 +13:00
|
|
|
from rare import shared
|
2021-04-08 08:39:23 +12:00
|
|
|
from rare.components.dialogs.path_input_dialog import PathInputDialog
|
2021-04-08 08:42:30 +12:00
|
|
|
from rare.components.tabs.cloud_saves.sync_widget import SyncWidget
|
2021-04-08 08:39:23 +12:00
|
|
|
from rare.utils.extra_widgets import WaitingSpinner
|
2021-04-07 20:44:16 +12:00
|
|
|
|
|
|
|
logger = getLogger("Sync Saves")
|
|
|
|
|
|
|
|
|
|
|
|
class LoadThread(QThread):
|
|
|
|
signal = pyqtSignal(list)
|
|
|
|
|
|
|
|
def __init__(self, core: LegendaryCore):
|
|
|
|
super(LoadThread, self).__init__()
|
|
|
|
self.core = core
|
|
|
|
|
|
|
|
def run(self) -> None:
|
|
|
|
saves = self.core.get_save_games()
|
|
|
|
self.signal.emit(saves)
|
|
|
|
|
|
|
|
|
|
|
|
class SyncSaves(QScrollArea):
|
2021-04-10 21:27:40 +12:00
|
|
|
finished = pyqtSignal(str)
|
2021-04-07 20:44:16 +12:00
|
|
|
|
2021-10-08 07:19:24 +13:00
|
|
|
def __init__(self):
|
2021-09-30 10:22:47 +13:00
|
|
|
super(SyncSaves, self).__init__()
|
2021-10-15 10:18:13 +13:00
|
|
|
self.core = shared.core
|
2021-10-08 07:19:24 +13:00
|
|
|
self.signals = shared.signals
|
2021-04-07 20:44:16 +12:00
|
|
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
|
|
self.load_saves()
|
|
|
|
|
2021-04-10 22:48:17 +12:00
|
|
|
def load_saves(self, app_name=None, auto=False):
|
2021-04-07 20:44:16 +12:00
|
|
|
self.widget = QWidget()
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
layout.addWidget(WaitingSpinner())
|
|
|
|
layout.addWidget(QLabel("<h4>Loading Cloud Saves</h4>"))
|
|
|
|
layout.addStretch()
|
|
|
|
self.widget.setLayout(layout)
|
|
|
|
self.setWidget(self.widget)
|
|
|
|
|
|
|
|
self.start_thread = LoadThread(self.core)
|
2021-04-10 22:48:17 +12:00
|
|
|
self.start_thread.signal.connect(lambda x: self.setup_ui(x, app_name, auto))
|
2021-04-07 20:44:16 +12:00
|
|
|
self.start_thread.start()
|
|
|
|
self.igames = self.core.get_installed_list()
|
|
|
|
|
2021-04-10 22:48:17 +12:00
|
|
|
def setup_ui(self, saves: list, app_name, auto=False):
|
2021-04-07 20:44:16 +12:00
|
|
|
self.start_thread.disconnect()
|
|
|
|
self.main_layout = QVBoxLayout()
|
|
|
|
self.title = QLabel(
|
|
|
|
f"<h1>" + self.tr("Cloud Saves") + "</h1>\n" + self.tr("Found Saves for folowing Games"))
|
|
|
|
self.main_layout.addWidget(self.title)
|
|
|
|
|
|
|
|
saves_games = []
|
|
|
|
for i in saves:
|
|
|
|
if not i.app_name in saves_games and self.core.is_installed(i.app_name):
|
|
|
|
saves_games.append(i.app_name)
|
|
|
|
if len(saves_games) == 0:
|
|
|
|
# QMessageBox.information(self.tr("No Games Found"), self.tr("Your games don't support cloud save"))
|
|
|
|
self.title.setText(
|
|
|
|
f"<h1>" + self.tr("Cloud Saves") + "</h1>\n" + self.tr("Your games does not support Cloud Saves"))
|
|
|
|
self.setWidget(self.title)
|
|
|
|
return
|
|
|
|
|
|
|
|
self.sync_all_button = QPushButton(self.tr("Sync all games"))
|
|
|
|
self.sync_all_button.clicked.connect(self.sync_all)
|
|
|
|
self.main_layout.addWidget(self.sync_all_button)
|
|
|
|
|
|
|
|
latest_save = {}
|
|
|
|
for i in sorted(saves, key=lambda a: a.datetime):
|
|
|
|
latest_save[i.app_name] = i
|
|
|
|
|
|
|
|
logger.info(f'Got {len(latest_save)} remote save game(s)')
|
|
|
|
|
|
|
|
self.widgets = []
|
|
|
|
for igame in self.igames:
|
|
|
|
game = self.core.get_game(igame.app_name)
|
|
|
|
if not game.supports_cloud_saves:
|
|
|
|
continue
|
|
|
|
if latest_save.get(igame.app_name):
|
2021-10-18 11:20:41 +13:00
|
|
|
sync_widget = SyncWidget(igame, latest_save[igame.app_name])
|
2021-04-07 20:44:16 +12:00
|
|
|
else:
|
|
|
|
continue
|
|
|
|
sync_widget.reload.connect(self.reload)
|
|
|
|
self.main_layout.addWidget(sync_widget)
|
|
|
|
self.widgets.append(sync_widget)
|
|
|
|
|
|
|
|
self.widget = QWidget()
|
|
|
|
self.main_layout.addStretch(1)
|
|
|
|
self.widget.setLayout(self.main_layout)
|
|
|
|
self.setWidgetResizable(True)
|
|
|
|
self.setWidget(self.widget)
|
|
|
|
|
2021-04-10 22:48:17 +12:00
|
|
|
if auto:
|
|
|
|
self.save(app_name, True)
|
|
|
|
|
|
|
|
def reload(self, app_name, auto=False):
|
2021-04-10 21:27:40 +12:00
|
|
|
self.finished.emit(app_name)
|
2021-04-07 20:44:16 +12:00
|
|
|
self.setWidget(QWidget())
|
2021-04-10 22:48:17 +12:00
|
|
|
self.load_saves(auto)
|
2021-04-07 20:44:16 +12:00
|
|
|
|
2021-04-10 21:27:40 +12:00
|
|
|
def sync_game(self, app_name, from_game_finish_auto=True):
|
2021-04-10 22:48:17 +12:00
|
|
|
self.setWidget(QWidget())
|
|
|
|
self.load_saves(app_name, from_game_finish_auto)
|
2021-04-10 21:27:40 +12:00
|
|
|
|
2021-04-10 22:48:17 +12:00
|
|
|
def save(self, app_name, from_game_finish_auto=True):
|
2021-04-10 21:27:40 +12:00
|
|
|
for w in self.widgets:
|
|
|
|
if w.igame.app_name == app_name:
|
|
|
|
widget = w
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
logger.warning("An Error occurred. Game does not support cloud saves")
|
|
|
|
return
|
|
|
|
|
|
|
|
if widget.res == SaveGameStatus.SAME_AGE:
|
|
|
|
logger.info("Game is up to date")
|
|
|
|
elif widget.res == SaveGameStatus.LOCAL_NEWER:
|
|
|
|
widget.upload()
|
|
|
|
elif widget.res == SaveGameStatus.REMOTE_NEWER:
|
|
|
|
if from_game_finish_auto:
|
|
|
|
if QMessageBox.question(self, "Really", self.tr("You finished playing game, but Remote game is newer. "
|
|
|
|
"Do you want to download anyway? This could remove "
|
|
|
|
"your game progress. Please check your save path or "
|
|
|
|
"make a backup"),
|
|
|
|
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes:
|
|
|
|
widget.download()
|
|
|
|
else:
|
|
|
|
logger.info("Cancel Download")
|
2021-04-13 02:02:16 +12:00
|
|
|
self.finished.emit(app_name)
|
2021-04-10 21:27:40 +12:00
|
|
|
|
2021-04-07 20:44:16 +12:00
|
|
|
def sync_all(self):
|
|
|
|
logger.info("Sync all Games")
|
|
|
|
for w in self.widgets:
|
|
|
|
if not w.igame.save_path:
|
|
|
|
save_path = self.core.get_save_path(w.igame.app_name)
|
|
|
|
if '%' in save_path or '{' in save_path:
|
|
|
|
self.logger.info_label("Could not find save_path")
|
|
|
|
save_path = PathInputDialog(self.tr("Found no savepath"),
|
|
|
|
self.tr("No save path was found. Please select path or skip"))
|
|
|
|
if save_path == "":
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
w.igame.save_path = save_path
|
|
|
|
if w.res == SaveGameStatus.SAME_AGE:
|
|
|
|
continue
|
|
|
|
if w.res == SaveGameStatus.REMOTE_NEWER:
|
|
|
|
logger.info("Download")
|
|
|
|
w.download()
|
|
|
|
elif w.res == SaveGameStatus.LOCAL_NEWER:
|
|
|
|
logger.info("Upload")
|
|
|
|
w.upload()
|