<commit_before>{ stdenv, lib, fetchFromGitHub, fetchurl, cmake, makeWrapper, pkgconfig
, curl, ffmpeg, glib, libjpeg, libselinux, libsepol, mp4v2, mysql, pcre, perl, perlPackages
, polkit, utillinuxMinimal, x264, zlib
, coreutils, procps, psmisc }:

# NOTES:
#
# 1. ZM_CONFIG_DIR is set to $out/etc/zoneminder as the .conf file distributed
# by upstream contains defaults and is not supposed to be edited so it is fine
# to keep it read-only.
#
# 2. ZM_CONFIG_SUBDIR is where we place our configuration from the NixOS module
# but as the installer will try to put files there, we patch Config.pm after the
# install.
#
# 3. ZoneMinder is run with -T passed to the perl interpreter which makes perl
# ignore PERL5LIB. We therefore have to do the substitution into -I parameters
# ourselves which results in ugly wrappers.
#
# 4. The makefile for the perl modules needs patching to put things into the
# right place. That also means we have to not run "make install" for them.
#
# 5. In principal the various ZM_xx variables should be overridable from the
# config file but some of them are baked into the perl scripts, so we *have* to
# set them here instead of in the configuration in the NixOS module.
#
# 6. I am no PolicyKit expert but the .policy file looks fishy:
#   a. The user needs to be known at build-time so we should probably throw
#   upstream's policy file away and generate it from the NixOS module
#   b. I *think* we may have to substitute the store paths with
#   /run/current-system/sw/bin paths for it to work.
#
# 7. we manually fix up the perl paths in the scripts as fixupPhase will only
# handle pkexec and not perl if both are present.
#
# 8. There are several perl modules needed at runtime which are not checked when
# building so if a new version stops working, check if there is a missing
# dependency by running the failing component manually.
#
# 9. Parts of the web UI has a hardcoded /zm path so we create a symlink to work
# around it.

let
  modules = [
    {
      path = "web/api/app/Plugin/Crud";
      src = fetchFromGitHub {
        owner = "ZoneMinder";
        repo = "crud";
        rev = "3.1.0-zm";
        sha256 = "061avzyml7mla4hlx057fm8a9yjh6m6qslgyzn74cv5p2y7f463l";
      };
    }
    {
      path = "web/api/app/Plugin/CakePHP-Enum-Behavior";
      src = fetchFromGitHub {
        owner = "ZoneMinder";
        repo = "CakePHP-Enum-Behavior";
        rev = "1.0-zm";
        sha256 = "0zsi6s8xymb183kx3szspbrwfjqcgga7786zqvydy6hc8c909cgx";
      };
    }
  ];

  addons = [
    {
      path = "scripts/ZoneMinder/lib/ZoneMinder/Control/Xiaomi.pm";
      src = fetchurl {
        url = "https://gist.githubusercontent.com/joshstrange/73a2f24dfaf5cd5b470024096ce2680f/raw/e964270c5cdbf95e5b7f214f7f0fc6113791530e/Xiaomi.pm";
        sha256 = "04n1ap8fx66xfl9q9rypj48pzbgzikq0gisfsfm8wdsmflarz43v";
      };
    }
  ];

  user    = "zoneminder";
  dirName = "zoneminder";
  perlBin = "${perl}/bin/perl";

