X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FQSL.pm;h=5101f25f6c561ca3ebfc67a6acf62a467bb0d536;hb=refs%2Fheads%2Fnewusers;hp=8849be0853cc5ce930e30701db57eab05ba7a247;hpb=e3beb3c736ca8e9ac9665d5c55f5d0f3cdb3f783;p=spider.git diff --git a/perl/QSL.pm b/perl/QSL.pm index 8849be08..5101f25f 100644 --- a/perl/QSL.pm +++ b/perl/QSL.pm @@ -2,7 +2,7 @@ # # Local 'autoqsl' module for DXSpider # -# Copyright (c) 2003 Dirk Koopman G1TLH +# Copyright (c) 2003-2020 Dirk Koopman G1TLH # package QSL; @@ -12,34 +12,29 @@ use DXVars; use DXUtil; use DB_File; use DXDebug; +use Prefix; -use vars qw($VERSION $BRANCH); -$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ ); -$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ || (0,0)); -$main::build += $VERSION; -$main::branch += $BRANCH; +use JSON; +use Data::Structure::Util qw(unbless); -use vars qw($qslfn $dbm); -$qslfn = 'qsl'; +use vars qw($qslfn $dbm $maxentries); +$qslfn = 'dxqsl'; $dbm = undef; +$maxentries = 10; + +my $json; +my %u; sub init { my $mode = shift; - my $ufn = "$main::root/data/$qslfn.v1"; - - eval { - require Storable; - }; - - if ($@) { - dbg("Storable appears to be missing"); - dbg("In order to use the QSL feature you must"); - dbg("load Storable from CPAN"); - return undef; - } - import Storable qw(nfreeze thaw); - my %u; + my $ufn = localdata("$qslfn.v2"); + + Prefix::load() unless Prefix::loaded(); + $json = JSON->new->canonical(1); + + untie %u; + undef $dbm; if ($mode) { $dbm = tie (%u, 'DB_File', $ufn, O_CREAT|O_RDWR, 0666, $DB_BTREE) or confess "can't open qsl file: $qslfn ($!)"; } else { @@ -50,16 +45,20 @@ sub init sub finish { + untie %u; undef $dbm; } sub new { my ($pkg, $call) = @_; + return undef if $call =~ /INFO|QSL|VIA/; return bless [uc $call, []], $pkg; } -# the format of each entry is [manager, times found, last time] +# called $self->update(comment, time, spotter) +# $self has the callsign as the first argument in an array of array references +# the format of each entry is [manager, times found, last time, last reporter] sub update { return unless $dbm; @@ -67,34 +66,58 @@ sub update my $line = shift; my $t = shift; my $by = shift; + my $changed; + + return unless length $line && $line =~ /\b(?:QSL|VIA|BUR[OE]?A?U?|OQRS|LOTW)\b/i; + foreach my $man (split /\b/, uc $line) { + my $tok; - my @tok = map {/^BUR/ || is_callsign($_) ? $_ : ()} split(/\b/, uc $line); - foreach my $man (@tok) { - $man = 'BUREAU' if $man =~ /^BUR/; - my ($r) = grep {$_->[0] eq $man} @{$self->[1]}; - if ($r) { - $r->[1]++; - if ($t > $r->[2]) { - $r->[2] = $t; - $r->[3] = $by; - } + if (is_callsign($man) && !is_qra($man)) { + my @pre = Prefix::extract($man); + $tok = $man if @pre && $pre[0] ne 'Q'; + } elsif ($man =~ /^BUR/) { + $tok = 'BUREAU'; + } elsif ($man =~ /^LOTW/) { + $tok = 'LOTW'; + } elsif ($man =~ /^OQRS/) { + $tok = 'OQRS'; + } elsif ($man eq 'HC' || $man =~ /^HOM/ || $man =~ /^DIR/) { + $tok = 'HOME CALL'; + } elsif ($man =~ /^QRZ/) { + $tok = 'QRZ.com'; } else { - $r = [$man, 1, $t, $by]; - push @{$self->[1]}, $r; + next; + } + if ($tok) { + my ($r) = grep {$_->[0] eq $tok} @{$self->[1]}; + if ($r) { + $r->[1]++; + if ($t > $r->[2]) { + $r->[2] = $t; + $r->[3] = $by; + } + $changed++; + } else { + $r = [$tok, 1, $t, $by]; + unshift @{$self->[1]}, $r; + $changed++; + } + # prune the number of entries + pop @{$self->[1]} while (@{$self->[1]} > $maxentries); } } - $self->put; + $self->put if $changed; } sub get { - my $key = uc shift; return undef unless $dbm; + my $key = uc shift; + my $value; - my $r = $dbm->get($key, $value); return undef if $r; - return thaw($value); + return json_decode($value); } sub put @@ -102,8 +125,30 @@ sub put return unless $dbm; my $self = shift; my $key = $self->[0]; - my $value = nfreeze($self); + my $value = json_encode($self); $dbm->put($key, $value); } +sub json_decode +{ + my $s = shift; + my $ref; + eval { $ref = $json->decode($s) }; + if ($ref && !$@) { + return bless $ref, __PACKAGE__; + } else { + LogDbg('DXUser', "__PACKAGE_::json_decode: on '$s' $@"); + } + return undef; +} + +sub json_encode +{ + my $ref = shift; + unbless($ref); + my $s = $json->encode($ref); + bless $ref, __PACKAGE__; + return $s; +} + 1;