Working?
[spider.git] / perl / USDB.pm
1 #
2 # Package to handle US Callsign -> City, State translations
3 #
4 # Copyright (c) 2002 Dirk Koopman G1TLH
5 #
6
7
8 package USDB;
9
10 use strict;
11
12 use DXVars;
13 use DB_File;
14 use File::Copy;
15 use DXDebug;
16 use Compress::Zlib;
17
18 use vars qw($VERSION $BRANCH);
19 $VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
20 $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/  || (0,0));
21 $main::build += $VERSION;
22 $main::branch += $BRANCH;
23
24 use vars qw(%db $present $dbfn);
25
26 $dbfn = "$main::data/usdb.v1";
27
28 sub init
29 {
30         end();
31         if (tie %db, 'DB_File', $dbfn, O_RDONLY, 0664, $DB_BTREE) {
32                 $present = 1;
33                 dbg("US Database loaded");
34         } else {
35                 dbg("US Database not loaded");
36         }
37 }
38
39 sub end
40 {
41         return unless $present;
42         untie %db;
43         undef $present;
44 }
45
46 sub get
47 {
48         return () unless $present;
49         my $ctyn = $db{$_[0]};
50         my @s = split /\|/, $db{$ctyn} if $ctyn;
51         return @s;
52 }
53
54 sub getstate
55 {
56         return () unless $present;
57         my @s = get($_[0]);
58         return @s ? $s[1] : undef;
59 }
60
61 sub getcity
62 {
63         return () unless $present;
64         my @s = get($_[0]);
65         return @s ? $s[0] : undef;
66 }
67
68 #
69 # load in / update an existing DB with a standard format (GZIPPED)
70 # "raw" file.
71 #
72 # Note that this removes and overwrites the existing DB file
73 # You will need to init again after doing this
74
75
76 sub load
77 {
78         return "Need a filename" unless @_;
79         
80         # create the new output file
81         my $a = new DB_File::BTREEINFO;
82         $a->{psize} = 4096 * 2;
83         my $s = 0;
84
85         # guess a cache size
86         for (@_) {
87                 my $ts = -s;
88                 $s = $ts if $ts > $s;
89         }
90         if ($s > 1024 * 1024) {
91                 $a->{cachesize} = int($s / (1024*1024)) * 3 * 1024 * 1024;
92         }
93
94 #       print "cache size " . $a->{cachesize} . "\n";
95         
96         my %dbn;
97         if (-e $dbfn ) {
98                 copy($dbfn, "$dbfn.new") or return "cannot copy $dbfn -> $dbfn.new $!";
99         }
100         
101         tie %dbn, 'DB_File', "$dbfn.new", O_RDWR|O_CREAT, 0664, $a or return "cannot tie $dbfn.new $!";
102         
103         # now write away all the files
104         for (@_) {
105                 my $fn = shift;
106                 my $if = gzopen($fn, "r") or return "Cannot open $fn $!";
107                 my $ofn = "$fn.upk";
108                 my $of = new IO::File "+>$ofn" or return "Cannot read $ofn $!";
109                 my ($l, $buf);
110                 while ($l = $if->gzread($buf)) {
111                         $of->write($buf, $l);
112                 }
113                 $if->gzclose;
114                 $of->close;
115                 $of = new IO::File "$ofn" or return "Cannot read $ofn $!";
116
117                 while (<$of>) {
118                         $l = $_;
119                         $l =~ s/[\r\n]+$//;
120                         my ($call, $city, $state) = split /\|/, $l;
121                         
122                         # lookup the city 
123                         my $s = "$city|$state";
124                         my $ctyn = $dbn{$s};
125                         unless ($ctyn) {
126                                 my $no = $dbn{'##'} || 1;
127                                 $ctyn = "#$no";
128                                 $dbn{$s} = $ctyn;
129                                 $dbn{$ctyn} = $s; 
130                                 $no++;
131                                 $dbn{'##'} = "$no";
132                         }
133                         $dbn{$call} = $ctyn; 
134                 }
135                 $of->close;
136                 unlink $ofn;
137         }
138         
139         untie %dbn;
140         rename "$dbfn.new", $dbfn;
141         return ();
142 }
143
144 1;