#!/usr/bin/env perl # Copyright (C) 2012, Enlik # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. use warnings; use strict; use Getopt::Long; use HTML::Template; use 5.010; # This makes accessing edition's data more clear. # Class EditionItem stores URL, size and date for an edition for one # architecture, for one file type (which means that one EditionType # is needed for an .iso, another one for a .md5sum file and so on). # We don't use, for example, size for .md5 files, but just in case it changes... { package EditionItem; my ($href, $size, $date); sub new { my $class = shift; my %self = @_; for my $item (qw(url size date)) { die "EditionItem::new(): $item not defined" unless defined $self{$item} } bless \%self, $class; } sub url { $_[0]->{url} } sub size { $_[0]->{size} } sub date { $_[0]->{date} } sub toString { my $self = shift; my ($url, $size, $date) = ($self->{url}, $self->{size}, $self->{date}); return "$url (size = $size, date = $date)"; } } # $sab{edition}->{arch}->{type} = EditionItem # type is one of: ".md5", ".pkglist", ".torrent", "" my %sab; my @oth; my $tmpl; sub print_other { return unless @oth; my @others_loop_data; for my $item (@oth) { push @others_loop_data, { url => $item->[0], name => $item->[1] } } $tmpl->param(others_loop => \@others_loop_data); } # Adds elements to template which will be printed. # $regex is a regular expression to specify which arches to select; # $negate - if true, $regex will be negated; # $editions_loop_arch - name of the loop in template to use; # $extra_fields - what to pass to template besides for "" and ".md5", # for example ".pkglist" to pass .pkglist for arches/editions which have # such files; supported types: ".pkglist" and ".torrent" sub print_items { my ($regex, $negate, $editions_loop_arch, $extra_fields) = @_; my $match; my %extra_fields = map { $_ => 1 } @{ $extra_fields }; my @editions_loop_data = (); for my $edition (sort keys %sab) { my $displayed_edition = 0; my @arches_loop_data = (); for my $arch (sort keys %{ $sab{$edition} }) { $match = $arch =~ $regex; $match = !$match if $negate; next unless $match; # these are EditionItem objects my $ISO = $sab{$edition}->{$arch}->{""}; my $md5 = $sab{$edition}->{$arch}->{".md5"}; my $pkglist = $sab{$edition}->{$arch}->{".pkglist"} if $extra_fields{".pkglist"}; my $torrent = $sab{$edition}->{$arch}->{".torrent"} if $extra_fields{".torrent"}; for my $item (qw(.torrent .pkglist)) { if (defined $sab{$edition}->{$arch}->{$item} and not $extra_fields{$item}) { warn "Warning: file type $item not specified to print, ", "but it is available for $edition -> $arch: ", $sab{$edition}->{$arch}->{$item}->url } } my %arches_loop_row; # fresh hash for new arch $arches_loop_row{name} = $edition; $arches_loop_row{arch} = $arch; # any item is counted, even if there's no ISO but only md5sum # not too pretty, but fast enough $arches_loop_row{arches_per_edition} = 0; for my $arch (keys %{ $sab{$edition} }) { my $match = $arch =~ $regex; $match = !$match if $negate; $arches_loop_row{arches_per_edition}++ if $match; } # Some of them (ISO, md5, pkglist) may be not defined, # depending on available file types. # If x is defined, then x->url, x->size and x->time are defined. # Note: size and date for non-ISO-like files are discarded here. if (defined $ISO) { $arches_loop_row{mainfile_url} = $ISO->url; $arches_loop_row{mainfile_size} = $ISO->size; $arches_loop_row{mainfile_date} = $ISO->date; } if (defined $md5) { $arches_loop_row{md5_url} = $md5->url; #$arches_loop_row{md5_size} = $md5->size; #$arches_loop_row{md5_date} = $md5->date; } if (defined $pkglist) { $arches_loop_row{pkglist_url} = $pkglist->url; #$arches_loop_row{pkglist_size} = $pkglist->size; #$arches_loop_row{pkglist_date} = $pkglist->date; } if (defined $torrent) { $arches_loop_row{torrent_url} = $torrent->url; } # push data (name, download links, ...) for an architecture push @arches_loop_data, \%arches_loop_row; } # say "
" if $displayed_edition; # with nested loops this template thingy goes a little obscure... push @editions_loop_data, { arches_loop => \@arches_loop_data } if (@arches_loop_data); } $tmpl->param($editions_loop_arch => \@editions_loop_data); } sub add_item { my ($edition, $arch, $type, $href, $size, $mdate) = @_; die "add_item: args!\n" unless @_ == 6; if (defined $sab{$edition}->{$arch}->{$type}) { my $ei = $sab{$edition}->{$arch}->{$type}; warn "Warning: already defined! ($edition, $arch, $type), item = ", $ei->toString, "\n"; } $sab{$edition}->{$arch}->{$type} = EditionItem->new (url => $href, size => $size, date => $mdate); } # Parse file name and add using add_item. First argument is file name; second # argument is prefix (see help for --prefix). # The rest will be passed to add_item (it's used to pass additional attributes # gathered by caller). sub parse_entry { my $href = shift; my $prefix = shift; my @extra_args = @_; my $href_full = $href; my $type_ext = ""; # find file type for my $ext (qw(.md5 .pkglist .torrent)) { if ($href =~ /\Q${ext}\E$/) { $type_ext = $ext; $href =~ s/\Q${ext}\E$//; # part without "well known extension" last; } } my $href_link = $prefix . $href_full; my $re_pref = "Sabayon_Linux"; my $re_arch = "(?