Browse Source

Adding build scripts for the test instance and for future production instance based on svn

svn path=/trunk/; revision=13809
tags/stw2018
cri 9 years ago
parent
commit
25868bbb89
7 changed files with 1730 additions and 0 deletions
  1. 166
    0
      tools/build-new.sh
  2. 738
    0
      tools/build-test.pl
  3. 166
    0
      tools/build-test.sh
  4. 47
    0
      tools/status-new.php
  5. 47
    0
      tools/status-test.php
  6. 283
    0
      tools/translation-log-new.sh
  7. 283
    0
      tools/translation-log-test.sh

+ 166
- 0
tools/build-new.sh View File

@@ -0,0 +1,166 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# Web page build script
# -----------------------------------------------------------------------------
# This script is called every 5 minutes on www.fsfe.org to rebuild the
# HTML pages from the .xhtml, .xml and .xsl source files. Most of the work,
# however, is done by the Perl script build.pl.
# -----------------------------------------------------------------------------

SOURCE=/home/www/fsfe
DEST=/home/www/html
TMP=/home/www/tmp.$$
STATUS=/var/www/web
ALARM_LOCKFILE=alarm_lockfile

# Since we must grep for svn output messages,
# let's ensure we get English messages
export LANG=C

# If there is a build.pl script started more than 30 minutes ago, mail alarm
BUILD_STARTED=$(ps --no-headers -C build.pl -o etime | cut -c 7-8 | sort -r | head -n 1)
if [[ -n "$BUILD_STARTED" && "10#${BUILD_STARTED}" -gt 30 && ! -f ${STATUS}/${ALARM_LOCKFILE} ]] ; then
echo -e "
A build.pl script has been running for more than 30 minutes!
Please:
- run 'ps aux | grep build.pl' and kill build.pl processes older than 30 minutes
- Check the build script log at http://status.fsfe.org/web/
- Fix the cause of the problem
- Delete the lockfile ${STATUS}/${ALARM_LOCKFILE}

" | mail -s "www.fsfe.org: build.pl warning" system-hackers@fsfeurope.org

# This lockfile avoids sending the mail alarm more than once;
# it must be deleted when the problem is solved.
touch ${STATUS}/${ALARM_LOCKFILE}
fi

# If build is already running, don't run it again.
if ps -C build.sh -o pid= | grep -q -v "$$"; then
exit
fi

# Redirect output
exec 1> ${STATUS}/status.txt 2>&1

cd ${SOURCE}

# -----------------------------------------------------------------------------
echo "$(date) Cleaning old build directories."
# -----------------------------------------------------------------------------

rm -rf /home/www/tmp.*

# -----------------------------------------------------------------------------
echo "$(date) Updating source files from SVN."
# -----------------------------------------------------------------------------

# Rebuild only if changes were made to the SVN or it hasn't run yet today
# (unless "-f" option is used)
#
# We must run it once every day at least to move events from future to current
# and from current to past.
#
# Since the "svn update" exit status cannot be trusted, and "svn update -q" is
# always quiet, we have to test the output of "svn update" (ignoring the final
# "At revision" line) and check for any output lines
if test -z "$(svn update 2>/dev/null | grep -v 'At revision')" \
-a "$(date -r ${STATUS}/last-run +%F)" == "$(date +%F)" \
-a "$1" != "-f" ; then
echo "$(date) No changes to SVN."
# In this case we only append to the cumulative status-log.txt file, we don't touch status-finished.txt
cat ${STATUS}/status.txt >> ${STATUS}/status-log.txt
exit
fi

# Make sure build.sh and build.pl are executable
# TODO: this can be removed once we set the "executable" svn property
# to these files
chmod +x tools/build.sh tools/build.pl
chmod +x cgi-bin/weborder.pl cgi-bin/stacs-register-capacity.pl
chmod +x cgi-bin/stacs-register-workshop.pl

if test "$1" == "-f" ; then
echo "Forced rebuild"
fi

# -----------------------------------------------------------------------------
echo "$(date) Running Makefiles."
# -----------------------------------------------------------------------------

make --silent

# -----------------------------------------------------------------------------
echo "$(date) Building HTML pages."
# -----------------------------------------------------------------------------

touch ${STATUS}/last-run

if test "x`hostname`" = "xekeberg"; then
tools/build.pl -t 16 -q -o ${TMP} -i .
elif test "x`hostname`" = "xberzelius"; then
tools/build.pl -t 2 -q -o ${TMP} -i .
else
tools/build.pl -q -o ${TMP} -i .
fi

if test $? -ne 0; then
echo "$(date) Build not complete. Aborting."
cp ${STATUS}/status.txt ${STATUS}/status-finished.txt
cat ${STATUS}/status-finished.txt >> ${STATUS}/status-log.txt
exit 1
fi

# -----------------------------------------------------------------------------
echo "$(date) Linking source files."
# -----------------------------------------------------------------------------

