1
0
Fork 0
mirror of synced 2024-05-18 19:42:54 +12:00
This commit is contained in:
Dummerle 2021-02-10 11:48:25 +01:00
commit 83fbee1e9b
63 changed files with 3085 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/RareNew.iml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -0,0 +1,43 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="certifi" />
<item index="1" class="java.lang.String" itemvalue="requests" />
<item index="2" class="java.lang.String" itemvalue="urllib3" />
<item index="3" class="java.lang.String" itemvalue="Pillow" />
<item index="4" class="java.lang.String" itemvalue="PyQt5" />
<item index="5" class="java.lang.String" itemvalue="legendary_gl" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N802" />
<option value="N806" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<list>
<option value="PyQt5-stubs==5.14.2.2" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="bool.sum" />
<option value="PyQt5.QtWidgets.clicked.connect" />
</list>
</option>
</inspection_tool>
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/RareNew.iml" filepath="$PROJECT_DIR$/.idea/RareNew.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,12 @@
from PyQt5.QtWidgets import QMainWindow
from Rare.Components.TabWidget import TabWidget
class MainWindow(QMainWindow):
def __init__(self, core):
super(MainWindow, self).__init__()
self.setGeometry(0, 0, 1000, 800)
self.setWindowTitle("Rare - GUI for legendary")
self.setCentralWidget(TabWidget(core))
self.show()

View file

@ -0,0 +1,67 @@
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QTabWidget, QTabBar, QWidget, QToolButton, QWidgetAction, QMenu
from Rare import style_path
from Rare.Components.Tabs.Account.AccountWidget import MiniWidget
from Rare.Components.Tabs.Games.Games import Games
class TabWidget(QTabWidget):
def __init__(self, core):
super(TabWidget, self).__init__()
self.setTabBar(TabBar(2))
self.game_list = Games(core)
self.addTab(self.game_list, self.tr("Games"))
self.downloads = QWidget()
self.addTab(self.downloads, "Downloads")
# Space Tab
self.addTab(QWidget(), "")
self.setTabEnabled(2, False)
self.account = QWidget()
self.addTab(self.account, "")
self.setTabEnabled(3, False)
# self.settings = SettingsTab(core)
self.settings = QWidget()
self.addTab(self.settings, QIcon(style_path + "/Icons/settings.png"), "")
self.tabBar().setTabButton(3, self.tabBar().RightSide, TabButtonWidget(core))
def resizeEvent(self, event):
self.tabBar().setMinimumWidth(self.width())
super(TabWidget, self).resizeEvent(event)
def download(self):
self.downloads.download()
class TabBar(QTabBar):
def __init__(self, expanded):
super(TabBar, self).__init__()
self._expanded = expanded
def tabSizeHint(self, index):
size = super(TabBar, self).tabSizeHint(index)
if index == self._expanded:
offset = self.width()
for index in range(self.count()):
offset -= super(TabBar, self).tabSizeHint(index).width()
size.setWidth(max(size.width(), size.width() + offset))
return size
class TabButtonWidget(QToolButton):
def __init__(self, core):
super(TabButtonWidget, self).__init__()
self.setText("Icon")
self.setPopupMode(QToolButton.InstantPopup)
self.setIcon(QIcon(style_path+"/Icons/account.png"))
self.setToolTip("Account")
self.setMenu(QMenu())
action = QWidgetAction(self)
action.setDefaultWidget(MiniWidget(core))
self.menu().addAction(action)

View file

