1
0
Fork 0
mirror of synced 2024-07-02 21:20:54 +12:00
Rare/rare/components/tabs/cloud_saves/sync_widget.py

232 lines
9.6 KiB
Python

import os
from logging import getLogger
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QSettings
from PyQt5.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QLabel, QGroupBox, QMessageBox
from legendary.core import LegendaryCore
from legendary.models.game import InstalledGame, SaveGameStatus
from rare import shared
from rare.components.dialogs.path_input_dialog import PathInputDialog
logger = getLogger("Sync")
def get_raw_save_path(app_name, core):
game = core.lgd.get_game_meta(app_name)
save_path = game.metadata['customAttributes'].get('CloudSaveFolder', {}).get('value')
return save_path
class _UploadThread(QThread):
signal = pyqtSignal(bool)
def __init__(self, app_name, date_time, save_path, core: LegendaryCore):
super(_UploadThread, self).__init__()
self.core = core
self.app_name = app_name
self.date_time = date_time
self.save_path = save_path
def run(self) -> None:
try:
self.core.upload_save(self.app_name, self.save_path, self.date_time)
self.signal.emit(True)
except Exception as e:
logger.error(e)
self.signal.emit(False)
class _DownloadThread(QThread):
signal = pyqtSignal(bool)
def __init__(self, app_name, latest_save, save_path, core: LegendaryCore):
super(_DownloadThread, self).__init__()
self.core = core
self.app_name = app_name
self.latest_save = latest_save
self.save_path = save_path
def run(self) -> None:
try:
self.core.download_saves(self.app_name, self.latest_save.manifest_name, self.save_path, clean_dir=True)
self.signal.emit(True)
except Exception as e:
logger.error(e)
self.signal.emit(False)
class SyncWidget(QGroupBox):
reload = pyqtSignal(str)
def __init__(self, igame: InstalledGame, save):
super(SyncWidget, self).__init__(igame.title)
self.setObjectName("group")
self.layout = QVBoxLayout()
self.setContentsMargins(10, 20, 10, 20)
self.thr = None
self.core = shared.core
self.save = save
self.logger = getLogger("Sync " + igame.app_name)
self.game = self.core.get_game(igame.app_name)
self.igame = igame
self.has_save_path = True
if not igame.save_path or igame.save_path is None:
try:
save_path = self.core.get_save_path(igame.app_name)
except Exception as e:
self.logger.error(e)
return
if '%' in save_path or '{' in save_path:
# status = self.tr("Path not found")
self.logger.info("Could not find save path")
igame.save_path = ""
else:
igame.save_path = save_path
if not igame.save_path:
igame.save_path = os.path.expanduser(f"~/{igame.app_name}/")
QMessageBox.warning(self, "Savepath error",
self.tr("Please edit save path of game {} manually in Cload saves tab").format(
igame.title))
if igame.save_path and not os.path.exists(igame.save_path):
os.makedirs(igame.save_path)
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
self.res, (self.dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, save)
if self.res == SaveGameStatus.NO_SAVE:
self.logger.debug('No cloud or local savegame found.')
return
# game_title = QLabel(f"<h2>{igame.title}</h2>")
if self.dt_local:
local_save_date = QLabel(
self.tr("Local Save date: ") + str(self.dt_local.strftime('%Y-%m-%d %H:%M:%S')))
else:
local_save_date = QLabel(self.tr("No Local Save files"))
if dt_remote:
cloud_save_date = QLabel(self.tr("Cloud save date: ") + str(dt_remote.strftime('%Y-%m-%d %H:%M:%S')))
else:
cloud_save_date = QLabel(self.tr("No Cloud saves"))
if self.res == SaveGameStatus.SAME_AGE:
self.logger.debug(f'Save game for "{igame.title}" is up to date')
status = self.tr("Game is up to date")
self.upload_button = QPushButton(self.tr("Upload anyway"))
self.download_button = QPushButton(self.tr("Download anyway"))
elif self.res == SaveGameStatus.REMOTE_NEWER:
status = self.tr("Cloud save is newer")
self.download_button = QPushButton(self.tr("Download Cloud saves"))
self.download_button.setObjectName("success")
self.upload_button = QPushButton(self.tr("Upload Saves"))
self.logger.debug(f'Cloud save for "{igame.title}" is newer:')
self.logger.debug(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
if self.dt_local:
self.logger.debug(f'- Local save date: {self.dt_local.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.debug('- Local save date: N/A')
self.upload_button.setDisabled(True)
self.upload_button.setToolTip("No local save")
elif self.res == SaveGameStatus.LOCAL_NEWER:
status = self.tr("Local save is newer")
self.upload_button = QPushButton(self.tr("Upload saves"))
self.upload_button.setObjectName("success")
self.download_button = QPushButton(self.tr("Download saves"))
self.logger.info(f'Local save for "{igame.title}" is newer')
if dt_remote:
self.logger.debug(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.debug('- Cloud save date: N/A')
self.download_button.setDisabled(True)
self.logger.debug(f'- Local save date: {self.dt_local.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.error(self.res)
return
self.upload_button.clicked.connect(self.upload)
self.download_button.clicked.connect(self.download)
self.info_text = QLabel(status)
# self.layout.addWidget(game_title)
self.layout.addWidget(local_save_date)
self.layout.addWidget(cloud_save_date)
save_path_layout = QHBoxLayout()
self.raw_path = QLabel("Raw path: " + get_raw_save_path(self.game.app_name, self.core))
self.raw_path.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.layout.addWidget(self.raw_path)
self.save_path_text = QLabel(igame.save_path)
self.save_path_text.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.save_path_text.setWordWrap(True)
self.change_save_path = QPushButton(self.tr("Change path"))
self.change_save_path.setFixedWidth(100)
self.change_save_path.clicked.connect(self.change_path)
save_path_layout.addWidget(self.save_path_text)
save_path_layout.addWidget(self.change_save_path)
self.layout.addLayout(save_path_layout)
self.layout.addWidget(self.info_text)
button_layout = QHBoxLayout()
button_layout.addWidget(self.upload_button)
button_layout.addWidget(self.download_button)
self.layout.addLayout(button_layout)
self.layout.addStretch(1)
self.setLayout(self.layout)
if self.res == SaveGameStatus.REMOTE_NEWER:
settings = QSettings()
if settings.value(f"{igame.app_name}/auto_sync_cloud", False, bool):
self.download()
def change_path(self):
path = PathInputDialog("Select directory", "Select savepath. Warning: Do not change if you are not sure",
self.igame.save_path).get_path()
if path != "":
self.igame.save_path = path
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
self.save_path_text.setText(self.igame.save_path)
self.reload.emit(self.game.app_name)
def upload(self):
self.logger.info("Uploading Saves for game " + self.igame.title)
self.info_text.setText(self.tr("Uploading..."))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.thr = _UploadThread(self.igame.app_name, self.dt_local, self.igame.save_path, self.core)
self.thr.signal.connect(self.uploaded)
self.thr.start()
def uploaded(self, success: bool):
if success:
self.info_text.setText(self.tr("Upload finished"))
else:
self.info_text.setText(self.tr("Upload failed"))
self.upload_button.setDisabled(False)
self.reload.emit(self.game.app_name)
def download(self):
if not os.path.exists(self.igame.save_path):
os.makedirs(self.igame.save_path)
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.logger.info("Downloading Saves for game " + self.igame.title)
self.info_text.setText(self.tr("Downloading..."))
self.thr = _DownloadThread(self.igame.app_name, self.save, self.igame.save_path, self.core)
self.thr.signal.connect(self.downloaded)
self.thr.start()
def downloaded(self, success: bool):
if success:
self.info_text.setText(self.tr("Download finished"))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.download_button.setStyleSheet("QPushButton{background-color: black}")
self.reload.emit(self.game.app_name)
else:
self.info_text.setText("Error while downloading save")
self.download_button.setStyleSheet("QPushButton{background-color: black}")