for target in ${TMP}/*; do
test -d ${target} && ln -s ${SOURCE} ${target}/source
done

# -----------------------------------------------------------------------------
echo "$(date) Creating symlinks."
# -----------------------------------------------------------------------------

for f in $(find ${TMP} -name .symlinks); do
cd $(dirname $f)
cat $f | while read source destination; do
ln -sf ${source} ${destination} 2>/dev/null
done
done
cd ${SOURCE}

# -----------------------------------------------------------------------------
echo "$(date) Obfuscating email addresses."
# -----------------------------------------------------------------------------

# This replaces all '@' in all html files with '@'. We use '-type f'
# because we want to exclude symlinks. Because 'sed -i' is a very expensive
# operation, even if there is no replacement done anyway, we first limit the
# files to operate on to those files that actually contain an '@'.
find ${TMP} -type f -name "*.html" | xargs grep -l '@' | xargs sed -i 's/@/\@/g'

# -----------------------------------------------------------------------------
echo "$(date) Activating new output."
# -----------------------------------------------------------------------------

mv ${DEST} ${DEST}.old
mv ${TMP} ${DEST}
rm -rf ${DEST}.old

# -----------------------------------------------------------------------------
echo "$(date) Generating translation logs."
# -----------------------------------------------------------------------------

tools/translation-log.sh ${DEST}/translations.log ${STATUS}

# -----------------------------------------------------------------------------
echo "$(date) Build complete."
# -----------------------------------------------------------------------------

cp ${STATUS}/status.txt ${STATUS}/status-finished.txt
cat ${STATUS}/status-finished.txt >> ${STATUS}/status-log.txt
cp tools/status.php ${STATUS}/index.php

+ 738
- 0
tools/build-test.pl View File

@@ -0,0 +1,738 @@
#! /usr/bin/perl
#
# build.pl - a tool for building FSF Europe web pages
#
# Copyright (C) 2003 Jonas Öberg
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
use File::Find::Rule;
use Getopt::Std;
use File::Path;
use File::Basename;
use XML::LibXSLT;
use XML::LibXML;
use File::Copy;
use POSIX qw(strftime);
use IO::Handle;
use IO::Select;
use Socket;
use Fcntl ':flock';

# This defines the focuses and their respective preferred / original
# language. For example, it says that we should have a focus called
# "se" (Sweden) which has the preferred language "sv" (Swedish).
#
# This also says that documents in the directory /se should be considered
# as having the Swedish version as the original, and so on.
#
our %countries = (global => 'en');
#our %countries = (
# global => 'en',
# de => 'de',
# es => 'es',
# it => 'it',
# fr => 'fr',
# se => 'sv' );

#
# This is a hash of all the languages that we have translations into, and their
# respective names in the local language. Make sure that one entry exists
# here for every language, or it won't be rendered.
#
# NOTE: Make sure that the language also is added to Apache configuration so
# content negotiation works.
#
our %languages = (
ar => 'العربيّة',
bg => 'Български',
ca => 'Català',
cs => 'Česky',
da => 'Dansk',
de => 'Deutsch',
el => 'Ελληνικά',
en => 'English',
es => 'Español',
et => 'Eesti',
fi => 'Suomi',
fr => 'Français',
hr => 'Hrvatski',
hu => 'Magyar',
it => 'Italiano',
ku => 'Kurdî',
mk => 'Mакедонски',
nb => 'Norsk (bokmål)',
nl => 'Nederlands',
nn => "Norsk (nynorsk)",
pl => 'Polski',
pt => 'Português',
ro => 'Română',
ru => 'Русский',
sk => 'Slovenčina',
sl => 'Slovenščina',
sq => 'Shqip',
sr => 'Srpski',
sv => 'Svenska',
tr => 'Türkçe',
);

our $current_date = strftime "%Y-%m-%d", localtime;
our $current_time = strftime "%Y-%m-%d %H:%M:%S", localtime;

#
# Parse the command line options. We need two; where to put the finished
# pages and what to use as base for the input.
#
getopts('o:i:t:duqn', \%opts);
unless ($opts{o}) {
print STDERR "Usage: $0 [-q] [-u] [-d] [-n] [-t #] -o <output directory>\n";
print STDERR " -q Quiet\n";
print STDERR " -u Update only\n";
print STDERR " -d Print some debug information\n";
print STDERR " -n Don't write any files\n";
print STDERR " -t Number of worker childs to create (default: 1)\n";
exit 1;
}

# It might be nice to be able to specify this, but it will break things as
# they are now. This is on the TODO list :-)

$opts{i} = ".";

$| = 1;

$SIG{CHLD} = 'IGNORE';

# Create XML and XSLT parser contexts. Also create the root note for the
# above mentioned XML file (used to feed the XSL transformation).

my $parser = XML::LibXML->new();
my $xslt_parser = XML::LibXSLT->new();

# Parse the global stylesheet

my $global_style_doc = $parser->parse_file($opts{i}."/fsfeurope.xsl");
my $global_stylesheet = $xslt_parser->parse_stylesheet($global_style_doc);

#
# First topic of today: create all directories we need. Instead of creating
# these as they are used, we create them in a batch at the beginning of each
# run, so we won't have to worry about them later.
# Note though that this also REMOVES the previous paths. You don't want to
# build directly into the production web tree.
#
my @dirs = File::Find::Rule->directory()
->in($opts{i});

while (my ($path, undef) = each %countries) {
print STDERR "Reseting path for $path\n" unless $opts{q};
rmtree($opts{o}.'/'.$path) unless ($opts{u} || $opts{n});
my @paths = map { $opts{o}."/$path/".$_ } grep(!/^\.\.?$/, @dirs);
foreach (@paths) {
print "Creating $_\n" if $opts{d};
mkpath($_) unless $opts{n};
}
}

#
# Here starts our real work. First we get ourselves a list of all files
# that we need to worry about and then single out the XHTML files. We
# create a hash of hashes, %bases, which contains the basename of each
# file, together with the translations that it exists in.
#
my @files = File::Find::Rule->file()
->in($opts{i});

my %bases;
foreach (grep(/\.xhtml$/, @files)) {
$_ =~ s/^$opts{i}\/?// unless $opts{i} eq ".";
my ($lang) = ($_ =~ /\.([a-z][a-z])\.xhtml$/);
unless ($lang) { $lang = "en"; }
$_ =~ s/\.[a-z][a-z]\.xhtml$//;
$_ =~ s/\.xhtml$//;
$bases{$_}{$lang} = 1;
}

# Open the file where we will log all outdated and missing translations
open (TRANSLATIONS, '>', "$opts{o}/translations.log");

#
# For each file, translation and focus, we create a new XML file. This will
# contain all information that the XSL needs to produce a finished page.
# The XML file will look like this:
#
# <buildinfo>
# <trlist> <!-- All translations that this page exists in -->
# <tr id="sv">Svenska</tr>
# ...
# </trlist>
# <localmenuset> <!-- Local menu items for some directories -->
# ...
# </localmenuset>
# <menuset> <!-- The menu items for the left hand bar -->
# ...
# </menuset>
# <textset> <!-- The static text set for this language -->
# ...
# </textset>
# <textsetbackup> <!-- The English textset as backup for missing translations -->
# ...
# </textsetbackup>
# <document> <!-- The actual document, as read from the XHTML -->
# <head>
# <title>...</title>
# <body>...</body>
# </head>
# </document>
# </buildinfo>
#
# In addition to this, the buildinfo and document root will be equipped with
# the following attributes:
#
# buildinfo/@original The language code of the original document
# buildinfo/@filename The filename without language or trailing .html
# buildinfo/@dirname The path to the file
# buildinfo/@language The language that we're building into
# buildinfo/@outdated Set to "yes" if the original is newer than this page
# document/@language The language that this documents is in
#
#
# $threads is the number of child processes to fork off to build the tree
#
unless ($threads = $opts{t}) {
$threads = 1;
}

#
# Start the required number of children, for each child we create a socket
# pair to communicate between parent and child. This information is kept in
# the %procs hash, which contains file handles for both child and parent.
#
foreach my $i (1..$threads) {
$procs[$i]{child} = new IO::Handle;
$procs[$i]{parent} = new IO::Handle;

socketpair($procs[$i]{child}, $procs[$i]{parent}, AF_UNIX,
SOCK_STREAM, PF_UNSPEC);

$procs[$i]{child}->autoflush(1);
$procs[$i]{parent}->autoflush(1);
#$procs[$i]{child}->blocking(false);
#$procs[$i]{parent}->blocking(false);

if (fork()) {
#
# The parent doesn't do anything at this stage, except close one of
# the filehandes not used.
#
close($procs[$i]{parent});
} else {
#
# This is the main worker for the children, which wait for a command
# to execute, either DIE or PROCESS. In the case of the first, the child
# exists gracefully, in the case of the second, it calls on process()
# to build the required page and languages.
#
# When waiting for the next page to be sent to it, the child sends NEXT
# to the parent to signify that it's ready for the next command.
#
close($procs[$i]{child});
my $io = $procs[$i]{parent};
print $io "NEXT\n";
while (!$io->error) {
my $cmd = <$io>;
if ($cmd =~ /DIE/) {
exit;
} elsif ($cmd =~ /PROCESS/) {
chomp($cmd);
my (undef, $file, $langs) = split(/\|/, $cmd);
process($file, $langs);
print $io "NEXT\n";
}
}
exit;
}
}

#
# This sets up an IO::Select object with the filehandles of all children.
# The parent uses this when looking for the next available child and blocks
# until any child is ready.
#
my $s = IO::Select->new();
foreach my $i (1..$threads) {
$s->add($procs[$i]{child});
}

while (my ($file, $langs) = each %bases) {
$s->can_read();

my $done = 0;
while (!$done) {
foreach my $fh ($s->can_read()) {
$cmd = <$fh>;
if ($cmd =~ /NEXT/) {
printf $fh "PROCESS|%s|%s\n", $file, join(':', keys(%{$langs}));
$done = 1;
last;
}
}
}
}

#
# When done, we send the DIE command to each child.
#
foreach my $i (1..$threads) {
my $io = $procs[$i]{child};
print $io "DIE\n";
}

#
# This ensures a timely wait for every child to finish processing and shutdown.
#
while (wait() != -1) {
sleep 2;
}

sub process {
my ($file, $langs) = @_;

print STDERR "Building $file.. \n" unless $opts{q};
# Create the root note for the above mentioned XML file (used to feed the XSL
# transformation).

my $dom = XML::LibXML::Document->new("1.0", "iso-8859-1");
my $root = $dom->createElement("buildinfo");
$dom->setDocumentElement($root);

#
# Set the current date, to use for comparision in the XSLT.
#
$root->setAttribute("date", $current_date);

#
# Find original language. It's en, unless we're in the country specific
# se/, fr/, de/ and so on, directories.
#
$root->setAttribute("original", "en");
my $srcfocus = "global";
if ($file =~ /^([a-z][a-z])\//) {
$srcfocus = "$1";
$root->setAttribute("original", $countries{$1});
}

$root->setAttribute("filename", "/$file");

#
# Set the directory name attribute
#
my (undef, $current_dir, undef) = fileparse($file);

$root->setAttribute("dirname", "$current_dir");

#
# Find all translations for this document, and create the trlist set
# for them.
#
my $trlist = $dom->createElement("trlist");
foreach my $lang (split(/:/, $langs)) {
my $tr = $dom->createElement("tr");
$tr->setAttribute("id", $lang);
$tr->appendText($languages{$lang});
$trlist->appendChild($tr);
}
$root->appendChild($trlist);

#
# Load the file with local menu's
#
my $localmenu = "$opts{i}/localmenuinfo.xml";
if (-f $localmenu) {
my $menudoc = $dom->createElement("localmenuset");
$root->appendChild($menudoc);
clone_document($menudoc, $localmenu);
}

#
# Load English backup texts
#

my $backup = $dom->createElement("textsetbackup");
$root->appendChild($backup);
clone_document($backup, $opts{i}."/tools/texts-en.xml");

#
# Transform it, once for every focus!
#
while (my ($dir, undef) = each %countries) {
# If we handle a focus specific file, only process it in that focus
next if (("$srcfocus" ne "global") && ("$dir" ne "$srcfocus"));

print STDERR "$dir " unless $opts{q};

#
# And once for every language!
#
while (my ($lang, undef) = each %languages) {
$root->setAttribute("language", $lang);

#
# This finds the source file to use. If we can't find a translation
# into the language, it uses the english version instead, or that in
# the local language. Or the first version it finds. This should be
# made prettier.
#
my $document = $dom->createElement("document");
$document->setAttribute("language", $lang);
$root->appendChild($document);

my $source = "$opts{i}/$file.$lang.xhtml";
unless (-f $source) {
my $missingsource = $source;
if (-f "$opts{i}/$file.en.xhtml") {
$document->setAttribute("language", "en");
$source = "$opts{i}/$file.en.xhtml";
} elsif (-f "$opts{i}/$file.".$root->getAttribute("original").".xhtml") {
$document->setAttribute("language", $root->getAttribute("original"));
$source = "$opts{i}/$file.".$root->getAttribute("original").".xhtml";
} else {
my $l = (keys %{$bases{$file}})[0];
$document->setAttribute("language", $l);
$source = "$opts{i}/$file.$l.xhtml";
}
if ($dir eq "global") {
lock(*TRANSLATIONS);
print TRANSLATIONS "$lang $missingsource $source\n";
unlock(*TRANSLATIONS);
}
}

if ( (stat("$opts{o}/$dir/$file.$lang.html"))[9] >
(stat($source))[9] && $opts{u} && ! -f "$opts{i}/$file.xsl" ) {
next;
}

#
# Here begins automated magic for those pages which we need to
# assemble other sets of informations for first (automatically
# updated pages).
#
if (-f "$opts{i}/$file.xsl") {
#
# Settle down please, children. First we remove all previous
# document leftovers.
#
foreach ($root->getElementsByTagName("document")) {
$root->removeChild($_);
}
$root->appendChild($document);

# Create the <timestamp> tag automatically for these documents
my $timestamp = $dom->createElement("timestamp");
$timestamp->appendText("\$"."Date: ".$current_time." \$ \$"."Author: automatic \$");
$document->appendChild($timestamp);

#
# Get the list of sources and create the files hash. The files
# hash contains the base name for each file we want to use, and
# then the language for it as a value. It prefers a file in the
# language we're building into, but will accept an English file as
# a substitute.
#
# "Learn all that is learnable and return that information
# to the Creator."
#
open(IN, '<', "$opts{i}/$file.sources");
my @auto_sources = <IN>;
close IN;
my %files;
foreach (@auto_sources) {
if (/(.*):[a-z,]*global/ || /(.*):[a-z,]*$dir/) {
foreach my $f (glob("$1*")) {
if ($f =~ /(.*)\.([a-z][a-z])\.xml$/) {
if (!$files{$1}) {
$files{$1} = $2;
} elsif ($2 eq $lang) {
$files{$1} = $2;
} elsif (($2 eq "en") &&
($files{$1} ne $lang)) {
$files{$1} = $2;
}
}
}
}
}

#
# With that information, we load the source document and create
# a new element in it, called <set>, which will hold the combined
# knowledge of all the sets in the source files.
#
my $sourcedoc = $parser->parse_file($source);
$sourcedoc->documentElement->setAttribute("date", $current_date);
$sourcedoc->documentElement->setAttribute("lang", $lang);
my $auto_data = $sourcedoc->createElement("set");

while (my ($base, $l) = each %files) {
if (($dir eq "global") && ($l ne $lang)) {
lock(*TRANSLATIONS);
print TRANSLATIONS "$lang $base.$lang.xml $base.$l.xml\n";
unlock(*TRANSLATIONS);
}
print STDERR "Loading $base.$l.xml\n" if $opts{d};
my $source_data = $parser->parse_file("$base.$l.xml");
foreach ($source_data->documentElement->childNodes) {
my $c = $_->cloneNode(1);
$auto_data->appendChild($c);
}
}
$sourcedoc->documentElement->appendChild($auto_data);

#
# Transform the document using the XSL file and then push the
# result into the <document> element of the document we're building.
#
my $style_doc = $parser->parse_file("$opts{i}/$file.xsl");
my $stylesheet = $xslt_parser->parse_stylesheet($style_doc);
my $results = $stylesheet->transform($sourcedoc);

foreach ($results->documentElement->childNodes) {
my $c = $_->cloneNode(1);
$document->appendChild($c);
}

#
# Now, while we're just at it, we create the RSS feeds if we want any
#
if (-f "$opts{i}/$file.rss.xsl") {
my $style_doc = $parser->parse_file("$opts{i}/$file.rss.xsl");
my $stylesheet = $xslt_parser->parse_stylesheet($style_doc);
my $results = $stylesheet->transform($sourcedoc);
$stylesheet->output_file($results, "$opts{o}/$dir/$file.$lang.rss")
unless $opts{n};
}
} else {
#
# If this wasn't an automatically updating document, we simply
# clone the contents of the source file into the document.
#
clone_document($document, $source);
}

#
# Find out if this translation is to be regarded as outdated or not.
# A translation is deemed outdated if it is more than 2 hours older
# than the original. This makes sure a translation committed together
# with the original (but maybe a second earlier) isn't marked outdated.
#
my $originalsource = "$file.".$root->getAttribute("original").".xhtml";
if ((stat("$opts{i}/$originalsource"))[9] > (stat($source))[9] + 7200) {
$root->setAttribute("outdated", "yes");
if ($dir eq "global") {
lock(*TRANSLATIONS);
print TRANSLATIONS "$lang $source $originalsource\n";
unlock(*TRANSLATIONS);
}
} else {
$root->setAttribute("outdated", "no");
}

#
# Get the appropriate textset for this language. If one can't be
# found, use the English. (I hope this never happens)
#
my $textlang = $lang;
unless (-f $opts{i}."/tools/texts-$textlang.xml") {
$textlang = "en";
}

my $textdoc = $dom->createElement("textset");
$root->appendChild($textdoc);
clone_document($textdoc, $opts{i}."/tools/texts-$textlang.xml");


#
# Read the fundraising text, if it exists.
#
if (-f $opts{i}."/fundraising.$lang.xml") {
my $fundraisingdoc = $dom->createElement("fundraising");
$root->appendChild($fundraisingdoc);
clone_document($fundraisingdoc, $opts{i}."/fundraising.$lang.xml");
} elsif (-f $opts{i}."/fundraising.en.xml") {
my $fundraisingdoc = $dom->createElement("fundraising");
$root->appendChild($fundraisingdoc);
clone_document($fundraisingdoc, $opts{i}."/fundraising.en.xml");
}


#
# And then we do the same thing for the menues. But first we take the
# global menu here, then we add any information that is specific to
# the focus.
#
foreach ($root->getElementsByTagName("menuset")) {
$root->removeChild($_);
}

my %menu;
foreach ('global', $dir) {
if (-f $opts{i}."/tools/menu-$_.xml") {
my $menudoc = $parser->parse_file($opts{i}."/tools/menu-$_.xml");
foreach my $n ($menudoc->documentElement->getElementsByTagName("menu")) {
$menu{$n->getAttribute("id")} = $n;
}
}
}
my $menuroot = $dom->createElement("menuset");
while (my ($id, $n) = each %menu) {
my $m = $n->cloneNode(1);
$menuroot->appendChild($m);
}
$root->appendChild($menuroot);

#
# Do the actual transformation.
#
my $results = $global_stylesheet->transform($dom);

#
# In post-processing, we replace links pointing back to ourselves
# so that they point to the correct language.
#
foreach ($results->documentElement->getElementsByTagName("a")) {
my $href = $_->getAttribute("href");
if ($href =~ /^http:\/\/test.fsfe.org/) {
if ($_->textContent != "Our global work") {
$href =~ s/http:\/\/test.fsfe.org//;
}
}
if (($href !~ /^http/) && ($href !~ /^#/)) {
# Save possible anchor and remove it from URL
my $anchor = $href;
if (!($anchor =~ s/.*#/#/)) {
$anchor = "";
}
$href =~ s/#.*//;
# proces URL
if (($href =~ /\.html$/) && ($href !~ /\.[a-z][a-z]\.html$/)) {
$href =~ s/\.html$/\.$lang.html/;
} elsif (($href =~ /\.rss$/) && ($href !~ /\.[a-z][a-z]\.rss$/)) {
$href =~ s/\.rss$/\.$lang.rss/;
} else {
if (-d $opts{i}."/$href") {
$href =~ s/\/?$/\/index.$lang.html/;
} elsif ($href =~ /\/\w+$/) {
$href .= ".$lang.html";
}
}
# replace anchor
$href .= $anchor;
$_->setAttribute("href", $href);
}
}