@ -0,0 +1,37 @@
import webbrowser
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton
from legendary.core import LegendaryCore
class MiniWidget(QWidget):
def __init__(self, core: LegendaryCore):
super(MiniWidget, self).__init__()
self.layout = QVBoxLayout()
self.core = core
self.layout.addWidget(QLabel("Account"))
self.layout.addWidget(QLabel("Logged in as "+ self.core.lgd.userdata["display_name"]))
self.open_browser = QPushButton("Account settings")
self.open_browser.clicked.connect(self.open_account)
self.layout.addWidget(self.open_browser)
self.logout_button = QPushButton("Logout")
self.logout_button.clicked.connect(self.logout)
self.layout.addWidget(self.logout_button)
self.setLayout(self.layout)
def logout(self):
reply = QMessageBox.question(self.parent().parent(), 'Message',
"Do you really want to logout", QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
self.core.lgd.invalidate_userdata()
QCoreApplication.exit(0)
# self.core.lgd.invalidate_userdata()
# exit()
def open_account(self):
webbrowser.open("https://www.epicgames.com/account/personal?productName=epicgames")

View file

@ -0,0 +1,6 @@
from PyQt5.QtWidgets import QWidget
class DownloadTab(QWidget):
def __init__(self):
super(DownloadTab, self).__init__()

View file

@ -0,0 +1,36 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from legendary.core import LegendaryCore
from Rare.Components.Tabs.Games.GameWidgetInstalled import GameWidgetInstalled
from Rare.Components.Tabs.Games.GameWidgetUninstalled import GameWidgetUninstalled
from Rare.utils.QtExtensions import FlowLayout
class GameList(QScrollArea):
def __init__(self, core: LegendaryCore):
super(GameList, self).__init__()
self.core = core
self.widget = QWidget()
self.setWidgetResizable(True)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.layout = FlowLayout()
for i in self.core.get_installed_list():
# continue
self.layout.addWidget(GameWidgetInstalled(core, i))
uninstalled_games = []
installed = [i.app_name for i in core.get_installed_list()]
for game in sorted(core.get_game_list(), key=lambda x: x.app_title):
if not game.app_name in installed:
uninstalled_games.append(game)
for i in uninstalled_games:
self.layout.addWidget(GameWidgetUninstalled(core, i))
self.widget.setLayout(self.layout)
self.setWidget(self.widget)

View file

@ -0,0 +1,108 @@
import os
from logging import getLogger
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QPixmap, QIcon, QMouseEvent
from PyQt5.QtWidgets import *
from legendary.core import LegendaryCore
from legendary.models.game import InstalledGame
from Rare import style_path
from Rare.utils import LegendaryApi
from Rare.utils.QtExtensions import ClickableLabel
from Rare.utils.RareConfig import IMAGE_DIR
logger = getLogger("FlowWidget")
class GameWidgetInstalled(QWidget):
def __init__(self, core: LegendaryCore, game: InstalledGame):
super(GameWidgetInstalled, self).__init__()
self.setObjectName("game_widget_parent")
self.layout = QVBoxLayout()
self.core = core
self.game = game
self.running = False
Qt.WA_MouseTracking = Qt.WA_Hover
if os.path.exists(f"{IMAGE_DIR}/{game.app_name}/FinalArt.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{game.app_name}/FinalArt.png")
elif os.path.exists(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png")
elif os.path.exists(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png")
else:
logger.warning(f"No Image found: {self.game.title}")
pixmap = None
if pixmap:
w = 200
pixmap = pixmap.scaled(w, int(w * 4 / 3))
self.image = ClickableLabel()
self.image.setObjectName("game_widget")
self.image.setPixmap(pixmap)
self.layout.addWidget(self.image)
self.title_label = QLabel(f"<h4>{game.title}</h4>")
self.title_label.setWordWrap(True)
self.title_label.setFixedWidth(180)
minilayout = QHBoxLayout()
self.title_label.setObjectName("game_widget")
minilayout.addWidget(self.title_label)
# minilayout.addStretch(1)
self.menu = QPushButton(QIcon(style_path + "/Icons/menu.png"), "")
self.menu.setMenu(Menu())
self.menu.setObjectName("menu")
self.menu.setFixedWidth(10)
minilayout.addWidget(self.menu)
minilayout.addStretch(1)
self.layout.addLayout(minilayout)
self.info_label = QLabel("")
self.info_label.setObjectName("info_label")
self.layout.addWidget(self.info_label)
self.setLayout(self.layout)
self.setFixedWidth(self.sizeHint().width())
def enterEvent(self, a0: QEvent) -> None:
if not self.running:
self.info_label.setText("Start Game")
def leaveEvent(self, a0: QEvent) -> None:
self.info_label.setText("")
#return QWidget.mouseMoveEvent(self, mouseEvent)
def mousePressEvent(self, a0) -> None:
self.launch()
def launch(self, offline=False):
if not self.running:
logger.info("Launching " + self.game.title)
self.proc = LegendaryApi.launch_game(self.core, self.game.app_name, offline)
if not self.proc:
logger.error("Could not start process")
return
self.proc.finished.connect(self.finished)
self.info_label.setText("Game running")
self.running = True
def finished(self):
self.info_label.setText("")
self.running = False
class Menu(QMenu):
def __init__(self):
super(Menu, self).__init__()
self.addAction("Game info", self.info)
self.addAction("Uninstall", self.uninstall)
def info(self):
pass
def uninstall(self):
pass

View file

@ -0,0 +1,57 @@
import os
from logging import getLogger
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QInputDialog
from legendary.core import LegendaryCore
from legendary.models.game import Game
from Rare.utils.Dialogs.InstallDialog import InstallDialog
from Rare.utils.QtExtensions import ClickableLabel
from Rare.utils.RareConfig import IMAGE_DIR
logger = getLogger("Uninstalled")
class GameWidgetUninstalled(QWidget):
def __init__(self, core: LegendaryCore, game: Game):
super(GameWidgetUninstalled, self).__init__()
self.layout = QVBoxLayout()
self.core = core
self.game = game
if os.path.exists(f"{IMAGE_DIR}/{game.app_name}/UninstalledArt.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{game.app_name}/UninstalledArt.png")
else:
logger.warning(f"No Image found: {self.game.app_title}")
pixmap = None
if pixmap:
w = 200
pixmap = pixmap.scaled(w, int(w * 4 / 3))
self.image = ClickableLabel()
self.image.setPixmap(pixmap)
self.layout.addWidget(self.image)
self.title_label = QLabel(f"<h3>{game.app_title}</h3>")
self.title_label.setStyleSheet("""
QLabel{
text-align: center;
}
""")
self.title_label.setWordWrap(True)
self.layout.addWidget(self.title_label)
self.info_label = QLabel("")
self.layout.addWidget(self.info_label)
self.setLayout(self.layout)
self.setFixedWidth(self.sizeHint().width())
def mousePressEvent(self, a0) -> None:
self.install()
def install(self):
logger.info("Install " + self.game.app_title)
infos = InstallDialog().get_information()
if infos != 0:
path, max_workers = infos
print(path, max_workers)

View file

@ -0,0 +1,24 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QCheckBox
from Rare.Components.Tabs.Games.GameList import GameList
class Games(QWidget):
def __init__(self, core):
super(Games, self).__init__()
self.layout = QVBoxLayout()
self.head_bar = GameListHeadBar()
self.game_list = GameList(core)
self.layout.addLayout(self.head_bar)
self.layout.addWidget(self.game_list)
#self.layout.addStretch(1)
self.setLayout(self.layout)
class GameListHeadBar(QHBoxLayout):
def __init__(self):
super(GameListHeadBar, self).__init__()
self.installed_only = QCheckBox("Installed only")
self.addWidget(self.installed_only)

View file

View file

View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

71
Rare/Main.py Normal file
View file

@ -0,0 +1,71 @@
import logging
import os
import sys
import requests
from PyQt5.QtCore import QTranslator
from PyQt5.QtWidgets import QApplication, QMessageBox
from legendary.core import LegendaryCore
from Rare import style_path, lang_path
from Rare.Components.MainWindow import MainWindow
# from Rare.Start.Launch import LaunchDialog
# from Rare.Start.Login import LoginWindow
# from Rare.utils.RareUtils import get_lang
logging.basicConfig(
format='[%(name)s] %(levelname)s: %(message)s',
level=logging.INFO
)
logger = logging.getLogger("Rare")
core = LegendaryCore()
def main():
app = QApplication(sys.argv)
translator = QTranslator()
# lang = get_lang()
lang = "de"
if os.path.exists(lang_path + lang + ".qm"):
translator.load(lang_path + lang + ".qm")
else:
logger.info("Your language is not supported")
app.installTranslator(translator)
app.setStyleSheet(open(style_path + "RareStyle.qss").read())
offline = True
logger.info("Try if you are logged in")
try:
if core.login():
logger.info("You are logged in")
offline = False
else:
logger.error("Login Failed")
main()
except ValueError:
logger.info("You are not logged in. Open Login Window")
login_window = LoginWindow(core)
if not login_window.login():
return
# Start Offline mode
except requests.exceptions.ConnectionError:
offline = True
QMessageBox.information(None, "Offline", "You are offline. Launching Rare in offline mode")
# Launch Offlienmode
if not offline:
# launch_dialog = LaunchDialog(core)
# launch_dialog.exec_()
pass
# mainwindow = MainWindow(core)
mainwindow = MainWindow(core)
app.exec_()
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Rare/Styles/Icons/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

44
Rare/Styles/RareStyle.qss Normal file
View file

@ -0,0 +1,44 @@
QWidget {
background-color: #202225;
color: white;
}
QTabBar::tab {
padding: 5px;
}
QTabBar::tab:hover {
background-color: black;
}
QTabBar::tab:disabled {
color: transparent;
background-color: transparent;
}
QToolButton {
padding: 5px;
}
QPushButton {
border: 2px solid white;
border-radius: 2px;
}
QPushButton::menu-indicator {
subcontrol-position: right center;
subcontrol-origin: padding;
left: -2px;
border-style: none;
}
QPushButton#menu {
padding: 0px;
margin: 0px;
border-style: none;
}

1
Rare/Styles/__init__.py Normal file
View file

@ -0,0 +1 @@

2174
Rare/Styles/dark.qss Normal file

File diff suppressed because it is too large Load diff

4
Rare/__init__.py Normal file
View file

@ -0,0 +1,4 @@
import os
__version__ = "0.3.5"
style_path = os.path.join(os.path.dirname(__file__), "Styles/")
lang_path = os.path.join(os.path.dirname(__file__), "languages/")

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,38 @@
import os
from PyQt5.QtWidgets import QDialog, QFormLayout, QVBoxLayout, QSpinBox, QFileDialog, QLabel, QPushButton, QHBoxLayout
from Rare.utils.QtExtensions import PathEdit
class InstallDialog(QDialog):
def __init__(self):
super(InstallDialog, self).__init__()
self.layout = QVBoxLayout()
self.form = QFormLayout()
default_path = os.path.expanduser("~/legendary")
#TODO read from config
self.install_path_field = PathEdit(text=default_path, type_of_file=QFileDialog.DirectoryOnly)
self.form.addRow(QLabel("Install directory"), self.install_path_field)
self.max_workes = QSpinBox()
self.form.addRow(QLabel("Max workers"), self.max_workes)
self.layout.addLayout(self.form)
self.ok = QPushButton("Install")
self.cancel = QPushButton("Cancel")
self.button_layout = QHBoxLayout()
self.button_layout.addStretch(1)
self.button_layout.addWidget(self.ok)
self.button_layout.addWidget(self.cancel)
self.layout.addLayout(self.button_layout)
self.setLayout(self.layout)
def get_information(self):
self.exec_()
return self.install_path_field.text(), self.max_workes.value()

View file

@ -0,0 +1,41 @@
import os
from PyQt5.QtCore import QProcess, QProcessEnvironment
from legendary.core import LegendaryCore
def launch_game(core, app_name: str, offline: bool = False, skip_version_check: bool = False):
game = core.get_installed_game(app_name)
if not game:
print("Game not found")
return None
if game.is_dlc:
print("Game is dlc")
return None
if not os.path.exists(game.install_path):
print("Game doesn't exist")
return None
if not offline:
if not skip_version_check and not core.is_noupdate_game(app_name):
# check updates
try:
latest = core.get_asset(app_name, update=True)
except ValueError:
print("Metadata doesn't exist")
return None
if latest.build_version != game.version:
print("Please update game")
return None
params, cwd, env = core.get_launch_parameters(app_name=app_name, offline=offline)
process = QProcess()
process.setWorkingDirectory(cwd)
environment = QProcessEnvironment()
for e in env:
environment.insert(e, env[e])
process.setProcessEnvironment(environment)
process.start(params[0], params[1:])
return process

148
Rare/utils/QtExtensions.py Normal file
View file

@ -0,0 +1,148 @@
import os
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QLineEdit, \
QPushButton
class FlowLayout(QLayout):
def __init__(self, parent=None, margin=-1, hspacing=-1, vspacing=-1):
super(FlowLayout, self).__init__(parent)
self._hspacing = hspacing
self._vspacing = vspacing
self._items = []
self.setContentsMargins(margin, margin, margin, margin)
def __del__(self):
del self._items[:]
def addItem(self, item):
self._items.append(item)
def horizontalSpacing(self):
if self._hspacing >= 0:
return self._hspacing
else:
return self.smartSpacing(
QStyle.PM_LayoutHorizontalSpacing)
def verticalSpacing(self):
if self._vspacing >= 0:
return self._vspacing
else:
return self.smartSpacing(
QStyle.PM_LayoutVerticalSpacing)
def count(self):
return len(self._items)
def itemAt(self, index):
if 0 <= index < len(self._items):
return self._items[index]
def takeAt(self, index):
if 0 <= index < len(self._items):
return self._items.pop(index)
def expandingDirections(self):
return Qt.Orientations(0)
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
return self.doLayout(QRect(0, 0, width, 0), True)
def setGeometry(self, rect):
super(FlowLayout, self).setGeometry(rect)
self.doLayout(rect, False)
def sizeHint(self):
return self.minimumSize()
def minimumSize(self):
size = QSize()
for item in self._items:
size = size.expandedTo(item.minimumSize())
left, top, right, bottom = self.getContentsMargins()
size += QSize(left + right, top + bottom)
return size
def doLayout(self, rect, testonly):
left, top, right, bottom = self.getContentsMargins()
effective = rect.adjusted(+left, +top, -right, -bottom)
x = effective.x()
y = effective.y()
lineheight = 0
for item in self._items:
widget = item.widget()
hspace = self.horizontalSpacing()
if hspace == -1:
hspace = widget.style().layoutSpacing(
QSizePolicy.PushButton,
QSizePolicy.PushButton, Qt.Horizontal)
vspace = self.verticalSpacing()
if vspace == -1:
vspace = widget.style().layoutSpacing(
QSizePolicy.PushButton,
QSizePolicy.PushButton, Qt.Vertical)
nextX = x + item.sizeHint().width() + hspace
if nextX - hspace > effective.right() and lineheight > 0:
x = effective.x()
y = y + lineheight + vspace
nextX = x + item.sizeHint().width() + hspace
lineheight = 0
if not testonly:
item.setGeometry(
QRect(QPoint(x, y), item.sizeHint()))
x = nextX
lineheight = max(lineheight, item.sizeHint().height())
return y + lineheight - rect.y() + bottom
def smartSpacing(self, pm):
parent = self.parent()
if parent is None:
return -1
elif parent.isWidgetType():
return parent.style().pixelMetric(pm, None, parent)
else:
return parent.spacing()
class ClickableLabel(QLabel):
clicked = pyqtSignal()
def __init__(self):
super(ClickableLabel, self).__init__()
class PathEdit(QWidget):
def __init__(self, text: str = "", type_of_file: QFileDialog.FileType = QFileDialog.AnyFile, infotext: str = "",
filter: str = None):
super(PathEdit, self).__init__()
self.filter = filter
self.type_of_file = type_of_file
self.info_text = infotext
self.layout = QHBoxLayout()
self.text_edit = QLineEdit(text)
self.path_select = QPushButton(self.tr("Select Path"))
self.path_select.clicked.connect(self.set_path)
self.layout.addWidget(self.text_edit)
self.layout.addWidget(self.path_select)
self.setLayout(self.layout)
def setPlaceholderText(self, text: str):
self.text_edit.setPlaceholderText(text)
def text(self):
return self.text_edit.text()
def set_path(self):
dlg = QFileDialog(self, self.tr("Choose Path"), os.path.expanduser("~/"))
dlg.setFileMode(self.type_of_file)
if self.filter:
dlg.setFilter([self.filter])
if dlg.exec_():
names = dlg.selectedFiles()
self.text_edit.setText(names[0])

36
Rare/utils/RareConfig.py Normal file
View file

@ -0,0 +1,36 @@
import configparser
import os
from logging import getLogger
config_path = os.path.join(os.path.expanduser("~"), ".config/Rare/")
rare_config = configparser.ConfigParser()
logger = getLogger("Config")
rare_config.read(config_path + "config.ini")
if not os.path.exists(config_path):
os.makedirs(config_path)
rare_config["Rare"] = {
"IMAGE_DIR": os.path.expanduser(f"~/.cache/images"),
"theme": "default"
}
rare_config.write(open(config_path + "config.ini", "w"))
elif not rare_config.sections():
rare_config["Rare"] = {
"IMAGE_DIR": os.path.expanduser("~/.cache/images"),
"theme": "default"
}
rare_config.write(open(config_path + "config.ini", "w"))
def get_config() -> {}:
return rare_config.__dict__["_sections"]
def set_config(new_config: {}):
rare_config.__dict__["_sections"] = new_config
rare_config.write(open(config_path + "config.ini", "w"))
IMAGE_DIR = rare_config["Rare"]["IMAGE_DIR"]
THEME = rare_config["Rare"]["theme"]

0
Rare/utils/__init__.py Normal file
View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,14 @@
import configparser
import os
from legendary.lfs.lgndry import LGDLFS
lgd = LGDLFS()
def get_config() -> {}:
return lgd.config
def set_config(new_config: {}):
lgd.config = new_config
with open(os.path.join(lgd.path, 'config.ini'), "w") as cf:
lgd.config.write(cf)

90
Rare/utils/utils.py Normal file
View file

@ -0,0 +1,90 @@
import json
import os
from logging import getLogger
import requests
from PIL import Image
from PyQt5.QtCore import pyqtSignal, QLocale
from legendary.core import LegendaryCore
from Rare.utils import legendaryConfig
from Rare.utils.RareConfig import IMAGE_DIR
logger = getLogger("Utils")
def download_images(signal: pyqtSignal, core: LegendaryCore):
if not os.path.isdir(IMAGE_DIR):
os.makedirs(IMAGE_DIR)
logger.info("Create Image dir")
# Download Images
for i, game in enumerate(sorted(core.get_game_list(), key=lambda x: x.app_title)):
if not os.path.isdir(f"{IMAGE_DIR}/" + game.app_name):
os.mkdir(f"{IMAGE_DIR}/" + game.app_name)
if not os.path.isfile(f"{IMAGE_DIR}/{game.app_name}/image.json"):
json_data = {"DieselGameBoxTall": None, "DieselGameBoxLogo": None}
else:
json_data = json.load(open(f"{IMAGE_DIR}/{game.app_name}/image.json", "r"))
for image in game.metadata["keyImages"]:
if image["type"] == "DieselGameBoxTall" or image["type"] == "DieselGameBoxLogo":
if json_data[image["type"]] != image["md5"] or not os.path.isfile(
f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png"):
# Download
json_data[image["type"]] = image["md5"]
# os.remove(f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png")
json.dump(json_data, open(f"{IMAGE_DIR}/{game.app_name}/image.json", "w"))
logger.info(f"Download Image for Game: {game.app_title}")
url = image["url"]
with open(f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png", "wb") as f:
f.write(requests.get(url).content)
f.close()
if not os.path.isfile(f'{IMAGE_DIR}/' + game.app_name + '/UninstalledArt.png'):
if os.path.isfile(f'{IMAGE_DIR}/' + game.app_name + '/DieselGameBoxTall.png'):
# finalArt = Image.open(f'{IMAGE_DIR}/' + game.app_name + '/DieselGameBoxTall.png')
# finalArt.save(f'{IMAGE_DIR}/{game.app_name}/FinalArt.png')
# And same with the grayscale one
bg = Image.open(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png")
uninstalledArt = bg.convert('L')
uninstalledArt.save(f'{IMAGE_DIR}/{game.app_name}/UninstalledArt.png')
elif os.path.isfile(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png"):
bg: Image.Image = Image.open(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png")
bg = bg.resize((int(bg.size[1] * 3 / 4), bg.size[1]))
logo = Image.open(f'{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png').convert('RGBA')
wpercent = ((bg.size[0] * (3 / 4)) / float(logo.size[0]))
hsize = int((float(logo.size[1]) * float(wpercent)))
logo = logo.resize((int(bg.size[0] * (3 / 4)), hsize), Image.ANTIALIAS)
# Calculate where the image has to be placed
pasteX = int((bg.size[0] - logo.size[0]) / 2)
pasteY = int((bg.size[1] - logo.size[1]) / 2)
# And finally copy the background and paste in the image
# finalArt = bg.copy()
# finalArt.paste(logo, (pasteX, pasteY), logo)
# Write out the file
# finalArt.save(f'{IMAGE_DIR}/' + game.app_name + '/FinalArt.png')
logoCopy = logo.copy()
logoCopy.putalpha(int(256 * 3 / 4))
logo.paste(logoCopy, logo)
uninstalledArt = bg.copy()
uninstalledArt.paste(logo, (pasteX, pasteY), logo)
uninstalledArt = uninstalledArt.convert('L')
uninstalledArt.save(f'{IMAGE_DIR}/' + game.app_name + '/UninstalledArt.png')
else:
logger.warning(f"File {IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png dowsn't exist")
signal.emit(i)
def get_lang():
if "Legendary" in legendaryConfig.get_config() and "locale" in legendaryConfig.get_config()["Legendary"]:
logger.info("Found locale in Legendary config: " + legendaryConfig.get_config()["Legendary"]["locale"])
return legendaryConfig.get_config()["Legendary"]["locale"].split("-")[0]
else:
logger.info("Found locale in system config: " + QLocale.system().name().split("_")[0])
return QLocale.system().name().split("_")[0]