normalize_vcard can now also compare two files automatically; it's also installed without .pl suffix

git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@43 15ad00c4-1369-45f4-8270-35d70d36bdcd
This commit is contained in:
Patrick Ohly 2006-03-15 22:09:04 +00:00
parent 92004b5f6d
commit d81eb58d44
4 changed files with 93 additions and 24 deletions

9
README
View File

@ -208,11 +208,16 @@ address book. Now one can either compare the address books in
Evolution or do that automatically:
- save the complete address books: mark all entries, save as vCard
- normalize the files with the provided Perl script:
normalize_vcard.pl list1.vcf >list1.normal.vcf
normalize_vcard.pl list2.vcf >list2.normal.vcf
normalize_vcard list1.vcf >list1.normal.vcf
normalize_vcard list2.vcf >list2.normal.vcf
- compare the normalized lists, e.g.:
diff -c list1.normal.vcf list2.normal.vcf
Alternatively, one can invoke normalize_vcard with two file names
as arguments and it will normalize and compare them automatically
with diff in the side-by-side mode:
normalize_vcard list1.vcf list2.vcf
Normalizing is necessary because the order of cards and their
properties as well as other minor formatting aspects may be
different. The automatic unit testing (see HACKING) also contains

View File

@ -10,3 +10,4 @@ test*.vcf
synclog.txt
client-api
client-api.build
normalize_vcard

View File

@ -4,10 +4,13 @@ INCLUDES = @EPACKAGE_CFLAGS@ @SYNC4J_CFLAGS@
AM_CFLAGS = -Wall -Werror -Wno-return-type
bin_PROGRAMS = syncevolution
bin_SCRIPTS = normalize_vcard.pl
bin_SCRIPTS = normalize_vcard
EXTRA_DIST = normalize_vcard.pl
normalize_vcard : normalize_vcard.pl
cp $< $@
chmod u+x $@
CORE_SOURCES = \
EvolutionContactSource.h \
EvolutionSmartPtr.h \

View File

@ -2,25 +2,85 @@
use strict;
$_ = join( "", grep( !/^(BEGIN:VCARD|VERSION|END:VCARD|UID:)/, <> ) );
s/\r//g;
my @cards = ();
foreach $_ ( split( /\n\n/ ) ) {
# undo line continuation
s/\n\s//gs;
# ignore charset specifications, assume UTF-8
s/;CHARSET="UTF-8"//g;
# ignore extra email type
s/EMAIL;TYPE=INTERNET/EMAIL/g;
# ignore extra ADR type
s/ADR;TYPE=OTHER/ADR/g;
# the type of certain fields is ignore by Evolution
s/X-(AIM|GROUPWISE|ICQ|YAHOO);TYPE=HOME/X-$1/g;
# sort entries, putting "N:" first
my @lines = split( "\n" );
push @cards, join( "\n", grep( /^N:/, @lines ), sort( grep ( !/^N:/, @lines ) ) );
sub Usage {
print "normalize_vcard <vcards.vcf\n";
print " vcards1.vcf vcards2.vcf\n\n";
print "Either normalizes one file (stdin or single argument)\n";
print "or compares the two files.\n";
}
print join( "\n\n", sort @cards ), "\n";
sub Normalize {
my $in = shift;
my $out = shift;
$_ = join( "", grep( !/^(BEGIN:VCARD|VERSION|END:VCARD|UID:)/, <$in> ) );
s/\r//g;
my @cards = ();
foreach $_ ( split( /\n\n/ ) ) {
# undo line continuation
s/\n\s//gs;
# ignore charset specifications, assume UTF-8
s/;CHARSET="UTF-8"//g;
# ignore extra email type
s/EMAIL;TYPE=INTERNET/EMAIL/g;
# ignore extra ADR type
s/ADR;TYPE=OTHER/ADR/g;
# the type of certain fields is ignore by Evolution
s/X-(AIM|GROUPWISE|ICQ|YAHOO);TYPE=HOME/X-$1/g;
# TYPE=VOICE is the default in Evolution and may or may not appear in the vcard
s/^TEL([^:]*);TYPE=VOICE([^:]*):/TEL$1$2:/mg;
# replace parameters with a sorted parameter list
s!^([^;:]*);(.*?):!$1 . ";" . join(';',sort(split(/;/, $2))) . ":"!meg;
# sort entries, putting "N:" first
my @lines = split( "\n" );
push @cards, join( "\n", grep( /^N:/, @lines ), sort( grep ( !/^N:/, @lines ) ) );
}
print $out join( "\n\n", sort @cards ), "\n";
}
if($#ARGV > 1) {
# error
Usage();
exit 1;
} elsif($#ARGV == 1) {
# comparison
my ($file1, $file2) = ($ARGV[0], $ARGV[1]);
my $normal1 = `mktemp`;
my $normal2 = `mktemp`;
chomp($normal1);
chomp($normal2);
open(IN1, "<$file1") || die "$file1: $!";
open(IN2, "<$file2") || die "$file2: $!";
open(OUT1, ">$normal1") || die "$normal1: $!";
open(OUT2, ">$normal2") || die "$normal2: $!";
Normalize(*IN1{IO}, *OUT1{IO});
Normalize(*IN2{IO}, *OUT2{IO});
close(IN1);
close(IN2);
close(OUT1);
close(OUT2);
my $res = system( "diff", "--suppress-common-lines", "-y", $normal1, $normal2 );
unlink($normal1);
unlink($normal2);
exit($res ? 1 : 0);
} else {
# normalize
my $in;
if( $#ARGV >= 0 ) {
open(IN, "<$ARGV[0]") || die "$ARGV[0]: $!";
$in = *IN{IO};
} else {
$in = *STDIN{IO};
}
Normalize($in, *STDOUT{IO});
}