print "Writing: $opts{o}/$dir/$file.$lang.html\n" if $opts{d};

$global_stylesheet->output_file($results, "$opts{o}/$dir/$file.$lang.html")
unless $opts{n};
# Add foo.html.xx link which is used by Apache's MultiViews option when
# a user enters foo.html as URL.
link("$opts{o}/$dir/$file.$lang.html", "$opts{o}/$dir/$file.html.$lang")
unless $opts{n};
}
}
print STDERR "\n" unless $opts{q};
}

# Close the logfile for outdated and missing translations
close (TRANSLATIONS);

print STDERR "Fixing index links\n" unless $opts{q};

while (my ($path, undef) = each %countries) {
my @dirs = File::Find::Rule->directory()
->in($opts{o}."/$path");
foreach (@dirs) {
my $base = basename($_);
while (my ($lang, undef) = each %languages) {
if (-f "$_/$base.$lang.html" &&
! -f "$_/index.$lang.html") {
link("$_/$base.$lang.html", "$_/index.$lang.html")
unless $opts{n};
link("$_/$base.html.$lang", "$_/index.html.$lang")
unless $opts{n};
}
}
}
}

#
# For all files that are not XHTML source files, we copy them verbatim to
# the final location, for each focus. These should be links instead to
# prevent us from wasting disk space.
#
print STDERR "Copying misc files\n" unless $opts{q};
foreach (grep(!/\.sources$/, grep(!/\.xsl$/, grep(!/\.xml$/, grep(!/\.xhtml$/,
@files))))) {
while (my ($dir, undef) = each %countries) {
if (-f "$opts{i}/$_" && !$opts{n}) {
link("$opts{i}/$_", "$opts{o}/$dir/$_");
}
}
}
#
# Helper function that clones a document. It accepts an XML node and
# a filename as parameters. Using this, it loads the source file into
# the XML node.
#
sub clone_document {
my ($doc, $source) = @_;
my $root = $doc->parentNode;

print "Source: $source\n" if $opts{d};

foreach ($root->getElementsByTagName($doc->nodeName)) {
$root->removeChild($_);
}
$root->appendChild($doc);

my $parser = XML::LibXML->new();
$parser->load_ext_dtd(0);
$parser->recover(1);

my $sourcedoc = $parser->parse_file($source);
foreach ($sourcedoc->documentElement->childNodes) {
$_->unbindNode();
my $n = $_->cloneNode(1);
$doc->appendChild($n);
}
}

