Time-OlsonTZ-Download

 view release on metacpan or  search on metacpan

lib/Time/OlsonTZ/Download.pm  view on Meta::CPAN

=head1 DESCRIPTION

An object of this class represents a local copy of the source of
the Olson timezone database, possibly used to build binary tzfiles.
The source copy always begins by being downloaded from the canonical
repository of the Olson database.  This class provides methods to help
with extracting useful information from the source.

=cut

package Time::OlsonTZ::Download;

{ use 5.008; }
use warnings;
use strict;

use Carp qw(croak);
use Encode 1.75 qw(decode FB_CROAK);
use File::Path 2.07 qw(rmtree);
use File::Temp 0.22 qw(tempdir);
use IO::Dir 1.03 ();
use IO::File 1.03 ();
use IPC::Filter 0.002 qw(filter);
use Net::FTP 3.07 ();
use Params::Classify 0.000 qw(is_undef is_string);
use utf8 ();

our $VERSION = "0.009";

my $keyring = unpack("u", <<'KEYRING');
MF0(-!$R`<F0!$`#``R'VQH3N[II&Y#W:\%,9$HG[X="O<X^JU7`V)VM!RVIP
M:3J?AIQQ=&`])CYT4)W/#X;24$@-\M+9TL:GX[EY73`%+BVXYZ<B2EYF\L*:
M'E&=M]7F``MF7J>95(87_4%2]Z?#S?XQA$FF_R[+;8$/0=4=QNX[Q`Y*A38I
MY;EM%W68#SU8@=[@QT[`NPI[BP[>-OGH#3`E*`E\*8#9S;#-"0&$;I8W>?9(
MO/=>(^%60-X6^D@AR^/Z:NZ/K((A8K:>N:[7#=;V+2U>GW2LF$W0CJ?1J(_`
MVN>\),PLO7>_6*W\$SLZQ[XB3:J(W`%'ZBE`A#JI,G=_FL2$2-%M[Z#B.U9*
M0,K]:F5/DGC?/F)(2J=A@!U#E$=PWXL1.?Z5\F9PTQ?J3Z/*$XZ+<%>?SLTD
M;@X&.1?\OC&V2?UMDY>4\,!BR-_;9TW;*-C-8,I.##00PN/\XD8+D7VP!QQ,
M`A!QP;#59N=SQ#9)U"V57NC".)5QJVDEC!,]$38N4&J=[Y`6V+7K+PZ^,N(L
M'%`8`@1K[^*<P#@!`?PA/!87WXG22B'EF+"^*:'+>"+%Y9(VO*FW'$>"3ME.
M@[Q9$.-@PS+^?=*H^#Z2H"\11Q)*L\:WL5?(XMZ"GK0SO);!GZ@Q=@"NYBV]
M)U0"8K"8OJEV4R%/`*^=H]]_UC.73XFV\WZCUP`1`0`!M"!0875L($5G9V5R
M="`\96=G97)T0&-S+G5C;&$N961U/HD"/@03`0(`*`4"3(!R9`(;`P4)$LP#
M``8+"0@'`P(&%0@""0H+!!8"`P$"'@$"%X``"@D0[9?I#F*J?C11&P_^(CTW
M=A8?8E_@751BNS5U@&K;'D^MG?K(_"[?`>H%S0YM5@5BG2A:/D9HT'3/?U\Q
MZ(#$=`B.\,JHURIT"M'FS&,")YTHX&K@?CEKZ@_^OM$.*;AE>LS-V7I)OIP,
MV0@&OG_E:3+4N\/']:163L[J))9***`;XLQ8<]V%>A/NZ%.#T=#BRAE#`JXE
M.5VF=!IS0;BHCH9S0+,0PCI@"3*VY[V>*]$.$0R243A7K2(SZ`2>GIX-83%'
ML]MN)0O7D]@9#=/2EW;I^X[=&QEQ$6+I!(,[S(.-PXDLX:S@3\GO#9Q`Y(9'
MMOJ!E)+!.;88T+>ZU6ITRW3E!#AVJ=*\>8+XVZ6XL<$,2NB@Y@;\.`M0B!6Z
MDVL&4QQ>BO\HO6N\8`9@*)?NH6(^N1G,$==KN8\)LH,YX*:*O9BDD*LV;@UG
M=M+5S'I)ZJ%9"[05C>'4AZ_!F@O=C6/98%3M-^*`]"67W&0**@-WNN]\\RSG
M#[+G!]\3X$4'U'`_&G?!J,5U@IS3O/<XJ50BG"F(D$%I\WSE^&Y?"C))W6[B
MOS"G8HX*A*+I%4F][HD3*1V+6WQ9S$6X<+26.W\[,3*W"S#.QYJ>ZLX:]U9N
M9,_C_30=3+#:J-G\WD`X'JX\4'78Q<(A^-=\D_WPZE%NH*TPK.%BRPC+Q^TN
.KYCFF;><!&'<UQ=A`%$`
KEYRING

sub _verify_signature($$) {
	my($self, $localname) = @_;
	my $krfile = $self->{top_dir}."/kr.gpg";
	unless($self->{have_keyring}) {
		filter($keyring, "tee", $krfile);
		$self->{have_keyring} = 1;
	}
	my $subjfile = $self->{top_dir}."/".$localname;
	filter("", "gpgv", "--keyring", $krfile, "$subjfile.asc", $subjfile);
}

my $archive_hash = <<'HASHES';
P$`IAK1/'QW'S,*892Y(QHOJBH5H}S8Y%YO)[;GZKP$
^+'@Q[[<#EOR3!YLOVNPT049W7$>C:B+`U'(QD"0>&8 tz32code2006b.tar.gz
VKM[][KTE<B13H0;J6`Z5"2778$%RT;R:641,>&MGBX
W4VW8\YND-$}}SJ>K:&1PQ]"&I2'B'WA@>J8U])7D"0 tz64code2006b.tar.gz
MNA!Y(:V"8<)JH;*GH\8."0W"SK"^AGOF"`U%P<$0!X
R(Y3G'R:4?_W0]Z[L\4H1;A*`1/ZY(FON0&9_>]U8#\ tzcode1996m.tar.gz
]A@KB.+SZ%WC[W%D740$5'WZ8*P(7.K46497CNJX7OD
P\0,)Z7_3B:1`#%JX63KZO2AP6CVCHJQ4JKT#"TX.HT tzcode1996n.tar.gz
>$LQ?T8},4/8PYSXAC%T<X$DM";14,,CY5ALZ]^"1?4
]KY>N'1E-HL@;('"0AHGC8'-BT/"@\J(Q!!#](PR$\L tzcode1996o.tar.gz
(@:9K9#^4'YP@O`[1L*"L/S]TZVG,)?_;/MA-<XG*!`
8%!.RF90V24VGA>FC8<G26>WFYN:-Q``M$W28*W:@+T tzcode1997a.tar.gz
K,ZBCE^VW6*_AKQPGJ'5&1A>`K!?ES.(+R&G!GNSF2@
"?G4I0H3[78@"K2`YX)>(J#!JYV(3Q4/4;$'VQYA_VD tzcode1997b.tar.gz
/*LHT0+AE;#6'ZCVZ6S@VP0$#G@?4Z/:ELZ%`ML^JPP
_O147ENUT'-}4F.NKO}LS'I:N),^H`)<M(5TR.Y9NJ< tzcode1997c.tar.gz
09S8MCYT"Z}'8X**'W5G&B*MK\:#7?$)K75S6K'%MY,
#`2^59N!B6(9\$5:XDIZKB*P@<'JLV6%4UK2@:-SF3P tzcode1997d.tar.gz
$HQI06E:FD2S;'-AO/U08IXL:GYKV,2LF'%S\</ZSB<
Z&DDN6JC6`.D']B,:205L%LE0CIA!G42P*O1)H">J?H tzcode1997e.tar.gz
QKZ[["IJ6[7VWJ)!-S("[_M02XCM:E8CGI-&!GW4;AX
A]9CKZY}%ZW&_?<FHI"-$'YF%ZM)AS>1%}H-8[Y%-*( tzcode1997f.tar.gz
#FPZ-(Q?,Z7^}^4<JJ:XNS`VLS>N:2U62}1P7KW;,E(
D[JK;$_XM)V_K+Z33J)>AEO9TM^G0D@YGI63&2F(CY0 tzcode1997g.tar.gz
;>XM4,W*LTZ9B+JI./#Z7X'?8F[$GYH`:1Q1LR%/&D\
JH+4K2EZ1XM%6$R^`NU4Z[*,BC2@P6F"5KM[}[`2+M\ tzcode1997h.tar.gz
#":0$VMCE7ZE@Q,Z!P"1@"*/N^2:T"@!JIMXDJ5;!E(
@9QB]GO&%(18/1T4SCM)QE0'B[!9/'X>}>9OL+35*SH tzcode1997i.tar.gz
[X%-#X4H;7[LUBSM`/<!9+GU/"YZO<Z;GDQ&H#GDZY<
M4\7'_UDFM!.Q1]'-T}B:VBKD?9\A0^&A'7)G`+I"K( tzcode1998a.tar.gz
1':-`"GE233?Z+^#23T72*U1B7})_?P#,?FR0%[<4,<
_-$XL/Q$5INX@7T'N:D@)LV:RXYWCD9}U\?E:U&RR:4 tzcode1998b.tar.gz
F6@N8$>[<+#8`:L`"%I-L:)4ZQO)Q0J"MG8EHL}UQ6L
"%;]G2:!.*Q`^+"3HE\9UTIX-"O6]%U"+'$,7?H0;$< tzcode1998c.tar.gz
OGT#:)(S_L&#`'6`%96EGNJ[D'OK3-LZD-H&2S8MD!@
1.1L+NNJR&2E2,0PPMN!:S)TMUK&'\V(G$8AI,N"W!P tzcode1998d.tar.gz
J$>9-;<)+Z,U2-F\KECK;>@L4U!C%MG)B7H6H>6SJ80
A;/YMV00%LL`^L0%QBC;E<KZ!$WN/*ELQM5W7.J#Q'` tzcode1998e.tar.gz
3;!<]_[C8UTV6NO`1&8[)[FZF4$BKK7@9^_6J/\VNEL
25#9+JU6@MJQ@(OG[H>N41Q;#Z$8.D].311#CF+C#@4 tzcode1998f.tar.gz
,%7V%)L1<.UQD}6:AI%FJEW4G-T;L91JPA+T`C!#&HT
V28})%G&$\/BPP+9D!8,A?1>O2ABCKW@JHD"4_SL`X( tzcode1998g.tar.gz
UUSM!AZ#D);N[IXQ9U6ZZ)GYN`I;+T?01#P>/SD:/Q@
HTSY\4#-<D$2F8I@K*A>5<6W$D?R74"_UK[[Z_+T>^$ tzcode1998h.tar.gz
B8X9%$4VK"1:?$&9;)H3!_-F5X*L`5>J*YD1W*OUE$8
_`YLN'QT:E\J}YBN*)Z1$>K_^A$F8WY7%#J3"*Z#!ZL tzcode1999a.tar.gz
0M7Z,7(`*KF1"SGY%V0;#}+U`HY,__@S3%+F_Q#}<+,
(W%J0QU9OZ.UFJM_Z<1OHA(_OU[(N5-SDJP}P0SROGP tzcode1999b.tar.gz
C}T642QR'*@$DP5P]AM)]1,*H;LD^Q(X-`3^K-;EI60
BJR`4,G@Z<9+E1M>ZEZC6<8O;JELN-)3IG@VZ:,`8^, tzcode1999c.tar.gz
$&N/VK]JF)"D"OUAU7U4I^N`.]@!0)3@UJ2K]N#;]$8
#0M&UN-:"]\]&9/P8POORT@I**@<XT@^W3*<V^}"><P tzcode1999d.tar.gz
Y4IXT]3HZBWYI*[EZ09%34OX}3D]2S#J%QN$Q#*VY&,
50:56X>(&I'!Z8<P:13PN8W%6+>(%L)"_C09*26BL?D tzcode1999e.tar.gz
'I%Q%3}}1T!+RBD4YRHC+>ZO+1&8};MH3O}_9MW}K>(
D%J)Q[R0!]6H184H-T"K%V;!@M>^VS?05W1+GVM@LV\ tzcode1999f.tar.gz
V*L0,}B.+3MP419UKZN$A_D6L].#:MC3PI?;8O43:CD

lib/Time/OlsonTZ/Download.pm  view on Meta::CPAN

1972 and the date of the database, and are intended to be used on a
system where C<time_t> is (from 1972 onwards) a linear count of TAI
seconds (which is a non-standard arrangement).

=back

=cut

sub _foreach_nondir_under($$);
sub _foreach_nondir_under($$) {
	my($dir, $callback) = @_;
	my $dh = IO::Dir->new($dir) or die "can't examine $dir: $!\n";
	while(defined(my $ent = $dh->read)) {
		next if $ent =~ /\A\.\.?\z/;
		my $entpath = $dir."/".$ent;
		if(-d $entpath) {
			_foreach_nondir_under($entpath, $callback);
		} else {
			$callback->($entpath);
		}
	}
}

sub zoneinfo_dir {
	my($self, $options) = @_;
	$options = {} if is_undef($options);
	foreach(keys %$options) {
		die "bad option `$_'\n" unless /\Aleaps\z/;
	}
	my $type = $options->{leaps} ? "right" : "posix";
	my $zidir = $self->dir."/zoneinfo_$type";
	unless($self->{"zoneinfo_built_$type"}) {
		filter("", "make", "-C", $self->unpacked_dir,
			"${type}_only", "TZDIR=$zidir", "VERSION_DEPS=");
		my %expect_names = %{$self->all_names};
		my $skiplen = length($zidir) + 1;
		_foreach_nondir_under($zidir, sub {
			my($fname) = @_;
			my $lname = substr($fname, $skiplen);
			unless(exists $expect_names{$lname}) {
				die "unexpected file $lname\n";
			}
			delete $expect_names{$lname};
		});
		if(keys %expect_names) {
			die "missing file @{[(sort keys %expect_names)[0]]}\n";
		}
		$self->{"zoneinfo_built_$type"} = 1;
	}
	return $zidir;
}

=back

=head1 BUGS

Most of what this class does will only work on Unix platforms.  This is
largely because the Olson database source is heavily Unix-oriented.

This class also depends on the availability of some tools beyond
baseline Unix.  Specifically, it requires GNU C<gpgv>, GNU C<tar>,
C<lzip>, C<sha512sum>, and GNU C<make>.

It also won't be much good if you're not connected to the Internet.

This class is liable to break if the format of the Olson database source
ever changes substantially.  If that happens, an update of this class
will be required.  It should at least recognise that it can't perform,
rather than do the wrong thing.

=head1 SEE ALSO

L<DateTime::TimeZone::Tzfile>,
L<Time::OlsonTZ::Data>,
L<tzfile(5)>

=head1 AUTHOR

Andrew Main (Zefram) <zefram@fysh.org>

=head1 COPYRIGHT

Copyright (C) 2010, 2011, 2012, 2017, 2018
Andrew Main (Zefram) <zefram@fysh.org>

=head1 LICENSE

This module is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1;



( run in 1.246 second using v1.01-cache-2.11-cpan-df04353d9ac )