diff --git a/pkgs/by-name/ri/rimsort/package.nix b/pkgs/by-name/ri/rimsort/package.nix new file mode 100644 index 000000000000..d5f569cf45ef --- /dev/null +++ b/pkgs/by-name/ri/rimsort/package.nix @@ -0,0 +1,182 @@ +{ + lib, + stdenv, + python3Packages, + fetchFromGitHub, + fetchzip, + makeBinaryWrapper, + + makeDesktopItem, + replaceVars, + + todds, + + steam, +}: +let + pname = "rimsort"; + version = "1.0.30"; + + src = fetchFromGitHub { + owner = "RimSort"; + repo = "RimSort"; + rev = "v${version}"; + hash = "sha256-f1wYoBC0EbkvYNJHkVuoMukJZMY7eNjCIzJra7/hpLs="; + fetchSubmodules = true; + }; + steamworksSrc = fetchzip { + url = "https://web.archive.org/web/20250527013243/https://partner.steamgames.com/downloads/steamworks_sdk_162.zip"; # Steam sometimes requires auth to download. + hash = "sha256-yDA92nGj3AKTNI4vnoLaa+7mDqupQv0E4YKRRUWqyZw="; + }; + + steamfiles = python3Packages.buildPythonPackage { + pname = "steamfiles"; + inherit version; + format = "setuptools"; + + src = "${src}/submodules/steamfiles"; + dependencies = with python3Packages; [ + protobuf + protobuf3-to-dict + ]; + }; + + steam-run = + (steam.override { + privateTmp = false; + }).run; +in + +stdenv.mkDerivation { + inherit pname; + inherit version; + + unpackPhase = '' + runHook preUnpack + + cp -r ${src} source + chmod -R 755 source + cp ${steamworksSrc}/redistributable_bin/linux64/libsteam_api.so source/ + + runHook postUnpack + ''; + + sourceRoot = "source"; + + patches = [ + (replaceVars ./todds-path.patch { inherit todds; }) + (replaceVars ./steam-run.patch { inherit steam-run; }) + ]; + + nativeBuildInputs = [ + makeBinaryWrapper + ]; + + buildInputs = + [ + todds + steamfiles + ] + ++ builtins.attrValues { + inherit (python3Packages) + beautifulsoup4 + certifi + chardet + imageio + loguru + lxml + msgspec + natsort + networkx + packaging + platformdirs + psutil + pygit2 + pygithub + pyperclip + pyside6 + requests + sqlalchemy + steam + toposort + watchdog + xmltodict + steamworkspy + ; + }; + + dontBuild = true; + + nativeCheckInputs = with python3Packages; [ + pytestCheckHook + pytest-cov-stub + pytest-qt + pytest-xvfb + ]; + + doCheck = true; + + preCheck = '' + export QT_DEBUG_PLUGINS=1 + export QT_QPA_PLATFORM=offscreen + export HOME=$(mktemp -d) # Some tests require a writable directory + ''; + + disabledTestPaths = [ + # requires network + "tests/models/metadata/test_metadata_factory.py" + ]; + + pytestFlags = [ "--doctest-modules" ]; + + desktopItems = [ + (makeDesktopItem { + name = "RimSort"; + desktopName = "RimSort"; + exec = "rimsort"; + icon = "io.github.rimsort.rimsort"; + comment = "RimWorld Mod Manager"; + categories = [ "Game" ]; + }) + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/lib/rimsort + cp -r ./* $out/lib/rimsort/ + + mkdir -p $out/bin + + makeBinaryWrapper \ + ${python3Packages.python.interpreter} \ + $out/bin/rimsort \ + --add-flags "-m app" \ + --chdir $out/lib/rimsort \ + --prefix PYTHONPATH : "$PYTHONPATH" \ + --set RIMSORT_DISABLE_UPDATER 1 + + install -D ./themes/default-icons/AppIcon_a.png $out/share/icons/hicolor/512x512/apps/io.github.rimsort.rimsort + + runHook postInstall + ''; + + meta = { + description = "Open source mod manager for the video game RimWorld"; + homepage = "https://github.com/RimSort/RimSort"; + license = with lib.licenses; [ + gpl3Only + # For libsteam_api.so + ( + unfreeRedistributable + // { + url = "https://partner.steamgames.com/documentation/sdk_access_agreement"; + } + ) + ]; + maintainers = with lib.maintainers; [ weirdrock ]; + mainProgram = "rimsort"; + # steamworksSrc is x86_64-linux only + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/pkgs/by-name/ri/rimsort/steam-run.patch b/pkgs/by-name/ri/rimsort/steam-run.patch new file mode 100644 index 000000000000..4969dacb75b6 --- /dev/null +++ b/pkgs/by-name/ri/rimsort/steam-run.patch @@ -0,0 +1,26 @@ +diff --git a/app/utils/generic.py b/app/utils/generic.py +--- a/app/utils/generic.py ++++ b/app/utils/generic.py +@@ -255,7 +255,7 @@ + popen_args.extend(args) + p = subprocess.Popen(popen_args) + else: +- popen_args = [executable_path] ++ popen_args = ["@steam-run@/bin/steam-run", executable_path] + popen_args.extend(args) + + if sys.platform == "win32": +diff --git a/app/utils/steam/steamcmd/wrapper.py b/app/utils/steam/steamcmd/wrapper.py +--- a/app/utils/steam/steamcmd/wrapper.py ++++ b/app/utils/steam/steamcmd/wrapper.py +@@ -316,8 +316,8 @@ + script_output.write("\n".join(script)) + runner.message(f"Compiled & using script: {script_path}") + runner.execute( +- self.steamcmd, +- [f'+runscript "{script_path}"'], ++ "@steam-run@/bin/steam-run", ++ [self.steamcmd, f'+runscript "{script_path}"'], + len(publishedfileids), + ) + else: diff --git a/pkgs/by-name/ri/rimsort/todds-path.patch b/pkgs/by-name/ri/rimsort/todds-path.patch new file mode 100644 index 000000000000..0174a2954b2e --- /dev/null +++ b/pkgs/by-name/ri/rimsort/todds-path.patch @@ -0,0 +1,17 @@ +diff --git a/app/utils/todds/wrapper.py b/app/utils/todds/wrapper.py +index a239fe0..3375b70 100644 +--- a/app/utils/todds/wrapper.py ++++ b/app/utils/todds/wrapper.py +@@ -66,11 +66,7 @@ class ToddsInterface: + :param todds_arguments: list of todds args to be passed to the todds executable + """ + +- if self.system == "Windows": +- todds_executable = "todds.exe" +- else: +- todds_executable = "todds" +- todds_exe_path = str(AppInfo().application_folder / "todds" / todds_executable) ++ todds_exe_path = "@todds@/bin/todds" + logger.info("Checking for todds...") + if os.path.exists(todds_exe_path): + logger.debug(f"Found todds executable at: {todds_exe_path}") diff --git a/pkgs/development/python-modules/gevent-eventemitter/default.nix b/pkgs/development/python-modules/gevent-eventemitter/default.nix new file mode 100644 index 000000000000..d6ec63359584 --- /dev/null +++ b/pkgs/development/python-modules/gevent-eventemitter/default.nix @@ -0,0 +1,41 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + + gevent, + + pytestCheckHook, + + setuptools, +}: +buildPythonPackage rec { + pname = "gevent-eventemitter"; + version = "2.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "rossengeorgiev"; + repo = "gevent-eventemitter"; + tag = "v${version}"; + hash = "sha256-aW4OsQi3N5yAMdbTd8rxbb2qYMfFJBR4WQFIXvxpiMw="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + gevent + ]; + + nativeCheckInputs = [ + pytestCheckHook + ]; + + meta = { + description = "EventEmitter using gevent"; + homepage = "https://github.com/rossengeorgiev/gevent-eventemitter"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + maintainers = with lib.maintainers; [ weirdrock ]; + }; +} diff --git a/pkgs/development/python-modules/steam/default.nix b/pkgs/development/python-modules/steam/default.nix new file mode 100644 index 000000000000..0a19c24d0382 --- /dev/null +++ b/pkgs/development/python-modules/steam/default.nix @@ -0,0 +1,50 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + + six, + pycryptodomex, + requests, + urllib3, + vdf, + gevent, + protobuf, + gevent-eventemitter, + cachetools, + setuptools, +}: +buildPythonPackage rec { + pname = "steam"; + version = "1.4.4"; + pyproject = true; + + src = fetchFromGitHub { + owner = "ValvePython"; + repo = "steam"; + rev = "v${version}"; + hash = "sha256-OY04GsX3KMPvpsQl8sUurzFyJu+JKpES8B0iD6Z5uyw="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + six + pycryptodomex + requests + urllib3 + vdf + gevent + protobuf + gevent-eventemitter + cachetools + ]; + + meta = { + description = "Python package for interacting with Steam"; + homepage = "https://github.com/ValvePython/steam"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + maintainers = with lib.maintainers; [ weirdrock ]; + }; +} diff --git a/pkgs/development/python-modules/steamworkspy/default.nix b/pkgs/development/python-modules/steamworkspy/default.nix new file mode 100644 index 000000000000..34b7c386bb84 --- /dev/null +++ b/pkgs/development/python-modules/steamworkspy/default.nix @@ -0,0 +1,79 @@ +{ + lib, + fetchzip, + stdenv, + buildPythonPackage, + fetchFromGitHub, + + setuptools, +}: +let + rev = "26780de81b8c14d48fe8d757c642086f2af2a66b"; + + src = fetchFromGitHub { + owner = "philippj"; + repo = "SteamworksPy"; + inherit rev; + hash = "sha256-nSGkEP6tny/Kv2+YjldFCYrLe1jnKOTa+w1/KCpSLsU="; + + }; + steamworksSrc = fetchzip { + url = "https://web.archive.org/web/20250527013243/https://partner.steamgames.com/downloads/steamworks_sdk_162.zip"; + hash = "sha256-yDA92nGj3AKTNI4vnoLaa+7mDqupQv0E4YKRRUWqyZw="; + }; + + library = stdenv.mkDerivation { + pname = "steamworkspy-c"; + version = rev; + + unpackPhase = '' + runHook preUnpack + + cp -r ${src} source + chmod -R 755 source + cp -r ${steamworksSrc}/public/steam source/library/sdk/ + cp ${steamworksSrc}/redistributable_bin/linux64/libsteam_api.so source/library/ + + runHook postUnpack + ''; + + sourceRoot = "source/library"; + + installPhase = '' + mkdir -p $out + cp SteamworksPy.so $out/ + ''; + }; +in + +buildPythonPackage { + pname = "steamworkspy"; + version = rev; + pyproject = true; + + inherit src; + + build-system = [ setuptools ]; + + postInstall = '' + cp ${library}/SteamworksPy.so $out/lib + ''; + + meta = { + description = "Python API system for Valve's Steamworks"; + homepage = "https://github.com/philippj/SteamworksPy"; + license = with lib.licenses; [ + mit + # For steamworks headers and libsteamapi.so + ( + unfreeRedistributable + // { + url = "https://partner.steamgames.com/documentation/sdk_access_agreement"; + } + ) + ]; + # steamworksSrc is x86_64-linux only + platforms = [ "x86_64-linux" ]; + maintainers = with lib.maintainers; [ weirdrock ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 2c6e5180a9ce..5562b754da5d 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5757,6 +5757,8 @@ self: super: with self; { gevent = callPackage ../development/python-modules/gevent { }; + gevent-eventemitter = callPackage ../development/python-modules/gevent-eventemitter { }; + gevent-socketio = callPackage ../development/python-modules/gevent-socketio { }; gevent-websocket = callPackage ../development/python-modules/gevent-websocket { }; @@ -17247,10 +17249,14 @@ self: super: with self; { stdlibs = callPackage ../development/python-modules/stdlibs { }; + steam = callPackage ../development/python-modules/steam { }; + steamodd = callPackage ../development/python-modules/steamodd { }; steamship = callPackage ../development/python-modules/steamship { }; + steamworkspy = callPackage ../development/python-modules/steamworkspy { }; + stem = callPackage ../development/python-modules/stem { }; stemming = callPackage ../development/python-modules/stemming { };