File Coverage

blib/lib/Data/Random/Contact.pm
Criterion Covered Total %
statement 5 7 71.4
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 8 10 80.0


line stmt bran cond sub pod time code
1             package Data::Random::Contact;
2             BEGIN {
3 1     1   53858 $Data::Random::Contact::VERSION = '0.05';
4             }
5              
6 1     1   883 use namespace::autoclean;
  1         25730  
  1         6  
7              
8 1     1   513 use Moose;
  0            
  0            
9              
10             use Class::Load qw( load_class );
11             use Data::Random::Contact::Language::EN;
12             use Data::Random::Contact::Country::US;
13             use Data::Random::Contact::Types qw( Country Language );
14             use DateTime;
15             use Scalar::Util qw( blessed );
16              
17             has language => (
18             is => 'ro',
19             isa => Language,
20             default => 'Data::Random::Contact::Language::EN',
21             );
22              
23             has country => (
24             is => 'ro',
25             isa => Country,
26             default => 'Data::Random::Contact::Country::US',
27             );
28              
29             override BUILDARGS => sub {
30             my $class = shift;
31             my $p = super();
32              
33             if ( $p->{language} && !blessed $p->{language} ) {
34             my $language
35             = $p->{language} =~ /^Data::Random::Contact::Language::/
36             ? $p->{language}
37             : 'Data::Random::Contact::Language::' . $p->{language};
38              
39             load_class($language);
40              
41             $p->{language} = $language;
42             }
43              
44             if ( $p->{country} && !blessed $p->{country} ) {
45             my $country
46             = $p->{country}
47             && $p->{country} =~ /^Data::Random::Contact::Country::/
48             ? $p->{country}
49             : 'Data::Random::Contact::Country::' . $p->{country};
50              
51             load_class($country);
52              
53             $p->{country} = $country;
54             }
55             return $p;
56             };
57              
58             my $MaxBirthdate = DateTime->today()->subtract( years => 15 );
59             my $MinBirthdate = DateTime->today()->subtract( years => 100 );
60             my $Days = $MaxBirthdate->delta_days($MinBirthdate)->in_units('days') - 1;
61              
62             my $Suffix = 0;
63              
64             sub person {
65             my $self = shift;
66              
67             my %contact;
68              
69             $contact{gender} = _percent() <= 50 ? 'male' : 'female';
70              
71             my $salutation_meth = $contact{gender} . '_salutation';
72              
73             $contact{salutation} = $self->language()->$salutation_meth();
74              
75             my $name_meth = $contact{gender} . '_given_name';
76              
77             $contact{given} = $self->language()->$name_meth();
78              
79             my $middle_name_meth = $contact{gender} . '_middle_name';
80              
81             $contact{middle} = $self->language()->$middle_name_meth();
82              
83             $contact{surname} = $self->language()->surname();
84              
85             my $suffix_meth = $contact{gender} . '_suffix';
86              
87             $contact{suffix} = $self->language()->$suffix_meth();
88              
89             $contact{birth_date}
90             = $MinBirthdate->clone()->add( days => int( rand($Days) ) );
91              
92             for my $type (qw( mobile home work )) {
93             $contact{phone}{$type} = $self->country()->phone_number();
94             }
95              
96             for my $type (qw( home work )) {
97             $contact{address}{$type} = $self->country()->address();
98             }
99              
100             $contact{email}{home}
101             = join '.',
102             map {lc} grep {defined} @contact{ 'given', 'middle', 'surname' };
103             $contact{email}{home} .= '@' . $self->_domain();
104              
105             $contact{email}{work} = lc $contact{given} . $Suffix++;
106             $contact{email}{work} .= '@' . $self->_domain();
107              
108             return \%contact;
109             }
110              
111             sub household {
112             my $self = shift;
113              
114             my %contact;
115              
116             $contact{name} = $self->language()->household_name();
117              
118             $contact{phone}{home} = $self->country()->phone_number();
119              
120             $contact{address}{home} = $self->country()->address();
121              
122             ( $contact{email}{home} = $contact{name} ) =~ s/\W/./g;
123             $contact{email}{home} .= '@' . $self->_domain();
124              
125             return \%contact;
126             }
127              
128             sub organization {
129             my $self = shift;
130              
131             my %contact;
132              
133             $contact{name} = $self->language()->organization_name();
134              
135             $contact{phone}{office} = $self->country()->phone_number();
136              
137             for my $type (qw( headquarters branch )) {
138             $contact{address}{$type} = $self->country()->address();
139             }
140              
141             ( $contact{email}{home} = $contact{name} ) =~ s/\W/./g;
142             $contact{email}{home} .= '@' . $self->_domain();
143              
144             return \%contact;
145             }
146              
147             {
148              
149             # Fake Name Generator uses these domains, so I assume they're safe.
150             my @Domains = qw(
151             pookmail.com
152             trashymail.com
153             dodgit.com
154             mailinator.com
155             spambob.com
156             );
157              
158             sub _domain {
159             return @Domains[ int( rand( scalar @Domains ) ) ];
160             }
161             }
162              
163             sub _percent {
164             return ( int( rand(100) ) ) + 1;
165             }
166              
167             __PACKAGE__->meta()->make_immutable();
168              
169             1;
170              
171             # ABSTRACT: Generate random contact data
172              
173              
174              
175             =pod
176              
177             =head1 NAME
178              
179             Data::Random::Contact - Generate random contact data
180              
181             =head1 VERSION
182              
183             version 0.05
184              
185             =head1 SYNOPSIS
186              
187             use Data::Random::Contact;
188              
189             my $randomizer = Data::Random::Contact->new();
190              
191             my $person = $rand->person();
192             my $household = $rand->household();
193             my $organization = $rand->organization();
194              
195             =head1 DESCRIPTION
196              
197             B<This module is still alpha, and the API may change in future releases.>
198              
199             This module generates random data for contacts. This is useful if you're
200             working an application that manages this sort of data.
201              
202             It generates three types of contacts, people, households, and
203             organizations.
204              
205             =head1 LICENSING
206              
207             The data that this module uses comes from several sources. Names are based on
208             data from Fake Name Generator (L<http://www.fakenamegenerator.com>). This
209             data is dual-licensed under GPLv3 or CC BY-SA 3.0 (United Stated). See
210             http://www.fakenamegenerator.com/license.php for licensing details.
211              
212             The address data is all B<real addresses> from the VegGuide.org website
213             (L<http://vegguide.org>). This data is licensed under the CC BY-NC-SA 3.0
214             (United Stated) license.
215              
216             All other data is generated algorithmically.
217              
218             Whether a license can apply to things like addresses and names is debatable,
219             but I am not a lawyer.
220              
221             =head1 METHODS
222              
223             This module provides just a few public methods:
224              
225             =head2 Data::Random::Contact->new()
226              
227             This constructs a new object. It accepts two optional parameters:
228              
229             =over 4
230              
231             =item * language
232              
233             This can either be a language name like "EN" or an instantiated language
234             class, for example L<Data::Random::Contact::Language::EN>.
235              
236             The language is used to generate names.
237              
238             This defaults to "EN".
239              
240             Currently this distribution only ships with one language, English
241             (L<Data::Random::Contact::Language::EN>).
242              
243             =item * country
244              
245             This can either be a country name like "US" or an instantiated country
246             class, for example L<Data::Random::Contact::Country::US>.
247              
248             The country is used to generate phone numbers and addresses.
249              
250             This defaults to "EN".
251              
252             Currently this distribution only ships with one country, US
253             (L<Data::Random::Contact::Country::US>).
254              
255             =back
256              
257             =head2 $randomizer->person()
258              
259             This returns a random set of data for a single person.
260              
261             See L</RETURNED DATA> for details.
262              
263             =head2 $randomizer->household()
264              
265             This returns a random set of data for a single household.
266              
267             See L</RETURNED DATA> for details.
268              
269             =head2 $randomizer->organization()
270              
271             This returns a random set of data for a single organization.
272              
273             See L</RETURNED DATA> for details.
274              
275             =head1 RETURNED DATA
276              
277             Each of the methods that return contact data returns a complicated
278             hashref-based data structure.
279              
280             =head2 Shared Data
281              
282             Some of the data is shared across all contact types:
283              
284             All contact types return email, phone, and address data. This data is
285             available under the appropriate key ("email", "phone", or "address") in the
286             top-level data structure.
287              
288             Under that key the data is further broken down by type, which will be
289             something like "home", "work", "office", etc. Every contact will have all the
290             valid keys set. In other words, a person will always have both a home and work
291             email address.
292              
293             The email data will always be at one of these domains: pookmail.com,
294             trashymail.com, dodgit.com, mailinator.com, or spambob.com.
295              
296             The phone number will be a string containing all the phone number data.
297              
298             Each address is further broken down as a hashref data structure.
299              
300             See the appropriate language module for details on phone numbers and
301             addresses.
302              
303             Here's an example of the shared data for a person (using US data):
304              
305             {
306             address => {
307             home => {
308             city => "Reno",
309             postal_code => 89503,
310             region => "Nevada",
311             region_abbr => "NV",
312             street_1 => "501 W. 1st St.",
313             street_2 => undef
314             },
315             work => {
316             city => "Minneapolis",
317             postal_code => 55406,
318             region => "Minnesota",
319             region_abbr => "MN",
320             street_1 => "2823 E. Franklin Avenue",
321             street_2 => undef
322             }
323             },
324             email => {
325             home => "charlotte.t.dolan\@pookmail.com",
326             work => "charlotte0\@dodgit.com"
327             },
328             phone => {
329             home => "508-383-7535",
330             mobile => "775-371-7227",
331             work => "602-995-6077"
332             },
333             }
334              
335             =head2 Person Data
336              
337             Since much of this data is language-specific, you should see the appropriate
338             language module for details. Some keys may be undefined, depending on the
339             language.
340              
341             The data for a person includes:
342              
343             =over 4
344              
345             =item * given
346              
347             The person's given name.
348              
349             The set of names used is determined by the language.
350              
351             =item * middle
352              
353             The person's middle name or initial.
354              
355             The set of names used is determined by the language.
356              
357             =item * surname
358              
359             The person's surname.
360              
361             The set of names used is determined by the language.
362              
363             =item * gender
364              
365             This will be either "male" or "female".
366              
367             =item * salutation
368              
369             A salutation for the person ("Mr", "Ms", etc.). These salutations are
370             gender-specific.
371              
372             The set of salutations used is determined by the language.
373              
374             =item * suffix
375              
376             An optional suffix like "Jr" or "III".
377              
378             The set of salutations used is determined by the language.
379              
380             =item * birth_date
381              
382             A L<DateTime> object representing the person's birth date. The date will be
383             somewhere between 15 and 100 years in the past.
384              
385             =item * email addresses
386              
387             The email address types for a person are "home" and "work".
388              
389             =item * phone numbers
390              
391             The phone number types for a person are "home", "work", and "mobile".
392              
393             =item * addresses
394              
395             The address types for a person are "home" and "work".
396              
397             =back
398              
399             =head2 Household Data
400              
401             The data for a person includes:
402              
403             =over 4
404              
405             =item * name
406              
407             The household name.
408              
409             The set of names used is determined by the language.
410              
411             =item * email addresses
412              
413             The only email address type for a household is "home".
414              
415             =item * phone numbers
416              
417             The only phone number type for a household is "home".
418              
419             =item * addresses
420              
421             The only address type for a household is "home".
422              
423             =back
424              
425             =head2 Organization Data
426              
427             The data for a person includes:
428              
429             =over 4
430              
431             =item * name
432              
433             The organization name.
434              
435             The set of names used is determined by the language.
436              
437             =item * email addresses
438              
439             The only email address type for an organization is "home".
440              
441             =item * phone numbers
442              
443             The only phone number type for an organization is "office".
444              
445             =item * addresses
446              
447             The address types for a organization are "headquarters" and "branch".
448              
449             =back
450              
451             =head2 Data Dumps
452              
453             Here are complete data dumps for each contact type:
454              
455             =over 4
456              
457             =item * Person
458              
459             {
460             given => "Gregory",
461             middle => "Antoine",
462             surname => "Jones",
463             birth_date => bless( {'...'}, 'DateTime' ),
464             salutation => "Mr",
465             suffix => "IV",
466             gender => "male",
467             address => {
468             home => {
469             city => "Boulder",
470             postal_code => 80304,
471             region => "Colorado",
472             region_abbr => "CO",
473             street_1 => "2785 Iris Avenue",
474             street_2 => undef
475             },
476             work => {
477             city => "Albuquerque",
478             postal_code => 87106,
479             region => "New Mexico",
480             region_abbr => "NM",
481             street_1 => "2110 Central Ave SE",
482             street_2 => undef
483             }
484             },
485             email => {
486             home => "gregory.antoine.jones\@trashymail.com",
487             work => "gregory0\@pookmail.com"
488             },
489             phone => {
490             home => "881-348-3582",
491             mobile => "727-862-8526",
492             work => "305-389-4232"
493             },
494             }
495              
496             =item * Household
497              
498             {
499             name => "The Briley Household",
500             address => {
501             home => {
502             city => "Lombard",
503             postal_code => undef,
504             region => "Illinois",
505             region_abbr => "IL",
506             street_1 => "2361 Fountain Square Dr.",
507             street_2 => undef
508             }
509             },
510             email => { home => "The.Briley.Household\@mailinator.com" },
511             phone => { home => "307-342-9913" }
512             }
513              
514             =item * Organization
515              
516             {
517             name => "pastorate womanish",
518             address => {
519             branch => {
520             city => "Northbrook",
521             postal_code => undef,
522             region => "Illinois",
523             region_abbr => "IL",
524             street_1 => "1819 Lake Cook Rd.",
525             street_2 => undef
526             },
527             headquarters => {
528             city => "Springfield",
529             postal_code => undef,
530             region => "New Jersey",
531             region_abbr => "NJ",
532             street_1 => "518 Millburn Ave",
533             street_2 => undef
534             }
535             },
536             email => { home => "pastorate.womanish\@mailinator.com" },
537             phone => { office => "876-278-8382" }
538             }
539              
540             =back
541              
542             =head1 AUTHOR
543              
544             Dave Rolsky <autarch@urth.org>
545              
546             =head1 COPYRIGHT AND LICENSE
547              
548             This software is Copyright (c) 2011 by Dave Rolsky.
549              
550             This is free software, licensed under:
551              
552             The Artistic License 2.0 (GPL Compatible)
553              
554             =cut
555              
556              
557             __END__
558