2021-10-12 10:19:32 +13:00
|
|
|
import json
|
|
|
|
import os
|
|
|
|
from logging import getLogger
|
2021-11-06 04:48:56 +13:00
|
|
|
from typing import List, Tuple
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2021-11-17 10:54:23 +13:00
|
|
|
from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal
|
2021-11-06 00:16:58 +13:00
|
|
|
from PyQt5.QtGui import QStandardItemModel
|
2021-11-17 10:54:23 +13:00
|
|
|
from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView
|
2021-10-12 10:19:32 +13:00
|
|
|
|
|
|
|
import rare.shared as shared
|
2021-10-17 12:17:54 +13:00
|
|
|
from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup
|
2021-10-12 10:19:32 +13:00
|
|
|
from rare.utils import legendary_utils
|
|
|
|
from rare.utils.extra_widgets import IndicatorLineEdit, PathEdit
|
|
|
|
|
|
|
|
logger = getLogger("Import")
|
|
|
|
|
|
|
|
|
2021-11-06 00:16:58 +13:00
|
|
|
class AppNameCompleter(QCompleter):
|
|
|
|
activated = pyqtSignal(str)
|
|
|
|
|
2021-11-06 04:48:56 +13:00
|
|
|
def __init__(self, app_names: List, parent=None):
|
2021-11-06 00:16:58 +13:00
|
|
|
super(AppNameCompleter, self).__init__(parent)
|
2021-11-06 04:48:56 +13:00
|
|
|
# pylint: disable=E1136
|
2021-11-06 11:49:37 +13:00
|
|
|
super(AppNameCompleter, self).activated[QModelIndex].connect(self.__activated_idx)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
|
|
|
model = QStandardItemModel(len(app_names), 2)
|
|
|
|
for idx, game in enumerate(app_names):
|
|
|
|
app_name, app_title = game
|
|
|
|
model.setData(model.index(idx, 0), app_title)
|
|
|
|
model.setData(model.index(idx, 1), app_name)
|
|
|
|
self.setModel(model)
|
|
|
|
|
2021-11-06 04:48:56 +13:00
|
|
|
treeview = QTreeView()
|
|
|
|
self.setPopup(treeview)
|
|
|
|
treeview.setRootIsDecorated(False)
|
|
|
|
treeview.header().hide()
|
|
|
|
treeview.header().setSectionResizeMode(0, QHeaderView.Stretch)
|
|
|
|
treeview.header().setSectionResizeMode(1, QHeaderView.Stretch)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
2021-11-06 04:48:56 +13:00
|
|
|
# listview = QListView()
|
|
|
|
# self.setPopup(listview)
|
|
|
|
# # listview.setModelColumn(1)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
|
|
|
self.setFilterMode(Qt.MatchContains)
|
|
|
|
self.setCaseSensitivity(Qt.CaseInsensitive)
|
|
|
|
# self.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
|
|
|
|
|
2021-11-06 11:49:37 +13:00
|
|
|
def __activated_idx(self, idx):
|
2021-11-06 00:16:58 +13:00
|
|
|
# lk: don't even look at this in a funny way, it will die of shame
|
|
|
|
# lk: Note to self, the completer and popup models are different.
|
|
|
|
# lk: Getting the index from the popup and trying to use it in the completer will return invalid results
|
2021-11-06 11:49:37 +13:00
|
|
|
if isinstance(idx, QModelIndex):
|
2021-11-06 00:16:58 +13:00
|
|
|
self.activated.emit(
|
|
|
|
self.popup().model().data(
|
2021-11-06 11:49:37 +13:00
|
|
|
self.popup().model().index(idx.row(), 1)
|
2021-11-06 00:16:58 +13:00
|
|
|
)
|
|
|
|
)
|
2021-11-06 11:49:37 +13:00
|
|
|
# TODO: implement conversion from app_name to app_title (signal loop here)
|
2021-11-06 00:16:58 +13:00
|
|
|
# if isinstance(idx_str, str):
|
|
|
|
# self.activated.emit(idx_str)
|
|
|
|
|
|
|
|
|
2021-10-12 10:19:32 +13:00
|
|
|
class ImportGroup(QGroupBox, Ui_ImportGroup):
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(ImportGroup, self).__init__(parent=parent)
|
|
|
|
self.setupUi(self)
|
2021-10-15 11:08:18 +13:00
|
|
|
self.core = shared.core
|
2021-11-17 10:54:23 +13:00
|
|
|
self.app_name_list = [game.app_name for game in shared.api_results.game_list]
|
2021-11-06 00:16:58 +13:00
|
|
|
self.install_dir_list = [
|
|
|
|
game.metadata.get('customAttributes', {}).get('FolderName', {}).get('value', game.app_name)
|
2021-11-17 10:54:23 +13:00
|
|
|
for game in shared.api_results.game_list if not game.is_dlc]
|
2021-10-12 10:19:32 +13:00
|
|
|
|
|
|
|
self.path_edit = PathEdit(
|
|
|
|
self.core.get_default_install_dir(),
|
|
|
|
QFileDialog.DirectoryOnly,
|
|
|
|
edit_func=self.path_edit_cb,
|
|
|
|
parent=self
|
|
|
|
)
|
|
|
|
self.path_edit.textChanged.connect(self.path_changed)
|
|
|
|
self.path_edit_layout.addWidget(self.path_edit)
|
|
|
|
|
|
|
|
self.app_name = IndicatorLineEdit(
|
|
|
|
ph_text=self.tr("Use in case the app name was not found automatically"),
|
2021-11-06 04:48:56 +13:00
|
|
|
completer=AppNameCompleter(app_names=[(i.app_name, i.app_title) for i in self.core.get_game_list()]),
|
2021-10-12 10:19:32 +13:00
|
|
|
edit_func=self.app_name_edit_cb,
|
|
|
|
parent=self
|
|
|
|
)
|
|
|
|
self.app_name.textChanged.connect(self.app_name_changed)
|
|
|
|
self.app_name_layout.addWidget(self.app_name)
|
|
|
|
|
|
|
|
self.import_button.setEnabled(False)
|
|
|
|
self.import_button.clicked.connect(self.import_game)
|
|
|
|
|
|
|
|
def path_edit_cb(self, path) -> Tuple[bool, str]:
|
|
|
|
if os.path.exists(path):
|
|
|
|
if os.path.exists(os.path.join(path, ".egstore")):
|
|
|
|
return True, path
|
2021-11-06 00:16:58 +13:00
|
|
|
elif os.path.basename(path) in self.install_dir_list:
|
|
|
|
return True, path
|
2021-10-12 10:19:32 +13:00
|
|
|
return False, path
|
|
|
|
|
|
|
|
def path_changed(self, path):
|
2021-11-06 00:16:58 +13:00
|
|
|
self.info_label.setText(str())
|
2021-10-12 10:19:32 +13:00
|
|
|
if self.path_edit.is_valid:
|
|
|
|
self.app_name.setText(self.find_app_name(path))
|
|
|
|
else:
|
|
|
|
self.app_name.setText(str())
|
|
|
|
|
|
|
|
def app_name_edit_cb(self, text) -> Tuple[bool, str]:
|
|
|
|
if not text:
|
|
|
|
return False, text
|
2021-11-06 00:16:58 +13:00
|
|
|
if text in self.app_name_list:
|
2021-10-12 10:19:32 +13:00
|
|
|
return True, text
|
|
|
|
else:
|
|
|
|
return False, text
|
|
|
|
|
|
|
|
def app_name_changed(self, text):
|
2021-11-06 00:16:58 +13:00
|
|
|
self.info_label.setText(str())
|
2021-10-12 10:19:32 +13:00
|
|
|
if self.app_name.is_valid:
|
|
|
|
self.import_button.setEnabled(True)
|
|
|
|
else:
|
|
|
|
self.import_button.setEnabled(False)
|
|
|
|
|
|
|
|
def find_app_name(self, path):
|
|
|
|
if not os.path.exists(os.path.join(path, ".egstore")):
|
|
|
|
return None
|
|
|
|
for i in os.listdir(os.path.join(path, ".egstore")):
|
|
|
|
if i.endswith(".mancpn"):
|
|
|
|
file = os.path.join(path, ".egstore", i)
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
logger.warning("File was not found")
|
|
|
|
return None
|
|
|
|
return json.load(open(file, "r"))["AppName"]
|
|
|
|
|
|
|
|
def import_game(self, path=None):
|
|
|
|
app_name = self.app_name.text()
|
|
|
|
if not path:
|
|
|
|
path = self.path_edit.text()
|
|
|
|
if not app_name:
|
|
|
|
# try to find app name
|
|
|
|
if a_n := self.find_app_name(path):
|
|
|
|
app_name = a_n
|
|
|
|
else:
|
|
|
|
self.info_label.setText(self.tr("Could not find app name"))
|
|
|
|
return
|
|
|
|
|
|
|
|
if legendary_utils.import_game(self.core, app_name=app_name, path=path):
|
|
|
|
self.info_label.setText(self.tr("Successfully imported {}. Reload library").format(
|
|
|
|
self.core.get_installed_game(app_name).title))
|
2021-11-06 00:16:58 +13:00
|
|
|
self.app_name.setText(str())
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2021-11-06 00:16:58 +13:00
|
|
|
shared.signals.update_gamelist.emit([app_name])
|
2021-10-12 10:19:32 +13:00
|
|
|
else:
|
2021-11-06 00:16:58 +13:00
|
|
|
logger.warning(f'Failed to import "{app_name}"')
|
2021-10-12 10:19:32 +13:00
|
|
|
self.info_label.setText(self.tr("Failed to import {}").format(app_name))
|
|
|
|
return
|