From 449c43370a79f7da79a7130256fdbbbe34f503d7 Mon Sep 17 00:00:00 2001
From: Andreas Romeyke <art1@andreas-romeyke.de>
Date: Sat, 23 Oct 2021 17:16:32 +0200
Subject: [PATCH] - dos2unix

---
 bin/slubsipbuilderbagit.pl | 854 ++++++++++++++++++-------------------
 1 file changed, 427 insertions(+), 427 deletions(-)

diff --git a/bin/slubsipbuilderbagit.pl b/bin/slubsipbuilderbagit.pl
index 4be3aa1..09e56d9 100644
--- a/bin/slubsipbuilderbagit.pl
+++ b/bin/slubsipbuilderbagit.pl
@@ -1,427 +1,427 @@
-#!/usr/bin/env perl
-#===============================================================================
-#         FILE: slubsipbuilderbagit.pl
-#
-#        USAGE: perl bin/slubsipbuilderbagit.pl --help
-#     EXAMPLES: perl bin/slubsipbuilderbagit.pl --man
-#
-#  DESCRIPTION: A CLI tool to create a valid SIP for ingest into SLUBArchiv.digital
-#
-# REQUIREMENTS: perl install version 5.28 or higher, as all necessary modules required
-#               module Archive::BagIt required version 0.070 or higher
-#               For Debian users: If cpan installations fails, please install libperl-dev and libperl5.28
-#               For Windows users: Check if UTF-8 flag set at
-#                                  Systemsteuerung > Zeit und Region > Region > Verwaltung/Gebietsschema ändern
-#
-#        NOTES: related to official document "SIP Spezifikation für automatischen Ingest SLUBArchiv"
-#               https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/
-#               option --save_option=copy is RECOMMENDED (If processing fails, manual restoration is needed!)
-#               option --add_meta_file="key: values" must be in quotes to be able to write whitespaces for values
-#
-#               Copyright (c) 2021
-# ORGANIZATION: Saxon State and University Library Dresden (SLUB)
-#      AUTHORS: Serhiy Bolkun (Serhiy.Bolkun@slub-dresden.de)
-#               Andreas Romeyke (Andreas.Romeyke@slub-dresden.de)
-#               Jens Steidl (Jens.Steidl@slub-dresden.de)
-#
-#
-#      This program is free software: you can redistribute it and/or modify
-#      it under the terms of the GNU General Public License as published by
-#      the Free Software Foundation, either version 3 of the License, or
-#      (at your option) any later version.
-#
-#      This program is distributed in the hope that it will be useful,
-#      but WITHOUT ANY WARRANTY; without even the implied warranty of
-#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#      GNU General Public License for more details.
-#
-#      You should have received a copy of the GNU General Public License
-#      along with this program. If not, see <https://www.gnu.org/licenses/>
-#===============================================================================
-
-
-use strict;
-use warnings;
-use utf8;
-
-#===============================================================================
-
-BEGIN{
-    if ($^O eq 'MSWin32') {
-        require Win32::Console::ANSI;
-        Win32::Console::ANSI->import();
-    }
-    ## no critic
-    $INC{'SLUB/LZA/SIPBuilderBagIt.pm'} = 1; # needed because inlined module
-    ## use critic
-}
-return 1 if caller;           # avoids main code running if module stuff is needed
-
-use utf8;
-use SLUB::LZA::SIPBuilderBagIt;
-use DateTime::Format::ISO8601;
-use Getopt::Long;
-use Path::Tiny;
-use Carp;                     # confess()
-use Pod::Usage;               # pod2usage()
-
-my $save;
-my $ieDirectory;
-my $outputPath;
-my $ppn;
-my $noppn;
-# bag-info data
-my $sipVersion;
-my $externalWorkflow;
-my $externalId;
-my $externalIsilId = "";
-my $exportToArchiveDate = DateTime->now(time_zone=>'local')->iso8601();
-my $hasConservationReason;
-my $archivalValueDescription;
-my $rightsVersion;
-my @addKeyValue;
-my @addBagInfo;    # array of hashes
-# not payload files
-my $rightsFilePath;
-my @addMetaFile;
-# extra
-my $help;
-my $man;
-
-GetOptions(
-    "save_option:s"                 => \$save,                                   # required
-    "IE_directory:s"                => \$ieDirectory,                            # required
-    "SIP_output_path:s"             => \$outputPath,                             # required, but by save=replace can be ignored
-    "ppn:s"                         => \$ppn,                                    # semi-optional (choice 1 of 2)
-    "noppn:s"                       => \$noppn,                                  # semi-optional (choice 2 of 2)
-    # bag-info data
-    "SIP_version:s"                 => \$sipVersion,                             # required
-    "external_workflow:s"           => \$externalWorkflow,                       # required
-    "external_id:s"                 => \$externalId,                             # required
-    "external_ISIL:s"               => \$externalIsilId,                         # optional, default: no ISIL
-    "external_conservation_flag"    => \$hasConservationReason,                  # optional, default: no special conservation
-    "external_value_descr:s"        => \$archivalValueDescription,               # required
-    "rights_version:s"              => \$rightsVersion,                          # required
-    # not payload files
-    "rights_xml:s"                  => \$rightsFilePath,                         # required
-    "add_meta_file:s"               => \@addMetaFile,                            # optional
-    "add_key_value:s"               => \@addKeyValue,                            # optional
-    # extra
-    "debug"                         => \$SLUB::LZA::SIPBuilderBagIt::with_debug, # optional
-    "help|?"                        => \$help,                                   # optional
-    "man"                           => \$man,                                    # optional
-) or pod2usage(2);
-
-# help
-if ($help) { pod2usage(1); }
-# man
-if ($man) { pod2usage(-exitval => 0, -verbose => 2); }
-# save
-if (!defined $save || $save eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a --save_option, available <replace> or <copy> or <move>", "", "red");
-    exit 1;
-}
-# ieDirectory
-if (!defined $ieDirectory || $ieDirectory eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --IE_directory, which needs to be archived", "", "red");
-    exit 1;
-}
-if (! -d $ieDirectory) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --IE_directory, status: is not a directory", "", "red");
-    exit 1;
-}
-# outputPath
-if (!defined $outputPath && ($save eq "copy" || $save eq "move")) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --SIP_output_path, where the SIP will be stored", "", "red");
-    exit 1;
-}
-if (defined $outputPath && $outputPath eq "" && ($save eq "copy" || $save eq "move")) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --SIP_output_path, where the SIP will be stored", "", "red");
-    exit 1;
-}
-# ppn, noppn
-if (defined $ppn && defined $noppn) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you can only specify either --ppn or --noppn", "", "red");
-    exit 1;
-}
-if ((!defined $ppn && !defined $noppn) || (!defined $ppn && $noppn eq "") || (!defined $noppn && $ppn eq "")) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a PPN with --ppn or use --noppn", "", "red");
-    exit 1;
-}
-
-#########################################################>  bag-info.txt  <###############################################################################
-# sipversion
-if (!defined $sipVersion || $sipVersion eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --SIP_version, current tool supports <v2020.1>", "", "red");
-    exit 1;
-}
-if ($sipVersion ne "v2020.1") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: not valid --SIP_version, current tool supports <v2020.1>", "", "red");
-    exit 1;
-}
-utf8::decode($sipVersion);
-push @addBagInfo, {'SLUBArchiv-sipVersion' => $sipVersion};
-# externalWorkflow
-if (!defined $externalWorkflow || $externalWorkflow eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify external workflow", "", "red");
-    exit 1;
-}
-if ($externalWorkflow !~ m#^[a-z0-9_-]+$#) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --external_workflow (^[a-z0-9_-]+\$)", "", "red");
-    exit 1;
-}
-utf8::decode($externalWorkflow);
-push @addBagInfo, {'SLUBArchiv-externalWorkflow' => $externalWorkflow};
-# externalId
-if (!defined $externalId || $externalId eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify external ID", "", "red");
-    exit 1;
-}
-if ($externalId !~ m#^[a-z0-9_-]+$#) {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --external_id (^[a-z0-9_-]+\$)", "", "red");
-    exit 1;
-}
-utf8::decode($externalId);
-push @addBagInfo, {'SLUBArchiv-externalId' => $externalId};
-# externalIsilId
-if (defined $externalIsilId && $externalIsilId ne "") {
-    utf8::decode($externalIsilId);
-    push @addBagInfo, {'SLUBArchiv-externalIsilId' => $externalIsilId};
-}
-# exportToArchiveDate
-utf8::decode($exportToArchiveDate);
-push @addBagInfo, {'SLUBArchiv-exportToArchiveDate' => $exportToArchiveDate};
-# hasConservationReason
-if (!defined $hasConservationReason) {
-    $hasConservationReason = "false";
-} else {
-    $hasConservationReason = "true";
-}
-utf8::decode($hasConservationReason);
-push @addBagInfo, {'SLUBArchiv-hasConservationReason' => $hasConservationReason};
-# archivalValueDescription
-if (!defined $archivalValueDescription || $archivalValueDescription eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --external_value_descr (reason for archiving)", "", "red");
-    exit 1;
-}
-utf8::decode($archivalValueDescription);
-push @addBagInfo, {'SLUBArchiv-archivalValueDescription' => $archivalValueDescription};
-# rightsVersion
-if (!defined $rightsVersion || $rightsVersion eq "") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_version", "", "red");
-    exit 1;
-}
-if($rightsVersion ne "1.0") {
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: invalid --rights_version, supported version <1.0>", "", "red");
-    exit 1;
-}
-utf8::decode($rightsVersion);
-push @addBagInfo, {'SLUBArchiv-rightsVersion' => $rightsVersion};
-# addKeyValue
-if (@addKeyValue) {
-    foreach my $zeile(@addKeyValue) {
-        if($zeile !~ m#^.*:.*$#) { # : must be minimum once present
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", 'ERROR: wrong construct in --add_key_value="' . $zeile . '", expected --add_key_value="key:value", regexp to match is (^[^:]+:[^:]+$)', "", "red");
-            exit 1;
-        }
-        utf8::decode($zeile);
-        my @keyvalue = split(/:/, $zeile, 2);    # split on first :
-        my $key = $keyvalue[0];
-        my $value = $keyvalue[1];
-        if($key eq 'SLUBArchiv-sipVersion' ||
-            $key eq 'SLUBArchiv-externalWorkflow' ||
-            $key eq 'SLUBArchiv-externalId' ||
-            $key eq 'SLUBArchiv-externalIsilId' ||
-            $key eq 'SLUBArchiv-exportToArchiveDate' ||
-            $key eq 'SLUBArchiv-hasConservationReason' ||
-            $key eq 'SLUBArchiv-archivalValueDescription' ||
-            $key eq 'SLUBArchiv-rightsVersion'){
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: duplicate key $key present at --add_key_value. Notice: $key is reserved by SLUB Dresden.", "", "red");
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
-            exit 1;
-        }
-        if($key eq 'Bag-Count'){
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: $key present at --add_key_value. This key is not available due to SLUB spesification.", "", "red");
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
-            exit 1;
-        }
-        if($key eq 'Bag-Group-Identifier'){
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: $key present at --add_key_value. This key is not available due to SLUB spesification.", "", "red"); 
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
-            exit 1;
-        }
-        push @addBagInfo, {$key => $value};
-    }
-}
-##########################################################################################################################################################
-
-# rightsFilePath
-if (!defined $rightsFilePath || $rightsFilePath eq "") { 
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_xml file, which needs to be added", "", "red"); 
-    exit 1;
-}
-if (! -f $rightsFilePath) { 
-    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_xml file, status: is not a file", "", "red");
-    exit 1;
-}
-# addMetaFile
-if (@addMetaFile) {
-    foreach my $file(@addMetaFile) {
-        if(! -f $file) {
-            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: file $file at --add_meta_file, is not a file or could not be found", "", "red");
-            exit 1;
-        }
-    }
-}
-#===============================================================================
-
-sub main{
-    # validate xml according to schema
-    SLUB::LZA::SIPBuilderBagIt::validateRightsXML($rightsFilePath, "rights1.xsd");
-
-    # get bag name
-    my $bagNameDir = SLUB::LZA::SIPBuilderBagIt::generateBagName($exportToArchiveDate, $ppn, $noppn);
-
-    # save options
-    if($save eq "copy") {
-        my $bagPath = "$outputPath/$bagNameDir";
-        my $dataPath = "$bagPath/data";
-        my $metaPath = "$bagPath/meta";
-
-        SLUB::LZA::SIPBuilderBagIt::buildBagWithCopyOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
-    } elsif($save eq "move") {
-        my $bagPath = "$outputPath/$bagNameDir";
-        my $dataPath = "$bagPath/data";
-        my $metaPath = "$bagPath/meta";
-
-        SLUB::LZA::SIPBuilderBagIt::buildBagWithMoveOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
-    } elsif($save eq "replace") {
-        my $bagPath = path($ieDirectory)->parent->child($bagNameDir)->realpath->stringify;
-        my $dataPath = "$bagPath/data";
-        my $metaPath = "$bagPath/meta";
-
-        SLUB::LZA::SIPBuilderBagIt::buildBagWithReplaceOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
-    }
-
-    return;
-}
-
-#===============================================================================
-
-main();
-1;
-#===============================================================================
-
-
-__END__
-
-=pod
-
-=head1 NAME
-
-preingest tool "SLUB SIP Builder BagIt" script to create Bags for SLUBArchive
-
-=head1 SYNOPSIS
-
-slubsipbuilderbagit.pl  [options]
-
-Options:
-        -help                           brief help message
-        -man                            full documentation
-
-        -save_option=<option>           payload files save as <copy>, <move>, <replace>, the <copy> option should be prefered
-        -IE_directory=<IE dir>          existing IE directory (absolute path!)
-        -SIP_output_path=<target dir>   where to put the SIP dir (absolute path!)
-        -ppn=<ppn>|-noppn=<noppn>       SWB-PPN or any identifier (uses minimalistic MODS)
-
-        -SIP_version=<version>          mandatory, needs for identification of SIP format, supported <v2020.1>
-        -external_workflow=<workflow>   mandatory, should be uniqe workflow name
-        -external_id=<id>               mandatory, should be uniqe ID (i.e. a catalog ID), reuse an ID only when updating existing AIP
-        -external_ISIL=<isil>           optional, ISIL number of library
-        -external_conservation_flag     optional, if set no other "original" still exists
-        -external_value_descr=<text>    mandatory, the reason why to archive
-        -rights_version=<version>       mandatory, SLUB law managment specification, supported <1.0>
-
-        -rights_xml=<file>              mandatory, path to SLUB rights xml file(absolute path!)
-        -add_meta_file=<file>           optional, can be repeated, additional meta files(absolute path!)
-        -add_key_value=<"key:value">    optional, can be repeated, additional key value pairs for bag-info.txt
-
-=head1 EXAMPLES
-
-=head2 Copy
-
-perl bin/slubsipbuilderbagit.pl
-     -save_option=copy
-     -IE_directory=./export_dir_kitodo/bagit/test2
-     -SIP_output_path=./output_sips
-     -ppn=457035137
-     -SIP_version=v2020.1
-     -external_id=10008
-     -external_workflow=kitodo
-     -external_ISIL=DE-14
-     -external_value_descr="Gesetzlicher Auftrag"
-     -rights_version=1.0
-     -rights_xml=export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
-     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
-     -add_key_value="Title:Krieg und Frieden"
-     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
-
-=head2 Replace
-
-NOT RECOMMENDED! IF FAILS, "IE" MUST BE MANUAL RESTORED TO THE PREVIOUS STATE!!!
-
-cp -a ./export_dir_kitodo/bagit/test2 ./ie_to_be_replaced
-
-perl bin/slubsipbuilderbagit.pl
-     -save_option=replace
-     -IE_directory=./ie_to_be_replaced
-     -ppn=457035137
-     -SIP_version=v2020.1
-     -external_id=10008
-     -external_workflow=kitodo
-     -external_ISIL=DE-14
-     -external_value_descr="Gesetzlicher Auftrag"
-     -rights_version=1.0
-     -rights_xml=./export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
-     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
-     -add_key_value="Title:Krieg und Frieden"
-     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
-
-=head2 Move
-
-NOT RECOMMENDED! IF FAILS, "IE" MUST BE MANUAL RESTORED TO THE PREVIOUS STATE!!!
-
-cp -a ./export_dir_kitodo/bagit/test2 ./ie_to_be_moved
-
-perl bin/slubsipbuilderbagit.pl
-     -save_option=move
-     -IE_directory=./ie_to_be_moved
-     --SIP_output_path=./output_sips
-     -ppn=457035137
-     -SIP_version=v2020.1
-     -external_id=10008
-     -external_workflow=kitodo
-     -external_ISIL=DE-14
-     -external_value_descr="Gesetzlicher Auftrag"
-     -rights_version=1.0
-     -rights_xml=./export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
-     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
-     -add_key_value="Title:Krieg und Frieden"
-     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
-
-=head1 OPTIONS
-
-=over 8
-
-=item B<-help>
-
-Print a brief help message and exits.
-
-=back
-
-=head1 DESCRIPTION
-
-B<This program> will process the given IE directory, add bibliographic metadata from catalogue with
-given PICA number and check and create a BagIt directory ready for SLUBarchiv
-
-=cut
+#!/usr/bin/env perl
+#===============================================================================
+#         FILE: slubsipbuilderbagit.pl
+#
+#        USAGE: perl bin/slubsipbuilderbagit.pl --help
+#     EXAMPLES: perl bin/slubsipbuilderbagit.pl --man
+#
+#  DESCRIPTION: A CLI tool to create a valid SIP for ingest into SLUBArchiv.digital
+#
+# REQUIREMENTS: perl install version 5.28 or higher, as all necessary modules required
+#               module Archive::BagIt required version 0.070 or higher
+#               For Debian users: If cpan installations fails, please install libperl-dev and libperl5.28
+#               For Windows users: Check if UTF-8 flag set at
+#                                  Systemsteuerung > Zeit und Region > Region > Verwaltung/Gebietsschema ändern
+#
+#        NOTES: related to official document "SIP Spezifikation für automatischen Ingest SLUBArchiv"
+#               https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/
+#               option --save_option=copy is RECOMMENDED (If processing fails, manual restoration is needed!)
+#               option --add_meta_file="key: values" must be in quotes to be able to write whitespaces for values
+#
+#               Copyright (c) 2021
+# ORGANIZATION: Saxon State and University Library Dresden (SLUB)
+#      AUTHORS: Serhiy Bolkun (Serhiy.Bolkun@slub-dresden.de)
+#               Andreas Romeyke (Andreas.Romeyke@slub-dresden.de)
+#               Jens Steidl (Jens.Steidl@slub-dresden.de)
+#
+#
+#      This program is free software: you can redistribute it and/or modify
+#      it under the terms of the GNU General Public License as published by
+#      the Free Software Foundation, either version 3 of the License, or
+#      (at your option) any later version.
+#
+#      This program is distributed in the hope that it will be useful,
+#      but WITHOUT ANY WARRANTY; without even the implied warranty of
+#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#      GNU General Public License for more details.
+#
+#      You should have received a copy of the GNU General Public License
+#      along with this program. If not, see <https://www.gnu.org/licenses/>
+#===============================================================================
+
+
+use strict;
+use warnings;
+use utf8;
+
+#===============================================================================
+
+BEGIN{
+    if ($^O eq 'MSWin32') {
+        require Win32::Console::ANSI;
+        Win32::Console::ANSI->import();
+    }
+    ## no critic
+    $INC{'SLUB/LZA/SIPBuilderBagIt.pm'} = 1; # needed because inlined module
+    ## use critic
+}
+return 1 if caller;           # avoids main code running if module stuff is needed
+
+use utf8;
+use SLUB::LZA::SIPBuilderBagIt;
+use DateTime::Format::ISO8601;
+use Getopt::Long;
+use Path::Tiny;
+use Carp;                     # confess()
+use Pod::Usage;               # pod2usage()
+
+my $save;
+my $ieDirectory;
+my $outputPath;
+my $ppn;
+my $noppn;
+# bag-info data
+my $sipVersion;
+my $externalWorkflow;
+my $externalId;
+my $externalIsilId = "";
+my $exportToArchiveDate = DateTime->now(time_zone=>'local')->iso8601();
+my $hasConservationReason;
+my $archivalValueDescription;
+my $rightsVersion;
+my @addKeyValue;
+my @addBagInfo;    # array of hashes
+# not payload files
+my $rightsFilePath;
+my @addMetaFile;
+# extra
+my $help;
+my $man;
+
+GetOptions(
+    "save_option:s"                 => \$save,                                   # required
+    "IE_directory:s"                => \$ieDirectory,                            # required
+    "SIP_output_path:s"             => \$outputPath,                             # required, but by save=replace can be ignored
+    "ppn:s"                         => \$ppn,                                    # semi-optional (choice 1 of 2)
+    "noppn:s"                       => \$noppn,                                  # semi-optional (choice 2 of 2)
+    # bag-info data
+    "SIP_version:s"                 => \$sipVersion,                             # required
+    "external_workflow:s"           => \$externalWorkflow,                       # required
+    "external_id:s"                 => \$externalId,                             # required
+    "external_ISIL:s"               => \$externalIsilId,                         # optional, default: no ISIL
+    "external_conservation_flag"    => \$hasConservationReason,                  # optional, default: no special conservation
+    "external_value_descr:s"        => \$archivalValueDescription,               # required
+    "rights_version:s"              => \$rightsVersion,                          # required
+    # not payload files
+    "rights_xml:s"                  => \$rightsFilePath,                         # required
+    "add_meta_file:s"               => \@addMetaFile,                            # optional
+    "add_key_value:s"               => \@addKeyValue,                            # optional
+    # extra
+    "debug"                         => \$SLUB::LZA::SIPBuilderBagIt::with_debug, # optional
+    "help|?"                        => \$help,                                   # optional
+    "man"                           => \$man,                                    # optional
+) or pod2usage(2);
+
+# help
+if ($help) { pod2usage(1); }
+# man
+if ($man) { pod2usage(-exitval => 0, -verbose => 2); }
+# save
+if (!defined $save || $save eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a --save_option, available <replace> or <copy> or <move>", "", "red");
+    exit 1;
+}
+# ieDirectory
+if (!defined $ieDirectory || $ieDirectory eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --IE_directory, which needs to be archived", "", "red");
+    exit 1;
+}
+if (! -d $ieDirectory) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --IE_directory, status: is not a directory", "", "red");
+    exit 1;
+}
+# outputPath
+if (!defined $outputPath && ($save eq "copy" || $save eq "move")) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --SIP_output_path, where the SIP will be stored", "", "red");
+    exit 1;
+}
+if (defined $outputPath && $outputPath eq "" && ($save eq "copy" || $save eq "move")) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --SIP_output_path, where the SIP will be stored", "", "red");
+    exit 1;
+}
+# ppn, noppn
+if (defined $ppn && defined $noppn) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you can only specify either --ppn or --noppn", "", "red");
+    exit 1;
+}
+if ((!defined $ppn && !defined $noppn) || (!defined $ppn && $noppn eq "") || (!defined $noppn && $ppn eq "")) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a PPN with --ppn or use --noppn", "", "red");
+    exit 1;
+}
+
+#########################################################>  bag-info.txt  <###############################################################################
+# sipversion
+if (!defined $sipVersion || $sipVersion eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --SIP_version, current tool supports <v2020.1>", "", "red");
+    exit 1;
+}
+if ($sipVersion ne "v2020.1") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: not valid --SIP_version, current tool supports <v2020.1>", "", "red");
+    exit 1;
+}
+utf8::decode($sipVersion);
+push @addBagInfo, {'SLUBArchiv-sipVersion' => $sipVersion};
+# externalWorkflow
+if (!defined $externalWorkflow || $externalWorkflow eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify external workflow", "", "red");
+    exit 1;
+}
+if ($externalWorkflow !~ m#^[a-z0-9_-]+$#) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --external_workflow (^[a-z0-9_-]+\$)", "", "red");
+    exit 1;
+}
+utf8::decode($externalWorkflow);
+push @addBagInfo, {'SLUBArchiv-externalWorkflow' => $externalWorkflow};
+# externalId
+if (!defined $externalId || $externalId eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify external ID", "", "red");
+    exit 1;
+}
+if ($externalId !~ m#^[a-z0-9_-]+$#) {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify a valid --external_id (^[a-z0-9_-]+\$)", "", "red");
+    exit 1;
+}
+utf8::decode($externalId);
+push @addBagInfo, {'SLUBArchiv-externalId' => $externalId};
+# externalIsilId
+if (defined $externalIsilId && $externalIsilId ne "") {
+    utf8::decode($externalIsilId);
+    push @addBagInfo, {'SLUBArchiv-externalIsilId' => $externalIsilId};
+}
+# exportToArchiveDate
+utf8::decode($exportToArchiveDate);
+push @addBagInfo, {'SLUBArchiv-exportToArchiveDate' => $exportToArchiveDate};
+# hasConservationReason
+if (!defined $hasConservationReason) {
+    $hasConservationReason = "false";
+} else {
+    $hasConservationReason = "true";
+}
+utf8::decode($hasConservationReason);
+push @addBagInfo, {'SLUBArchiv-hasConservationReason' => $hasConservationReason};
+# archivalValueDescription
+if (!defined $archivalValueDescription || $archivalValueDescription eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify an --external_value_descr (reason for archiving)", "", "red");
+    exit 1;
+}
+utf8::decode($archivalValueDescription);
+push @addBagInfo, {'SLUBArchiv-archivalValueDescription' => $archivalValueDescription};
+# rightsVersion
+if (!defined $rightsVersion || $rightsVersion eq "") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_version", "", "red");
+    exit 1;
+}
+if($rightsVersion ne "1.0") {
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: invalid --rights_version, supported version <1.0>", "", "red");
+    exit 1;
+}
+utf8::decode($rightsVersion);
+push @addBagInfo, {'SLUBArchiv-rightsVersion' => $rightsVersion};
+# addKeyValue
+if (@addKeyValue) {
+    foreach my $zeile(@addKeyValue) {
+        if($zeile !~ m#^.*:.*$#) { # : must be minimum once present
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", 'ERROR: wrong construct in --add_key_value="' . $zeile . '", expected --add_key_value="key:value", regexp to match is (^[^:]+:[^:]+$)', "", "red");
+            exit 1;
+        }
+        utf8::decode($zeile);
+        my @keyvalue = split(/:/, $zeile, 2);    # split on first :
+        my $key = $keyvalue[0];
+        my $value = $keyvalue[1];
+        if($key eq 'SLUBArchiv-sipVersion' ||
+            $key eq 'SLUBArchiv-externalWorkflow' ||
+            $key eq 'SLUBArchiv-externalId' ||
+            $key eq 'SLUBArchiv-externalIsilId' ||
+            $key eq 'SLUBArchiv-exportToArchiveDate' ||
+            $key eq 'SLUBArchiv-hasConservationReason' ||
+            $key eq 'SLUBArchiv-archivalValueDescription' ||
+            $key eq 'SLUBArchiv-rightsVersion'){
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: duplicate key $key present at --add_key_value. Notice: $key is reserved by SLUB Dresden.", "", "red");
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
+            exit 1;
+        }
+        if($key eq 'Bag-Count'){
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: $key present at --add_key_value. This key is not available due to SLUB spesification.", "", "red");
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
+            exit 1;
+        }
+        if($key eq 'Bag-Group-Identifier'){
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: $key present at --add_key_value. This key is not available due to SLUB spesification.", "", "red"); 
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "INFO: Read Docu for more information at https://slubarchiv.slub-dresden.de/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/", "", "white");
+            exit 1;
+        }
+        push @addBagInfo, {$key => $value};
+    }
+}
+##########################################################################################################################################################
+
+# rightsFilePath
+if (!defined $rightsFilePath || $rightsFilePath eq "") { 
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_xml file, which needs to be added", "", "red"); 
+    exit 1;
+}
+if (! -f $rightsFilePath) { 
+    SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: you need to specify --rights_xml file, status: is not a file", "", "red");
+    exit 1;
+}
+# addMetaFile
+if (@addMetaFile) {
+    foreach my $file(@addMetaFile) {
+        if(! -f $file) {
+            SLUB::LZA::SIPBuilderBagIt::print_scalar_data("", "ERROR: file $file at --add_meta_file, is not a file or could not be found", "", "red");
+            exit 1;
+        }
+    }
+}
+#===============================================================================
+
+sub main{
+    # validate xml according to schema
+    SLUB::LZA::SIPBuilderBagIt::validateRightsXML($rightsFilePath, "rights1.xsd");
+
+    # get bag name
+    my $bagNameDir = SLUB::LZA::SIPBuilderBagIt::generateBagName($exportToArchiveDate, $ppn, $noppn);
+
+    # save options
+    if($save eq "copy") {
+        my $bagPath = "$outputPath/$bagNameDir";
+        my $dataPath = "$bagPath/data";
+        my $metaPath = "$bagPath/meta";
+
+        SLUB::LZA::SIPBuilderBagIt::buildBagWithCopyOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
+    } elsif($save eq "move") {
+        my $bagPath = "$outputPath/$bagNameDir";
+        my $dataPath = "$bagPath/data";
+        my $metaPath = "$bagPath/meta";
+
+        SLUB::LZA::SIPBuilderBagIt::buildBagWithMoveOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
+    } elsif($save eq "replace") {
+        my $bagPath = path($ieDirectory)->parent->child($bagNameDir)->realpath->stringify;
+        my $dataPath = "$bagPath/data";
+        my $metaPath = "$bagPath/meta";
+
+        SLUB::LZA::SIPBuilderBagIt::buildBagWithReplaceOption($ppn, $noppn, $ieDirectory, $rightsFilePath, \@addMetaFile, \@addBagInfo, $bagPath, $dataPath, $metaPath);
+    }
+
+    return;
+}
+
+#===============================================================================
+
+main();
+1;
+#===============================================================================
+
+
+__END__
+
+=pod
+
+=head1 NAME
+
+preingest tool "SLUB SIP Builder BagIt" script to create Bags for SLUBArchive
+
+=head1 SYNOPSIS
+
+slubsipbuilderbagit.pl  [options]
+
+Options:
+        -help                           brief help message
+        -man                            full documentation
+
+        -save_option=<option>           payload files save as <copy>, <move>, <replace>, the <copy> option should be prefered
+        -IE_directory=<IE dir>          existing IE directory (absolute path!)
+        -SIP_output_path=<target dir>   where to put the SIP dir (absolute path!)
+        -ppn=<ppn>|-noppn=<noppn>       SWB-PPN or any identifier (uses minimalistic MODS)
+
+        -SIP_version=<version>          mandatory, needs for identification of SIP format, supported <v2020.1>
+        -external_workflow=<workflow>   mandatory, should be uniqe workflow name
+        -external_id=<id>               mandatory, should be uniqe ID (i.e. a catalog ID), reuse an ID only when updating existing AIP
+        -external_ISIL=<isil>           optional, ISIL number of library
+        -external_conservation_flag     optional, if set no other "original" still exists
+        -external_value_descr=<text>    mandatory, the reason why to archive
+        -rights_version=<version>       mandatory, SLUB law managment specification, supported <1.0>
+
+        -rights_xml=<file>              mandatory, path to SLUB rights xml file(absolute path!)
+        -add_meta_file=<file>           optional, can be repeated, additional meta files(absolute path!)
+        -add_key_value=<"key:value">    optional, can be repeated, additional key value pairs for bag-info.txt
+
+=head1 EXAMPLES
+
+=head2 Copy
+
+perl bin/slubsipbuilderbagit.pl
+     -save_option=copy
+     -IE_directory=./export_dir_kitodo/bagit/test2
+     -SIP_output_path=./output_sips
+     -ppn=457035137
+     -SIP_version=v2020.1
+     -external_id=10008
+     -external_workflow=kitodo
+     -external_ISIL=DE-14
+     -external_value_descr="Gesetzlicher Auftrag"
+     -rights_version=1.0
+     -rights_xml=export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
+     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
+     -add_key_value="Title:Krieg und Frieden"
+     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
+
+=head2 Replace
+
+NOT RECOMMENDED! IF FAILS, "IE" MUST BE MANUAL RESTORED TO THE PREVIOUS STATE!!!
+
+cp -a ./export_dir_kitodo/bagit/test2 ./ie_to_be_replaced
+
+perl bin/slubsipbuilderbagit.pl
+     -save_option=replace
+     -IE_directory=./ie_to_be_replaced
+     -ppn=457035137
+     -SIP_version=v2020.1
+     -external_id=10008
+     -external_workflow=kitodo
+     -external_ISIL=DE-14
+     -external_value_descr="Gesetzlicher Auftrag"
+     -rights_version=1.0
+     -rights_xml=./export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
+     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
+     -add_key_value="Title:Krieg und Frieden"
+     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
+
+=head2 Move
+
+NOT RECOMMENDED! IF FAILS, "IE" MUST BE MANUAL RESTORED TO THE PREVIOUS STATE!!!
+
+cp -a ./export_dir_kitodo/bagit/test2 ./ie_to_be_moved
+
+perl bin/slubsipbuilderbagit.pl
+     -save_option=move
+     -IE_directory=./ie_to_be_moved
+     --SIP_output_path=./output_sips
+     -ppn=457035137
+     -SIP_version=v2020.1
+     -external_id=10008
+     -external_workflow=kitodo
+     -external_ISIL=DE-14
+     -external_value_descr="Gesetzlicher Auftrag"
+     -rights_version=1.0
+     -rights_xml=./export_dir_kitodo/bagit/rights/Fallbeispiel-01.xml
+     -add_meta_file=./export_dir_kitodo/bagit/meta/lido.xml
+     -add_key_value="Title:Krieg und Frieden"
+     -add_key_value="Author:Lew Nikolajewitsch Tolstoi"
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-help>
+
+Print a brief help message and exits.
+
+=back
+
+=head1 DESCRIPTION
+
+B<This program> will process the given IE directory, add bibliographic metadata from catalogue with
+given PICA number and check and create a BagIt directory ready for SLUBarchiv
+
+=cut
-- 
GitLab