#!/bin/perl -w # Parses the text output of the Florida Repeater Council Repeater Database PDF files # KE3VIN - K. P. Inscoe (kevin@inscoe.org) - July 1, 2002 # # Instructions: # # 1) Download "allistings" PDF from FRC web site: # # http://florida-repeaters.org/alllisting.pdf # # 2) Load up PDF in Acrobat Reader 4.x # # 3) Select "View Continuous". # # 4) Edit->Select All (or Control-A) # # 5) Edit->Copy (or Control-C) # # 6) Paste below the dotted line # # 7) Run frc.pl against this file as ascii text. # # Revision history # # K. P. Inscoe 1.0 - July 1, 2002 Create original. # K. P. Inscoe (KE3VIN) 1.1 - July 8, 2002 Fix a bug with two-word county names. # K. Inscoe 1.2 - October 30, 2003 Allow VE callsigns as legal since FRC # used one in 2003 listing. :-O # globals use Getopt::Std; use strict; my $vers="1.2"; my $count=0; my $inrecs=0; # Check our params getopts("y"); my $ifile = $ARGV[0]; # Determine our output file my $tmp = index($ifile, "."); my $ofile = substr($ifile, 0, $tmp); $ofile = $ofile . ".csv"; # Announce ourselves my $date = localtime; print "frc.pl: vers $vers processing $ifile ... $date\n"; open(IN, "<$ifile") or die "cannot open $ifile for reading - $!\n"; open(OUT, ">$ofile") or die "cannot open $ofile for writing - $!\n"; # Generate our header print OUT "\042Output\042,\042Location\042,\042Call\042,\042Input\042,\042Features\042,\042PL\042,\042Sponsor\042,\042Updated\042,\042County\042,\042Region\042\n"; while () { $inrecs++; # chomp($_); my $inbuf = $_; # collapse leading and trailing line spaces $inbuf =~ s/^\s+//; $inbuf =~ s/\s+$//; # only process lines that start in the format 99.99 if ( $inbuf =~ m/^(-?[0-9][0-9]+)(\.)(-?[0-9][0-9]+)/ ) { my @outrec=parse_frc($inbuf); $count++; print OUT "@outrec\n"; } } close(IN); close(OUT); print "Conversion complete. $count listings converted to $ofile.\n\n"; $date = localtime; my ($user,$system) = times; print "$date elapsed time: user: $user secs, system: $system secs\n"; sub parse_frc { my $tmp = $_; # remove leading and trailing spaces $tmp =~ s/^\s+//; $tmp =~ s/\s+$//; my $city = ""; my $freq = ""; my $callsign = ""; # First get our freq. $freq = substr($tmp, 0, index($tmp, " ")); $tmp = substr($tmp, index($tmp, " ")+1); $tmp =~ s/^\s+//; $tmp =~ s/\s+$//; # now the city. This requires intelligence because the city can be whitespaced # and is only delimted by a valid US callsign $city = substr($tmp, 0, &locate_callsign($tmp)); $city =~ s/^\s+//; $city =~ s/\s+$//; # callsign $tmp = substr($tmp, &locate_callsign($tmp)); $callsign = substr($tmp, 0, index($tmp, " ")); $callsign =~ s/^\s+//; $callsign =~ s/\s+$//; $callsign =~ tr/[a-z]/[A-Z]/; # validate the callsign if ( IsValidCallsign($callsign) ) { } else { $callsign = "unknown"; } # input $tmp = substr($tmp, &locate_callsign($tmp)+length($callsign)); $tmp =~ s/^\s+//; my $input = substr($tmp, 0, index($tmp, " ")); $input =~ s/^\s+//; $input =~ s/\s+$//; # repeater codes $tmp = substr($tmp, index($tmp, $input)+length($input)); $tmp =~ s/^\s+//; my $codes = substr($tmp, 0, index($tmp, " ")+1); $codes =~ s/^\s+//; $codes =~ s/\s+$//; # PL - this one is tricky too because sometimes there is no PL. $tmp = substr($tmp, index($tmp, $codes)+length($codes)); $tmp =~ s/^\s+//; my $pl = " "; my $possible_pl = substr($tmp, 0, index($tmp, " ")+1); if ( IsValidPL($possible_pl) ) { $pl = $possible_pl; } $pl =~ s/^\s+//; $pl =~ s/\s+$//; # sponsor $tmp = substr($tmp, index($tmp, $pl)+length($pl)); $tmp =~ s/^\s+//; my $sponsor = substr($tmp, 0, index($tmp, " ")+1); $sponsor =~ s/^\s+//; $sponsor =~ s/\s+$//; # last update - this one is unusual too because often the callsign is the # same as the sponsor $tmp = substr($tmp, index($tmp, "/")-2); $tmp =~ s/^\s+//; my $updated = substr($tmp, 0, index($tmp, " ")+1); $updated =~ s/^\s+//; $updated =~ s/\s+$//; # region - we are doing region next because it is a single character and the # last column and therefore the last character in our buffer $tmp =~ s/\s+$//; my $region = substr($tmp, length($tmp)-1); $region =~ s/^\s+//; # county $tmp = substr($tmp, index($tmp, $updated)+length($updated)); $tmp =~ s/^\s+//; my $county = substr($tmp, 0, index($tmp, $region)-1); $county =~ s/^\s+//; $county =~ s/\s+$//; # region $region = substr($tmp, index($tmp, $county)+length($county)); $region =~ s/^\s+//; $region =~ s/\s+$//; return "\042$freq\042,\042$city\042,\042$callsign\042,\042$input\042,\042$codes\042,\042$pl\042,\042$sponsor\042,\042$updated\042,\042$county\042,\042$region\042"; } sub locate_callsign { my @x = (); my $val = ""; my $callsign = ""; my $pos = ""; @x = split(" ", $_[0]); foreach $val (@x) { $val =~ s/^\s+//; $val =~ s/\s+$//; if ( IsValidCallsign($val) ) { $callsign = $val; last; } else { $callsign = ""; } } if ( $callsign eq "" ) { $pos = -1; } else { $pos = index($_[0], $callsign); } return $pos; } sub IsValidCallsign { my $passed = $_[0]; # assume capitalization $passed =~ tr/[a-z]/[A-Z]/; # trim spaces $passed =~ s/^\s+//; $passed =~ s/\s+$//; # validate if ( $passed =~ m/^([VWKAN]{1,1})+([A-Z])*([0-9]{1,1})+([A-Z]{1,3})+$/ ) { return 1 } else { return 0 }; } sub IsValidPL { my $passed = $_[0]; # trim spaces $passed =~ s/^\s+//; $passed =~ s/\s+$//; # validate if ( $passed =~ m/^([0-9]{2,3})+\.+([0-9])+$/ ) { return 1 } else { return 0 }; }