#
# Helper functions to lock and unlock the translation log.
#
sub lock {
my ($fh) = @_;

flock($fh, LOCK_EX);
seek($fh, 0, 2);
}

sub unlock {
my ($fh) = @_;
flock($fh, LOCK_UN);
}

+ 166
- 0
tools/build-test.sh View File

@@ -0,0 +1,166 @@
#!/bin/bash
# -----------------------------------------------------------------------------
# Web page build script
# -----------------------------------------------------------------------------
# This script is called every 5 minutes on test.fsfe.org to rebuild the
# HTML pages from the .xhtml, .xml and .xsl source files. Most of the work,
# however, is done by the Perl script build-test.pl.
# -----------------------------------------------------------------------------

SOURCE=/home/www/fsfe-test
DEST=/home/www/html-test
TMP=/home/www/tmp-test.$$
STATUS=/var/www/web-test
ALARM_LOCKFILE=alarm_lockfile

# Since we must grep for svn output messages,
# let's ensure we get English messages
export LANG=C

# If there is a build-test.pl script started more than 30 minutes ago, mail alarm
BUILD_STARTED=$(ps --no-headers -C build-test.pl -o etime | cut -c 7-8 | sort -r | head -n 1)
if [[ -n "$BUILD_STARTED" && "10#${BUILD_STARTED}" -gt 30 && ! -f ${STATUS}/${ALARM_LOCKFILE} ]] ; then
echo -e "
A build-test.pl script has been running for more than 30 minutes!
Please:
- run 'ps aux | grep build-test.pl' and kill build-test.pl processes older than 30 minutes
- Check the build script log at http://status.fsfe.org/web-test/
- Fix the cause of the problem
- Delete the lockfile ${STATUS}/${ALARM_LOCKFILE}

