#!/bin/sh

# This script sends all patches to a given Translation file of the DDTP
# project back to the DDTP. This allows large commits which just a little
# command.
# Translation files are available on many mirrors such as
# http://ftp.de.debian.org/debian/dists/sid/main/i18n/
#
# Usage: $0 Translation.orig Translation.modified
#
# If a conflict occurs during the attempt to integrate an update into the
# DDTP template file, this single patch (not only the actual hunk) will be
# ignored ...
#
# (c) Jens Seidel, 2006/08/13, licensed under GPL v2 or higher

# stop on first error
set -e

# language code of the translation files
DLANG=de

# encoding of the descriptions
DESC_ENC=UTF-8

# local email address for testing (use it first!)
EMAIL=$(who am I | cut -d" " -f1)@localhost
# real email address
#EMAIL=pdesc@ddtp.debian.net 

# default mutt commandline options
MUTTOPTS=
MUTTOPTS="-b jensseidel@users.sf.net" # add myself to BCC: (FIXME: -c does not work (CC:))

REPLYTO=jensseidel@users.sf.net

# set it to 0 for no debug output
DEBUG=1

# Attention: If the first line of a description is changed (the Description-*:
# line) this will result in a patch conflict. Use the option -F of patch to
# handle these (after manual check) as well. Reason: The content diff cannot
# refer to lines above, since it's the first line. But the DDTP template has
# the English description above!
# The last (non empty) line is not affected, since it is followed by an empty line.

AWK=gawk

usage()
{
  echo Usage: $0 Translation.orig Translation.modified
  echo
  echo Sends all changes found in Translation.modified compared to Translation.orig
  echo back to the DDTP server.
  echo
}

check_options()
{
  if [ $# -ne 2 ]; then
    usage
    exit 1
  fi

  if ! [ -r $1 ] || ! [ -r $2 ]; then
    echo $1 or $2 is not a file name
    echo
    usage
    exit 1
  fi
}

check_options $* 

FILEorig=$1
FILEpatched=$2

status()
{
  echo $1
}

debug()
{
  [ "$DEBUG" -gt 0 ] && echo $1
}

TMP=$(mktemp -d /tmp/ddtp.XXXXX)
status "Using data directory $TMP"

# Extracts all package descriptions from the large translation file $1 and writes
# each description into $2 (%s in it is replaced by the package name). A list of
# packages with a description is written to $3.
create_all_package_description_files()
{
  TRANSLATEFILE=$1
  MAILFILE=$2
  PKGFFILE=$3
  echo -n > $PKGFFILE
  (cat $TRANSLATEFILE; echo "Package: get_last_package_processed") | $AWK '\
    /^Package: / { \
       if (pkg) { \
         # output old package: \
         mail="'"$MAILFILE"'"; \
         gsub("%s", pkg, mail); \
         print pkg >> "'"$PKGFFILE"'"; \
         print descBody > mail; \
       } \
       pkg=$2; \
    } \
    /^Description/ { $0=gensub(":", ".'$DESC_ENC':", 1); descBody="" } \
    { if (descBody) descBody=descBody "\n"; descBody=descBody $0; } \
  '
}

# Create patch files for each individual package (we don't blindly overwrite)
# We apply patches to DDTP templates to ensure we do not harm the DDTP in
# case we we do not have up-to-date translation files.
# FIXME: Not true (fill a wishlist bug against patch?):
# The patch should apply cleanly because there is no surrounding content before and
# after the translated package description (we do not depend on small changes in the
# English part of the DDTP data outside the description translation)
status "Create patch files for each individual package ..."
mkdir $TMP/mails
create_all_package_description_files "$FILEorig" "$TMP/mails/%s.orig" "$TMP/package_list.orig"
create_all_package_description_files "$FILEpatched" "$TMP/mails/%s.patched" "$TMP/package_list.patched"

if ! diff -u "$TMP/package_list.orig" "$TMP/package_list.patched" > /dev/null; then
  echo "The specified files do not contain the same packages in the same order."
  echo "Compare $TMP/package_list.orig $TMP/package_list.patched"
  exit 1
fi

rm "$TMP/package_list.patched"
echo -n > "$TMP/changed_package_list"

status "Checking modified descriptions ..."
# ignore all not patched packages
for pkg in $(cat "$TMP/package_list.orig"); do
  if ! diff "$TMP/mails/$pkg.orig" "$TMP/mails/$pkg.patched" > /dev/null; then
    echo $pkg >> "$TMP/changed_package_list"
  fi
done
rm "$TMP/package_list.orig"

# Obtain all mail attachment file templates from DDTP for which we have patches
# (in all versions, even old one, maybe the patch applies to it as well)
# FIXME: These files are currently outdated, whereas &language=de returns
# current data!
status "Get templates from DDTP ..."
echo -n > "$TMP/package_descid_list"
for pkg in $(cat "$TMP/changed_package_list"); do
  wget --no-verbose --output-document=- http://ddtp.debian.net/ddt.cgi?package=$pkg > "$TMP/pkg.html"
  for descid in $(cat "$TMP/pkg.html" | \
    sed -n 's,^Description: <a href="ddt\.cgi?desc_id=\([0-9]*\)">\1</a><br>,\1,p'); do
    wget --no-verbose --output-document=- "http://ddtp.debian.net/ddt.cgi?desc_id=$descid&getuntrans=$DLANG" | \
    sed "/^Description-/ s/:/.$DESC_ENC:/1" > "$TMP/mails/${pkg}_$descid.mail.orig"
    echo $pkg $descid >> "$TMP/package_descid_list" 
  done
done

# Create patches in DDTP's description attachment file format
status "Start patching created DDTP mail attachment files ..."
echo -n > "$TMP/patched_package_descid_list"
cat "$TMP/package_descid_list" | while read pkg descid; do
  diff -u "$TMP/mails/$pkg.orig" "$TMP/mails/$pkg.patched" > "$TMP/patch" || true
  cp "$TMP/mails/${pkg}_$descid.mail.orig" "$TMP/mails/${pkg}_$descid.mail.patched"
  if ! patch -U --no-backup-if-mismatch -p0 -i "$TMP/patch" "$TMP/mails/${pkg}_$descid.mail.patched"; then
    status "Patching $TMP/mails/$pkg.mail.orig failed"
  else
    echo $pkg $descid >> "$TMP/patched_package_descid_list"
  fi
done

# Send mails
status "Start sending patches to DDTP ..."
echo > "$TMP/muttinput"

cat "$TMP/patched_package_descid_list" | while read pkg descid; do
  echo "The DDTP description update contains the following patch:" > "$TMP/mail"
  echo >> "$TMP/mail"
  diff -u "$TMP/mails/${pkg}_$descid.mail.orig" "$TMP/mails/${pkg}_$descid.mail.patched" >> "$TMP/mail" || true
  mutt -e "set send_charset=\"$DESC_ENC\"" -a "$TMP/mails/${pkg}_$descid.mail.patched" $MUTTOPTS -i "$TMP/mail" -s "[DDTP] ${pkg} ($descid) update (sent via $0)" $EMAIL < "$TMP/muttinput"
done

status "Delete $TMP if you no longer need it"

