package WWW::Contact; use Class::MOP (); use Moose; use Moose::Util::TypeConstraints; our $VERSION = '0.15'; our $AUTHORITY = 'cpan:FAYLAND'; has 'errstr' => ( is => 'rw', isa => 'Maybe[Str]' ); has 'supplier_pattern' => ( is => 'rw', isa => 'ArrayRef', auto_deref => 1, default => sub { [] } ); has 'known_supplier' => ( is => 'rw', isa => 'HashRef', auto_deref => 1, default => sub { { 'gmail.com' => 'Gmail', 'ymail.com' => 'Yahoo', 'rocketmail.com' => 'Yahoo', 'rediffmail.com' => 'Rediffmail', 'aol.com' => 'AOL', 'indiatimes.com' => 'Indiatimes', 'lycos.com' => 'Lycos', # cn '163.com' => 'CN::163', 'yeah.net' => 'CN::163', 'netease.com' => 'CN::163', 'popo.163.com' => 'CN::163', # Mail 'mail.com' => 'Mail', 'email.com' => 'Mail', 'iname.com' => 'Mail', 'cheerful.com' => 'Mail', 'consultant.com' => 'Mail', 'europe.com' => 'Mail', 'mindless.com' => 'Mail', 'earthling.com' => 'Mail', 'myself.com' => 'Mail', 'techie.com' => 'Mail', 'usa.com' => 'Mail', 'writeme.com' => 'Mail', # hotmail 'hotmail.com' => 'Hotmail', 'live.com' => 'Hotmail', 'compaq.net' => 'Hotmail', 'hotmail.co.jp' => 'Hotmail', 'hotmail.co.uk' => 'Hotmail', 'hotmail.de' => 'Hotmail', 'hotmail.fr' => 'Hotmail', 'hotmail.it' => 'Hotmail', 'messengeruser.com' => 'Hotmail', 'msn.com' => 'Hotmail', 'passport.com' => 'Hotmail', 'webtv.net' => 'Hotmail', } } ); has 'social_network' => ( is => 'rw', isa => 'HashRef', auto_deref => 1, default => sub { { # Social networks. 'plaxo' => 'Plaxo', } } ); sub get_contacts { my $self = shift; my ( $email, $password, $social_network ) = @_; unless ( $email and $password ) { $self->errstr('Both email and password are required.'); return; } unless ( $email =~ m/^(.+)\@(([^.]+)\.(.+))$/ ) { $self->errstr('You must supply full email address.'); return; } my ( $username, $postfix ) = ( lc($1), lc($2) ); # get supplier module my $supplier; if($social_network) { $social_network = lc($social_network); $supplier = $self->get_supplier_by_socialnetwork($social_network); } else { $supplier = $self->get_supplier_by_email($email); } unless ($supplier) { if($social_network) { $self->errstr("$social_network is not supported yet."); } else { $self->errstr("$email is not supported yet."); } return; } my $module = 'WWW::Contact::' . $supplier; Class::MOP::load_class($module); my $wc = new $module; # reset $self->errstr(undef); my $contacts = $wc->get_contacts( $email, $password ); if ( $wc->errstr ) { $self->errstr( $wc->errstr ); return; } else { return wantarray ? @$contacts : $contacts; } } sub get_supplier_by_email { my ($self, $email) = @_; my %known_supplier = $self->known_supplier; my ($username, $domain) = split('@', $email); if ( exists $known_supplier{ $domain } ) { return $known_supplier{ $domain }; } # @yahoo.com @yahoo.XX @XX.yahoo.XX if ( $email =~ /[\@\.]yahoo\./ ) { return 'Yahoo'; } my @supplier_pattern = $self->supplier_pattern; foreach my $supplier (@supplier_pattern) { my $pattern = $supplier->{pattern}; my $mtype = ref($pattern); if ( $mtype eq 'Regexp' and $email =~ $pattern ) { return $supplier->{supplier}; } elsif ( $domain eq $pattern ) { return $supplier->{supplier}; } } return; } sub get_supplier_by_socialnetwork { my ($self, $social_network) = @_; my %social_supplier = $self->social_network; if ( exists $social_supplier{ $social_network } ) { return $social_supplier{ $social_network }; } return; } sub register_supplier { my ($self, $pattern, $supplier) = @_; unshift @{ $self->supplier_pattern }, { pattern => $pattern, supplier => $supplier }; } no Moose; no Moose::Util::TypeConstraints; __PACKAGE__->meta->make_immutable; 1; __END__ =head1 NAME WWW::Contact - Get contacts/addressbook from Web =head1 SYNOPSIS use WWW::Contact; # Get contacts from email providers. my $wc = WWW::Contact->new(); my @contacts = $wc->get_contacts('fayland@gmail.com', 'password'); my $errstr = $wc->errstr; if ($errstr) { die $errstr; # like 'Wrong Password' } else { print Dumper(\@contacts); } # Get contacts from social networks.(eg: Plaxo) my $ws = WWW::Contact->new(); # Note that the last argument for get_contacts() is mandatory, # or else it will try to fetch contacts from gmail.com my @contacts = $ws->get_contacts('itsa@gmail.com', 'password', 'plaxo'); my $errstr = $ws->errstr; if ($errstr) { die $errstr; # like 'Wrong Username or Password' } else { print Dumper(\@contacts); } =head1 DESCRIPTION Get Contacts/AddressBook from public websites. =head1 SUPPORTED EMAIL SUPPLIER =over 4 =item Gmail L<WWW::Contact::Gmail> By Fayland Lam =item Yahoo! Mail L<WWW::Contact::Yahoo> By Fayland Lam =item Rediffmail L<WWW::Contact::Rediffmail> By Sachin Sebastian =item mail.163.com L<WWW::Contact::CN::163> By Fayland Lam =item AOL L<WWW::Contact::AOL> By Fayland Lam =item Mail L<WWW::Contact::Mail> By Sachin Sebastian =item Hotmail/Live Mail L<WWW::Contact::Hotmail> By Fayland Lam =item Indiatimes L<WWW::Contact::Indiatimes> By Sachin Sebastian =item Lycos L<WWW::Contact::Lycos> By Sachin Sebastian =item Plaxo L<WWW::Contact::Plaxo> By Sachin Sebastian =back =head1 METHODS =head2 register_supplier To use custom supplier, we must register within WWW::Contact $wc->register_supplier( qr/\@a\.com$/, 'Unknown' ); $wc->register_supplier( 'a.com', 'Unknown' ); The first arg is a Regexp or domain from email postfix. The second arg is the according module postfix like 'Unknown' form WWW::Contact::Unknown =head2 get_supplier_by_email get supplier by email. my $supplier = $wc->get_supplier_by_email('a@gmail.com'); # 'Gmail' my $supplier = $wc->get_supplier_by_email('a@a.com'); # 'Unknown' =head2 get_supplier_by_socialnetwork get supplier by social network name. my $supplier = $wc->get_supplier_by_socialnetwork('plaxo'); # 'Plaxo' =head1 HOW TO WRITE YOUR OWN MODULE please read L<WWW::Contact::Base> and examples: L<WWW::Contact::Yahoo> and L<WWW::Contact::Plaxo> Assuming we write a custom module as WWW::Contact::Unknown package WWW::Contact::Unknown; use Moose; extends 'WWW::Contact::Base'; sub get_contacts { my ($self, $email, $password) = @_; # reset $self->errstr(undef); if ($email eq 'a@a.com' and $password ne 'a') { $self->errstr('Wrong Username or Password'); return; } my @contacts = ( { email => 'b@b.com', name => 'b', }, { email => 'c@c.com', name => 'c' } ); return wantarray ? @contacts : \@contacts; } 1; We can use it within WWW::Contact my $wc = new WWW::Contact; $wc->register_supplier( qr/\@a\.com$/, 'Unknown' ); # or # $wc->register_supplier( 'a.com', 'Unknown' ); my @contacts = $wc->get_contacts('a@a.com', 'b'); my $errstr = $wc->errstr; =head1 SEE ALSO L<WWW::Mechanize>, L<Moose> =head1 SUPPORTS =over 4 =item Code trunk L<http://code.google.com/p/perl-www-contact/> =item Group L<http://groups.google.com/group/perl-www-contact> =back =head1 AUTHOR Fayland Lam, C<< <fayland at gmail.com> >> Sachin Sebastian, C<< <sachinjsk at cpan.org> >> =head1 COPYRIGHT & LICENSE Copyright 2008 *AUTHOR* all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut