X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FSpot.pm;h=8b66b0f6c762f78c398c230a64856a7ae89a621a;hb=db7747a775a39ec1828fc78b9442f301ed32b195;hp=c9178ddb13b3f8668d25676544d69a6365218512;hpb=f21f292746ef4a2edc703e48542d1ed2d85d14cd;p=spider.git diff --git a/perl/Spot.pm b/perl/Spot.pm index c9178ddb..8b66b0f6 100644 --- a/perl/Spot.pm +++ b/perl/Spot.pm @@ -23,13 +23,14 @@ use vars qw($fp $maxspots $defaultspots $maxdays $dirprefix $duplth $dupage $fil $fp = undef; $maxspots = 50; # maximum spots to return $defaultspots = 10; # normal number of spots to return -$maxdays = 35; # 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 $filterdef = bless ([ # tag, sort, field, priv, special parser ['freq', 'r', 0, 0, \&decodefreq], + ['on', 'r', 0, 0, \&decodefreq], ['call', 'c', 1], ['info', 't', 3], ['by', 'c', 4], @@ -44,6 +45,14 @@ $filterdef = bless ([ ], 'Filter::Cmd'); +# create a Spot Object +sub new +{ + my $class = shift; + my $self = [ @_ ]; + return bless $self, $class; +} + sub decodefreq { my $dxchan = shift; @@ -53,14 +62,18 @@ sub decodefreq my $f; foreach $f (@f) { - my ($a, $b) = $f =~ m{^(\d+)/(\d+)$}; - if ($a && $b) { - push @out, $a, $b; + my ($a, $b); + if (m{^\d+/\d+$}) { + push @out, $f; } elsif (($a, $b) = $f =~ m{^(\w+)(?:/(\w+))?$}) { $b = lc $b if $b; my @fr = Bands::get_freq(lc $a, $b); if (@fr) { - push @out, @fr; # add these to the list + while (@fr) { + $a = shift @fr; + $b = shift @fr; + push @out, "$a/$b"; # add them as ranges + } } else { return ('dfreq', $dxchan->msg('dfreq1', $f)); } @@ -82,20 +95,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]); @@ -108,17 +121,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 # @@ -146,7 +158,7 @@ sub add sub search { - my ($expr, $dayfrom, $dayto, $from, $to) = @_; + my ($expr, $dayfrom, $dayto, $from, $to, $hint) = @_; my $eval; my @out; my $ref; @@ -157,21 +169,29 @@ 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; $to = $defaultspots unless $to; + $hint = $hint ? "next unless $hint" : ""; + $expr = "1" unless $expr; $to = $from + $maxspots if $to - $from > $maxspots || $to - $from <= 0; $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("search", "hint='$hint', expr='$expr', spotno=$from-$to, day=$dayfrom-$dayto\n"); # build up eval to execute $eval = qq( + while (<\$fh>) { + $hint; + chomp; + push \@spots, [ split '\\^' ]; + } my \$c; my \$ref; for (\$c = \$#spots; \$c >= 0; \$c--) { @@ -195,10 +215,6 @@ sub search my $fh = $fp->open(@now); # get the next file if ($fh) { my $in; - while (<$fh>) { - chomp; - push @spots, [ split '\^' ]; - } eval $eval; # do the search on this file last if $count >= $to; # stop after to return ("Spot search error", $@) if $@; @@ -208,6 +224,35 @@ sub search return @out; } +# change a freq range->regular expression +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; + while (@b > @a) { + $out .= shift @b; + } + while (@b) { + my $aa = shift @a; + my $bb = shift @b; + if (@b < (length $d) - 1) { + $out .= '\\d'; + } elsif ($aa eq $bb) { + $out .= $aa; + } elsif ($aa < $bb) { + $out .= "[$aa-$bb]"; + } else { + $out .= "[0-$bb$aa-9]"; + } + } + return $out; +} + # format a spot for user output in 'broadcast' mode sub formatb { @@ -258,6 +303,7 @@ sub dup chomp $text; $text = substr($text, 0, $duplth) if length $text > $duplth; unpad($text); + $text =~ s/[\\\%]\d+//g; $text =~ s/[^a-zA-Z0-9]//g; my $dupkey = "X$freq|$call|$d|\L$text"; return DXDupe::check($dupkey, $main::systime+$dupage);