in stdenv.mkDerivation rec {
  name = "zoneminder-${version}";
  version = "1.32.3";

  src = fetchFromGitHub {
    owner  = "ZoneMinder";
    repo   = "zoneminder";
    rev    = version;
    sha256 = "1sx2fn99861zh0gp8g53ynr1q6yfmymxamn82y54jqj6nv475njz";
  };

  patches = [
    ./default-to-http-1dot1.patch
    # Explicitly link with dynamic linking library to fix build
    ./link-with-libdl.patch
  ];

  postPatch = ''
    ${lib.concatStringsSep "\n" (map (e: ''
      rm -rf ${e.path}/*
      cp -r ${e.src}/* ${e.path}/
    '') modules)}

    rm -rf web/api/lib/Cake/Test

    ${lib.concatStringsSep "\n" (map (e: ''
      cp ${e.src} ${e.path}
    '') addons)}

    for d in scripts/ZoneMinder onvif/{modules,proxy} ; do
      substituteInPlace $d/CMakeLists.txt \
        --replace 'DESTDIR="''${CMAKE_CURRENT_BINARY_DIR}/output"' "PREFIX=$out INSTALLDIRS=site"
      sed -i '/^install/d' $d/CMakeLists.txt
    done

    substituteInPlace misc/CMakeLists.txt \
      --replace '"''${PC_POLKIT_PREFIX}/''${CMAKE_INSTALL_DATAROOTDIR}' "\"$out/share"

    for f in misc/*.policy.in \
             scripts/*.pl* \
             scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in ; do
      substituteInPlace $f \
        --replace '/usr/bin/perl' '${perlBin}' \
        --replace '/bin:/usr/bin' "$out/bin:${lib.makeBinPath [ coreutils procps psmisc ]}"
    done

    substituteInPlace scripts/zmdbbackup.in \
      --replace /usr/bin/mysqldump ${mysql}/bin/mysqldump

    for f in scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in \
             scripts/zmupdate.pl.in \
             src/zm_config.h.in \
             web/api/app/Config/bootstrap.php.in \
             web/includes/config.php.in ; do
      substituteInPlace $f --replace @ZM_CONFIG_SUBDIR@ /etc/zoneminder
    done

   for f in includes/Event.php views/image.php skins/classic/views/image-ffmpeg.php ; do
     substituteInPlace web/$f \
       --replace "'ffmpeg " "'${ffmpeg}/bin/ffmpeg "
   done
  '';

  buildInputs = [
    curl ffmpeg glib libjpeg libselinux libsepol mp4v2 mysql pcre perl polkit x264 zlib
    utillinuxMinimal # for libmount
  ] ++ (with perlPackages; [
    # build-time dependencies
    DateManip DBI DBDmysql LWP SysMmap
    # run-time dependencies not checked at build-time
    ClassStdFast DataDump JSONMaybeXS LWPProtocolHttps NumberBytesHuman SysCPU SysMemInfo TimeDate
  ]);

  nativeBuildInputs = [ cmake makeWrapper pkgconfig ];

  enableParallelBuilding = true;
<commit_msg>zoneminder: use DeviceSerialPort for zmtrigger.pl<commit_after>{ stdenv, lib, fetchFromGitHub, fetchurl, cmake, makeWrapper, pkgconfig
, curl, ffmpeg, glib, libjpeg, libselinux, libsepol, mp4v2, mysql, pcre, perl, perlPackages
, polkit, utillinuxMinimal, x264, zlib
, coreutils, procps, psmisc }:

# NOTES:
#
# 1. ZM_CONFIG_DIR is set to $out/etc/zoneminder as the .conf file distributed
# by upstream contains defaults and is not supposed to be edited so it is fine
# to keep it read-only.
#
# 2. ZM_CONFIG_SUBDIR is where we place our configuration from the NixOS module
# but as the installer will try to put files there, we patch Config.pm after the
# install.
#
# 3. ZoneMinder is run with -T passed to the perl interpreter which makes perl
# ignore PERL5LIB. We therefore have to do the substitution into -I parameters
# ourselves which results in ugly wrappers.
#
# 4. The makefile for the perl modules needs patching to put things into the
# right place. That also means we have to not run "make install" for them.
#
# 5. In principal the various ZM_xx variables should be overridable from the
# config file but some of them are baked into the perl scripts, so we *have* to
# set them here instead of in the configuration in the NixOS module.
#
# 6. I am no PolicyKit expert but the .policy file looks fishy:
#   a. The user needs to be known at build-time so we should probably throw
#   upstream's policy file away and generate it from the NixOS module
#   b. I *think* we may have to substitute the store paths with
#   /run/current-system/sw/bin paths for it to work.
#
# 7. we manually fix up the perl paths in the scripts as fixupPhase will only
# handle pkexec and not perl if both are present.
#
# 8. There are several perl modules needed at runtime which are not checked when
# building so if a new version stops working, check if there is a missing
# dependency by running the failing component manually.
#
# 9. Parts of the web UI has a hardcoded /zm path so we create a symlink to work
# around it.

let
  modules = [
    {
      path = "web/api/app/Plugin/Crud";
      src = fetchFromGitHub {
        owner = "ZoneMinder";
        repo = "crud";
        rev = "3.1.0-zm";
        sha256 = "061avzyml7mla4hlx057fm8a9yjh6m6qslgyzn74cv5p2y7f463l";
      };
    }
    {
      path = "web/api/app/Plugin/CakePHP-Enum-Behavior";
      src = fetchFromGitHub {
        owner = "ZoneMinder";
        repo = "CakePHP-Enum-Behavior";
        rev = "1.0-zm";
        sha256 = "0zsi6s8xymb183kx3szspbrwfjqcgga7786zqvydy6hc8c909cgx";
      };
    }
  ];

  addons = [
    {
      path = "scripts/ZoneMinder/lib/ZoneMinder/Control/Xiaomi.pm";
      src = fetchurl {
        url = "https://gist.githubusercontent.com/joshstrange/73a2f24dfaf5cd5b470024096ce2680f/raw/e964270c5cdbf95e5b7f214f7f0fc6113791530e/Xiaomi.pm";
        sha256 = "04n1ap8fx66xfl9q9rypj48pzbgzikq0gisfsfm8wdsmflarz43v";
      };
    }
  ];

  user    = "zoneminder";
  dirName = "zoneminder";
  perlBin = "${perl}/bin/perl";

in stdenv.mkDerivation rec {
  name = "zoneminder-${version}";
  version = "1.32.3";

  src = fetchFromGitHub {
    owner  = "ZoneMinder";
    repo   = "zoneminder";
    rev    = version;
    sha256 = "1sx2fn99861zh0gp8g53ynr1q6yfmymxamn82y54jqj6nv475njz";
  };

  patches = [
    ./default-to-http-1dot1.patch
    # Explicitly link with dynamic linking library to fix build
    ./link-with-libdl.patch
  ];

  postPatch = ''
    ${lib.concatStringsSep "\n" (map (e: ''
      rm -rf ${e.path}/*
      cp -r ${e.src}/* ${e.path}/
    '') modules)}

    rm -rf web/api/lib/Cake/Test

    ${lib.concatStringsSep "\n" (map (e: ''
      cp ${e.src} ${e.path}
    '') addons)}

    for d in scripts/ZoneMinder onvif/{modules,proxy} ; do
      substituteInPlace $d/CMakeLists.txt \
        --replace 'DESTDIR="''${CMAKE_CURRENT_BINARY_DIR}/output"' "PREFIX=$out INSTALLDIRS=site"
      sed -i '/^install/d' $d/CMakeLists.txt
    done

    substituteInPlace misc/CMakeLists.txt \
      --replace '"''${PC_POLKIT_PREFIX}/''${CMAKE_INSTALL_DATAROOTDIR}' "\"$out/share"

    for f in misc/*.policy.in \
             scripts/*.pl* \
             scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in ; do
      substituteInPlace $f \
        --replace '/usr/bin/perl' '${perlBin}' \
        --replace '/bin:/usr/bin' "$out/bin:${lib.makeBinPath [ coreutils procps psmisc ]}"
    done

    substituteInPlace scripts/zmdbbackup.in \
      --replace /usr/bin/mysqldump ${mysql}/bin/mysqldump

    for f in scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in \
             scripts/zmupdate.pl.in \
             src/zm_config.h.in \
             web/api/app/Config/bootstrap.php.in \
             web/includes/config.php.in ; do
      substituteInPlace $f --replace @ZM_CONFIG_SUBDIR@ /etc/zoneminder
    done

   for f in includes/Event.php views/image.php skins/classic/views/image-ffmpeg.php ; do
     substituteInPlace web/$f \
       --replace "'ffmpeg " "'${ffmpeg}/bin/ffmpeg "
   done
  '';

  buildInputs = [
    curl ffmpeg glib libjpeg libselinux libsepol mp4v2 mysql pcre perl polkit x264 zlib
    utillinuxMinimal # for libmount
  ] ++ (with perlPackages; [
    # build-time dependencies
    DateManip DBI DBDmysql LWP SysMmap
    # run-time dependencies not checked at build-time
    ClassStdFast DataDump DeviceSerialPort JSONMaybeXS LWPProtocolHttps NumberBytesHuman SysCPU SysMemInfo TimeDate
  ]);

  nativeBuildInputs = [ cmake makeWrapper pkgconfig ];

  enableParallelBuilding = true;

{'fraction_non_alphanumeric': 0.10541754514620955, 'fraction_numerical': 0.02933357777981483, 'mean_word_length': 2.9202299676607977, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2746133', 'n_tokens_mistral': 4016, 'n_tokens_neox': 3776, 'n_words': 1071}