+ $freq = sprintf "%.1f", $freq; # normalise frequency
+ $call = substr($call, 0, 12) if length $call > 12;
+
+ # quick test now for simple case
+ my $sdupkey = "X$freq|$call|$d|$by";
+ return 1 if DXDupe::find($sdupkey);
+
+ chomp $text;
+ $text =~ s/\%([0-9A-F][0-9A-F])/chr(hex($1))/eg;
+ $text = substr($text, 0, $duplth) if length $text > $duplth;
+ unpad($text);
+ $text = pack("C*", map {$_ & 127} unpack("C*", $text));
+ $text =~ s/[^a-zA-Z0-9]//g;
+ for (-60, -120, -180, -240, 0, 60, 120, 180, 240, 300) {
+ my $dt = $d - $_;
+ my $ldupkey = "X$freq|$call|$dt|\L$text";
+ my $sdupkey = "X$freq|$call|$dt|$by";
+ return 1 if DXDupe::find($ldupkey) || DXDupe::find($sdupkey);
+ }
+ my $ldupkey = "X$freq|$call|$d|\L$text";
+ $sdupkey = "X$freq|$call|$d|$by";
+ DXDupe::add($ldupkey, $main::systime+$dupage);
+ DXDupe::add($sdupkey, $main::systime+$dupage);
+ return 0;
+}
+
+sub listdups
+{
+ return DXDupe::listdups('X', $dupage, @_);
+}
+
+sub genstats($)
+{
+ my $date = shift;
+ my $in = $fp->open($date);
+ my $out = $statp->open($date, 'w');
+ my @freq;
+ my %list;
+ my @tot;
+
+ if ($in && $out) {
+ my $i = 0;
+ @freq = map {[$i++, Bands::get_freq($_)]} qw(136khz 160m 80m 60m 40m 30m 20m 17m 15m 12m 10m 6m 4m 2m 220 70cm 23cm 13cm 9cm 6cm 3cm 12mm 6mm);
+ while (<$in>) {
+ chomp;
+ my ($freq, $by, $dxcc) = (split /\^/)[0,4,6];
+ my $ref = $list{$by} || [0, $dxcc];
+ for (@freq) {
+ next unless defined $_;
+ if ($freq >= $_->[1] && $freq <= $_->[2]) {
+ $$ref[$_->[0]+2]++;
+ $tot[$_->[0]+2]++;
+ $$ref[0]++;
+ $tot[0]++;
+ $list{$by} = $ref;
+ last;
+ }
+ }
+ }
+
+ for ($i = 0; $i < @freq+2; $i++) {
+ $tot[$i] ||= 0;
+ }
+ $statp->write($date, join('^', 'TOTALS', @tot));
+
+ 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;
+ }
+ $statp->write($date, join('^', $call, @$ref));
+ }
+ $statp->close;
+ }
+}
+
+# return true if the stat file is newer than than the spot file
+sub checkstats($)
+{
+ my $date = shift;
+ my $in = $fp->mtime($date);
+ my $out = $statp->mtime($date);
+ return defined $out && defined $in && $out >= $in;
+}
+
+# daily processing
+sub daily
+{
+ my $date = Julian::Day->new($main::systime)->sub(1);
+ genstats($date) unless checkstats($date);
+}