feat: full anonymization of buspro xml dumps
This commit is contained in:
@@ -27,8 +27,8 @@ class BpnXmlAnonymizeCommand extends Command
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->addArgument('infile', InputArgument::REQUIRED, 'Path to the input XML file')
|
||||
->addArgument('outfile', InputArgument::OPTIONAL, 'Path to the output XML file (defaults to infile)')
|
||||
->addArgument('infile', InputArgument::REQUIRED, 'Path to the input XML file or folder')
|
||||
->addArgument('outfile', InputArgument::OPTIONAL, 'Path to the output XML file or folder (defaults to infile)')
|
||||
;
|
||||
}
|
||||
|
||||
@@ -39,19 +39,31 @@ class BpnXmlAnonymizeCommand extends Command
|
||||
$inputFile = (string) $input->getArgument('infile');
|
||||
$outputFile = $input->getArgument('outfile');
|
||||
|
||||
if (true === is_dir($inputFile)) {
|
||||
$targetDirectory = null === $outputFile ? $inputFile : (string) $outputFile;
|
||||
|
||||
return $this->anonymizeDirectory($io, $inputFile, $targetDirectory);
|
||||
}
|
||||
|
||||
if (false === is_file($inputFile)) {
|
||||
$io->error(sprintf('Input file not found: %s', $inputFile));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$targetFile = null === $outputFile ? $inputFile : (string) $outputFile;
|
||||
|
||||
return $this->anonymizeSingleFile($io, $inputFile, $targetFile);
|
||||
}
|
||||
|
||||
private function anonymizeSingleFile(SymfonyStyle $io, string $inputFile, string $targetFile): int
|
||||
{
|
||||
if (false === is_readable($inputFile)) {
|
||||
$io->error(sprintf('Input file is not readable: %s', $inputFile));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$targetFile = null === $outputFile ? $inputFile : (string) $outputFile;
|
||||
$this->xmlAnonymizer->resetState();
|
||||
|
||||
$processingResult = $this->anonymizeFile($io, $inputFile, $targetFile, false);
|
||||
@@ -85,12 +97,120 @@ class BpnXmlAnonymizeCommand extends Command
|
||||
$io->note(sprintf('Paired file anonymized: %s -> %s', $pairedInputFile, $pairedTargetFile));
|
||||
}
|
||||
|
||||
$io->success(sprintf(
|
||||
'Anonymized %d persons from %s to %s',
|
||||
$this->xmlAnonymizer->getLastIdentityCount(),
|
||||
$inputFile,
|
||||
$targetFile,
|
||||
));
|
||||
$identityCount = $this->xmlAnonymizer->getLastIdentityCount();
|
||||
if (0 === $identityCount) {
|
||||
$io->warning(sprintf('No anonymizable person data found in %s', $inputFile));
|
||||
} else {
|
||||
$io->success(sprintf(
|
||||
'Anonymized %d persons from %s to %s',
|
||||
$identityCount,
|
||||
$inputFile,
|
||||
$targetFile,
|
||||
));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function anonymizeDirectory(SymfonyStyle $io, string $inputDirectory, string $targetDirectory): int
|
||||
{
|
||||
if (false === is_readable($inputDirectory)) {
|
||||
$io->error(sprintf('Input directory is not readable: %s', $inputDirectory));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
if (true === file_exists($targetDirectory) && false === is_dir($targetDirectory)) {
|
||||
$io->error(sprintf('Output path is not a directory: %s', $targetDirectory));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
if (false === file_exists($targetDirectory) && false === mkdir($targetDirectory, 0777, true) && false === is_dir($targetDirectory)) {
|
||||
$io->error(sprintf('Unable to create output directory: %s', $targetDirectory));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$entries = scandir($inputDirectory);
|
||||
if (false === $entries) {
|
||||
$io->error(sprintf('Unable to list input directory: %s', $inputDirectory));
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$processed = [];
|
||||
$fileCount = 0;
|
||||
$personCount = 0;
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ('.' === $entry || '..' === $entry) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$inputPath = $inputDirectory.DIRECTORY_SEPARATOR.$entry;
|
||||
if (false === is_file($inputPath) || false === str_ends_with($entry, '.xml')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (true === isset($processed[$inputPath])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pairedInputPath = $this->derivePairedFilename($inputPath);
|
||||
if (null !== $pairedInputPath && true === is_file($pairedInputPath) && false === isset($processed[$pairedInputPath])) {
|
||||
$this->xmlAnonymizer->resetState();
|
||||
|
||||
$targetPath = $targetDirectory.DIRECTORY_SEPARATOR.$entry;
|
||||
$result = $this->anonymizeFile($io, $inputPath, $targetPath, false);
|
||||
if (Command::SUCCESS !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$processed[$inputPath] = true;
|
||||
++$fileCount;
|
||||
|
||||
$pairedEntry = basename($pairedInputPath);
|
||||
$pairedTargetPath = $targetDirectory.DIRECTORY_SEPARATOR.$pairedEntry;
|
||||
$result = $this->anonymizeFile($io, $pairedInputPath, $pairedTargetPath, true);
|
||||
if (Command::SUCCESS !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$processed[$pairedInputPath] = true;
|
||||
++$fileCount;
|
||||
$personCount += $this->xmlAnonymizer->getLastIdentityCount();
|
||||
|
||||
$io->note(sprintf('Paired file anonymized: %s -> %s', $pairedInputPath, $pairedTargetPath));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->xmlAnonymizer->resetState();
|
||||
|
||||
$targetPath = $targetDirectory.DIRECTORY_SEPARATOR.$entry;
|
||||
$result = $this->anonymizeFile($io, $inputPath, $targetPath, false);
|
||||
if (Command::SUCCESS !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$processed[$inputPath] = true;
|
||||
++$fileCount;
|
||||
$personCount += $this->xmlAnonymizer->getLastIdentityCount();
|
||||
}
|
||||
|
||||
$io->text(sprintf('Processed %d XML files', $fileCount));
|
||||
|
||||
if (0 === $personCount) {
|
||||
$io->warning(sprintf('No anonymizable person data found in %s', $inputDirectory));
|
||||
} else {
|
||||
$io->success(sprintf(
|
||||
'Anonymized %d persons from %s to %s',
|
||||
$personCount,
|
||||
$inputDirectory,
|
||||
$targetDirectory,
|
||||
));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user