" | mail -s "test.fsfe.org: build-test.pl warning" system-hackers@fsfeurope.org

# This lockfile avoids sending the mail alarm more than once;
# it must be deleted when the problem is solved.
touch ${STATUS}/${ALARM_LOCKFILE}
fi

# If build is already running, don't run it again.
if ps -C build-test.sh -o pid= | grep -q -v "$$"; then
exit
fi

# Redirect output
exec 1> ${STATUS}/status.txt 2>&1

cd ${SOURCE}

# -----------------------------------------------------------------------------
echo "$(date) Cleaning old build directories."
# -----------------------------------------------------------------------------

rm -rf /home/www/tmp-test.*

# -----------------------------------------------------------------------------
echo "$(date) Updating source files from SVN test branch."
# -----------------------------------------------------------------------------

# Rebuild only if changes were made to the SVN or it hasn't run yet today
# (unless "-f" option is used)
#
# We must run it once every day at least to move events from future to current
# and from current to past.
#
# Since the "svn update" exit status cannot be trusted, and "svn update -q" is
# always quiet, we have to test the output of "svn update" (ignoring the final
# "At revision" line) and check for any output lines
if test -z "$(svn update 2>/dev/null | grep -v 'At revision')" \
-a "$(date -r ${STATUS}/last-run +%F)" == "$(date +%F)" \
-a "$1" != "-f" ; then
echo "$(date) No changes to SVN test branch."
# In this case we only append to the cumulative status-log.txt file, we don't touch status-finished.txt
cat ${STATUS}/status.txt >> ${STATUS}/status-log.txt
exit
fi

