providing option to connect to memcache at general connect time
[OpenSRF.git] / src / perlmods / OpenSRF / Utils.pm
index af9e3b9..46816cb 100644 (file)
@@ -29,14 +29,19 @@ use FileHandle;
 #use Storable qw(dclone);
 use Digest::MD5 qw(md5 md5_hex md5_base64);
 use Exporter;
+use DateTime;
+use DateTime::Format::ISO8601;
+use DateTime::TimeZone;
+
+our $date_parser = DateTime::Format::ISO8601->new;
 
 # This turns errors into warnings, so daemons don't die.
 #$Storable::forgive_me = 1;
 
 %EXPORT_TAGS = (
-       common          => [qw(interval_to_seconds seconds_to_interval sendmail)],
+       common          => [qw(interval_to_seconds seconds_to_interval sendmail tree_filter)],
        daemon          => [qw(safe_fork set_psname daemonize)],
-       datetime        => [qw(clense_ISO8601 interval_to_seconds seconds_to_interval)],
+       datetime        => [qw(clense_ISO8601 gmtime_ISO8601 interval_to_seconds seconds_to_interval)],
 );
 
 Exporter::export_ok_tags('common','daemon','datetime');  # add aa, cc and dd to @EXPORT_OK
@@ -72,6 +77,19 @@ sub _sub_builder {
        }
 }
 
+sub tree_filter {
+       my $tree = shift;
+       my $field = shift;
+       my $filter = shift;
+
+       my @things = $filter->($tree);
+       for my $v ( @{$tree->$field} ){
+               push @things, $filter->($v);
+               push @things, tree_filter($v, $field, $filter);
+       }
+       return @things
+}
+
 #sub standalone_ipc_cache {
 #      my $self = shift;
 #      my $class = ref($self) || $self;
@@ -241,14 +259,15 @@ sub interval_to_seconds {
         $interval =~ s/,/ /g;
 
         my $amount = 0;
-        while ($interval =~ /\s*\+?\s*(\d+)\s*(\w{1})\w*\s*/g) {
-                $amount += $1 if ($2 eq 's');
-                $amount += 60 * $1 if ($2 eq 'm');
-                $amount += 60 * 60 * $1 if ($2 eq 'h');
-                $amount += 60 * 60 * 24 * $1 if ($2 eq 'd');
-                $amount += 60 * 60 * 24 * 7 * $1 if ($2 eq 'w');
-                $amount += ((60 * 60 * 24 * 365)/12) * $1 if ($2 eq 'M');
-                $amount += 60 * 60 * 24 * 365 * $1 if ($2 eq 'y');
+        while ($interval =~ /\s*\+?\s*(\d+)\s*(\w+)\s*/g) {
+               my ($count, $type) = ($1, $2);
+                $amount += $count if ($type eq 's');
+                $amount += 60 * $count if ($type =~ /^m(?!o)/oi);
+                $amount += 60 * 60 * $count if ($type =~ /^h/);
+                $amount += 60 * 60 * 24 * $count if ($type =~ /^d/oi);
+                $amount += 60 * 60 * 24 * 7 * $count if ($2 =~ /^w/oi);
+                $amount += ((60 * 60 * 24 * 365)/12) * $count if ($type =~ /^mo/io);
+                $amount += 60 * 60 * 24 * 365 * $count if ($type =~ /^y/oi);
         }
         return $amount;
 }
@@ -338,15 +357,53 @@ sub set_psname {
        $0 = $PS_NAME if ($PS_NAME);
 }
 
+sub gmtime_ISO8601 {
+       my $self = shift;
+       my @date = gmtime;
+
+       my $y = $date[5] + 1900;
+       my $M = $date[4] + 1;
+       my $d = $date[3];
+       my $h = $date[2];
+       my $m = $date[1];
+       my $s = $date[0];
+
+       return sprintf('%d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2d+00:00', $y, $M, $d, $h, $m, $s);
+}
+
 sub clense_ISO8601 {
        my $self = shift;
        my $date = shift || $self;
-       if ($date =~ /(\d{4})-?(\d{2})-?(\d{2}).?(\d{2}):(\d{2}):(\d{2})\.?\d*((?:-|\+)[0-9:]{2,5})?$/) {
-               my $z = $7 || '+00:00';
-               if (length($z) > 3 && $z !~ /:/o) {
-                       substr($z,3,0,':');
+       if ($date =~ /^\s*(\d{4})-?(\d{2})-?(\d{2})/o) {
+               my $new_date = "$1-$2-$3";
+
+               if ($date =~/(\d{2}):(\d{2}):(\d{2})/o) {
+                       $new_date .= "T$1:$2:$3";
+
+                       my $z;
+                       if ($date =~ /([-+]{1})([0-9]{1,2})(?::?([0-9]{1,2}))*\s*$/o) {
+                               $z = sprintf('%s%0.2d%0.2d',$1,$2,$3)
+                       } else {
+                               $z =  DateTime::TimeZone::offset_as_string(
+                                       DateTime::TimeZone
+                                               ->new( name => 'local' )
+                                               ->offset_for_datetime(
+                                                       $date_parser->parse_datetime($new_date)
+                                               )
+                               );
+                       }
+
+                       if (length($z) > 3 && index($z, ':') == -1) {
+                               substr($z,3,0) = ':';
+                               substr($z,6,0) = ':' if (length($z) > 6);
+                       }
+               
+                       $new_date .= $z;
+               } else {
+                       $new_date .= "T00:00:00";
                }
-               $date = "$1-$2-$3T$4:$5:$6$z";
+
+               return $new_date;
        }
        return $date;
 }