File Coverage

blib/lib/Geo/Local/Server.pm
Criterion Covered Total %
statement 51 63 80.9
branch 12 28 42.8
condition 5 11 45.4
subroutine 15 15 100.0
pod 9 9 100.0
total 92 126 73.0


line stmt bran cond sub pod time code
1             package Geo::Local::Server;
2 3     3   401967 use strict;
  3         7  
  3         154  
3 3     3   19 use warnings;
  3         6  
  3         230  
4 3     3   20 use base qw{Package::New};
  3         17  
  3         1803  
5 3     3   3519 use Config::IniFiles qw{};
  3         116501  
  3         136  
6 3     3   1306 use Path::Class qw{file};
  3         67380  
  3         3183  
7             #runtime use Win32 if Windows
8             #runtime use Sys::Config unless Windows
9              
10             our $VERSION = '0.10';
11              
12             =head1 NAME
13              
14             Geo::Local::Server - Returns the configured coordinates of the local server
15              
16             =head1 SYNOPSIS
17              
18             use Geo::Local::Server;
19             my $gls = Geo::Local::Server->new;
20             my ($lat, $lon) = $gls->latlon;
21              
22             =head1 DESCRIPTION
23              
24             Reads coordinates from either the user environment variable COORDINATES_WGS84_LON_LAT_HAE or the file /etc/local.coordinates or C:\Windows\local.coordinates.
25              
26             =head1 USAGE
27              
28             =head2 Scripts
29              
30             Typical use is with the provided scripts
31              
32             is_nighttime && power-outlet WeMo on host mylamp
33             is_daytime && power-outlet WeMo off host mylamp
34             echo "power-outlet WeMo on host mylamp" | at `sunset_time`
35             echo "power-outlet WeMo off host mylamp" | at `sunrise_time`
36              
37             =head2 One Liner
38              
39             $ perl -MGeo::Local::Server -e 'printf "Lat: %s, Lon: %s\n", Geo::Local::Server->new->latlon'
40             Lat: 38.7803, Lon: -77.3867
41              
42             =head1 METHODS
43              
44             =head2 latlon, latlong
45              
46             Returns a list of latitude, longitude
47              
48             =cut
49              
50 2     2 1 9 sub latlon {(shift->lonlathae)[1,0]};
51              
52 2     2 1 2844 sub latlong {(shift->lonlathae)[1,0]};
53              
54             =head2 lat
55              
56             Returns the latitude.
57              
58             =cut
59              
60 2     2 1 481888 sub lat {(shift->lonlathae)[1]};
61              
62             =head2 lon
63              
64             Returns the longitude
65              
66             =cut
67              
68 2     2 1 8 sub lon {(shift->lonlathae)[0]};
69              
70             =head2 hae
71              
72             Returns the configured height of above the ellipsoid
73              
74             =cut
75              
76 2     2 1 10 sub hae {(shift->lonlathae)[2]};
77              
78             =head2 lonlathae
79              
80             Returns a list of longitude, latitude and height above the ellipsoid
81              
82             =cut
83              
84             sub lonlathae {
85 10     10 1 22 my $self=shift;
86 10 100       36 unless ($self->{"lonlathae"}) {
87 2         7 my $coordinates = "";
88 2         40 my $envname = $self->envname;
89 2         5 my $file = "";
90 2 50       6 if ($envname) {
91 2   100     12 $coordinates = $ENV{$envname} || "";
92 2         13 $coordinates =~ s/^\s*//; #trim white space from beginning
93 2         14 $coordinates =~ s/\s*$//; #trim white space from end
94             }
95 2 100 33     9 if ($coordinates) {
    50 33        
      33        
96             #First Step Pull from environment which can be configured by user
97 1         5 my ($lon, $lat, $hae) = split(/\s+/, $coordinates);
98 1         6 $self->{"lonlathae"} = [$lon, $lat, $hae];
99             } elsif (defined($file = $self->configfile) and -r $file and defined($self->ci) and $self->ci->SectionExists("wgs84")) {
100             #We assign the config filename inside the elsif to not load runtime requires if we hit the ENV above.
101             #Second Step Pull from file system which can be configured by system
102 1         16 my $lat = $self->ci->val(wgs84 => "latitude");
103 1         34 my $lon = $self->ci->val(wgs84 => "longitude");
104 1         16 my $hae = $self->ci->val(wgs84 => "hae");
105 1         17 $self->{"lonlathae"} = [$lon, $lat, $hae];
106             } else {
107             #TODO: GeoIP
108             #TODO: gpsd
109             #TODO: some kind of memory block transfer
110 0         0 my $error = qq{Error: None of the following supported coordinate standards are configured.\n\n};
111 0 0       0 $error .= $envname ? qq{ - Environment variable "$envname" is not set\n} : qq{ - Environment variable is disabled\n};
112 0 0       0 $error .= $file ? qq{ - Config file "$file" is not readable.\n} : qq{ - Config file is disabled\n};
113 0         0 die("$error ");
114             }
115             }
116 10         15 return @{$self->{"lonlathae"}};
  10         62  
117             }
118              
119             =head1 PROPERTIES
120              
121             =head2 envname
122              
123             Sets and returns the name of the environment variable.
124              
125             my $var=$gls->envname; #default COORDINATES_WGS84_LON_LAT_HAE
126             $gls->envname(""); #disable environment lookup
127             $gls->envname(undef); #reset to default
128              
129             =cut
130              
131             sub envname {
132 2     2 1 10 my $self = shift;
133 2 50       10 $self->{"envname"} = shift if $_;
134 2 50       12 $self->{"envname"} = $self->_envname_default unless defined $self->{"envname"};
135 2         6 return $self->{"envname"};
136             }
137              
138 2     2   8 sub _envname_default {'COORDINATES_WGS84_LON_LAT_HAE'}
139              
140             =head2 configfile
141              
142             Sets and returns the location of the local.coordinates filename.
143              
144             my $var = $gls->configfile; #default /etc/local.coordinates or C:\Windows\local.coordinates
145             $gls->configfile(""); #disable file-based lookup
146             $gls->configfile(undef); #reset to default
147              
148             =cut
149              
150             sub configfile {
151 6     6 1 7 my $self = shift;
152 6 50       11 $self->{"configfile"} = shift if @_;
153 6 50       10 unless (defined $self->{"configfile"}) {
154 0         0 my $file = "local.coordinates";
155 0         0 my $path = "/etc"; #default is unix-like systems
156 0 0       0 if ($^O eq "MSWin32") {
157 0         0 eval("use Win32");
158 0 0       0 $path = eval("Win32::GetFolderPath(Win32::CSIDL_WINDOWS)") unless $@;
159             } else {
160 0         0 eval("use Sys::Path");
161 0 0       0 $path = eval("Sys::Path->sysconfdir") unless $@;
162             }
163 0         0 $self->{"configfile"} = file($path => $file); #isa Path::Class::File
164             }
165 6         14 return $self->{"configfile"};
166             }
167              
168             =head1 CONFIGURATION
169              
170             =head2 File
171              
172             I recommend building and installing an RPM from the included SPEC file which installs /etc/local.coorindates.
173              
174             rpmbuild -ta Geo-Local-Server-?.??.tar.gz
175              
176             Outerwise copy the example etc/local.coorindates file to either /etc/ or C:\Windows\ and then update the coordinates to match your server location.
177              
178             =head2 Environment
179              
180             I recommend building and installing an RPM with the included SPEC file which installs /etc/profile.d/local.coordinates.sh which correctly sets the COORDINATES_WGS84_LON_LAT_HAE environment variable.
181              
182             Otherwise you can export the COORDINATES_WGS84_LON_LAT_HAE variable or add it to your .bashrc file.
183              
184             export COORDINATES_WGS84_LON_LAT_HAE="-77.3867 38.7803 63"
185              
186             =head2 Format
187              
188             The /etc/local.coordinates file is an INI file. The [wgs84] section is required for this package to function.
189              
190             [main]
191             version=1
192              
193             [wgs84]
194             latitude=38.7803
195             longitude=-77.3867
196             hae=63
197              
198             =head1 OBJECT ACCESSORS
199              
200             =head2 ci
201              
202             Returns the L object so that you can read additional information from the INI file.
203              
204             my $config = $gls->ci; #isa Config::IniFiles
205              
206             Example
207              
208             my $version = $gls->ci->val("main", "version");
209              
210             =cut
211              
212             sub ci {
213 5     5 1 114 my $self = shift;
214 5         8 my $file = $self->configfile; #support for objects that can stringify paths.
215             $self->{'ci'} = Config::IniFiles->new(-file=>"$file")
216 5 100       11 unless ref($self->{'ci'}) eq "Config::IniFiles";
217 5         1799 return $self->{'ci'};
218             }
219              
220             =head1 BUGS
221              
222             Please log on GitHub
223              
224             =head1 AUTHOR
225              
226             Michael R. Davis
227              
228             =head1 COPYRIGHT
229              
230             MIT
231              
232             =head1 SEE ALSO
233              
234             L, L, L, L
235              
236             =cut
237              
238             1;