1
0
Fork 0
mirror of synced 2024-05-09 07:02:59 +12:00

Lgndr: Replace the monkey functions with factories to create them

The factories are also usable in Rare's code to create compatible
functions for the callbacks. If they there is no callback they just
log what is happening. It also removes the need for `typing-extentions`
module.
This commit is contained in:
loathingKernel 2023-12-10 22:43:31 +02:00
parent df0f7603f2
commit fa5294b1d5
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
10 changed files with 82 additions and 70 deletions

View file

@ -12,7 +12,7 @@ script:
# copy Logo
- cp AppDir/usr/src/rare/resources/images/Rare.png AppDir/usr/share/icons/hicolor/256x256/apps/
# Install application dependencies
- python3 -m pip install --ignore-installed --prefix=/usr --root=AppDir pypresence qtawesome legendary-gl orjson typing_extensions
- python3 -m pip install --ignore-installed --prefix=/usr --root=AppDir pypresence qtawesome legendary-gl orjson
AppDir:
path: AppDir

View file

@ -45,32 +45,36 @@ Run it via:
There are some AUR packages available:
- [rare](https://aur.archlinux.org/packages/rare) - for stable releases
- [rare-git](https://aur.archlinux.org/packages/rare-git) - for the latest features, which are not in a stable release
- [rare-git](https://aur.archlinux.org/packages/rare-git) - for the latest development version
#### Debian based
- DUR package: [rare](https://mpr.hunterwittenborn.com/packages/rare)
- .deb file in [releases page](https://github.com/Dummerle/Rare/releases)
- `.deb` file in [releases page](https://github.com/Dummerle/Rare/releases)
**Note**:
- pypresence is an optional package. You can install it
from [DUR](https://mpr.hunterwittenborn.com/packages/python3-pypresence) or with pip.
- Do not wonder if some icons look strange, because the official python3-qtawesome package is too old. Many icons were
replaced.
- pypresence is an optional package. You can install it from [DUR](https://mpr.hunterwittenborn.com/packages/python3-pypresence) or with pip.
- Some icons might look strange on Debian based distributions. The official python3-qtawesome package is too old.
### macOS
There is a .dmg file available in [releases page](https://github.com/Dummerle/Rare/releases).
There is a `.dmg` file available in [releases page](https://github.com/Dummerle/Rare/releases).
**Note**: When you launch it, you will see an error, that the package is from an unknown source. You have to enable it
manually in `Settings -> Security and Privacy`. Otherwise, Gatekeeper will block Rare from running.
**Note**: When you launch it, you will see an error, that the package is from an unknown source. You have to enable it manually in `Settings -> Security and Privacy`. Otherwise, Gatekeeper will block Rare from running.
You can also use `pip`.
### Windows
There is an `.msi` installer available in [releases page](https://github.com/Dummerle/Rare/releases).
There is also a semi-portable `.zip` archive in [releases page](https://github.com/Dummerle/Rare/releases) that lets you run Rare without installing it.
**Important**: On recent version of Windows you should have MSVC 2015 installed, you can get it from [here](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022)
#### Packages
- Rare is available as a [Winget package](https://github.com/microsoft/winget-pkgs/tree/master/manifests/d/Dummerle/Rare)
You can install Rare with the following one-liner:
@ -81,10 +85,7 @@ You can install Rare with the following one-liner:
`choco install rare`
- There is a small beta tool for Windows: [Rare Updater](https://github.com/Dummerle/RareUpdater), which installs and updates rare with a single click
*NOTE*: On recent Windows you should have MSVC 2015 installed, you can get it from [here](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022)
- We also have a beta tool for Windows: [Rare Updater](https://github.com/Dummerle/RareUpdater), which installs and updates rare with a single click
### Packages
@ -95,7 +96,8 @@ file for macOS.
In the [actions](https://github.com/Dummerle/Rare/actions) tab you can find packages for the latest commits.
**Note**: They might be unstable.
**Note**: They might be unstable and likely broken.
### Installation via pip (platform independent)
@ -105,22 +107,13 @@ Linux, Mac and FreeBSD: execute `rare` in your terminal.
Windows: execute `pythonw -m rare` in cmd
It is possible to create a desktop link, or a start menu link. Execute the command above with `--desktop-shortcut`
or `--startmenu-shortcut` option, alternatively you can create them in the settings.
It is possible to create a desktop link, or a start menu link. Execute the command above with `--desktop-shortcut` or `--startmenu-shortcut` option, alternatively you can create them in the settings.
**Note about $PATH**:
On Linux:
`/home/user/.local/bin` must be in your PATH.
On Windows:
`PythonInstallationDirectory\Scripts` must be in your PATH.
On Mac:
`/Users/user/Library/Python/3.x/bin` must be in your PATH.
* On Linux `/home/user/.local/bin` must be in your PATH.
* On Windows `PythonInstallationDirectory\Scripts` must be in your PATH.
* On Mac `/Users/user/Library/Python/3.x/bin` must be in your PATH.
### Run from source
@ -128,10 +121,9 @@ On Mac:
1. Clone the repo: `git clone https://github.com/Dummerle/Rare
2. Change your working directory to the project folder: `cd Rare`
3. Run `pip install -r requirements.txt` to install all required dependencies.
If you want to be able to use the automatic login and Discord pypresence, run `pip install -r requirements-full.txt`
If you are on Arch you can
run `sudo pacman --needed -S python-wheel python-setuptools python-pyqt5 python-qtawesome python-requests python-typing_extensions` and `yay -S legendary`
If you are on FreeBSD you have to install py39-qt5 from the packages: `sudo pkg install py39-qt5`
* If you want to be able to use the automatic login and Discord pypresence, run `pip install -r requirements-full.txt`
* If you are on Arch you can run `sudo pacman --needed -S python-wheel python-setuptools python-pyqt5 python-qtawesome python-requests python-orjson` and `yay -S legendary`
* If you are on FreeBSD you have to install py39-qt5 from the packages: `sudo pkg install py39-qt5`
4. Run `python3 -m rare`
## Contributing
@ -139,8 +131,7 @@ On Mac:
There are several options to contribute.
- If you know Python and PyQt, you can implement new features (Some ideas are in the projects tab).
- You can translate the application in your language: Check our [transifex](https://www.transifex.com/rare-1/rare) page
for that.
- You can translate the application in your language: Check our [transifex](https://www.transifex.com/rare-1/rare) page for that.
More information is available in CONTRIBUTING.md.

View file

@ -388,7 +388,6 @@ class LegendaryCLI(LegendaryCLIReal):
# Override logger for the local context to use message as part of the indirect return value
logger = LgndrIndirectLogger(args.indirect_status, self.logger, logging.WARNING)
get_boolean_choice = args.get_boolean_choice_main
# def get_boolean_choice(x, default): return True
if not self.core.lgd.lock_installed():
logger.fatal('Failed to acquire installed data lock, only one instance of Legendary may '
'install/import/move applications at a time.')
@ -429,7 +428,6 @@ class LegendaryCLI(LegendaryCLIReal):
# Override logger for the local context to use message as part of the indirect return value
logger = LgndrIndirectLogger(args.indirect_status, self.logger, logging.WARNING)
get_boolean_choice = args.get_boolean_choice_handler
# def get_boolean_choice(x, default): return True
# noinspection PyShadowingBuiltins
def print(x): self.logger.info(x) if x else None

View file

@ -4,9 +4,10 @@ from typing import Callable, List, Optional, Dict
from rare.lgndr.glue.monkeys import (
LgndrIndirectStatus,
GetBooleanChoiceProtocol,
get_boolean_choice,
verify_stdout,
get_boolean_choice_factory,
sdl_prompt_factory,
verify_stdout_factory,
ui_update_factory,
DLManagerSignals,
)
from rare.lgndr.models.downloading import UIUpdate
@ -33,7 +34,7 @@ class LgndrImportGameArgs:
yes: bool = False
# Rare: Extra arguments
indirect_status: LgndrIndirectStatus = field(default_factory=LgndrIndirectStatus)
get_boolean_choice: GetBooleanChoiceProtocol = get_boolean_choice
get_boolean_choice: Callable[[str, bool], bool] = get_boolean_choice_factory(True)
@dataclass
@ -44,8 +45,8 @@ class LgndrUninstallGameArgs:
yes: bool = False
# Rare: Extra arguments
indirect_status: LgndrIndirectStatus = field(default_factory=LgndrIndirectStatus)
get_boolean_choice_main: GetBooleanChoiceProtocol = get_boolean_choice
get_boolean_choice_handler: GetBooleanChoiceProtocol = get_boolean_choice
get_boolean_choice_main: Callable[[str, bool], bool] = get_boolean_choice_factory(True)
get_boolean_choice_handler: Callable[[str, bool], bool] = get_boolean_choice_factory(True)
@dataclass
@ -53,7 +54,7 @@ class LgndrVerifyGameArgs:
app_name: str
# Rare: Extra arguments
indirect_status: LgndrIndirectStatus = field(default_factory=LgndrIndirectStatus)
verify_stdout: Callable[[int, int, float, float], None] = verify_stdout
verify_stdout: Callable[[int, int, float, float], None] = verify_stdout_factory(None)
@dataclass
@ -94,14 +95,11 @@ class LgndrInstallGameArgs:
yes: bool = True
# Rare: Extra arguments
indirect_status: LgndrIndirectStatus = field(default_factory=LgndrIndirectStatus)
get_boolean_choice: GetBooleanChoiceProtocol = get_boolean_choice
sdl_prompt: Callable[[str, str], List[str]] = lambda app_name, title: [""]
verify_stdout: Callable[[int, int, float, float], None] = verify_stdout
get_boolean_choice: Callable[[str, bool], bool] = get_boolean_choice_factory(True)
verify_stdout: Callable[[int, int, float, float], None] = verify_stdout_factory(None)
# def __post_init__(self):
# if self.sdl_prompt is None:
# self.sdl_prompt: Callable[[str, str], list] = \
# lambda app_name, title: self.install_tag if self.install_tag is not None else [""]
def __post_init__(self):
self.sdl_prompt: Callable[[Dict, str], List[str]] = sdl_prompt_factory(self.install_tag)
@dataclass
@ -119,8 +117,8 @@ class LgndrInstallGameRealArgs:
# Rare: Extra arguments
install_prereqs: bool = False
indirect_status: LgndrIndirectStatus = field(default_factory=LgndrIndirectStatus)
ui_update: Callable[[UIUpdate], None] = lambda ui: None
dlm_signals: DLManagerSignals = DLManagerSignals()
ui_update: Callable[[UIUpdate], None] = ui_update_factory(None)
dlm_signals: DLManagerSignals = field(default_factory=DLManagerSignals)
@dataclass

View file

@ -1,20 +1,48 @@
import logging
from dataclasses import dataclass
from typing import Callable, List, Optional, Dict
from typing_extensions import Protocol
from rare.lgndr.models.downloading import UIUpdate
logger = logging.getLogger("LgndrMonkeys")
class GetBooleanChoiceProtocol(Protocol):
def __call__(self, prompt: str, default: bool = ...) -> bool:
...
def get_boolean_choice_factory(value: bool = True) -> Callable[[str, bool], bool]:
def get_boolean_choice(prompt: str, default: bool) -> bool:
logger.debug("get_boolean_choice: %s, default: %s, choice: %s", prompt, default, value)
return value
return get_boolean_choice
def get_boolean_choice(prompt: str, default: bool = True) -> bool:
return default
def sdl_prompt_factory(install_tag: Optional[List[str]] = None) -> Callable[[Dict, str], List[str]]:
def sdl_prompt(sdl_data: Dict, title: str) -> List[str]:
logger.debug("sdl_prompt: %s", title)
for key in sdl_data.keys():
logger.debug("%s: %s %s", key, sdl_data[key]["tags"], sdl_data[key]["name"])
tags = install_tag if install_tag is not None else [""]
logger.debug("choice: %s, tags: %s", install_tag, tags)
return tags
return sdl_prompt
def verify_stdout(a0: int, a1: int, a2: float, a3: float) -> None:
print(f"Verification progress: {a0}/{a1} ({a2:.01f}%) [{a3:.1f} MiB/s]\t\r")
def verify_stdout_factory(
callback: Callable[[int, int, float, float], None] = None
) -> Callable[[int, int, float, float], None]:
def verify_stdout(a0: int, a1: int, a2: float, a3: float) -> None:
if callback is not None and callable(callback):
callback(a0, a1, a2, a3)
else:
logger.info("Verification progress: %d/%d (%.01f%%) [%.1f MiB/s]", a0, a1, a2, a3)
return verify_stdout
def ui_update_factory(callback: Callable[[UIUpdate], None] = None) -> Callable[[UIUpdate], None]:
def ui_update(status: UIUpdate) -> None:
if callback is not None and callable(callback):
callback(status)
else:
logger.info("Installation progress: %s", status)
return ui_update
class DLManagerSignals:

View file

@ -1,8 +1,7 @@
import os
import platform as pf
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import List, Optional, Callable, Dict, Tuple
from typing import List, Optional, Dict, Tuple
from legendary.models.downloading import AnalysisResult, ConditionCheckResult
from legendary.models.game import Game, InstalledGame
@ -35,10 +34,6 @@ class InstallOptionsModel:
silent: bool = False
install_prereqs: bool = False
def __post_init__(self):
self.sdl_prompt: Callable[[str, str], list] = \
lambda app_name, title: self.install_tag if self.install_tag is not None else [""]
def as_install_kwargs(self) -> Dict:
return {
k: getattr(self, k)

5
requirements-flatpak.txt Normal file
View file

@ -0,0 +1,5 @@
requests
QtAwesome
setuptools
legendary-gl>=0.20.34
pypresence

View file

@ -1,4 +1,3 @@
typing_extensions
requests
PyQt5
QtAwesome

View file

@ -1,4 +1,3 @@
typing_extensions
requests
PyQt5
QtAwesome

View file

@ -14,7 +14,6 @@ requirements = [
"PyQt5",
"QtAwesome",
'pywin32; platform_system == "Windows"',
"typing_extensions"
]
optional_reqs = dict(