From 53c16708fe8e814eef5b8672085e257a253f994c Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Fri, 11 Aug 2023 20:15:36 +0200 Subject: [PATCH] Added script to recombine 2 dumps into a new one." --- bin/sync-combine-two-yaml-exports-into-one.pl | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 bin/sync-combine-two-yaml-exports-into-one.pl diff --git a/bin/sync-combine-two-yaml-exports-into-one.pl b/bin/sync-combine-two-yaml-exports-into-one.pl new file mode 100755 index 0000000..6f4051a --- /dev/null +++ b/bin/sync-combine-two-yaml-exports-into-one.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl +use warnings; +use strict; +no strict "refs"; + +use IO::All; +use Encode; +use YAML::XS qw(Load Dump); +use Data::Dumper; + +my ($yf1, $yf2) = @ARGV; + +# read both input files and parse yaml into data structure, fix +# non-printables +my $badutf81 < io $yf1; +my $yaml1 = decode( 'UTF-8', $badutf81 =~ s/[^\x00-\x7F]+//gr ); +my $y1 = Load $yaml1 or die "Could not load $yf1: $!"; + +my $badutf82 < io $yf2; +my $yaml2 = decode( 'UTF-8', $badutf82 =~ s/[^\x00-\x7F]+//gr ); +my $y2 = Load $yaml2 or die "Could not load $yf2: $!"; + +# convert to comparable hashes with unique keys +my $hash1 = &hashify($y1); +my $hash2 = &hashify($y2); + +# diff and recombine the two into a new one +my $combinedhash = &hash2note(&diff($hash1, $hash2)); + +# turn into yaml +my $combindedyaml = Dump($combinedhash); + +# perl uses scalars as hash keys (read: strings) so we need to unquote +# them here to make note happy +$combindedyaml =~ s/^'(\d+)':/$1:/gm; + + +print $combindedyaml; + + +sub hash2note { + # convert given hash into note format with number as key + my $hash = shift; + my $new; + my $i = 0; + + foreach my $path (sort keys %{$hash}) { + $new->{++$i} = $hash->{$path}; + } + + return $new; +} + +sub diff { + # diff the two hashes, create a new combined one + my($hash1, $hash2) = @_; + my $new; + + # iterate over hash1, store duplicates and remove them in hash2, + # store different entries and remove in both, + # store those missing in hash2 and delete them in hash1 + foreach my $path (sort keys %{$hash1}) { + if (exists $hash2->{$path}) { + if ($hash2->{$path}->{body} eq $hash1->{$path}->{body}) { + printf STDERR "%s => %s is duplicate\n", $path, $hash1->{$path}->{title}; + $new->{$path} = delete $hash2->{$path}; + delete $hash1->{$path}; + } + else { + printf STDERR "%s => %s is different\n", $path, $hash1->{$path}->{title}; + $new->{$path} = delete $hash1->{$path}; + $new->{$path . 2} = delete $hash2->{$path}; + } + } + else { + printf STDERR "%s => %s is missing in hash2\n", $path, $hash1->{$path}->{title}; + $new->{$path} = delete $hash1->{$path}; + } + } + + # store any lefovers of hash1 + foreach my $path (sort keys %{$hash1}) { + printf STDERR "%s => %s is left in hash1\n", $path, $hash1->{$path}->{title}; + $new->{$path} = $hash1->{$path}; + } + + # store any lefovers of hash2 + foreach my $path (sort keys %{$hash2}) { + printf STDERR "%s => %s is left in hash2\n", $path, $hash2->{$path}->{title}; + $new->{$path} = $hash2->{$path}; + } + + return $new +} + +sub hashify { + # create new hash with path+title as key instead of id's + my $data = shift; + my $new = {}; + + foreach my $id (keys %{$data} ) { + my $path = $data->{$id}->{path} . '|' . $data->{$id}->{title}; + if (exists $new->{$path}) { + die "$path already exists!\n"; + } + else { + $new->{$path} = $data->{$id}; + } + } + + return $new; +} +