diff --git a/pkgs/development/python-modules/mat2/default.nix b/pkgs/development/python-modules/mat2/default.nix new file mode 100644 index 000000000000..07957606b098 --- /dev/null +++ b/pkgs/development/python-modules/mat2/default.nix @@ -0,0 +1,95 @@ +{ lib +, buildPythonPackage +, python +, pythonOlder +, fetchFromGitLab +, substituteAll +, bubblewrap +, exiftool +, ffmpeg +, mime-types +, wrapGAppsHook +, gdk-pixbuf +, gobject-introspection +, librsvg +, poppler_gi +, mutagen +, pygobject3 +, pycairo +, dolphinIntegration ? false, plasma5Packages +}: + +buildPythonPackage rec { + pname = "mat2"; + version = "0.12.0"; + + disabled = pythonOlder "3.5"; + + src = fetchFromGitLab { + domain = "0xacab.org"; + owner = "jvoisin"; + repo = "mat2"; + rev = version; + sha256 = "0amxwwmcf47dakfm6zvsksv6ja7rz7dpmd1z2rsspy8yds6zgxs7"; + }; + + patches = [ + # hardcode paths to some binaries + (substituteAll ({ + src = ./paths.patch; + bwrap = "${bubblewrap}/bin/bwrap"; + exiftool = "${exiftool}/bin/exiftool"; + ffmpeg = "${ffmpeg}/bin/ffmpeg"; + # remove once faf0f8a8a4134edbeec0a73de7f938453444186d is in master + mimetypes = "${mime-types}/etc/mime.types"; + } // lib.optionalAttrs dolphinIntegration { + kdialog = "${plasma5Packages.kdialog}/bin/kdialog"; + })) + # the executable shouldn't be called .mat2-wrapped + ./executable-name.patch + # hardcode path to mat2 executable + ./tests.patch + ]; + + postPatch = '' + substituteInPlace dolphin/mat2.desktop \ + --replace "@mat2@" "$out/bin/mat2" \ + --replace "@mat2svg@" "$out/share/icons/hicolor/scalable/apps/mat2.svg" + ''; + + nativeBuildInputs = [ + wrapGAppsHook + ]; + + buildInputs = [ + gdk-pixbuf + gobject-introspection + librsvg + poppler_gi + ]; + + propagatedBuildInputs = [ + mutagen + pygobject3 + pycairo + ]; + + postInstall = '' + install -Dm 444 data/mat2.svg -t "$out/share/icons/hicolor/scalable/apps" + install -Dm 444 doc/mat2.1 -t "$out/share/man/man1" + '' + lib.optionalString dolphinIntegration '' + install -Dm 444 dolphin/mat2.desktop -t "$out/share/kservices5/ServiceMenus" + ''; + + checkPhase = '' + ${python.interpreter} -m unittest discover -v + ''; + + meta = with lib; { + description = "A handy tool to trash your metadata"; + homepage = "https://0xacab.org/jvoisin/mat2"; + changelog = "https://0xacab.org/jvoisin/mat2/-/blob/${version}/CHANGELOG.md"; + license = licenses.lgpl3Plus; + maintainers = with maintainers; [ dotlambda ]; + }; +} diff --git a/pkgs/development/python-modules/mat2/executable-name.patch b/pkgs/development/python-modules/mat2/executable-name.patch new file mode 100644 index 000000000000..6eee0a949400 --- /dev/null +++ b/pkgs/development/python-modules/mat2/executable-name.patch @@ -0,0 +1,13 @@ +diff --git a/mat2 b/mat2 +index 3b77e1e..b99a633 100755 +--- a/mat2 ++++ b/mat2 +@@ -46,7 +46,7 @@ def __check_file(filename: str, mode: int = os.R_OK) -> bool: + + + def create_arg_parser() -> argparse.ArgumentParser: +- parser = argparse.ArgumentParser(description='Metadata anonymisation toolkit 2') ++ parser = argparse.ArgumentParser(description='Metadata anonymisation toolkit 2', prog='mat2') + + parser.add_argument('-V', '--verbose', action='store_true', + help='show more verbose status information') diff --git a/pkgs/development/python-modules/mat2/paths.patch b/pkgs/development/python-modules/mat2/paths.patch new file mode 100644 index 000000000000..e0144be9fef6 --- /dev/null +++ b/pkgs/development/python-modules/mat2/paths.patch @@ -0,0 +1,111 @@ +diff --git a/dolphin/mat2.desktop b/dolphin/mat2.desktop +index e623962..5d69ae2 100644 +--- a/dolphin/mat2.desktop ++++ b/dolphin/mat2.desktop +@@ -7,5 +7,5 @@ Type=Service + [Desktop Action cleanMetadata] + Name=Clean metadata + Name[es]=Limpiar metadatos +-Icon=/usr/share/icons/hicolor/scalable/apps/mat2.svg +-Exec=kdialog --yesno "$( mat2 -s %U )" --title "Clean Metadata?" && mat2 %U ++Icon=@mat2svg@ ++Exec=@kdialog@ --yesno "$( @mat2@ -s %U )" --title "Clean Metadata?" && @mat2@ %U +diff --git a/libmat2/bubblewrap.py b/libmat2/bubblewrap.py +index 970d5dd..5d3c0b7 100644 +--- a/libmat2/bubblewrap.py ++++ b/libmat2/bubblewrap.py +@@ -22,11 +22,7 @@ CalledProcessError = subprocess.CalledProcessError + + + def _get_bwrap_path() -> str: +- which_path = shutil.which('bwrap') +- if which_path: +- return which_path +- +- raise RuntimeError("Unable to find bwrap") # pragma: no cover ++ return '@bwrap@' + + + def _get_bwrap_args(tempdir: str, +@@ -37,16 +33,11 @@ def _get_bwrap_args(tempdir: str, + + # XXX: use --ro-bind-try once all supported platforms + # have a bubblewrap recent enough to support it. +- ro_bind_dirs = ['/usr', '/lib', '/lib64', '/bin', '/sbin', '/etc/alternatives', cwd] ++ ro_bind_dirs = ['/nix/store', cwd] + for bind_dir in ro_bind_dirs: + if os.path.isdir(bind_dir): # pragma: no cover + ro_bind_args.extend(['--ro-bind', bind_dir, bind_dir]) + +- ro_bind_files = ['/etc/ld.so.cache'] +- for bind_file in ro_bind_files: +- if os.path.isfile(bind_file): # pragma: no cover +- ro_bind_args.extend(['--ro-bind', bind_file, bind_file]) +- + args = ro_bind_args + \ + ['--dev', '/dev', + '--proc', '/proc', +diff --git a/libmat2/exiftool.py b/libmat2/exiftool.py +index eb65b2a..51a0fa1 100644 +--- a/libmat2/exiftool.py ++++ b/libmat2/exiftool.py +@@ -1,8 +1,6 @@ +-import functools + import json + import logging + import os +-import shutil + import subprocess + from typing import Dict, Union, Set + +@@ -70,14 +68,5 @@ class ExiftoolParser(abstract.AbstractParser): + return False + return True + +-@functools.lru_cache() + def _get_exiftool_path() -> str: # pragma: no cover +- which_path = shutil.which('exiftool') +- if which_path: +- return which_path +- +- # Exiftool on Arch Linux has a weird path +- if os.access('/usr/bin/vendor_perl/exiftool', os.X_OK): +- return '/usr/bin/vendor_perl/exiftool' +- +- raise RuntimeError("Unable to find exiftool") ++ return '@exiftool@' +diff --git a/libmat2/parser_factory.py b/libmat2/parser_factory.py +index 9965432..bd45179 100644 +--- a/libmat2/parser_factory.py ++++ b/libmat2/parser_factory.py +@@ -8,6 +8,7 @@ from . import abstract, UNSUPPORTED_EXTENSIONS + + T = TypeVar('T', bound='abstract.AbstractParser') + ++mimetypes.init(['@mimetypes@']) + mimetypes.add_type('application/epub+zip', '.epub') + mimetypes.add_type('application/x-dtbncx+xml', '.ncx') # EPUB Navigation Control XML File + +diff --git a/libmat2/video.py b/libmat2/video.py +index b4a3232..3dd7ee5 100644 +--- a/libmat2/video.py ++++ b/libmat2/video.py +@@ -1,6 +1,4 @@ + import subprocess +-import functools +-import shutil + import logging + + from typing import Dict, Union +@@ -135,10 +133,5 @@ class MP4Parser(AbstractFFmpegParser): + } + + +-@functools.lru_cache() + def _get_ffmpeg_path() -> str: # pragma: no cover +- which_path = shutil.which('ffmpeg') +- if which_path: +- return which_path +- +- raise RuntimeError("Unable to find ffmpeg") ++ return '@ffmpeg@' diff --git a/pkgs/development/python-modules/mat2/tests.patch b/pkgs/development/python-modules/mat2/tests.patch new file mode 100644 index 000000000000..8958d937dd43 --- /dev/null +++ b/pkgs/development/python-modules/mat2/tests.patch @@ -0,0 +1,18 @@ +diff --git a/tests/test_climat2.py b/tests/test_climat2.py +index cede642..2d5ad77 100644 +--- a/tests/test_climat2.py ++++ b/tests/test_climat2.py +@@ -10,12 +10,7 @@ import glob + from libmat2 import images, parser_factory + + +-mat2_binary = ['./mat2'] +- +-if 'MAT2_GLOBAL_PATH_TESTSUITE' in os.environ: +- # Debian runs tests after installing the package +- # https://0xacab.org/jvoisin/mat2/issues/16#note_153878 +- mat2_binary = ['/usr/bin/env', 'mat2'] ++mat2_binary = [os.environ['out'] + '/bin/mat2'] + + + class TestHelp(unittest.TestCase): diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a47a94c08e7f..f3c63135745f 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2616,6 +2616,8 @@ in massren = callPackage ../tools/misc/massren { }; + mat2 = with python3.pkgs; toPythonApplication mat2; + maxcso = callPackage ../tools/archivers/maxcso {}; medusa = callPackage ../tools/security/medusa { }; diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 7799b6356b39..ca64bc704b5d 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -4044,6 +4044,8 @@ in { mask-rcnn = callPackage ../development/python-modules/mask-rcnn { }; + mat2 = callPackage ../development/python-modules/mat2 { }; + matchpy = callPackage ../development/python-modules/matchpy { }; mathlibtools = callPackage ../development/python-modules/mathlibtools { };