From 653cfffc0e00dfb59b36813c1b45c53d3f773c65 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Tue, 21 Oct 2003 18:49:34 +0000 Subject: Merge new-ui-branch to the trunk. svn path=/trunk/; revision=22965 --- addressbook/tools/Makefile.am | 25 ++- addressbook/tools/csv2vcard | 236 +++++++++++++++++++++++ addressbook/tools/evolution-addressbook-abuse.c | 127 ++++++++++++ addressbook/tools/evolution-addressbook-clean.in | 24 +++ addressbook/tools/evolution-addressbook-import.c | 90 +++++++++ 5 files changed, 498 insertions(+), 4 deletions(-) create mode 100755 addressbook/tools/csv2vcard create mode 100644 addressbook/tools/evolution-addressbook-abuse.c create mode 100644 addressbook/tools/evolution-addressbook-clean.in create mode 100644 addressbook/tools/evolution-addressbook-import.c (limited to 'addressbook/tools') diff --git a/addressbook/tools/Makefile.am b/addressbook/tools/Makefile.am index 79a1c746ad..c9e082603e 100644 --- a/addressbook/tools/Makefile.am +++ b/addressbook/tools/Makefile.am @@ -1,6 +1,12 @@ +privlibexec_SCRIPTS = \ + csv2vcard \ + evolution-addressbook-clean + bin_PROGRAMS = \ evolution-addressbook-export +noinst_PROGRAMS= evolution-addressbook-abuse + INCLUDES = \ -DG_LOG_DOMAIN=\"evolution-addressbook-tools\" \ -I$(top_srcdir) \ @@ -23,11 +29,22 @@ evolution_addressbook_export_SOURCES = \ evolution-addressbook-export.h evolution_addressbook_export_LDADD = \ - $(GNOME_FULL_LIBS) \ $(top_builddir)/addressbook/backend/ebook/libebook.la \ - $(top_builddir)/widgets/menus/libmenus.la \ - $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/libversit/libversit.la \ $(top_builddir)/e-util/ename/libename.la \ $(top_builddir)/e-util/libeutil.la +evolution_addressbook_abuse_LDADD = \ + $(top_builddir)/addressbook/backend/ebook/libebook.la \ + $(top_builddir)/e-util/ename/libename.la \ + $(top_builddir)/e-util/libeutil.la + +EXTRA_DIST = $(privlibexec_SCRIPTS) \ + evolution-addressbook-clean.in + +CLEANFILES= evolution-addressbook-clean + +evolution-addressbook-clean: evolution-addressbook-clean.in Makefile +## Use sed and then mv to avoid problems if the user interrupts. + sed -e 's?\@EVOLUTION_TOOLSDIR\@?$(privlibexecdir)?g' \ + < $(srcdir)/evolution-addressbook-clean.in > evolution-addressbook-clean.tmp \ + && mv evolution-addressbook-clean.tmp evolution-addressbook-clean diff --git a/addressbook/tools/csv2vcard b/addressbook/tools/csv2vcard new file mode 100755 index 0000000000..b968fbd9c3 --- /dev/null +++ b/addressbook/tools/csv2vcard @@ -0,0 +1,236 @@ +#!/usr/bin/perl -w +# +# cvs2vcard - Script to convert Outlook CSV files into VCard files +# suitable to be imported into Evolution. +# +# Copyright (C) 2001 Ximian, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# 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, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# Author: Michael MacDonald +# + +use strict; +use diagnostics; +use Text::ParseWords; + +sub usage +{ + print STDERR << "--EndOfUsage"; + +Takes a CSV-formatted list of contacts from Outlook and attempts to +convert it into a list of VCards suitable for import into Evolution. + +Usage: $0 [infile outfile] + +--EndOfUsage + + exit; +} + +sub is_recognized_format +{ + my $line = shift; + + # Making some assumptions here... Prolly OK. + return $line =~ /(First Name|Middle Name|Last Name)/; +} + +sub map_columns +{ + my $line = shift; + + my @names = parse_line(',', 0, $line); + + my $ctr = 0; + my %fieldmap = map { $_ => $ctr++ } @names; + + return %fieldmap; +} + +sub build_vcard_attr_from_def +{ + my ($def, $fields, $map) = @_; + + # Valid chars for lookup (from Outlook CSV) are + # A-Za-z0-9_-'/ + # Valid chars for formatting of attr are + # \s,| + my @lookup = map { s/=0A$//; s/[^\w\s\-'\/]//; $_; } split /[\s,]*\|[\s,]*/, $def; + + foreach my $el (@lookup) { + unless (defined($map->{ $el })) { + print STDERR "$el is undefined\n"; + next; + } + if (defined($fields->[$map->{ $el }])) { + unless ($fields->[$map->{ $el }] =~ /(^$|0\/0\/00)/) { + $def =~ s/$el/$fields->[$map->{ $el }]/; + } else { + $def =~ s/((?<=\|)\s*)?$el(\s*?(?=\|))?(=0A)?,?//; + } + } else { + $def =~ s/((?<=\|)\s*)?$el(\s*?(?=\|))?(=0A)?,?//; + } + } + # Get rid of field delimiters + $def =~ s/\|//g; + # Snip off any trailing semicolons or whitespace + $def =~ s/[\s;]*$//; + + return $def; +} + +sub build_vcard_from_line { + my ($line, %map) = @_; + my %vcard; + + my @fields = parse_line(',', 0, $line); + + my %vcard_def = ( FN => 'Title |First Name |Middle Name |Last Name |Suffix', + N => 'Last Name| Suffix|;First Name|;Middle Name|;Title', + 'ADR;WORK' => 'PO Box|;Business Street 2|;Business Street|;Business City|;Business State|;Business Postal Code|;Business Country', + 'LABEL;QUOTED-PRINTABLE;WORK' => 'PO Box |Business Street=0A|Business Street 2=0A|Business City,| Business State| Business Postal Code=0A|Business Country', + 'TEL;WORK;VOICE' => 'Business Phone', + 'TEL;WORK;VOICE2' => 'Business Phone 2', + 'TEL;WORK;FAX' => 'Business Fax', + 'TEL;WORK;COMPANY' => 'Company Main Phone', + 'ADR;HOME' => ';Home Street 2|;Home Street|;Home City|;Home State|;Home Postal Code|;Home Country', + 'LABEL;QUOTED-PRINTABLE;HOME' => 'Home Street=0A|Home Street 2=0A|Home City,| Home State| Home Postal Code=0A|Home Country', + 'TEL;HOME;VOICE' => 'Home Phone', + 'TEL;HOME;VOICE2' => 'Home Phone 2', + 'TEL;HOME;FAX' => 'Home Fax', + 'ADR;POSTAL' => ';Other Street 2|;Other Street|;Other City|;Other State|;Other Postal Code|;Other Country', + 'LABEL;QUOTED-PRINTABLE;POSTAL' => 'Other Street=0A|Other Street 2=0A|Other City,| Other State| Other Postal Code=0A|Other Country', + 'TEL;VOICE' => 'Other Phone', + 'TEL;FAX' => 'Other Fax', + 'TEL;CELL' => 'Mobile Phone', + 'TEL;CAR' => 'Car Phone', + 'TEL;PAGER' => 'Pager', + 'TEL;PREF' => 'Primary Phone', + 'TEL;ISDN' => 'ISDN', + 'TEL;X-EVOLUTION-CALLBACK' => 'Callback', + 'TEL;X-EVOLUTION-TTYTDD' => 'TTY/TDD Phone', + 'TEL;X-EVOLUTION-TELEX' => 'Telex', + 'TEL;X-EVOLUTION-RADIO' => 'Radio Phone', + 'EMAIL;INTERNET' => 'E-mail Address', + 'EMAIL;INTERNET2' => 'E-mail 2 Address', + 'EMAIL;INTERNET3' => 'E-mail 3 Address', + ORG => 'Company|;Department', + TITLE => 'Job Title', + ROLE => 'Profession', + 'X-EVOLUTION-ASSISTANT' => "Assistant's Name", + 'TEL;X-EVOLUTION-ASSISTANT' => "Assistant's Phone", + 'X-EVOLUTION-SPOUSE' => 'Spouse', + 'X-EVOLUTION-ANNIVERSARY' => 'Anniversary', + 'X-EVOLUTION-MANAGER' => "Manager's Name", + 'X-EVOLUTION-OFFICE' => 'Office Location', + BDAY => 'Birthday', + NOTE => 'Notes', + FBURL => 'Internet Free Busy', + URL => 'Web Page', + ); + + foreach my $key (keys(%vcard_def)) { + my $attr = build_vcard_attr_from_def($vcard_def{ $key }, \@fields, \%map); + if (defined($attr)) { + $vcard{ $key } = $attr unless ($attr =~ /^$/); + } + } + + return %vcard; +} + +sub print_vcard_to_fh +{ + my ($fh, %vcard) = @_; + + print $fh "BEGIN:VCARD\n"; + foreach my $key (keys(%vcard)) { + # Dirty hack because Evolution's vcard stores multiple email addrs + # with same sttribute, hence key collision. Bleah. + # Ugh! Same deal for multiple phones... (eg. bus. phone) + # + # And finally, while we're special-casing... Outlook exports dates + # differently, so munge 'em if we find 'em. + if ($key =~ /EMAIL;INTERNET/o) { + (my $temp = $key) =~ s/\d$//; + print $fh "$temp:$vcard{ $key }\n"; + } elsif ($key =~ /TEL;(HOME|WORK)/o) { + (my $temp = $key) =~ s/\d$//; + print $fh "$temp:$vcard{ $key }\n"; + } elsif ($key =~ /(BDAY|X\-EVOLUTION\-ANNIVERSARY)/o) { + my $temp = $vcard{ $key }; + if ($temp =~ /(\d\d)\/(\d\d)\/(\d\d)/) { + # Y2k !! MS Didn't learn anything. + # Hope no one was born before 1915 + if ((1900 + $3) < 1915) { + print $fh "$key:20$3-$1-$2\n"; + } else { + print $fh "$key:19$3-$1-$2\n"; + } + } else { + # Something's funky... Just delete the attribute + print STDERR "Couldn't figure out what to do with $key:$vcard{ $key }\n"; + delete($vcard{ $key }); + } + } else { + print $fh "$key:$vcard{ $key }\n"; + } + } + print $fh "END:VCARD\n\n"; +} + +my $in = $ARGV[0]; +my $out = $ARGV[1]; + +usage() unless(defined($in) && defined($out)); + +open (IN, $in) + or die "Can't open($in): $!\n"; + +open (OUT, ">$out") + or die "Can't open($out): $!\n"; + +my $linectr = 0; +my %map; + +while (my $line = ) { + $line =~ s/\r//g; + $line =~ s/\n$//; + if ($linectr == 0) { + $linectr++; + usage() unless is_recognized_format($line); + %map = map_columns($line); + #if ($line =~ /\r\n$/) { + # print STDERR "Apparenlty found DOS-style EOL indicators...\n"; + $/ = "\r\n"; + #} + } else { + $linectr++; + while ($line =~ /^(("([^"]|\n|"")*")?,)*"([^"]|\n|"")*$/) { + my $temp = $line; + $line = ; + $line =~ s/\r//g; + $line =~ s/\n$//; + $line = "$temp $line"; + } + my %vcard = build_vcard_from_line($line, %map); + print_vcard_to_fh(\*OUT, %vcard); + } +} + +close(IN); +close(OUT); diff --git a/addressbook/tools/evolution-addressbook-abuse.c b/addressbook/tools/evolution-addressbook-abuse.c new file mode 100644 index 0000000000..7801ed7e9d --- /dev/null +++ b/addressbook/tools/evolution-addressbook-abuse.c @@ -0,0 +1,127 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +#include + +#include +#include + +#include +#include + +static int contacts_to_add_total = 1000; +static int contacts_to_add = 50; +static int call_count = 0; + +static gchar * +make_random_string (void) +{ + const gchar *elements = " abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + gint len = strlen (elements); + gint i, N = 5 + (random () % 10); + gchar *str = g_malloc (N+1); + + for (i = 0; i < N; ++i) { + str[i] = elements[random () % len]; + } + str[i] = '\0'; + + return str; +} + +static gchar * +make_random_vcard (void) +{ + gchar *fa = make_random_string (); + gchar *name = make_random_string (); + gchar *email = make_random_string (); + gchar *org = make_random_string (); + + gchar *vcard; + + vcard = g_strdup_printf ("BEGIN:VCARD\n" + "X-EVOLUTION-FILE-AS:%s\n" + "N:%s\n" + "EMAIL;INTERNET:%s\n" + "ORG:%s\n" + "END:VCARD", + fa, name, email, org); + g_free (fa); + g_free (name); + g_free (email); + g_free (org); + + return vcard; +} + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + +static void +add_cb (EBook *book, EBookStatus status, const char *id, gpointer closure) +{ + switch (status) { + case E_BOOK_ERROR_OK: + --contacts_to_add_total; + g_message ("succesful add! (%d remaining)", contacts_to_add_total); + if (contacts_to_add_total <= 0) + g_main_loop_quit (NULL); + break; + default: + g_message ("something went wrong..."); + g_main_loop_quit (NULL); + break; + } +} + +static void +use_addressbook (EBook *book, EBookStatus status, gpointer closure) +{ + gint i; + + if (book == NULL || status != E_BOOK_ERROR_OK) + g_error (_("Error loading default addressbook.")); + + for (i = 0; i < contacts_to_add; ++i) { + gchar *vcard = make_random_vcard (); + EContact *contact = e_contact_new_from_vcard (vcard); + g_message ("adding %d", i); + e_book_async_add_contact (book, contact, add_cb, NULL); + g_free (vcard); + g_object_unref (contact); + } + + g_object_unref (book); +} + +static gint +abuse_timeout (gpointer foo) +{ + e_book_async_get_default_addressbook (use_addressbook, NULL); + + ++call_count; + g_message ("timeout!"); + return call_count < contacts_to_add_total / contacts_to_add; +} + +int +main (int argc, char *argv[]) +{ + if (getenv ("ABUSE_THE_WOMBAT") == NULL) { + g_print ("You probably don't want to use this program.\n" + "It isn't very nice.\n"); + exit(0); + } + + bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); + textdomain (GETTEXT_PACKAGE); + + gnome_program_init ("evolution-addressbook-abuse", VERSION, + LIBGNOMEUI_MODULE, argc, argv, + GNOME_PROGRAM_STANDARD_PROPERTIES, + NULL); + + g_timeout_add (20, abuse_timeout, NULL); + + bonobo_main (); + + return 0; +} diff --git a/addressbook/tools/evolution-addressbook-clean.in b/addressbook/tools/evolution-addressbook-clean.in new file mode 100644 index 0000000000..b7ee7ba167 --- /dev/null +++ b/addressbook/tools/evolution-addressbook-clean.in @@ -0,0 +1,24 @@ +#! /usr/bin/perl -w + +sub do_system +{ + my ($command) = @_; + system ($command); + if ($? != 0) { + die "Command failed: $command"; + } +} + +$filename = `@EVOLUTION_TOOLSDIR@/evolution-addressbook-export`; +if ($? != 0) { + $! = $?; + die $!; +} + +$HOME = $ENV{"HOME"}; + +system ("@EVOLUTION_TOOLSDIR@/killev"); +do_system ("/bin/mv ${HOME}/evolution/local/Contacts/addressbook.db ${HOME}/evolution/local/Contacts/addressbook-backup.db"); +do_system ("@EVOLUTION_TOOLSDIR@/evolution-addressbook-import --input-file $filename"); +do_system ("/bin/rm $filename"); + diff --git a/addressbook/tools/evolution-addressbook-import.c b/addressbook/tools/evolution-addressbook-import.c new file mode 100644 index 0000000000..28871efd96 --- /dev/null +++ b/addressbook/tools/evolution-addressbook-import.c @@ -0,0 +1,90 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +#include + +#include +#include +#include +#include + +static int exec_ref_count = 0; + +static void +ref_executable (void) +{ + exec_ref_count ++; +} + +static void +unref_executable (void) +{ + exec_ref_count --; + if (exec_ref_count == 0) + g_main_loop_quit (0); +} + +static void +add_cb (EBook *book, EBookStatus status, const char *id, gpointer closure) +{ + switch (status) { + case E_BOOK_ERROR_OK: + unref_executable (); + break; + default: + g_main_loop_quit (NULL); + break; + } +} + +static void +use_addressbook (EBook *book, gpointer closure) +{ + GList *cards, *list; + char *filename = closure; + + if (book == NULL) + g_error (_("Error loading default addressbook.")); + + cards = e_card_load_cards_from_file (filename); + + ref_executable (); + + for (list = cards; list; list = list->next) { + ref_executable (); + e_book_add_card (book, list->data, add_cb, closure); + } + sync(); + + unref_executable (); +} + +int +main (int argc, char *argv[]) +{ + char *filename = NULL; + + struct poptOption options[] = { + { "input-file", '\0', POPT_ARG_STRING, &filename, 0, N_("Input File"), NULL }, + POPT_AUTOHELP + { NULL, '\0', 0, NULL, 0, NULL, NULL } + }; + + bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); + textdomain (GETTEXT_PACKAGE); + + gnome_program_init ("evolution-addressbook-import", VERSION, + LIBGNOMEUI_MODULE, argc, argv, + GNOME_PROGRAM_STANDARD_PROPERTIES, + GNOME_PARAM_POPT_TABLE, options, + NULL); + + if (filename == NULL) { + g_error (_("No filename provided.")); + } + + e_book_async_get_default_addressbook (use_addressbook, filename); + + bonobo_main (); + + return 0; +} -- cgit v1.2.3