File Coverage

blib/lib/Geo/Local/Server.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Geo::Local::Server;
2 3     3   112294 use strict;
  3         6  
  3         119  
3 3     3   16 use warnings;
  3         4  
  3         102  
4 3     3   15 use base qw{Package::New};
  3         15  
  3         1859  
5 3     3   1663 use Config::IniFiles qw{};
  0            
  0            
6             use Path::Class qw{file};
7             #runtime use Win32 if Windows
8             #runtime use Sys::Config unless Windows
9              
10             our $VERSION = '0.09';
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.780276, Lon: -77.386706
41              
42             =head1 METHODS
43              
44             =head2 latlon, latlong
45              
46             Returns a list of latitude, longitude
47              
48             =cut
49              
50             sub latlon {(shift->lonlathae)[1,0]};
51              
52             sub latlong {(shift->lonlathae)[1,0]};
53              
54             =head2 lat
55              
56             Returns the latitude.
57              
58             =cut
59              
60             sub lat {(shift->lonlathae)[1]};
61              
62             =head2 lon
63              
64             Returns the longitude
65              
66             =cut
67              
68             sub lon {(shift->lonlathae)[0]};
69              
70             =head2 hae
71              
72             Returns the configured height of above the ellipsoid
73              
74             =cut
75              
76             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             my $self=shift;
86             unless ($self->{"lonlathae"}) {
87             my $coordinates="";
88             my $envname=$self->envname;
89             my $file="";
90             if ($envname) {
91             $coordinates=$ENV{$envname} || "";
92             $coordinates=~s/^\s*//; #trim white space from beginning
93             $coordinates=~s/\s*$//; #trim white space from end
94             }
95             if ($coordinates) {
96             #First Step Pull from environment which can be configured by user
97             my ($lon, $lat, $hae)=split(/\s+/, $coordinates);
98             $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             my $lat=$self->ci->val(wgs84 => "latitude");
103             my $lon=$self->ci->val(wgs84 => "longitude");
104             my $hae=$self->ci->val(wgs84 => "hae");
105             $self->{"lonlathae"}=[$lon, $lat, $hae];
106             } else {
107             #TODO: GeoIP
108             #TODO: gpsd
109             #TODO: some kind of memory block transfer
110             my $error=qq{Error: None of the following supported coordinate standards are configured.\n\n};
111             $error.=$envname ? qq{ - Environment variable "$envname" is not set\n} : qq{ - Environment variable is disabled\n};
112             $error.=$file ? qq{ - Config file "$file" is not readable.\n} : qq{ - Config file is disabled\n};
113             die("$error ");
114             }
115             }
116             return @{$self->{"lonlathae"}};
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             my $self=shift;
133             $self->{"envname"}=shift if $_;
134             $self->{"envname"}="COORDINATES_WGS84_LON_LAT_HAE" unless defined $self->{"envname"};
135             return $self->{"envname"};
136             }
137              
138             =head2 configfile
139              
140             Sets and returns the location of the local.coordinates filename.
141              
142             my $var=$gls->configfile; #default /etc/local.coordinates or C:\Windows\local.coordinates
143             $gls->configfile(""); #disable file-based lookup
144             $gls->configfile(undef); #reset to default
145              
146             =cut
147              
148             sub configfile {
149             my $self=shift;
150             $self->{"configfile"}=shift if @_;
151             unless (defined $self->{"configfile"}) {
152             my $file="local.coordinates";
153             my $path="/etc"; #default is unix-like systems
154             if ($^O eq "MSWin32") {
155             eval("use Win32");
156             $path=eval("Win32::GetFolderPath(Win32::CSIDL_WINDOWS)") unless $@;
157             } else {
158             eval("use Sys::Path");
159             $path=eval("Sys::Path->sysconfdir") unless $@;
160             }
161             $self->{"configfile"}=file($path => $file); #isa Path::Class::File
162             }
163             return $self->{"configfile"};
164             }
165              
166             =head1 CONFIGURATION
167              
168             =head2 File
169              
170             I recommend building and installing an RPM from the included SPEC file which installs /etc/local.coorindates.
171              
172             rpmbuild -ta Geo-Local-Server-?.??.tar.gz
173              
174             Outerwise copy the example etc/local.coorindates file to either /etc/ or C:\Windows\ and then update the coordinates to match your server location.
175              
176             =head2 Environment
177              
178             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.
179              
180             Otherwise you can export the COORDINATES_WGS84_LON_LAT_HAE variable or add it to your .bashrc file.
181              
182             export COORDINATES_WGS84_LON_LAT_HAE="-77.386706 38.780276 63"
183              
184             =head2 Format
185              
186             The /etc/local.coordinates file is an INI file. The [wgs84] section is required for this package to function.
187              
188             [main]
189             version=1
190              
191             [wgs84]
192             latitude=38.780276
193             longitude=-77.386706
194             hae=63
195              
196             =head1 OBJECT ACCESSORS
197              
198             =head2 ci
199              
200             Returns the L object so that you can read additional information from the INI file.
201              
202             my $config=$gls->ci; #isa Config::IniFiles
203              
204             Example
205              
206             my $version=$gls->ci->val("main", "version");
207              
208             =cut
209              
210             sub ci {
211             my $self=shift;
212             my $file=$self->configfile; #support for objects that can stringify paths.
213             $self->{'ci'}=Config::IniFiles->new(-file=>"$file")
214             unless ref($self->{'ci'}) eq "Config::IniFiles";
215             return $self->{'ci'};
216             }
217              
218             =head1 BUGS
219              
220             Please log on RT and send an email to the author.
221              
222             =head1 SUPPORT
223              
224             DavisNetworks.com supports all Perl applications including this package.
225              
226             =head1 AUTHOR
227              
228             Michael R. Davis
229             CPAN ID: MRDVT
230             Satellite Tracking of People, LLC
231             mdavis@stopllc.com
232             http://www.stopllc.com/
233              
234             =head1 COPYRIGHT
235              
236             This program is free software licensed under the...
237              
238             The BSD License
239              
240             The full text of the license can be found in the LICENSE file included with this module.
241              
242             =head1 SEE ALSO
243              
244             L, L, L, L
245              
246             =cut
247              
248             1;