Merge remote-tracking branch 'origin/github/pr/45'
[grml.org.git] / gen_website
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Template;
7 use File::Find::Rule;
8 use File::Path qw(make_path remove_tree);
9 use File::Basename qw (fileparse dirname);
10 use File::Copy::Recursive qw(fcopy dirmove);
11 use File::Temp qw (tempdir);
12
13 use lib '/usr/share/perl5/';
14
15 my $have_mirmon = 0;
16 my $masterlist = '/usr/local/src/grml-mirrors/Mirrors.masterlist';
17 my $mirmonconf = '/etc/mirmon.conf';
18
19 my $fh;
20 my $m;
21 my $conf;
22 my $state;
23 if (eval {require Mirmon; 1 } && -f $masterlist && -f $mirmonconf) {
24         $have_mirmon = 1;
25         open ($fh, '<', $masterlist) or die "Could not open $masterlist: $!";
26         $m = Mirmon ->new($mirmonconf);
27         $conf  = $m->conf  ; # a Mirmon::Conf object
28         $state = $m->state ; # the mirmon state
29 } else {
30         print "Skipping mirmon, it's either not installed or not configured.\n";
31 }
32
33
34 my $out_dir = shift || "out/";
35
36 my $mirrors; 
37
38 sub get_last_state ($) {
39         my $url = shift;
40         my $mirror_state = $state->{ $url } ; # a Mirmon::Mirror object
41         my ($time, $history) = split('-', $mirror_state->{state_history});
42         my $last_state = substr($history,-1,1);
43         return $last_state;
44 }
45
46
47 my $data;
48 while (($have_mirmon) && (my $line = <$fh>)) {
49     chomp $line;
50     if ($line =~ /([^:]+): (.*)/) {
51         my $key = lc($1);
52         my $value = $2;
53         $data->{$key} = $value;
54     } elsif ($line eq '') {
55         my $url = sprintf ("https://%s%s", $data->{'site'}, $data->{'grml-http'});
56         next if get_last_state($url) eq 'f';
57         $mirrors->{ $data->{'country'} }->{ $data->{'site'} } = $data;
58         $data = undef;
59     } else {
60         print "Malformed line: $line\n";
61     }
62 }
63
64 if ($data) {
65         my $url = sprintf ("https://%s%s", $data->{'site'}, $data->{'grml-http'});
66         $mirrors->{ $data->{'country'} }->{ $data->{'site'} } = $data if get_last_state($url) eq 'f';
67 }
68
69 #find all files
70
71 #rule to match git directorys
72 my $git = File::Find::Rule->directory
73                           ->name(".git")
74                           ->prune
75                           ->discard;
76
77 #matches all files
78 my $file_rule = File::Find::Rule->file();
79
80 #match symlinks
81 my $symlink_rule =  File::Find::Rule->symlink();
82
83 #combine all rules
84 my @files = File::Find::Rule->or( $git, $file_rule, $symlink_rule )
85                             ->in('.');
86
87 #create a tempdir
88 my $tempdir = tempdir( CLEANUP => 1 );
89 make_path("$tempdir/out") or die "Could not create $tempdir/out: $!";
90
91
92 #initialize template toolkit
93
94 my $template = Template->new;
95
96 foreach my $file (@files) {
97         next if $file =~ /^$out_dir/;
98         next if $file =~ /$0$/;
99         if ($file =~ /\.tt2$/) {
100                 my $output;
101                 $template->process($file, { mirrors => $mirrors }, \$output)
102                         || die "Could not process file \"$file\": $!";
103
104                 my ($name,$path,$suffix) = fileparse($file,qw (.tt2));
105                 make_path("$tempdir/out/$path") unless -d "$tempdir/out/$path";
106                 open (my $fh, '>', "$tempdir/out/$path/$name")
107                         or die "Could not write to $file: $!";
108                 print $fh $output;
109                 close($fh);
110         } else {
111                 fcopy ($file, "$tempdir/out/$file") or die "Could not copy $file to $tempdir/out/$file: $!";
112         }
113 }
114
115 $out_dir =~ s/\/$//;
116 if (-d $out_dir) {
117     dirmove ($out_dir, $out_dir . ".bak")
118         or die "Could not move $out_dir to $out_dir.bak: $!";
119 }
120 if (! dirmove ("$tempdir/out", "$out_dir")) {
121         warn "Could not move $tempdir/out to $out_dir: $!";
122         warn "Rollback";
123         remove_tree($out_dir);
124         dirmove ($out_dir . ".bak", $out_dir);
125 } else {
126         remove_tree($out_dir . ".bak");
127 }