Python script to bulk import a directory of ROM files into Lutris
Project description
lutris-bulk-adder
Description
This is a simple Python script to import a directory of ROM files into Lutris. The directory must contain only games from one platform. I have only tested this on my own computer for a limited number of platforms.
I don't really know what will happen if Lutris is open during the import, so make sure to restart Lutris immediately after importing, or close it before the import - this script will write directly to Lutris's SQLite database, so proceed with caution.
Rambling
This is a fork of the original project from @hwangeug, developed by yours truly, @SpeedRunHunter - or just Hunter if you don't have much time. In prior commits you can find a different version of the README with a lot more text. I grabbed a load of ROMs for the sake of RetroAchievement hunting, and ran into the problem of not being able to easily import my ROMs - because Lutris only knows of the TOSEC project ROMs' file checksums.
I tried to use the PyPI package version of this script, realizing though that it is outdated compared to the original github repo, which fixed the issue with Lutris's SQLite DB no longer having a steam_id columns but instead splitting it into service and service_id columns. Coupled with some other smaller fixes from @ronicaltech that have pull requests, but weren't upstreamed - if @ronicaltech sees this, I hope you don't mind that I yoinked your fixes; I made sure to include credits to you in code comments, but if you don't like that, I'm absolutely open to figuring something out about it.
Again, in the previous README, I talked about a new feature I thought to add to this script. It's essentially automatic runner and if necessary libretro core setup for your ROMs. So compared to having to specify a runner with directory and platform when using the script, the runner argument is no longer required. At the same time though, this did require storing a lot of information about platforms in the app, so I figured for users who may want to learn more, they can view this information. At the same time, since libretro, a.k.a. RetroArch is an option for a runner for a lot of platforms, I felt it would be useful to provide the additional option to change what core is used - compared to having to do that via the game-options flag.
Let me make something clear: I'm sure that some of the things I'm doing may seem to other people who are better versed in open-source code development, project/version/source/git management, and above all Python development will consider me an utter amateur. Which,
-
firstly, excuse me, but that is a bit harsh to some extent.
-
Secondly, I'd like to provide a bit of background on me. I graduated from the second best IT trade school in my home country of Hungary and took an additional year of adult education there. Said year primarly consisted of Java with Spring Boot for RESTful APIs and JS with React for frontend development, with a side of MySQL database management, and pretty much self-taught and improvised git management. So, my possibly bad skills speaks either of my defficencies or the quality of the trade school's teachings - I like to believe both is fine, though.
-
Thirdly, as I also admit in my prior README, this is my first attempt at a proper Python project. I have started with Java in trade school, and have always been a Java person. I barely had much if any exposure to Python, and wasn't a big fan especially because of the weird syntax. And to get myself better familiarized with Python, I chose to play the game "The Farmer Was Replaced" - for the uninitiated, basically you control a farmer drone by programming it in a Python-like language, which language isn't 100% Python, but for the sake of the game it might as well be, especially considering in your save, the scripts are saved as
.pyfiles, and there's also support for external code editors in the game. I explicitly decided to fork this project, update it and expand on it - without overwriting its original functionality - to get a better taste of developing with Python. So yes, I am functionally amateur in Python. -
And finally, back to git stuff, but this time open source related; I don't know how badly one could screw up with this kind of stuff. As far as I can interpret the LICENSE set in place by the original creator, I'm not breaking it by including the original in this repo. And I'm not about to tackle potentially sublicensing or whatever that maybe or change the license to something else. I'm not a lawyer or license expert; I'm just a stupid software dev, that just want's to look at a fancy text-editor and type a boat-load - which is clearly happening.
Requirements
PyYAML
Installation
Basic installation with pip:
pip install --user --upgrade lutris-bulk-adder-srh
If you are on a system with a Python install that throws the externally-managed-environment error when trying to install PyPI packages, which is typical for a Linux system in my experience, and your package manager doesn't have this PyPI package available in it, you have two options:
- either use a Python virtual environment for the script, and activate that everytime you want to use the script, like so:
python3 -m venv path/to/venv
source path/to/venv/bin/activate
# you mustn't install as a user here with pip
# the only way to do that would be changing a
# venv config setting in path/to/venv/pyvenv.cfg
# which would cause pip to install to a folder
# outside of the venv folder
# ask me how I know
pip install --upgarde lutris-bulk-adder-srh
- alternatively, install and use
pipxinstead to install the script; it will automate creating the virtual environment, but will also setup a link to the script in a folder that's on your system's PATH environment variable
pipx install lutris-bulk-adder-srh
pipx by default already installs PyPI packages for the user only.
To update with pipx:
pipx upgrade lutris-bulk-adder-srh
You can also install the package globally in pipx to install it for every user:
pipx install --global lutris-bulk-adder-srh
Usage
Required arguments
-d / --directory: Directory to scan for ROM files.
-p / --platform: Platform name.
Optional arguments
-r / --runner: Slug name of Lutris runner to use (e.g. dolphin, snes9x, libretro)
-c / --core: Slug name of libretro core to use (e.g. DoubleCherryGB, mednafen_psx_hw, picodrive)
Lutris path arguments
These default to the default locations that Lutris will install to.
-ld / --lutris-database: Path to the Lutris SQLite database. Default: ~/.local/share/lutris/pga.db
-ly / --lutris-yml-dir: Directory containing Lutris installed game YAML files. Default: ~/.local/share/lutris/games
-lg / --lutris-game-dir: Lutris games installation directory. This shouldn't do anything as ROMs aren't installed, but the Lutris database needs it. Default: ~/Games
Informational arguments
-i / --platform-info: Takes a single string argument - requires single (') or double (") quotes - that matches case-sensitively to the name of a platform known by the script.
-a / --dump-platform-info: A zero parameter flag that, when set, prints all information of known platforms from the script.
Other arguments
-f / --file-types: Space-separated list of file types to scan for. Defaults to iso,zip,sfc,gba,gbc,gb,md,n64,nes,32x,gg,sms,chd
-o / --game-options: Additional options to write to the YAML file under the "game" key (e.g. platform number as required for Dolphin)
-s / --strip-filename: Space-separated list of strings to strip from filenames when generating game names.
-n / --no-write: Do not write YML files or alter Lutris database, only print data to be written out to stdout. (i.e. dry run)
Examples
lutris-bulk-adder -d /data/Emulation/Wii -r dolphin -s '(USA)' -p "Nintendo Wii" -o platform=1
Adds all files in /data/Emulation/Wii to Lutris via the dolphin runner, ignoring substrings containing (USA) in the filename when deriving the game name, for the Nintendo Wii platform, and adds platform: '1' to the game key in the YAML file.
lutris-bulk-adder -d ~/ROMZZZ/SegaLibrary/MegaDriveLibrary -p "Sega Mega Drive"
Adds all files in ~/ROMZZZ/SegaLibrary/MegaDriveLibrary to Lutris via the default runner for the Sega Mega Drive platform. For Mega Drive - or Genesis, both names are supported and that includes the Sega CD/Mega CD -, or other platforms where the default may be libretro, which it is for the Mega Drive, as is required and setup usually by Lutris itself, the YAML file will contain the core information for libretro. And in this case whatever the default core is.
Also
How did you know I was not American? Oh wait, I guess you know I live in Hungary, huh.
lutris-bulk-adder -d /run/media/user/CDZZZ/SegaCD -p "Sega CD" -c clowncdemu
Adds all files in /run/media/user/CDZZZ/SegaCD to Lutris via the default runner for the Sega CD platform, and use the clowncdemu libretro core. In this scenario we make the assumption on the script side - spoiler, correctly as well - that the default runner for the Sega CD is RetroArch. If that's not the case, the -c flag and its argument are ignored.
Why is it ignored?
If we wanted the script to not ignore the the -c libretro core setting flag, but the default runner for the given platform is not RetroArch - an example case would be the Commodore 8-bit machines1 - we need to make a choice in the implementation of the script as to what it should do.
We could ignore the flag, like I chose to. Or we could instead make the -c flag additionally equivalent to -r libretro (or --runner libretro) and itself, and therefore silently - without user's explicit knowledge - switch runners.
Unless we ask for confirmation from the user, even then, if they decline to make the change, then what should happen? Should the script error out, should it respect the user's choice, and stick with the default, at which point getting back to square one basically. Unless they agree to change the runner as well, which does mean smooth sailing.
Maybe a silent switch like this could be desirable though, but I struggle to see the appeal in my opinion. And I admit I'm probably just overthinking this, but in my opinion again, good software is made to be ready for all situations, and rationale is clearly explained for it. Hence you're reading... well, this.
-
(inside the "Why is it ignored?" details section) in RetroArch the
viceemulator LR core implementation is split into individual and unique cores for different machines, such as C64, C128, Plus/4, etc., and different sub-configurations for the same machine, whether that's emulation config or additional hardware, like the C64 SuperCPU ↩
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lutris_bulk_adder_srh-0.1.1.tar.gz.
File metadata
- Download URL: lutris_bulk_adder_srh-0.1.1.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc98d9f9d3e74eb59dafee77b1d58ed64ecdb7ee21d549734b5cb71e974e35d9
|
|
| MD5 |
81a1845c83f9e93b6fac5c6a96797abe
|
|
| BLAKE2b-256 |
e95108d27faf8e257a01af5edf3d3f4fa0861ecf709731e9b324767952aa66da
|
File details
Details for the file lutris_bulk_adder_srh-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lutris_bulk_adder_srh-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a0ec402b75014228c4c9697d56ee035c68f52159506a5879e0177921f5350ec
|
|
| MD5 |
b179debe2f6a1d5757284b1c5957fb20
|
|
| BLAKE2b-256 |
0521092c2a29b080e56f354690a0909aed7470af66ce4ccaaef47965c0a9c68e
|