From a469aa29b0e2bb829ebdcf916a5e39294bb900be Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Wed, 11 Mar 2026 09:23:08 -0700 Subject: [PATCH] shelfmark: init at 1.2.0 Self-hosted web interface for searching and downloading books and audiobooks from multiple sources. This packages the lite variant, which relies on an external Cloudflare bypass (e.g. FlareSolverr). https://github.com/calibrain/shelfmark --- .../by-name/sh/shelfmark-frontend/package.nix | 25 +++++ pkgs/by-name/sh/shelfmark/package.nix | 96 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 pkgs/by-name/sh/shelfmark-frontend/package.nix create mode 100644 pkgs/by-name/sh/shelfmark/package.nix diff --git a/pkgs/by-name/sh/shelfmark-frontend/package.nix b/pkgs/by-name/sh/shelfmark-frontend/package.nix new file mode 100644 index 000000000000..d8f448281fe8 --- /dev/null +++ b/pkgs/by-name/sh/shelfmark-frontend/package.nix @@ -0,0 +1,25 @@ +{ + buildNpmPackage, + shelfmark, +}: + +buildNpmPackage (finalAttrs: { + pname = "shelfmark-frontend"; + inherit (shelfmark) version src; + + sourceRoot = "${finalAttrs.src.name}/src/frontend"; + + npmDepsHash = "sha256-RAzotFGj0FGpfF7iyB5f2fdKFvMLcpJx142yplRwboU="; + + installPhase = '' + runHook preInstall + cp -r dist $out + runHook postInstall + ''; + + meta = { + description = "Shelfmark frontend"; + homepage = "https://github.com/calibrain/shelfmark/tree/main/src/frontend"; + inherit (shelfmark.meta) changelog license maintainers; + }; +}) diff --git a/pkgs/by-name/sh/shelfmark/package.nix b/pkgs/by-name/sh/shelfmark/package.nix new file mode 100644 index 000000000000..464e4755bef4 --- /dev/null +++ b/pkgs/by-name/sh/shelfmark/package.nix @@ -0,0 +1,96 @@ +{ + lib, + stdenv, + fetchFromGitHub, + python3Packages, + makeWrapper, + nixosTests, + shelfmark-frontend, + unrar-free, +}: + +let + pythonDeps = with python3Packages; [ + flask + flask-cors + flask-socketio + python-socketio + requests + pysocks + defusedxml + beautifulsoup4 + tqdm + dnspython + gunicorn + gevent + gevent-websocket + psutil + emoji + rarfile + qbittorrent-api + transmission-rpc + authlib + apprise + ]; +in +stdenv.mkDerivation (finalAttrs: { + pname = "shelfmark"; + version = "1.2.0"; + + src = fetchFromGitHub { + owner = "calibrain"; + repo = "shelfmark"; + tag = "v${finalAttrs.version}"; + hash = "sha256-t4t7je7Y/aezx/EX7paJIcsCq5qyZeU/+mPLeZ8oTPg="; + }; + + nativeBuildInputs = [ + python3Packages.wrapPython + makeWrapper + ]; + + pythonPath = pythonDeps; + + installPhase = '' + runHook preInstall + + wrapPythonPrograms + + mkdir -p $out/libexec $out/bin + + cp -r shelfmark $out/libexec/shelfmark + cp -r data $out/libexec/data + ln -s ${finalAttrs.passthru.frontend} $out/libexec/frontend-dist + + makeWrapper ${python3Packages.python.interpreter} $out/bin/shelfmark \ + --prefix PATH : ${ + lib.makeBinPath [ + python3Packages.python + unrar-free + ] + } \ + --set PYTHONPATH "$out/libexec:$program_PYTHONPATH" \ + --set USING_EXTERNAL_BYPASSER true \ + --add-flags "-m gunicorn.app.wsgiapp --worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker --workers 1 -t 300 shelfmark.main:app" + + runHook postInstall + ''; + + passthru = { + frontend = shelfmark-frontend.override { + shelfmark = finalAttrs.finalPackage; + }; + tests = { + inherit (nixosTests) shelfmark; + }; + }; + + meta = { + description = "Self-hosted web interface for searching and downloading books and audiobooks"; + homepage = "https://github.com/calibrain/shelfmark"; + changelog = "https://github.com/calibrain/shelfmark/releases/tag/${finalAttrs.src.tag}"; + license = lib.licenses.mit; + maintainers = [ lib.maintainers.jamiemagee ]; + mainProgram = "shelfmark"; + }; +})