File Coverage

lib/Mojolicious/Plugin/Vparam/Address.pm
Criterion Covered Total %
statement 80 87 91.9
branch 38 56 67.8
condition 11 15 73.3
subroutine 24 24 100.0
pod 2 17 11.7
total 155 199 77.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Vparam::Address;
2 72     72   4301043 use Mojo::Base -strict;
  72         9487  
  72         705  
3 72     72   11327 use Mojolicious::Plugin::Vparam::Common qw(load_class decode_json);
  72         181  
  72         5400  
4              
5 72     72   1108 use Mojo::JSON;
  72         20836  
  72         2936  
6 72     72   465 use Digest::MD5 qw(md5_hex);
  72         188  
  72         3359  
7 72     72   465 use Encode qw(encode is_utf8);
  72         168  
  72         86629  
8              
9              
10             sub new {
11 33     33 0 77 my ($class, $opts) = @_;
12 33         129 return bless $opts => $class;
13             }
14              
15             =head2 parse $str
16              
17             Parse address from string
18              
19             =cut
20              
21             sub parse {
22 34     34 1 91 my ($class, $str) = @_;
23              
24 34 100       110 return undef unless defined $str;
25 32         71 my ($full, $address, $lon, $lat, $md5, $id, $type, $lang, $opt);
26              
27 32 100 66     282 if( $str =~ m{^\s*\[} and $str =~ m{\]\s*$} ) {
28             # JSON format
29 12         43 my $json = decode_json $str;
30 12 50 33     2268 if( $json and 'ARRAY' eq ref($json)) {
31 12   100     165 $full = sprintf '%s : %s , %s',
      100        
      100        
32             $json->[2]//'', $json->[3]//'', $json->[4]//'';
33 12         29 $address = $json->[2];
34 12         22 $lon = $json->[3];
35 12         20 $lat = $json->[4];
36 12         19 $id = $json->[0];
37 12         19 $type = $json->[1];
38 12         22 $lang = $json->[5];
39 12 100       47 $opt = 'ARRAY' eq ref($json->[6])
40             ? $class->new($json->[6])
41             : $json->[6];
42             }
43             } else {
44             # Text format
45 20         222 ($full, $address, $lon, $lat, $md5) = $str =~ m{^
46             (
47             \s*
48             # address
49             (\S.*?)
50             \s*:\s*
51             # longitude
52             (-?\d{1,3}(?:\.\d+)?)
53             \s*,\s*
54             # latitude
55             (-?\d{1,3}(?:\.\d+)?)
56             \s*
57             )
58             # md5
59             (?:\[\s*(\w*)\s*\])?
60             \s*
61             $}x;
62             }
63              
64 32         161 return $class->new([
65             $address, $lon, $lat, $md5, $full, $id, $type, $lang, $opt
66             ]);
67             }
68              
69             =head2 check_secret $secret
70              
71             Check address sign for $secret
72              
73             =cut
74              
75             sub check_secret {
76 23     23 1 61 my ($self, $secret) = @_;
77 23 50       61 return 1 unless defined $secret;
78 23 100       83 return 1 unless length $secret;
79 8 100       27 return 0 unless defined $self->md5;
80              
81 7         26 my $check = $secret . $self->fullname;
82 7 50       68 $check = encode utf8 => $check if is_utf8 $check;
83 7         382 return $self->md5 eq md5_hex( $check );
84             }
85              
86 73     73 0 1560 sub address { return $_[0]->[0]; }
87 23     23 0 113 sub lon { return $_[0]->[1]; }
88 23     23 0 114 sub lat { return $_[0]->[2]; }
89 27     27 0 170 sub md5 { return $_[0]->[3]; }
90 9     9 0 41 sub fullname { return $_[0]->[4]; }
91              
92 2     2 0 28 sub id { return $_[0]->[5]; }
93 39     39 0 132 sub type { return $_[0]->[6]; }
94 2     2 0 11 sub lang { return $_[0]->[7]; }
95              
96 23     23 0 114 sub opt { return $_[0]->[8]; }
97              
98             sub is_extra {
99 3     3 0 15 my ($self) = @_;
100 3 100       13 return 0 unless defined $self->opt;
101 2 100 66     7 return 1 if not ref( $self->opt ) and $self->opt eq 'extra';
102 1         6 return 0;
103             }
104              
105             sub is_near {
106 5     5 0 12 my ($self) = @_;
107 5 50       17 return 0 unless defined $self->opt;
108 5 50       13 return 1 if ref( $self->opt );
109 0         0 return 0;
110             }
111              
112             sub near {
113 4     4 0 10 my ($self) = @_;
114 4 50       12 return unless $self->is_near;
115 4         11 return $self->opt;
116             }
117              
118             sub check_address($;$) {
119 34     34 0 88 my ($self, $secret) = (@_);
120 34 100       99 return 'Value not defined' unless defined $self;
121 32 50       90 return 'Wrong format' unless ref $self;
122 32 100       92 return 'Wrong format' unless defined $self->address;
123 24 50       63 return 'Wrong format' unless length $self->address;
124              
125 24 100       86 if( $self->type ) {
126 10 100       23 if( $self->type eq 'p' ) {
    100          
    50          
127             # Standart point type
128              
129 8         21 my $e = load_class('Mojolicious::Plugin::Vparam::Numbers');
130 8 50       805 die $e if $e;
131              
132 8         24 my $lon = Mojolicious::Plugin::Vparam::Numbers::check_lon(
133             $self->lon
134             );
135 8 50       22 return $lon if $lon;
136              
137 8         48 my $lat = Mojolicious::Plugin::Vparam::Numbers::check_lat(
138             $self->lat
139             );
140 8 50       26 return $lat if $lat;
141             } elsif( $self->type eq 't' ) {
142             # Some text without point
143              
144             } elsif( not defined $self->type ) {
145             # Undefined type (legacy)
146              
147 0         0 my $e = load_class('Mojolicious::Plugin::Vparam::Numbers');
148 0 0       0 die $e if $e;
149              
150 0         0 my $lon = Mojolicious::Plugin::Vparam::Numbers::check_lon(
151             $self->lon
152             );
153 0 0       0 return $lon if $lon;
154              
155 0         0 my $lat = Mojolicious::Plugin::Vparam::Numbers::check_lat(
156             $self->lat
157             );
158 0 0       0 return $lat if $lat;
159             } else {
160 1         4 return 'Unknown type';
161             }
162             }
163              
164 23 100       73 return 'Unknown source' unless $self->check_secret( $secret );
165 20         87 return 0;
166             }
167              
168              
169             sub register {
170 74     74 0 292 my ($class, $self, $app, $conf) = @_;
171              
172             $app->vtype(
173             address =>
174             load => 'Mojolicious::Plugin::Vparam::Address',
175             pre => sub {
176 34     34   142 return Mojolicious::Plugin::Vparam::Address->parse( $_[1] );
177             },
178 34     34   116 valid => sub { check_address($_[1], $conf->{address_secret}) },
179 74         1833 );
180              
181 74         659 return;
182             }
183              
184             1;
185              
186             =head1 AUTHORS
187              
188             Dmitry E. Oboukhov <unera@debian.org>
189             Roman V. Nikolaev <rshadow@rambler.ru>
190              
191             =head1 COPYRIGHT
192              
193             Copyright (C) 2011 Dmitry E. Oboukhov <unera@debian.org>
194             Copyright (C) 2011 Roman V. Nikolaev <rshadow@rambler.ru>
195              
196             This program is free software, you can redistribute it and/or
197             modify it under the terms of the Artistic License.
198              
199             =cut