diff --git a/pkgs/tools/graphics/pdf-sign/default.nix b/pkgs/tools/graphics/pdf-sign/default.nix new file mode 100644 index 000000000000..c2590ac00cf6 --- /dev/null +++ b/pkgs/tools/graphics/pdf-sign/default.nix @@ -0,0 +1,57 @@ +{ lib +, stdenv +, fetchFromGitHub +, substituteAll + +, python3 +, ghostscript +, coreutils +, pdftk +, poppler_utils +}: + +let + python-env = python3.withPackages (ps: with ps; [ tkinter ]); +in +stdenv.mkDerivation { + pname = "pdf-sign"; + version = "unstable-2023-08-08"; + + src = fetchFromGitHub { + owner = "svenssonaxel"; + repo = "pdf-sign"; + rev = "98742c6b12ebe2ca3ba375c695f43b52fe38b362"; + hash = "sha256-5GRk0T1iLqmvWI8zvZE3OWEHPS0/zN/Ie9brjZiFpqc="; + }; + + patches = [ + (substituteAll { + src = ./use-nix-paths.patch; + gs = "${ghostscript}/bin/gs"; + mv = "${coreutils}/bin/mv"; + pdftk = "${pdftk}/bin/pdftk"; + pdfinfo = "${poppler_utils}/bin/pdfinfo"; + }) + ]; + + buildInputs = [ python-env ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin + cp pdf-sign pdf-create-empty $out/bin + patchShebangs $out/bin + + runHook postInstall + ''; + + meta = { + description = "A tool to visually sign PDF files"; + homepage = "https://github.com/svenssonaxel/pdf-sign"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ tomasajt ]; + platforms = lib.platforms.unix; + }; +} + diff --git a/pkgs/tools/graphics/pdf-sign/use-nix-paths.patch b/pkgs/tools/graphics/pdf-sign/use-nix-paths.patch new file mode 100644 index 000000000000..d2b14c27a618 --- /dev/null +++ b/pkgs/tools/graphics/pdf-sign/use-nix-paths.patch @@ -0,0 +1,93 @@ +diff --git a/pdf-create-empty b/pdf-create-empty +index e4768af..5caf34c 100755 +--- a/pdf-create-empty ++++ b/pdf-create-empty +@@ -20,7 +20,7 @@ def main(args): + except: + die('Invalid dimensions') + subprocess.run([ +- 'gs', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', ++ '@gs@', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', + f'-sOutputFile={o}', + '-sDEVICE=pdfwrite', + f'-dDEVICEWIDTHPOINTS={w}', f'-dDEVICEHEIGHTPOINTS={h}', +diff --git a/pdf-sign b/pdf-sign +index 64be231..37d508d 100755 +--- a/pdf-sign ++++ b/pdf-sign +@@ -17,7 +17,7 @@ def main(args): + if args.flatten: + outFile=intmp('input.pdf') + subprocess.run([ +- 'pdftk', filePath, ++ '@pdftk@', filePath, + 'output', outFile, + 'flatten' + ], check=True) +@@ -28,7 +28,7 @@ def main(args): + if args.page < -pageCount or args.page==0 or pageCount < args.page: + die('Page number out of range') + pageNumber=Cell(args.page if 0 < args.page else pageCount+args.page+1) +- pagePDF=Cell(lambda: subprocess.run(['pdftk', inputPDF(), 'cat', str(pageNumber()), 'output', intmp('page.pdf')], check=True) and intmp('page.pdf')) ++ pagePDF=Cell(lambda: subprocess.run(['@pdftk@', inputPDF(), 'cat', str(pageNumber()), 'output', intmp('page.pdf')], check=True) and intmp('page.pdf')) + pageSize=Cell(lambda: pdfGetSize(pagePDF())) + # The chosen signature + if not args.signature and args.batch: +@@ -52,7 +52,7 @@ def main(args): + dy=h*(1-signaturePositionY())/resize - sh/2 + outFile=intmp('signature-positioned.pdf') + subprocess.run([ +- 'gs', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', ++ '@gs@', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', + f'-sOutputFile={outFile}', + '-sDEVICE=pdfwrite', + f'-dDEVICEWIDTHPOINTS={w}', f'-dDEVICEHEIGHTPOINTS={h}', '-dFIXEDMEDIA', +@@ -62,7 +62,7 @@ def main(args): + return outFile + # The signed page + signedPagePDF=Cell(lambda: subprocess.run([ +- 'pdftk', ++ '@pdftk@', + pagePDF(), + 'stamp', signaturePositionedPDF(), + 'output', intmp('signed-page.pdf'), +@@ -80,7 +80,7 @@ def main(args): + (w, h)=displaySize() + outFile=intmp('display.png') + subprocess.run([ +- 'gs', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', ++ '@gs@', '-dBATCH', '-dNOPAUSE', '-dSAFER', '-dQUIET', + f'-sOutputFile={outFile}', + '-sDEVICE=pngalpha', + '-dMaxBitmap=2147483647', +@@ -258,7 +258,7 @@ def main(args): + if args.existing=='backup': + backupFilePath=f'{signedFilePath}.backup{time.strftime("%Y%m%d_%H%M%S")}' + subprocess.run([ +- 'mv', ++ '@mv@', + signedFilePath, + backupFilePath, + ], check=True) +@@ -269,7 +269,7 @@ def main(args): + assert args.existing=='overwrite' + pnr=pageNumber() + subprocess.run([ +- 'pdftk', ++ '@pdftk@', + f'A={inputPDF()}', + f'B={signedPagePDF()}', + 'cat', +@@ -352,10 +352,10 @@ def tkthrottle(frequency, root): + return decorator + + def pdfCountPages(filePath): +- return int(fromCmdOutput(["pdfinfo", filePath], "^.*\nPages: +([0-9]+)\n.*$")[1]) ++ return int(fromCmdOutput(["@pdfinfo@", filePath], "^.*\nPages: +([0-9]+)\n.*$")[1]) + + def pdfGetSize(filePath): +- [ignored, w, h, *ignored2]=fromCmdOutput(['pdfinfo', filePath], '^.*\nPage size: +([0-9.]+) x ([0-9.]+) pts( \([A-Za-z0-9]+\))?\n.*$') ++ [ignored, w, h, *ignored2]=fromCmdOutput(['@pdfinfo@', filePath], '^.*\nPage size: +([0-9.]+) x ([0-9.]+) pts( \([A-Za-z0-9]+\))?\n.*$') + return (float(w), float(h)) + + def m(pattern, string): diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ded768cc63a7..f9240c4306ca 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11761,6 +11761,8 @@ with pkgs; pdf-quench = callPackage ../applications/misc/pdf-quench { }; + pdf-sign = callPackage ../tools/graphics/pdf-sign { }; + pdfarranger = callPackage ../applications/misc/pdfarranger { }; briss = callPackage ../tools/graphics/briss { };