X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FSpot.pm;h=074ae740b4aa7842b0a24ef4fa43e4cd709a9910;hb=86316dcf45d7cbdcd8e3f512be655242ab1701ff;hp=7e621c91f4a947b4f7efa75e8c742916a9440c94;hpb=b228776e730a2aaf6c18d2f88a458719e6b0275a;p=spider.git diff --git a/perl/Spot.pm b/perl/Spot.pm index 7e621c91..074ae740 100644 --- a/perl/Spot.pm +++ b/perl/Spot.pm @@ -16,14 +16,16 @@ use DXLog; use Julian; use Prefix; use DXDupe; +use Data::Dumper; use strict; -use vars qw($fp $maxspots $defaultspots $maxdays $dirprefix $duplth $dupage $filterdef); +use vars qw($fp $statp $maxspots $defaultspots $maxdays $dirprefix $duplth $dupage $filterdef); $fp = undef; +$statp = undef; $maxspots = 50; # maximum spots to return $defaultspots = 10; # normal number of spots to return -$maxdays = 365; # normal maximum no of days to go back +$maxdays = 100; # normal maximum no of days to go back $dirprefix = "spots"; $duplth = 20; # the length of text to use in the deduping $dupage = 3*3600; # the length of time to hold spot dups @@ -88,6 +90,7 @@ sub init { mkdir "$dirprefix", 0777 if !-e "$dirprefix"; $fp = DXLog::new($dirprefix, "dat", 'd'); + $statp = DXLog::new($dirprefix, "bys", 'd'); } sub prefix @@ -95,20 +98,20 @@ sub prefix return $fp->{prefix}; } -# add a spot to the data file (call as Spot::add) -sub add +# fix up the full spot data from the basic spot data +sub prepare { - my @spot = @_; # $freq, $call, $t, $comment, $spotter = @_ - my @out = @spot[0..4]; # just up to the spotter + # $freq, $call, $t, $comment, $spotter = @_ + my @out = @_[0..4]; # just up to the spotter # normalise frequency - $spot[0] = sprintf "%.f", $spot[0]; + $_[0] = sprintf "%.1f", $_[0]; # remove ssids if present on spotter $out[4] =~ s/-\d+$//o; # remove leading and trailing spaces - $spot[3] = unpad($spot[3]); + $_[3] = unpad($_[3]); # add the 'dxcc' country on the end for both spotted and spotter, then the cluster call my @dxcc = Prefix::extract($out[1]); @@ -121,17 +124,16 @@ sub add my $spotter_itu = (@dxcc > 0 ) ? $dxcc[1]->itu() : 0; my $spotter_cq = (@dxcc > 0 ) ? $dxcc[1]->cq() : 0; push @out, $spotter_dxcc; - push @out, $spot[5]; - - my $buf = join("\^", @out); - - # compare dates to see whether need to open another save file (remember, redefining $fp - # automagically closes the output file (if any)). - $fp->writeunix($out[2], $buf); - + push @out, $_[5]; return (@out, $spotted_itu, $spotted_cq, $spotter_itu, $spotter_cq); } +sub add +{ + my $buf = join("\^", @_[0..7]); + $fp->writeunix($_[2], $buf); +} + # search the spot database for records based on the field no and an expression # this returns a set of references to the spots # @@ -170,7 +172,8 @@ sub search my @todate; $dayfrom = 0 if !$dayfrom; - $dayto = $maxdays if !$dayto; + $dayto = $maxdays unless $dayto; + $dayto = $dayfrom + $maxdays if $dayto < $dayfrom; @fromdate = Julian::sub(@today, $dayfrom); @todate = Julian::sub(@fromdate, $dayto); $from = 0 unless $from; @@ -183,7 +186,7 @@ sub search $expr =~ s/\$f(\d)/\$ref->[$1]/g; # swap the letter n for the correct field name # $expr =~ s/\$f(\d)/\$spots[$1]/g; # swap the letter n for the correct field name - dbg("search", "expr='$expr', spotno=$from-$to, day=$dayfrom-$dayto\n"); + dbg("hint='$hint', expr='$expr', spotno=$from-$to, day=$dayfrom-$dayto\n") if isdbg('search'); # build up eval to execute $eval = qq( @@ -230,6 +233,7 @@ sub ftor my ($a, $b) = @_; return undef unless $a < $b; $b--; + my $d = $b - $a; my @a = split //, $a; my @b = split //, $b; my $out; @@ -239,12 +243,14 @@ sub ftor while (@b) { my $aa = shift @a; my $bb = shift @b; - if ($aa eq $bb) { + if (@b < (length $d) - 1) { + $out .= '\\d'; + } elsif ($aa eq $bb) { $out .= $aa; } elsif ($aa < $bb) { $out .= "[$aa-$bb]"; } else { - $out .= "[$bb-$aa]"; + $out .= "[0-$bb$aa-9]"; } } return $out; @@ -310,6 +316,87 @@ sub listdups { return DXDupe::listdups('X', $dupage, @_); } + +sub genstats +{ + my @date = @_; + my $in = $fp->open(@date); + my $out = $statp->open(@date, 'w'); + my @freq = ( + [0, Bands::get_freq('160m')], + [1, Bands::get_freq('80m')], + [2, Bands::get_freq('40m')], + [3, Bands::get_freq('30m')], + [4, Bands::get_freq('20m')], + [5, Bands::get_freq('17m')], + [6, Bands::get_freq('15m')], + [7, Bands::get_freq('12m')], + [8, Bands::get_freq('10m')], + [9, Bands::get_freq('6m')], + [10, Bands::get_freq('4m')], + [11, Bands::get_freq('2m')], + [12, Bands::get_freq('70cm')], + [13, Bands::get_freq('13cm')], + [14, Bands::get_freq('9cm')], + [15, Bands::get_freq('6cm')], + [16, Bands::get_freq('3cm')], + [17, Bands::get_freq('12mm')], + [18, Bands::get_freq('6cm')], + ); + my %list; + my @tot; + + if ($in && $out) { + while (<$in>) { + chomp; + my ($freq, $by, $dxcc) = (split /\^/)[0,4,6]; + my $ref = $list{$by} || [0, $dxcc]; + for (@freq) { + if ($freq >= $_->[1] && $freq <= $_->[2]) { + $$ref[$_->[0]+2]++; + $tot[$_->[0]+2]++; + $$ref[0]++; + $tot[0]++; + $list{$by} = $ref; + last; + } + } + } + + my $i; + for ($i = 0; $i < @freq+2; $i++) { + $tot[$i] ||= 0; + } + $out->write(join('^', 'TOTALS', @tot) . "\n"); + + for (sort {$list{$b}->[0] <=> $list{$a}->[0]} keys %list) { + my $ref = $list{$_}; + my $call = $_; + for ($i = 0; $i < @freq+2; ++$i) { + $ref->[$i] ||= 0; + } + $out->write(join('^', $call, @$ref) . "\n"); + } + $out->close; + } +} + +# return true if the stat file is newer than than the spot file +sub checkstats +{ + my @date = @_; + my $in = $fp->mtime(@date); + my $out = $statp->mtime(@date); + return defined $out && defined $in && $out >= $in; +} + +# daily processing +sub daily +{ + my @date = Julian::unixtoj($main::systime); + @date = Julian::sub(@date, 1); + genstats(@date) unless checkstats(@date); +} 1;