X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXUtil.pm;h=500a615023ebdcf3fcf22fd001d715814c9372f2;hb=2462f5e2370ec0bdafe12deea0d131ea3718fb29;hp=49cba9e972ad55fab0d4300c5d4eb72103254382;hpb=cd5b993f99b52d3c3c51779e9ea1fa150232225e;p=spider.git diff --git a/perl/DXUtil.pm b/perl/DXUtil.pm index 49cba9e9..500a6150 100644 --- a/perl/DXUtil.pm +++ b/perl/DXUtil.pm @@ -8,23 +8,26 @@ package DXUtil; + use Date::Parse; use IO::File; use File::Copy; use Data::Dumper; +use Time::HiRes qw(gettimeofday tv_interval); use strict; -use vars qw(@month %patmap @ISA @EXPORT); +use vars qw(@month %patmap $pi $d2r $r2d @ISA @EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw(atime ztime cldate cldatetime slat slong yesno promptf parray parraypairs phex phash shellregex readfilestr writefilestr filecopy ptimelist - print_all_fields cltounix unpad is_callsign is_long_callsign is_latlong + print_all_fields cltounix unpad is_callsign is_latlong is_qra is_freq is_digits is_pctext is_pcflag insertitem deleteitem - is_prefix dd is_ipaddr + is_prefix dd is_ipaddr $pi $d2r $r2d localdata localdata_mv + diffms _diffms difft parraydifft ); @@ -36,6 +39,11 @@ require Exporter; ']' => ']' ); +$pi = 3.141592653589; +$d2r = ($pi/180); +$r2d = (180/$pi); + + # a full time for logging and other purposes sub atime { @@ -133,6 +141,7 @@ sub dd { my $value = shift; my $dd = new Data::Dumper([$value]); + $dd->Sortkeys(1); $dd->Indent(0); $dd->Terse(1); $dd->Quotekeys($] < 5.005 ? 1 : 0); @@ -174,7 +183,7 @@ sub ptimelist my $ref = shift; my $out; for (sort keys %$ref) { - $out .= "$_=$ref->{$_}, "; + $out .= "$_=" . atime($ref->{$_}) . ", "; } chop $out; chop $out; @@ -374,30 +383,20 @@ sub unpad # check that a field only has callsign characters in it sub is_callsign { - return $_[0] =~ m!^(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+) # basic prefix - (?:/(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+))? # / another one (possibly) - [A-Z]{1,3} # callsign letters - (?:/(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+))? # / another prefix possibly - (?:/[0-9A-Z]{1,2})? # /0-9A-Z+ possibly - (?:-\d{1,2})? # - nn possibly - $!x; -} + return $_[0] =~ m!^ + (?:\d?[A-Z]{1,2}\d*/)? # out of area prefix / + (?:\d?[A-Z]{1,2}\d+) # main prefix one (required) + [A-Z]{1,5} # callsign letters (required) + (?:-(?:\d{1,2}|\#))? # - nn possibly (eg G8BPQ-8) or -# (an RBN spot) + (?:/[0-9A-Z]{1,7})? # / another prefix, callsign or special label (including /MM, /P as well as /EURO or /LGT) possibly + $!x; -# check that a field only has callsign characters in it but has more than the standard 3 callsign letters -sub is_long_callsign -{ - return $_[0] =~ m!^(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+) # basic prefix - (?:/(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+))? # / another one (possibly) - [A-Z]{1,5} # callsign letters - (?:/(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+))? # / another prefix possibly - (?:/[0-9A-Z]{1,2})? # /0-9A-Z+ possibly - (?:-\d{1,2})? # - nn possibly - $!x; + # longest callign allowed is 1X11/1Y11XXXXX-11/XXXXXXX } sub is_prefix { - return $_[0] =~ m!^(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}\d+)!x # basic prefix + return $_[0] =~ m!^(?:[A-Z]{1,2}\d+ | \d[A-Z]{1,2}}\d+)!x # basic prefix } @@ -430,7 +429,8 @@ sub is_digits # does it look like a qra locator? sub is_qra { - return $_[0] =~ /^[A-Ra-r][A-Ra-r]\d\d[A-Xa-x][A-Xa-x]$/; + return unless length $_[0] == 4 || length $_[0] == 6; + return $_[0] =~ /^[A-Ra-r][A-Ra-r]\d\d(?:[A-Xa-x][A-Xa-x])?$/; } # does it look like a valid lat/long @@ -442,7 +442,7 @@ sub is_latlong # is it an ip address? sub is_ipaddr { - return $_[0] =~ /^\d+\.\d+\.\d+\.\d+$/ || $_[0] =~ /^[0-9a-f:]+$/; + return $_[0] =~ /^\d+\.\d+\.\d+\.\d+$/ || $_[0] =~ /^[0-9a-f:,]+$/; } # insert an item into a list if it isn't already there returns 1 if there 0 if not @@ -467,3 +467,99 @@ sub deleteitem return $n - @$list; } +# find the correct local_data directory +# basically, if there is a local_data directory with this filename and it is younger than the +# equivalent one in the (system) data directory then return that name rather than the system one +sub localdata +{ + my $ifn = shift; + my $ofn = "$main::local_data/$ifn"; + my $tfn; + + if (-e "$main::local_data") { + $tfn = "$main::data/$ifn"; + if ((-e $tfn) && (-e $ofn)) { + $ofn = $tfn if -M $ofn < -M $tfn; + } else { + $ofn = $tfn if -e $tfn; + } + } + + return $ofn; +} + +# move a file or a directory from data -> local_data if isn't there already +sub localdata_mv +{ + my $ifn = shift; + if (-e "$main::data/$ifn" ) { + unless (-e "$main::local_data/$ifn") { + move("$main::data/$ifn", "$main::local_data/$ifn") or die "localdata_mv: cannot move $ifn from '$main::data' -> '$main::local_data' $!\n"; + } + } +} + +# measure the time taken for something to happen; use Time::HiRes qw(gettimeofday tv_interval); +sub _diffms +{ + my $ta = shift; + my $tb = shift || [gettimeofday]; + my $a = int($ta->[0] * 1000) + int($ta->[1] / 1000); + my $b = int($tb->[0] * 1000) + int($tb->[1] / 1000); + return $b - $a; +} + +sub diffms +{ + my $pkg = shift; + my $call = shift; + my $line = shift; + my $ta = shift; + my $no = shift; + my $tb = shift; + my $msecs = _diffms($ta, $tb); + + $line =~ s|\s+$||; + my $s = "$pkg subprocess stats cmd: '$line' $call ${msecs}mS"; + $s .= " $no lines" if $no; + DXDebug::dbg($s); +} + +# expects either an array reference or two times (in the correct order [start, end]) +sub difft +{ + my $b = shift; + my $t; + if (ref $b eq 'ARRAY') { + $t = $b->[1] - $b->[0]; + } else { + $t = shift() - $b; + } + return '-(ve)' if $t < 0; + my ($d,$h,$m,$s); + my $out = ''; + $d = int $t / 86400; + $out .= "${d}d" if $d; + $t -= $d * 86400; + $h = int $t / 3600; + $out .= "${h}h" if $h || $d; + $t -= $h * 3600; + $m = int $t / 60; + $out .= "${m}m" if $m || $h || $d; + $s = int $t % 60; + $out .= "${s}s"; + return $out; +} + +# print an array ref of difft refs +sub parraydifft +{ + my $r = shift; + my $out = ''; + for (@$r) { + my $s = $_->[2] ? "($_->[2])" : ''; + $out .= sprintf "%s=%s$s, ", atime($_->[0]), difft($_->[0], $_->[1]); + } + $out =~ s/,\s*$//; + return $out; +}