From f57a89e963382c8bf44150381058acb2cb603b79 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Thu, 9 Feb 2017 09:52:07 +0100 Subject: Initial commit. findcontact licensed under the MIT license. --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++ findcontact | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 README.md create mode 100755 findcontact diff --git a/README.md b/README.md new file mode 100644 index 0000000..f219c81 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# findcontact + +Find contacts (vcards) from a given .vcf file + +Hosted at https://git.faster-it.com/findcontact +Mirrored at https://github.com/fasterit/findcontact + +## About + +**findcontact** is a small perl script that enables searching with a set of regexes to find contacts within a (large) .vcf file. + +Obtaining a contacts.vcf depends on which CardDAV server / client you run. +With [radicale](http://radicale.org/) you can just copy the file off the server into the directory where your findcontact resides. Or copy / link findcontact into the correct radicale collections subdirectory. + +Unfortunately every .vcf client decides on a specific set of attributes to support and the [Inverse Sogo Connector](https://sogo.nu/download.html#/frontends) everybody uses for getting the Thunderbird address book synced can't search over all fields. So if you want to search for a phone number you're out of luck. Unless you run findcontact :). + +It has been written to only depend on perl modules that ship with a default installation and does __not__ depend on Text::vCard::Addressbook or the like. + +## License + +The script is licensed under the [MIT license](https://opensource.org/licenses/MIT). + +## Installation + +Clone this repository and **copy** or **symlink** `findcontact` to the directory where your `contacts.vcf` file resides. The name is hard-coded as that is what we use inside Faster IT GmbH and it's customary for collections of vcards. Obviously if your organizations does differently, change the $contacts_file line. + +This script requires perl and runs under Linux, MacOSX and Windows/cygwin. +It assumes Linux line endings in the `contacts.vcf` file (\n only). We never saw anything different but if you run MacOSX server ... you may have to adopt the script a bit. + +## Usage + +`findcontact` takes an arbitrary number of arguments which all all regexes. All of the arguments to give must match to have a vcard shown. All matches are case-insensitive. + +Thus you can easily iterate: + + $ findcontact pizza + $ findcontact pizza "m(ü|ue)nchen" + $ findcontact pizza "m(ü|ue)nchen" schwabing + +All fields are searched, so you can also search for phone numbers or parts of the comment field: + + $ findcontact "89.*4209" + +If you want to limit the fields printed, use grep: + + $ findcontact pizza | grep "^\(FN\|TEL\|$\|Found \)" + +Inside `findcontact` you'll find that the `VERSION`, `PRODID`, `PHOTO`, `UID` and `X-RADICALE-NAME` fields are removed form the output. If you need any of them or want to always remove further fields from output ... change the appropriate lines. + +## Support + +Commercial support is available from Faster IT GmbH. diff --git a/findcontact b/findcontact new file mode 100755 index 0000000..ec8d422 --- /dev/null +++ b/findcontact @@ -0,0 +1,80 @@ +#!/usr/bin/perl +# +# Find contacts searching within a .vcf file +# (c) 2017 Daniel Lange, Faster IT GmbH +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# DL170203 Initial version +# DL170209 Improve semicolon removals, open source under the MIT license +# + +use File::Basename; +use File::Spec; +use strict; +use warnings; + +my ($execname,$contacts_file) = fileparse($0); +$contacts_file = File::Spec->catfile(File::Spec->rel2abs($contacts_file), "contacts.vcf"); +my $delimiter = "END:VCARD\n"; +my $hit = 0; +my $match = 0; +my $numargs = $#ARGV + 1; + +if ($numargs == 0) { + print "Findcontact in vcf file (using $contacts_file).\n"; + print "Usage: $execname ...\n"; + exit 1; +} + +open(DAT,"$contacts_file") || die("Fatal: Cannot open $contacts_file file"); + my @file = ; +close(DAT); + +my $vcfs = join('',@file); +my @vcfs = split(/$delimiter/,$vcfs); + +foreach my $vcf (@vcfs) +{ + $match = 0; + foreach my $argv (@ARGV) { + if ($vcf =~ /$argv/i) { $match++; } + } + if ($match == $numargs) { + if ($hit > 0) { print "\n"; } + $_ = $vcf; + # clean cruft + $_ =~ s/BEGIN:VCARD\n//; + $_ =~ s/VERSION:.*?\n//; + $_ =~ s/PRODID:.*?\n//; + $_ =~ s/PHOTO[:;].*?\n//; + $_ =~ s/UID:.*?\n//; + $_ =~ s/X-RADICALE-NAME:.*?\n//; + $_ =~ s/;+/;/g; + $_ =~ s/;\n/\n/g; + $_ =~ s/:;/:/g; + print "$_"; + $hit++ + } +} + +if ($hit > 0) { print "\n"; } +print "Found $hit in " . scalar @vcfs . " records.\n"; + +exit; -- cgit v1.2.3