# Make sure build-test.sh and build-test.pl are executable
# TODO: this can be removed once we set the "executable" svn property
# to these files
chmod +x tools/build-test.sh tools/build-test.pl
chmod +x cgi-bin/weborder.pl cgi-bin/stacs-register-capacity.pl
chmod +x cgi-bin/stacs-register-workshop.pl

if test "$1" == "-f" ; then
echo "Forced rebuild"
fi

# -----------------------------------------------------------------------------
echo "$(date) Running Makefiles."
# -----------------------------------------------------------------------------

make --silent

# -----------------------------------------------------------------------------
echo "$(date) Building HTML pages."
# -----------------------------------------------------------------------------

touch ${STATUS}/last-run

if test "x`hostname`" = "xekeberg"; then
tools/build-test.pl -t 16 -q -o ${TMP} -i .
elif test "x`hostname`" = "xberzelius"; then
tools/build-test.pl -t 2 -q -o ${TMP} -i .
else
tools/build-test.pl -q -o ${TMP} -i .
fi

if test $? -ne 0; then
echo "$(date) Build not complete. Aborting."
cp ${STATUS}/status.txt ${STATUS}/status-finished.txt
cat ${STATUS}/status-finished.txt >> ${STATUS}/status-log.txt
exit 1
fi

# -----------------------------------------------------------------------------
echo "$(date) Linking source files."
# -----------------------------------------------------------------------------

