File Coverage

lib/Net/Domain/Regex.pm
Criterion Covered Total %
statement 25 83 30.1
branch 3 20 15.0
condition 0 3 0.0
subroutine 7 10 70.0
pod 3 5 60.0
total 38 121 31.4


line stmt bran cond sub pod time code
1             package Net::Domain::Regex;
2              
3 1     1   27517 use strict;
  1         2  
  1         30  
4              
5 1     1   740 use version; our $VERSION = qv('0.2.1');
  1         2130  
  1         6  
6              
7             our $LOCAL = '/tmp/effective_tld_names.dat';
8             our $CACHE = '/tmp/effective_tld_names.dat.cache';
9             our $SOURCE = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
10              
11 1     1   1343492 use LWP::UserAgent;
  1         1521913  
  1         262  
12              
13             sub import {
14 1 50   1   11 if( grep { /:pdata/ } @_ ){
  1         2345  
15 0         0 $SOURCE = 'https://raw.github.com/petermblair/Perl-CPAN/master/Net-Domain-Regex/misc/tld.txt';
16             }
17             }
18              
19             sub new {
20 1     1 1 12 my $class = shift;
21              
22 1         8 my $args = {
23             local => $LOCAL,
24             source => $SOURCE,
25             cache => $CACHE,
26             @_,
27             };
28              
29 1         4 my $o = bless $args => $class;
30              
31 1 50       30 unless( -e $o->{local} ){
32 1         5 $o->pull;
33             }
34              
35 0         0 $o->refresh;
36              
37 0         0 return $o;
38             }
39              
40             sub refresh {
41 0     0 1 0 my $self = shift;
42              
43 1     1   1008 use open qw(:std :utf8);
  1         1415  
  1         6  
44 0         0 open FD, "<$self->{local}";
45              
46 0         0 my $tlds = {};
47 0         0 my $slds = {};
48              
49 0         0 while( ){
50 0         0 chomp;
51              
52 0 0 0     0 if(/^(\S[^\.\s]+)$/){
    0          
53 0         0 $tlds->{$1}++;
54             }
55             elsif ( /^\S[^\.\s]+\.(.+)$/ && exists $tlds->{$1} ) {
56 0         0 $slds->{$_}++;
57             }
58             }
59              
60             # any manual overrides
61 0         0 for( qw/ co.uk / ){
62 0         0 $tlds->{"$_"}++;
63             }
64              
65 0         0 $self->{tld} = $tlds;
66 0         0 $self->{sld} = $slds;
67             }
68              
69             sub pull {
70 1     1 1 2 my $self = shift;
71              
72 1         10 my $ua = LWP::UserAgent->new;
73 1         2977 my $req = HTTP::Request->new( GET => $self->{source} );
74 1         8622 my $res = $ua->request( $req );
75              
76 1 50       1275656 if( $res->is_success ){
77 0         0 open FD, ">$self->{local}";
78 0         0 local $/;
79 0         0 print FD $res->content;
80             } else {
81 1         13 die $res->status_line;
82             }
83             }
84              
85             sub generate_regex {
86 0     0 0   my $self = shift;
87              
88 0           my @a;
89              
90 0           for( keys %{$self->{sld}} ){
  0            
91 0           push( @a, $_ );
92             }
93              
94 0           for( keys %{$self->{tld}} ){
  0            
95 0           push( @a, $_ );
96             }
97              
98 0           my @atld = sort { length $b cmp length $a } @a;
  0            
99              
100 0           my $tld = join( "|", @atld );
101 0           $tld =~ s/\./\\./g;
102              
103             #my $regex = "((?:[a-zA-Z0-9]\\w+\\.)(($tld)|($sld)))";
104 0           my $regex = "((?:[a-zA-Z0-9][\\w\\-]+\\.)+(com|net|org|edu|$tld))\$";
105              
106 0           return $regex;
107             }
108              
109             sub match {
110 0     0 0   my $self = shift;
111 0           my $target = shift;
112 0           my $orig = $target;
113              
114 0           my $regex = $self->generate_regex;
115            
116             #print "Regex: [$regex]\n";
117              
118 0           my @tokens = split /[^\w\.\-]/, $target;
119 0           my @results;
120              
121 0           for my $target( @tokens ){
122 0 0         if( $target =~ /$regex/g ){
123 0           my $match = $orig = $1;
124             # Extract the TLD
125 0           my @atld = sort { length $b cmp length $a } keys %{$self->{tld}};
  0            
  0            
126             #my $tld = join( "|", sort keys %{$self->{tld}} );
127 0           my $tld = join( "|", @atld );
128 0           $tld =~ s/\./\\./g;
129              
130             # Extract the TLD from the match
131 0 0         my $t = $1 if $match =~ /^.*?\.($tld)$/;
132              
133 0 0         if( $t ){
134 0           $match =~ s/\.$t$//;
135             }
136              
137             # Extract the domain from the match
138 0 0         my $d = $1 if $match =~ /([^\.]+)$/;
139 0           $d =~ s/\.$//;
140              
141 0 0         if( $d ){
142 0           $match =~ s/$d$//;
143             }
144              
145 0           my $h = $match;
146 0           $h =~ s/\.$//;
147              
148 0           push( @results, { match => $orig, hostname => $h, domain => $d, tld => $t } );
149             }
150             }
151 0           return @results;
152             }
153              
154             1;
155              
156             __END__