File Coverage

blib/lib/Ham/Scraper.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Ham::Scraper;
2              
3 1     1   557 use 5.008008;
  1         4  
  1         40  
4 1     1   4 use strict;
  1         1  
  1         23  
5 1     1   5 use warnings;
  1         3  
  1         22  
6 1     1   715 use diagnostics;
  1         173518  
  1         13  
7              
8 1     1   1393 use FileHandle;
  1         10879  
  1         9  
9 1     1   717 use HTML::TableExtract;
  0            
  0            
10             use HTTP::Request::Common qw(GET POST);
11             use LWP::Simple;
12             use LWP::UserAgent;
13             use Net::HTTP;
14             use XML::Element;
15             use XML::TreeBuilder;
16              
17             require Exporter;
18              
19             our @ISA = qw(Exporter);
20             our @EXPORT_OK = ( [ qw(FindU FindUXml APRSWorld APRSWorldXml QRZ QRZxml) ] );
21              
22             our $VERSION = '0.9';
23              
24             sub AppendElement
25             {
26             my $tree = shift;
27             my $elementName = shift;
28             my $elementContent = shift;
29              
30             my $element = XML::Element->new($elementName);
31             $element->push_content($elementContent);
32             $tree->push_content($element);
33              
34             return $tree;
35             }
36              
37             sub CreateStationXml(\%)
38             {
39             my %argumentHash = %{(shift)};
40             my @now = localtime;
41             my $date = $now[4] . '/' . $now[3];
42            
43             my $tree = XML::Element->new('station', 'local-date' => $date);
44              
45             foreach my $elementName (keys (%argumentHash))
46             {
47             &AppendElement($tree, $elementName, $argumentHash{$elementName});
48             }
49              
50             return $tree;
51             }
52              
53             sub WriteRawTextToFile
54             {
55             my %stationInfo = @_;
56             my $callsign = $stationInfo{Callsign};
57             my $timestamp =$stationInfo{LastHeard};
58             my $position = $stationInfo{Position};
59             my $status = $stationInfo{Status};
60            
61             my $output = new IO::File("station.txt", O_WRONLY);
62            
63             print $output "Callsign: $callsign\n";
64             print $output "Timestamp: $timestamp\n";
65             print $output "Position (Latitude & Longitude), Region: $position\n";
66             print $output "Status: $status\n";
67             }
68              
69             sub PrintXmlTree
70             {
71             my $tree = shift;
72             print STDOUT $tree->as_XML;
73             }
74              
75             sub WriteXmlTreeToFile
76             {
77             my $xmlTree = shift;
78             my $handle = new IO::File ">station.xml" or die "Can't open station.xml for writing\n";
79             print $handle $xmlTree;
80             }
81              
82             sub FindU
83             {
84             # Our requesting agent. Define our URL and POST.
85             my $baseUrl = 'http://www.findu.com/cgi-bin/find.cgi';
86             my $post = "call=" . shift;
87            
88             # Here are the headers we'll send off...
89             my $headers = HTTP::Headers->new(Accept => 'text/plain',
90             'User-Agent' => 'AutoLookup/1.0');
91            
92             # and the final requested web page.
93             my $uable = HTTP::Request->new('POST', $baseUrl, $headers, $post);
94             my $userAgent = LWP::UserAgent->new;
95             my $request = $userAgent->request($uable);
96            
97             die $request->message unless $request->is_success;
98            
99             my $webPage = $request->content;
100            
101             $webPage =~ s/(<[^>]*>)*//isg; # Remove all HTML tags
102             $webPage =~ s/ / /g; # As well as NBSPs
103            
104             my $callsign = "N/A";
105             if ($webPage =~ m/Position of ([A-Z]{1,2}[0-9]{1}[A-Z]{2,3})/)
106             {
107             $callsign = $1;
108             }
109             # Write a regex that matches the following string:
110             # 1.2 miles southwest of Bolingbrook, IL
111             # (\d)*.(\d)*\s(rest of string)
112            
113             my $status = "N/A";
114             if ($webPage =~ m/Status: ([^,]*)/g)
115             {
116             $status = $1;
117             }
118            
119             my $reportReceived = "N/A";
120             if ($webPage =~ m/Report received ([^\n]*)/)
121             {
122             $reportReceived = $1;
123             }
124            
125             my $rawPacket = "N/A";
126             if ($webPage =~ m/Raw packet: ([^\n]*)/)
127             {
128             $rawPacket = $1;
129             }
130            
131             return ( Callsign=>$callsign, LastHeard=>$reportReceived, Status=>$status );
132             }
133              
134             sub FindUXml
135             {
136             my $queryCallsign = shift;
137             my %aprsInfo = FindU($queryCallsign);
138             my $xmlTree = CreateStationXml(%aprsInfo)->as_XML;
139             return $xmlTree;
140             }
141              
142             sub APRSWorld
143             {
144             my $queryCallsign = shift;
145             my $baseUrl = "http://db.aprsworld.net/datamart/switch.php?call=$queryCallsign&table=position&maps=yes";
146            
147             my $webPage = get("$baseUrl") or die $!;
148            
149             my $tableData = new HTML::TableExtract->new(headers => [
150             "Callsign", "Date", "Latitude / Longitude", "Status"]);
151             $tableData->parse($webPage);
152            
153             my $callsign;
154             my $position;
155             my $timestamp;
156             my $status;
157            
158             foreach my $tableStates ($tableData->table_states) {
159             foreach my $row ($tableStates->rows) {
160              
161             my $currentCallsign = @$row[0];
162             next if length $currentCallsign == 0;
163             $callsign = $currentCallsign;
164            
165             $timestamp = "Timestamp not available";
166             if (defined(@$row[1])) {
167             $timestamp = @$row[1];
168             }
169            
170             $position = "Position not available";
171             if (defined(@$row[2])) {
172             $position = @$row[2];
173             }
174            
175             $status = "Status not available";
176             if (defined(@$row[4])) {
177             $status = @$row[4];
178             }
179             }
180             }
181              
182             return ( Callsign=>$callsign, Position=>$position, LastHeard=>$timestamp, Status=>$status );
183             }
184              
185             sub APRSWorldXml
186             {
187             my $queryCallsign = shift;
188             my %aprsInfo = APRSWorld($queryCallsign);
189             my $xmlTree = CreateStationXml(%aprsInfo)->as_XML;
190             return $xmlTree;
191             }
192              
193             sub QRZ
194             {
195             my $queryCallsign = shift;
196             my $baseUrl = "http://www.qrz.com/detail/";
197            
198             my $webPage = get("$baseUrl$queryCallsign") or die $!;
199             $webPage =~ s/(<[^>]*>)*//isg;
200             $webPage =~ s/ / /g;
201            
202             $webPage =~ m/Name:([^\n]*)/;
203             my $name = $1;
204            
205             # This pattern currently does not match!
206             $webPage =~ m/Class: (Novice|Technician|General)/;
207             my $class = $1;
208            
209             $webPage =~ m/GMT Offset:([^\n]*)/;
210             my $gmtOffset = $1;
211            
212             $webPage =~ m/Time Zone:([^\n]*)/;
213             my $timeZone = $1;
214            
215             $webPage =~ m/Addr2:([^\n]*)/;
216             my $cityStateZip = $1;
217            
218             $webPage =~ m/County:([^\n]*)/;
219             my $county = $1;
220            
221             $webPage =~ m/Grid:([^\n]*)/;
222             my $grid = $1;
223              
224             return ( Name=>$name, Class=>$class, CityStateZip => $cityStateZip, GMTOffset=>$gmtOffset, TimeZone=>$timeZone, Grid=>$grid );
225             }
226              
227             sub QRZxml
228             {
229             my $queryCallsign = shift;
230             my %qrzInfo = QRZ($queryCallsign);
231             my $xmlTree = CreateStationXml(%qrzInfo)->as_XML;
232             return $xmlTree;
233             }
234              
235             1;
236             __END__