for target in ${TMP}/*; do
test -d ${target} && ln -s ${SOURCE} ${target}/source
done

# -----------------------------------------------------------------------------
echo "$(date) Creating symlinks."
# -----------------------------------------------------------------------------

for f in $(find ${TMP} -name .symlinks); do
cd $(dirname $f)
cat $f | while read source destination; do
ln -sf ${source} ${destination} 2>/dev/null
done
done
cd ${SOURCE}

# -----------------------------------------------------------------------------
echo "$(date) Obfuscating email addresses."
# -----------------------------------------------------------------------------

# This replaces all '@' in all html files with '&#64;'. We use '-type f'
# because we want to exclude symlinks. Because 'sed -i' is a very expensive
# operation, even if there is no replacement done anyway, we first limit the
# files to operate on to those files that actually contain an '@'.
find ${TMP} -type f -name "*.html" | xargs grep -l '@' | xargs sed -i 's/@/\&#64;/g'

# -----------------------------------------------------------------------------
echo "$(date) Activating new output."
# -----------------------------------------------------------------------------

mv ${DEST} ${DEST}.old
mv ${TMP} ${DEST}
rm -rf ${DEST}.old

# -----------------------------------------------------------------------------
echo "$(date) Generating translation logs."
# -----------------------------------------------------------------------------

tools/translation-log-test.sh ${DEST}/translations.log ${STATUS}

# -----------------------------------------------------------------------------
echo "$(date) Build complete."
# -----------------------------------------------------------------------------

cp ${STATUS}/status.txt ${STATUS}/status-finished.txt
cat ${STATUS}/status-finished.txt >> ${STATUS}/status-log.txt
cp tools/status-test.php ${STATUS}/index.php

+ 47
- 0
tools/status-new.php View File

@@ -0,0 +1,47 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Build script output</title>
</head>
<body>

<h1>Build script output</h1>

<p><a href="http://status.fsfe.org/">« Back to <em>Web server status</em></a></p>


<h2>Last attempted or currently running build</h2>

<p>
<pre>
<?php
$status = file_get_contents("status.txt");
echo htmlspecialchars($status);
?>
</pre>
</p>


<h2>Last finished build</h2>

<p>
<pre>
<?php
$statusfinished = file_get_contents("status-finished.txt");
echo htmlspecialchars($statusfinished);
?>
</pre>
</p>


<h2>Other tools</h2>

<ul>
<li><a href="./status-log.txt">Previously finished builds</a></li>
<li><a href="https://trac.fsfe.org/fsfe-web/browser/trunk">SVN web browser</a></li>
</ul>

</body>
</html>


+ 47
- 0
tools/status-test.php View File

@@ -0,0 +1,47 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Build script output - test instance</title>
</head>
<body>

<h1>Build script output - test instance</h1>

<p><a href="http://status.fsfe.org/">« Back to <em>Web server status</em></a></p>


<h2>Last attempted or currently running build</h2>

<p>
<pre>
<?php
$status = file_get_contents("status.txt");
echo htmlspecialchars($status);
?>
</pre>
</p>


<h2>Last finished build</h2>

<p>
<pre>
<?php
$statusfinished = file_get_contents("status-finished.txt");
echo htmlspecialchars($statusfinished);
?>
</pre>
</p>


<h2>Other tools</h2>

<ul>
<li><a href="./status-log.txt">Previously finished builds</a></li>
<li><a href="https://trac.fsfe.org/fsfe-web/browser/branches/test">SVN web browser</a></li>
</ul>

</body>
</html>


+ 283
- 0
tools/translation-log-new.sh View File

@@ -0,0 +1,283 @@
#!/bin/bash

# This script is called by build.sh to create the translation log html
# files from the translations.log file created by build.pl.
#
# Copyright (C) 2005 Free Software Foundation Europe
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------

srcroot="http://www.fsfe.org/source"
cvsroot="https://trac.fsfe.org/fsfe-web/log/trunk"


# -----------------------------------------------------------------------------
# Parameters
# -----------------------------------------------------------------------------

infile=$1
outdir=$2


# -----------------------------------------------------------------------------
# Create a separate file per language
# -----------------------------------------------------------------------------

# Remove all "./" at the beginning of filenames, and create a separate file per
# language. For missing translations, remove all files mentioned in
# translation-ignore.txt.

# Performance seems to be much better if we do it in 2 separate runs.
# Otherwise, we would have to run the grep for each line of the file.

# First run: missing translations
sort "${infile}" \
| uniq \
| sed --expression='s/\.\///g' \
| grep --invert-match --file="tools/translation-ignore.txt" \
| while read language wantfile havefile; do
if [ ! -f "${wantfile}" ]; then
date="$(date --iso-8601 --reference=${havefile})"
echo "missing ${date} ${wantfile} NONE ${havefile}" >> "${infile}.${language}"
fi
done

# Second run: outdated translations
sort "${infile}" \
| uniq \
| sed --expression='s/\.\///g' \
| while read language wantfile havefile; do
if [ -f "${wantfile}" ]; then
date1="$(date --iso-8601 --reference=${wantfile})"
date2="$(date --iso-8601 --reference=${havefile})"
echo "outdated ${date2} ${wantfile} ${date1} ${havefile}" >> "${infile}.${language}"
fi
done


# -----------------------------------------------------------------------------
# Convert the ASCII files to HTML files
# -----------------------------------------------------------------------------

for file in ${infile}.*; do
language=${file##*.}
(
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Translation status for ${language}</title>"
echo " </head>"
echo " <body>"
echo " <h1>Translation status for ${language}</h1>"
echo " <p>"
echo " <a href=\"translations.html\">« Back to <em>Translation status overview</em></a>"
echo " </p>"
lastgroup=""
sort --reverse ${file} | while read group date2 wantfile date1 havefile; do
if [ "${group}" != "${lastgroup}" ]; then
if [ "${group}" == "outdated" ]; then
echo " <h2>Outdated translations</h2>"
echo " <p>"
echo " The following pages are already translated. However, the"
echo " original version has been changed since the translation"
echo " was done, and the translation has not been updated so far"
echo " to reflect these changes."
echo " </p>"
echo " <p>"
echo " Updating these translations is generally considered more"
echo " urgent than translating new pages."
echo " </p>"
echo " <table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">"
echo " <tr>"
echo " <th colspan=\"3\">translated file</th>"
echo " <th colspan=\"3\">original file</th>"
echo " </tr>"
elif [ "${group}" == "missing" ]; then
if [ "${lastgroup}" == "outdated" ]; then
echo " </table>"
fi
echo " <h2>Missing translations</h2>"
echo " <p>"
echo " The following pages have not yet been translated."
echo " </p>"
echo " <p>"
echo " This list is ordered by the date of the original version,"
echo " newest first. Generally, it's a good idea to translate"
echo " newer texts before older ones, as people will probably be"
echo " more interested in current information."
echo " </p>"
echo " <table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">"
echo " <tr>"
echo " <th>translated file</th>"
echo " <th>original file</th>"
echo " <th align=\"center\">last change of original</th>"
echo " </tr>"
fi
lastgroup="${group}"
fi

echo " <tr>"
if [ "${group}" = "outdated" ]; then
echo " <td>"
echo " <a href=\"${srcroot}/${wantfile}\">${wantfile}</a>"
echo " </td>"
echo " <td align=\"center\">${date1}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${wantfile}\">[changelog]</a>"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${havefile}\">[changelog]</a>"
echo " </td>"
else
echo " <td>"
echo " ${wantfile}"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
fi
echo " </tr>"
done
if [ "${lastgroup}" != "" ]; then
echo " </table>"
fi
echo " </body>"
echo "</html>"
) > $outdir/$language.html
done


# -----------------------------------------------------------------------------
# Create hit parade of outdated translations
# -----------------------------------------------------------------------------

grep --no-filename "^outdated" ${infile}.* \
| sort --key=2 \
| (
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Hit parade of outdated translations</title>"
echo " <style>"
echo " table,"
echo " th,"
echo " td {"
echo " border: 1px outset gray;"
echo " }"
echo " th,"
echo " td {"
echo " padding: 3px;"
echo " }"
echo " </style>"
echo " </head>"
echo " <body>"
echo " <h1>Hit parade of outdated translations</h1>"
echo " <p>"
echo " <a href=\"translations.html\">« Back to <em>Translation status overview</em></a>"
echo " </p>"
echo " <table>"
echo " <tr>"
echo " <th colspan=\"3\">translated file</th>"
echo " <th colspan=\"3\">original file</th>"
echo " </tr>"
while read group date2 wantfile date1 havefile; do
echo " <tr>"
echo " <td>"
echo " <a href=\"${srcroot}/${wantfile}\">${wantfile}</a>"
echo " </td>"
echo " <td align=\"center\">${date1}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${wantfile}\">[changelog]</a>"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${havefile}\">[changelog]</a>"
echo " </td>"
done
echo " </tr>"
echo " </table>"
echo " </body>"
echo "</html>"
) > $outdir/outdated.html


# -----------------------------------------------------------------------------
# Create the overview page
# -----------------------------------------------------------------------------

(
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Translation status overview</title>"
echo " <style>"
echo " table,"
echo " th,"
echo " td {"
echo " border: 1px outset gray;"
echo " }"
echo " th,"
echo " td {"
echo " padding: 3px;"
echo " text-align: center;"
echo " }"
echo " </style>"
echo " </head>"
echo " <body>"
echo " <h1>Translation status overview</h1>"
echo " <p>"
echo " <a href=\"http://status.fsfe.org/\">« Back to <em>Web server status</em></a>"
echo " </p>"
echo " <table>"
echo " <tr>"
echo " <th>language</td>"
echo " <th>outdated translations</td>"
echo " <th>missing translations</td>"
echo " </tr>"
for file in ${infile}.*; do
language=${file##*.}
outdated=$(grep "^outdated" ${file} | wc --lines)
missing=$(grep "^missing" ${file} | wc --lines)
echo " <tr>"
echo " <td><a href=\"${language}.html\">${language}</a></td>"
echo " <td>${outdated}</td>"
echo " <td>${missing}</td>"
echo " </tr>"
done
echo " </table>"
echo " <p>"
echo " A <a href=\"outdated.html\">hit parade of outdated translations</a>"
echo " for all languages is also available."
echo " </p>"
echo " </body>"
echo "</html>"
) > $outdir/translations.html


+ 283
- 0
tools/translation-log-test.sh View File

@@ -0,0 +1,283 @@
#!/bin/bash

# This script is called by build.sh to create the translation log html
# files from the translations.log file created by build.pl.
#
# Copyright (C) 2005 Free Software Foundation Europe
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------

srcroot="http://test.fsfe.org/source"
cvsroot="https://trac.fsfe.org/fsfe-web/log/branches/test"


# -----------------------------------------------------------------------------
# Parameters
# -----------------------------------------------------------------------------

infile=$1
outdir=$2


# -----------------------------------------------------------------------------
# Create a separate file per language
# -----------------------------------------------------------------------------

# Remove all "./" at the beginning of filenames, and create a separate file per
# language. For missing translations, remove all files mentioned in
# translation-ignore.txt.

# Performance seems to be much better if we do it in 2 separate runs.
# Otherwise, we would have to run the grep for each line of the file.

# First run: missing translations
sort "${infile}" \
| uniq \
| sed --expression='s/\.\///g' \
| grep --invert-match --file="tools/translation-ignore.txt" \
| while read language wantfile havefile; do
if [ ! -f "${wantfile}" ]; then
date="$(date --iso-8601 --reference=${havefile})"
echo "missing ${date} ${wantfile} NONE ${havefile}" >> "${infile}.${language}"
fi
done

# Second run: outdated translations
sort "${infile}" \
| uniq \
| sed --expression='s/\.\///g' \
| while read language wantfile havefile; do
if [ -f "${wantfile}" ]; then
date1="$(date --iso-8601 --reference=${wantfile})"
date2="$(date --iso-8601 --reference=${havefile})"
echo "outdated ${date2} ${wantfile} ${date1} ${havefile}" >> "${infile}.${language}"
fi
done


# -----------------------------------------------------------------------------
# Convert the ASCII files to HTML files
# -----------------------------------------------------------------------------

for file in ${infile}.*; do
language=${file##*.}
(
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Translation status for ${language} (test instance)</title>"
echo " </head>"
echo " <body>"
echo " <h1>Translation status for ${language} (test instance)</h1>"
echo " <p>"
echo " <a href=\"translations.html\">« Back to <em>Translation status overview</em></a>"
echo " </p>"
lastgroup=""
sort --reverse ${file} | while read group date2 wantfile date1 havefile; do
if [ "${group}" != "${lastgroup}" ]; then
if [ "${group}" == "outdated" ]; then
echo " <h2>Outdated translations</h2>"
echo " <p>"
echo " The following pages are already translated. However, the"
echo " original version has been changed since the translation"
echo " was done, and the translation has not been updated so far"
echo " to reflect these changes."
echo " </p>"
echo " <p>"
echo " Updating these translations is generally considered more"
echo " urgent than translating new pages."
echo " </p>"
echo " <table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">"
echo " <tr>"
echo " <th colspan=\"3\">translated file</th>"
echo " <th colspan=\"3\">original file</th>"
echo " </tr>"
elif [ "${group}" == "missing" ]; then
if [ "${lastgroup}" == "outdated" ]; then
echo " </table>"
fi
echo " <h2>Missing translations</h2>"
echo " <p>"
echo " The following pages have not yet been translated."
echo " </p>"
echo " <p>"
echo " This list is ordered by the date of the original version,"
echo " newest first. Generally, it's a good idea to translate"
echo " newer texts before older ones, as people will probably be"
echo " more interested in current information."
echo " </p>"
echo " <table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">"
echo " <tr>"
echo " <th>translated file</th>"
echo " <th>original file</th>"
echo " <th align=\"center\">last change of original</th>"
echo " </tr>"
fi
lastgroup="${group}"
fi

echo " <tr>"
if [ "${group}" = "outdated" ]; then
echo " <td>"
echo " <a href=\"${srcroot}/${wantfile}\">${wantfile}</a>"
echo " </td>"
echo " <td align=\"center\">${date1}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${wantfile}\">[changelog]</a>"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${havefile}\">[changelog]</a>"
echo " </td>"
else
echo " <td>"
echo " ${wantfile}"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
fi
echo " </tr>"
done
if [ "${lastgroup}" != "" ]; then
echo " </table>"
fi
echo " </body>"
echo "</html>"
) > $outdir/$language.html
done


# -----------------------------------------------------------------------------
# Create hit parade of outdated translations
# -----------------------------------------------------------------------------

grep --no-filename "^outdated" ${infile}.* \
| sort --key=2 \
| (
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Hit parade of outdated translations (test instance)</title>"
echo " <style>"
echo " table,"
echo " th,"
echo " td {"
echo " border: 1px outset gray;"
echo " }"
echo " th,"
echo " td {"
echo " padding: 3px;"
echo " }"
echo " </style>"
echo " </head>"
echo " <body>"
echo " <h1>Hit parade of outdated translations (test instance)</h1>"
echo " <p>"
echo " <a href=\"translations.html\">« Back to <em>Translation status overview</em></a>"
echo " </p>"
echo " <table>"
echo " <tr>"
echo " <th colspan=\"3\">translated file</th>"
echo " <th colspan=\"3\">original file</th>"
echo " </tr>"
while read group date2 wantfile date1 havefile; do
echo " <tr>"
echo " <td>"
echo " <a href=\"${srcroot}/${wantfile}\">${wantfile}</a>"
echo " </td>"
echo " <td align=\"center\">${date1}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${wantfile}\">[changelog]</a>"
echo " </td>"
echo " <td>"
echo " <a href=\"${srcroot}/${havefile}\">${havefile}</a>"
echo " </td>"
echo " <td align=\"center\">${date2}</td>"
echo " <td>"
echo " <a href=\"${cvsroot}/${havefile}\">[changelog]</a>"
echo " </td>"
done
echo " </tr>"
echo " </table>"
echo " </body>"
echo "</html>"
) > $outdir/outdated.html


# -----------------------------------------------------------------------------
# Create the overview page
# -----------------------------------------------------------------------------

(
echo "<!doctype html>"
echo "<html>"
echo " <head>"
echo " <meta charset=\"utf-8\" />"
echo " <title>Translation status overview (test instance)</title>"
echo " <style>"
echo " table,"
echo " th,"
echo " td {"
echo " border: 1px outset gray;"
echo " }"
echo " th,"
echo " td {"
echo " padding: 3px;"
echo " text-align: center;"
echo " }"
echo " </style>"
echo " </head>"
echo " <body>"
echo " <h1>Translation status overview (test instance)</h1>"
echo " <p>"
echo " <a href=\"http://status.fsfe.org/\">« Back to <em>Web server status</em></a>"
echo " </p>"
echo " <table>"
echo " <tr>"
echo " <th>language</td>"
echo " <th>outdated translations</td>"
echo " <th>missing translations</td>"
echo " </tr>"
for file in ${infile}.*; do
language=${file##*.}
outdated=$(grep "^outdated" ${file} | wc --lines)
missing=$(grep "^missing" ${file} | wc --lines)
echo " <tr>"
echo " <td><a href=\"${language}.html\">${language}</a></td>"
echo " <td>${outdated}</td>"
echo " <td>${missing}</td>"
echo " </tr>"
done
echo " </table>"
echo " <p>"
echo " A <a href=\"outdated.html\">hit parade of outdated translations</a>"
echo " for all languages is also available."
echo " </p>"
echo " </body>"
echo "</html>"
) > $outdir/translations.html


Loading…
Cancel
Save