home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl -w
-
- # podebconf-report-po, Send outdated debconf PO files to the last translator
- # Copyright (C) 2004-2006 Fabio Tranchitella <kobold@kobold.it>
- # Denis Barbier <barbier@debian.org>
- #
- # 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 Library 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.
- #
-
- ## Release information
- my $PROGRAM = "podebconf-report-po";
- my $VERSION = "0.10";
-
- ## Loaded modules, require libmail-sendmail-perl
- use strict;
- eval q{use Mail::Sendmail;};
- die "$PROGRAM: This program requires the libmail-sendmail-perl package.\n".
- "$PROGRAM: Aborting!\n" if $@;
- my $no_zlib = 0;
- eval q{use Compress::Zlib;};
- if ($@) {
- $no_zlib = 1;
- eval q{ sub Compress::Zlib::memGzip { return shift; } };
- }
- my $no_encode = 0;
- eval q{use Encode;};
- if ($@) {
- $no_encode = 1;
- }
- use MIME::Base64;
- use MIME::QuotedPrint;
- use Getopt::Long;
- use POSIX;
-
- ## Global variables
- my $CONF_ARG;
- if (-e $ENV{'HOME'}."/.podebconf-report-po.conf") {
- $CONF_ARG = $ENV{'HOME'}."/.podebconf-report-po.conf";
- }
- my $NO_CONF;
- my $HELP_ARG = 0;
- my $VERSION_ARG = 0;
- my $VERBOSE_ARG;
- my $NO_VERBOSE;
- my $SUBMIT_ARG = 0;
- my $FORCE_ARG;
- my $NO_FORCE;
- my $CALL;
- my $POTFILE = "";
- my $LANGS = "";
- my $LANGUAGETEAM_ARG;
- my $NO_LANGUAGETEAM;
- my $SMTP_ARG;
- my $TEMPLATE_ARG;
- my $NO_TEMPLATE;
- my $DEFAULT_ARG;
- my $NO_DEFAULT;
- my $PACKAGE_ARG = "";
- my $SUMMARY_ARG;
- my $NO_SUMMARY;
- my $FROM_ARG;
- my $BTS_ARG = "";
- my $DEADLINE_ARG = "";
- my $PODIR_ARG = "";
- my $GZIP_ARG;
- my $NO_GZIP;
- my $UTF8;
- my $NO_UTF8;
-
- my @TOPDIRS = qw{../.. .. .};
-
- my $PODIR = '';
-
- my $EDITOR = '/usr/bin/sensible-editor';
-
- ## Default templates
- my $comments = "# Lines beginning with a number sign are comments, they are removed when
- # sending mails. If a line is composed of a # followed by a 'Name: Value'
- # pair, it is interpreted as a mail header field and is passed to your mail
- # transport agent. You can edit/add/remove those header fields.";
-
- my $SUBJECT_TRANSLATOR = "Please update debconf PO translation for the package <package_and_version>";
- my $BODY_TRANSLATOR = $comments. "
- #
- # From: <from>
- # Subject: <subject>
- # Reply-To: <reply-to>
- #
- # This mail will be sent to the following people:
- # (you can update email addresses, remove a line or add/remove the cross
- # between the brackets)
- <filelist>
-
- Hi,
-
- You are noted as the last translator of the debconf translation for
- <package>. The English template has been changed, and now some messages
- are marked \"fuzzy\" in your translation or are missing.
- I would be grateful if you could take the time and update it.
- <reply>
- <deadline>
-
- Thanks,
- ";
-
- my $SUBJECT_SUBMIT = "debconf PO translations for the package <package> are outdated";
- my $BODY_SUBMIT = $comments. "
- #
- # From: <from>
- # Subject: <subject>
-
- Package: <package>
- Version: N/A
- Severity: wishlist
- Tags: l10n
-
- The following debconf translations are outdated:
- <filelist>
-
- Translators, please send your translations to this bugreport.
- <deadline>
-
- Thanks,
- ";
-
- my $SUBJECT_CALL = "debconf PO translations for the package <package>";
- my $BODY_CALL = $comments. "
- #
- # From: <from>
- # Subject: <subject>
- # Reply-To: <reply-to>
-
- Dear Debian I18N people,
-
- I would like to know if some of you would be interested in translating
- <package>.
-
- <package> already includes <filelist>.
- So do not translate it to these languages (the translators will be
- contacted separately).
-
- <statistics>
-
- <reply>
- <deadline>
-
- If you have read so far, please find the POT file in attachement.
-
- Thanks in advance,
- ";
-
- my $SUBJECT = '';
- my $BODY = '';
- # Warnings may be deleted from screen when entering editor,
- # so display them when it is closed.
- my $warn = '';
-
- ## Handle options
- GetOptions
- (
- "conf=s" => \$CONF_ARG,
- "noconf" => \$NO_CONF,
- "help" => \$HELP_ARG,
- "version" => \$VERSION_ARG,
- "v|verbose" => \$VERBOSE_ARG,
- "noverbose" => \$NO_VERBOSE,
- "f|force" => \$FORCE_ARG,
- "noforce" => \$NO_FORCE,
- "podir=s" => \$PODIR_ARG,
- "smtp=s" => \$SMTP_ARG,
- "template=s" => \$TEMPLATE_ARG,
- "notemplate" => \$NO_TEMPLATE,
- "default" => \$DEFAULT_ARG,
- "nodefault" => \$NO_DEFAULT,
- "gzip" => \$GZIP_ARG,
- "nogzip" => \$NO_GZIP,
- "langs=s" => \$LANGS,
- "languageteam" => \$LANGUAGETEAM_ARG,
- "nolanguageteam" => \$NO_LANGUAGETEAM,
- "package=s" => \$PACKAGE_ARG,
- "deadline=s" => \$DEADLINE_ARG,
- "call:s" => \$CALL,
- "potfile=s" => \$POTFILE,
- "summary" => \$SUMMARY_ARG,
- "nosummary" => \$NO_SUMMARY,
- "from=s" => \$FROM_ARG,
- "bts=s" => \$BTS_ARG,
- "submit" => \$SUBMIT_ARG,
- "utf8" => \$UTF8,
- "noutf8" => \$NO_UTF8
- ) or &Help_InvalidOption;
-
- my $conf = "";
-
- unless ($NO_CONF or !defined $CONF_ARG) {
- open (CNF, "< $CONF_ARG")
- or die ("Couldn't read $CONF_ARG: $!\nExiting!\n");
- while (<CNF>) {
- $conf .= $_;
- }
- close(CNF)
- or die ("Couldn't close $CONF_ARG: $!\nExiting!\n");
-
- $conf =~ s/^\s*#.*$//m;
- $conf =~ s/\s*$//m;
- }
-
- if ($conf =~ m/^smtp\s*(?:\s|=)\s*(.*)$/m) {
- $SMTP_ARG = $1;
- } elsif (!defined $SMTP_ARG) {
- $SMTP_ARG = "";
- }
-
- if ($conf =~ m/^from\s*(?:\s|=)\s*(.*)$/m) {
- $FROM_ARG = $1;
- } elsif (!defined $FROM_ARG) {
- $FROM_ARG = (exists($ENV{'DEBEMAIL'}) ? $ENV{'DEBEMAIL'} : "");
- }
-
- if (defined $NO_VERBOSE) {
- $VERBOSE_ARG = 0;
- } elsif ($conf =~ m/^verbose$/m) {
- $VERBOSE_ARG = 1;
- } elsif (!defined $VERBOSE_ARG) {
- $VERBOSE_ARG = 0;
- }
-
- if (defined $NO_FORCE) {
- $FORCE_ARG = 0;
- } elsif ($conf =~ m/^force$/m) {
- $FORCE_ARG = 1;
- } elsif (!defined $FORCE_ARG) {
- $FORCE_ARG = 0;
- }
-
- if (defined $NO_TEMPLATE) {
- $TEMPLATE_ARG = "";
- } elsif ($conf =~ m/^template\s*(?:\s|=)\s*(.*)$/m) {
- $TEMPLATE_ARG = $1;
- } elsif (!defined $TEMPLATE_ARG) {
- $TEMPLATE_ARG = "";
- }
-
- if (defined $NO_DEFAULT) {
- $DEFAULT_ARG = 0;
- } elsif ($conf =~ m/^default$/m) {
- $DEFAULT_ARG = 1;
- } elsif (!defined $DEFAULT_ARG) {
- $DEFAULT_ARG = 0;
- }
-
- if (defined $NO_GZIP) {
- $GZIP_ARG = 0;
- } elsif ($conf =~ m/^nogzip$/m) {
- $GZIP_ARG = 1;
- } elsif (!defined $GZIP_ARG) {
- $GZIP_ARG = 0;
- }
-
- if (defined $NO_LANGUAGETEAM) {
- $LANGUAGETEAM_ARG = 0;
- } elsif ($conf =~ m/^languageteam$/m) {
- $LANGUAGETEAM_ARG = 1;
- } elsif (!defined $LANGUAGETEAM_ARG) {
- $LANGUAGETEAM_ARG = 0;
- }
-
- if (defined $NO_SUMMARY) {
- $SUMMARY_ARG = 0;
- } elsif ($conf =~ m/^summary$/m) {
- $SUMMARY_ARG = 1;
- } elsif (!defined $SUMMARY_ARG) {
- $SUMMARY_ARG = 0;
- }
-
- if (defined $NO_UTF8) {
- $UTF8 = 0;
- } elsif ($conf =~ m/^utf8$/m) {
- $UTF8 = 1;
- } elsif (!defined $UTF8) {
- $UTF8 = 0;
- }
-
- &Help_PrintVersion if $VERSION_ARG;
- &Help_PrintHelp if $HELP_ARG;
-
- if ($no_encode and $UTF8) {
- $warn .= "--utf8 requires the Encode perl module. ".
- "Turning this option off.\n";
- $UTF8 = 0;
- }
-
- ## Try to find default editor
- $EDITOR = $ENV{'EDITOR'} if exists($ENV{'EDITOR'});
- $EDITOR = $ENV{'VISUAL'} if exists($ENV{'VISUAL'});
-
- ## Try to locate the PO directory
- if ($PODIR_ARG eq "") {
- foreach my $d (@TOPDIRS) {
- $PODIR = "$d/debian/po" if (-d "$d/debian/po");
- }
- } else {
- $PODIR = $PODIR_ARG;
- }
- die "Directory po not found, exiting!\n" if $PODIR eq "";
- die "Wrong argument: $PODIR is not a directory!\n" unless -d $PODIR;
-
- if ($no_zlib && $GZIP_ARG) {
- $warn .=
- "Warning: This program requires the libcompress-zlib-perl package in order\n".
- " to support the --gzip flag, but it is not installed.\n".
- " PO files will not be compressed!\n\n";
- $GZIP_ARG = 0;
- }
-
- ## Try to find the maintainer e-mail address and the package name
-
- # Package version
- my $PKG_VERSION = "N/A";
- # Expanded into "<package> <version>" if version is found, <package> otherwise
- my $PACKAGE_AND_VERSION = "";
- if ($PACKAGE_ARG =~ s/_(.*)//) {
- $PKG_VERSION = $1;
- }
-
- if ($PACKAGE_ARG eq "" or $FROM_ARG eq "") {
- my $CONTROL = '';
- foreach my $d (@TOPDIRS) {
- $CONTROL = "$d/debian/control" if (-f "$d/debian/control");
- }
- if ($CONTROL eq '') {
- foreach my $d (@TOPDIRS) {
- $CONTROL = "$d/debian/control.in" if (-f "$d/debian/control.in");
- }
- }
-
- if (-f $CONTROL) {
- ## Only read the first stanza
- local $/ = "\n\n";
- open (CNTRL, "< $CONTROL")
- or die "Unable to read $CONTROL: $!\n";
- my $text = <CNTRL>;
- close (CNTRL)
- or die "Unable to close $CONTROL: $!\n";
- if ($PACKAGE_ARG eq "" && $text =~ m/^Source: (.*)/m) {
- $PACKAGE_ARG = $1;
- }
-
- if ($FROM_ARG eq "" && $text =~ m/^Maintainer: (.*)/m) {
- $FROM_ARG = $1;
- }
- }
- }
- if ($PKG_VERSION eq "N/A") {
- my $CHANGELOG = '';
- foreach my $d (@TOPDIRS) {
- $CHANGELOG = "$d/debian/changelog" if (-f "$d/debian/changelog");
- }
- if (-f $CHANGELOG) {
- # Version information is not vital, do not abort
- # if it cannot be retrieved.
- if (open (CHG, "< $CHANGELOG")) {
- while (<CHG>) {
- if (m/^$PACKAGE_ARG\s+\((.*)\)\s/) {
- $PKG_VERSION = $1;
- }
- last if m/^ --/;
- }
- }
- close (CHG);
- }
- }
- $PACKAGE_AND_VERSION = $PACKAGE_ARG .
- ($PKG_VERSION ne 'N/A' ? " ".$PKG_VERSION : "");
- Verbose("Package: $PACKAGE_ARG");
- Verbose("Version: $PKG_VERSION");
- Verbose("Maintainer: $FROM_ARG");
-
- if ($DEADLINE_ARG ne "") {
- $DEADLINE_ARG = "\nThe deadline for receiving the updated translation is $DEADLINE_ARG.";
- }
-
- my $REPLY = '';
- if ($BTS_ARG =~ m/^\d+$/) {
- $BTS_ARG .= "\@bugs.debian.org";
- $REPLY = "Please respect the Reply-To: field and send your updated translation to\n$BTS_ARG.";
- } else {
- $REPLY = "Please send the updated file to me, or submit it as a wishlist bug\nagainst <package>.";
- }
-
- if ($SUBMIT_ARG) {
- $BODY = $BODY_SUBMIT;
- $SUBJECT = $SUBJECT_SUBMIT;
- } elsif (defined $CALL) {
- $CALL="Debian Internationalization <debian-i18n\@lists.debian.org>"
- unless length $CALL;
- $BODY = $BODY_CALL;
- $SUBJECT = $SUBJECT_CALL;
- } else {
- $CALL="";
- $BODY = $BODY_TRANSLATOR;
- $SUBJECT = $SUBJECT_TRANSLATOR;
- }
-
- ## Apply the values to the subject and to the body of the message
-
- $SUBJECT =~ s/<package>/$PACKAGE_ARG/g;
- $SUBJECT =~ s/<version>/$PKG_VERSION/g;
- $SUBJECT =~ s/<package_and_version>/$PACKAGE_AND_VERSION/g;
- $BODY =~ s/<reply>/$REPLY/g;
- $BODY =~ s/<reply-to>/$BTS_ARG/g;
- $BODY =~ s/\n# Reply-To: \n/\n/;
- $BODY =~ s/<subject>/$SUBJECT/g;
- $BODY =~ s/<package>/$PACKAGE_ARG/g;
- $BODY =~ s/<version>/$PKG_VERSION/g;
- $BODY =~ s/<package_and_version>/$PACKAGE_AND_VERSION/g;
- $BODY =~ s/<from>/$FROM_ARG/g;
- $BODY =~ s/\n<deadline>/$DEADLINE_ARG/g;
-
- ## Check every file with .po extension in $PODIR ...
- Verbose("Checking for PO files in $PODIR");
- opendir(DIR, $PODIR);
- my $poFiles = {};
- my $statistics = "language translated fuzzy untranslated\n".
- "-----------------------------------------------------\n";
- if (length $CALL and $POTFILE eq "") {
- foreach my $potFile (grep(/\.pot$/, readdir(DIR))) {
- if (length $POTFILE) {
- die "Too many pot file found.\n".
- "Please specify one with the --potfile option.\n";
- }
- $POTFILE = $potFile;
- }
- closedir(DIR);
- opendir(DIR, $PODIR);
- if (length $POTFILE) {
- print "Using $POTFILE for the call for translation\n";
- } else {
- warn "No POT file found. You should specify one with the ".
- "--potfile option, or specify in the mail how to ".
- "retrieve it."
- }
- }
- if (length $CALL) {
- foreach my $poFile (grep(/\.po$/, readdir(DIR))) {
- $poFiles->{$poFile} = {};
- my $cmd = "LC_ALL=C /usr/bin/msgfmt -o /dev/null --stat $PODIR/$poFile 2>&1";
- my $stats = qx/$cmd/;
- chomp $stats;
- my ($t, $f, $u) = ("", "", "");
- my $lang = $poFile;
- $lang =~ s/\.po$//;
- if ($stats =~ s/^([0-9]+) translated message[s ,]*//) {
- $t = $1;
- }
- if ($stats =~ s/^([0-9]+) fuzzy translation[s ,]*//) {
- $f = $1;
- }
- if ($stats =~ s/^([0-9]+) untranslated message[s ,]*//) {
- $u = $1;
- }
- $statistics .= sprintf(" %-10s%10s %10s %10s\n", $lang, $t, $f, $u);
- }
- $BODY =~ s/<statistics>\n/$statistics/g;
- } else {
- foreach my $poFile (grep(/\.po$/, readdir(DIR))) {
- local $/ = "\n\n";
- $poFiles->{$poFile} = {};
- my $outdated = 0;
- my $found_header = 0;
- open (PO, "< $PODIR/$poFile")
- or die "Unable to read $PODIR/$poFile: $!\n";
- while (<PO>) {
- if ($found_header == 0 && m/msgid ""\nmsgstr/s) {
- $found_header = 1;
- # Concatenate lines
- s/"\n"//g;
- if (m/\\nLast-Translator: (.*?)\\n/ && $1 ne 'FULL NAME <EMAIL@ADDRESS>') {
- $poFiles->{$poFile}->{translator} = $1;
- } else {
- $warn .= "Warning: $poFile: Unable to determine last translator. Skipping file!\n";
- last;
- }
- if (m/\\nContent-Type: [^;]*; charset=(.*?)\\n/) {
- $poFiles->{$poFile}->{charset} = $1;
- } else {
- $warn .= "Warning: $poFile: Unable to determine charset. Skipping file!\n";
- last;
- }
- if ($LANGUAGETEAM_ARG && m/\\nLanguage-Team: (.*?)\\n/) {
- $poFiles->{$poFile}->{team} = $1
- if $1 ne 'LANGUAGE <LL@li.org>';
- }
- next;
- }
- # Ignore outdated msgids
- next unless m/^msgid /m;
- # Check for fuzzy or missing translations
- s/\n+$//s;
- if (m/^#, .*fuzzy/m or m/\nmsgstr ""$/s) {
- $outdated = 1;
- last;
- }
- }
- if ($UTF8) {
- Encode::from_to($poFiles->{$poFile}->{translator},
- $poFiles->{$poFile}->{charset},
- "UTF-8");
- Encode::from_to($poFiles->{$poFile}->{team},
- $poFiles->{$poFile}->{charset},
- "UTF-8");
- }
- close (PO)
- or die "Unable to close $PODIR/$poFile: $!\n";
- delete $poFiles->{$poFile} unless $outdated;
- }
- closedir(DIR);
- if (keys %$poFiles) {
- print "Outdated files: ".join(' ', keys %$poFiles)."\n";
- } else {
- print "No outdated files\n";
- exit(0);
- }
- }
-
- my %langs=();
- foreach (split(",", $LANGS)) {
- $langs{$_.".po"} = 1;
- }
-
- my $filelist = '';
- if ($SUBMIT_ARG or length $CALL) {
- $filelist = join(' ', sort keys %$poFiles)."\n";
- } else {
- foreach my $poFile (sort keys %$poFiles) {
- $filelist .= '### ';
- $filelist .= '[' .((!%langs or $langs{$poFile})?'*':' '). '] ';
- $filelist .= $poFile . ': ' . $poFiles->{$poFile}->{translator};
- $filelist .= ', ' . $poFiles->{$poFile}->{team} if defined($poFiles->{$poFile}->{team});
- $filelist .= "\n";
- }
- # Remove non-ASCII characters
- $filelist = DropNonASCII($filelist)
- unless ($UTF8);
- }
- $filelist =~ s/\n$//s;
- $BODY =~ s/<filelist>/$filelist/g;
-
- my %headers = ();
- if ($TEMPLATE_ARG ne "") {
- $BODY = &ReadFile($TEMPLATE_ARG);
- }
-
- OPEN_EDITOR:
- $BODY = &OpenEditor($EDITOR, $BODY) if not $DEFAULT_ARG;
-
- %headers = &ParseHeaders($BODY);
- my %To = &ParseTo($BODY);
-
- print STDERR $warn if $warn ne '';
-
- my @mails = ();
- if ($SUBMIT_ARG) {
- $BODY =~ s/<filelist>/$filelist/g;
- my %mail = (
- From => $FROM_ARG,
- To => "maintonly\@bugs.debian.org",
- Subject => $SUBJECT,
- 'X-Mail-Originator' => "$PROGRAM $VERSION"
- );
- $mail{body} = encode_qp(&RemoveHeaders($BODY));
- @mails = (\%mail);
- } elsif (length $CALL) {
- $BODY =~ s/<filelist>/$filelist/g;
- $BODY =~ s/<statistics>/$statistics/g;
- my %mail = (
- From => $FROM_ARG,
- To => $CALL,
- Subject => $SUBJECT,
- 'X-Mail-Originator' => "$PROGRAM $VERSION"
- );
- my $ext = ($GZIP_ARG ? '.gz' : '');
- my $file = $POTFILE;
- my $content = &ReadFile($PODIR . "/" . $file);
- $content = Compress::Zlib::memGzip($content) if $GZIP_ARG;
- my $file_encoded = encode_base64($content);
- my $contentType = ($GZIP_ARG ? "application/octet-stream": "text/x-gettext; name=\"$file\"; charset=\"US-ASCII\"");
- my $boundary = "=" . time() . "=";
- $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
- my $charset = $UTF8?"utf-8":"us-ascii";
- my $body = &RemoveHeaders($BODY);
- $mail{body} = <<_EOF_;
- --$boundary
- Content-Type: text/plain; charset="$charset"
- Content-Transfer-Encoding: quoted-printable
-
- $body
-
- --$boundary
- Content-Type: $contentType
- Content-Transfer-Encoding: base64
- Content-Disposition: attachment; filename="$file$ext"
-
- $file_encoded
- --$boundary--
- _EOF_
- @mails = (\%mail);
- } else {
- my $body = encode_qp(&RemoveHeaders($BODY));
- my $ext = ($GZIP_ARG ? '.gz' : '');
- foreach my $file (keys %$poFiles) {
- if (defined $To{$file}) {
- my $content = &ReadFile($PODIR . "/" . $file);
- $content = Compress::Zlib::memGzip($content) if $GZIP_ARG;
- my $file_encoded = encode_base64($content);
- my $contentType = ($GZIP_ARG ? "application/octet-stream" : "text/x-gettext; name=\"$file\"; charset=\"$poFiles->{$file}->{charset}\"");
- my %mail = (
- From => $FROM_ARG,
- To => $To{$file},
- Subject => $SUBJECT,
- 'X-Mail-Originator' => "$PROGRAM $VERSION"
- );
-
- my $boundary = "=" . time() . "=";
- $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
- my $charset = $UTF8?"utf-8":"us-ascii";
- $mail{body} = <<_EOF_;
- --$boundary
- Content-Type: text/plain; charset="$charset"
- Content-Transfer-Encoding: quoted-printable
-
- $body
-
- --$boundary
- Content-Type: $contentType
- Content-Transfer-Encoding: base64
- Content-Disposition: attachment; filename="$file$ext"
-
- $file_encoded
- --$boundary--
- _EOF_
-
- push(@mails, \%mail);
- }
- }
- }
-
- # Add mail headers and remove non-ASCII characters
- foreach my $refmail (@mails) {
- foreach my $h (keys(%headers)) {
- if ($UTF8) {
- $refmail->{$h} = encode_qp($headers{$h});
- $refmail->{$h} =~ s/=$//m;
- $refmail->{$h} =~ s/(\S*=\S*)/=?utf-8?Q?$1?=/g;
- } else {
- $refmail->{$h} = &DropNonASCII($headers{$h});
- }
- }
- foreach my $h (qw(From To Subject)) {
- if ($UTF8) {
- unless ($refmail->{$h} =~ m/=\?utf-8\?Q\?/) {
- $refmail->{$h} = encode_qp($refmail->{$h});
- $refmail->{$h} =~ s/=$//m;
- $refmail->{$h} =~ s/(\S*=\S*)/=?utf-8?Q?$1?=/g;
- }
- } else {
- $refmail->{$h} = &DropNonASCII($refmail->{$h});
- }
- }
- $refmail->{smtp} = $SMTP_ARG if ($SMTP_ARG ne '');
- }
-
- if (!$FORCE_ARG) {
- my $answers = ($DEFAULT_ARG)?"[y/N/?]":"[y/N/e/?]";
- QUESTION:
- if ($SUBMIT_ARG) {
- print "Ready to send the bug report against the package $PACKAGE_ARG, are you sure? $answers ";
- } elsif (length $CALL) {
- print "Ready to send the call for translation to $CALL, are you sure? $answers ";
- } else {
- print "Ready to send the emails, are you sure? $answers ";
- }
- my $line = <>;
- chop $line;
- if ($line eq "e" or $line eq "E") {
- goto OPEN_EDITOR unless ($DEFAULT_ARG);
- } elsif ($line eq "?") {
- print "y send the mail(s).\n".
- "? display this help message.\n".
- ($DEFAULT_ARG?"":"e reopen the editor.\n").
- "N exit, without sending mails.\n";
- goto QUESTION;
- }
- exit(0) if ($line ne "Y" and $line ne "y");
- }
-
- # Make Perl compiler quiet
- print $Mail::Sendmail::error . $Mail::Sendmail::error if 0;
- foreach my $mail (@mails) {
- sendmail(%{$mail}) || print "Couldn't send the email: $Mail::Sendmail::error\n";
- }
- if ($SUMMARY_ARG) {
- my %summary = (
- From => $FROM_ARG,
- To => $FROM_ARG,
- Subject => $SUBJECT,
- 'X-Mail-Originator' => "$PROGRAM $VERSION"
- );
- $summary{body} = "List of outdated files:\n";
- foreach my $poFile (sort keys %$poFiles) {
- $summary{body} .= ' ' . $poFile . ': ' . $poFiles->{$poFile}->{translator};
- $summary{body} .= ', ' . $poFiles->{$poFile}->{team} if defined($poFiles->{$poFile}->{team});
- $summary{body} .= "\n";
- }
- $summary{body} .= "Translators received the mail below.\n\n";
- $summary{body} .= encode_qp(&RemoveHeaders($BODY));
- sendmail(%summary) || print "Couldn't send the email: $Mail::Sendmail::error\n";
- }
- exit(0);
-
- ###############################################################################
-
- sub OpenEditor
- {
- my $editor = shift;
- my $body = shift;
- my $opts = "";
- my $tmpnam = tmpnam();
-
- open (OUT, "> $tmpnam")
- or die ("Couldn't write $tmpnam: $!\nExiting!\n");
- print OUT $body;
- close(OUT)
- or die ("Couldn't close $tmpnam: $!\nExiting!\n");
-
- $opts = "-f" if ($editor eq "vim");
- system("$editor $opts $tmpnam");
-
- $body = &ReadFile($tmpnam) if (-f $tmpnam);
- unlink($tmpnam);
-
- return $body;
- }
-
- sub ParseHeaders
- {
- my $body = shift;
- my %headers = ();
-
- while ($body =~ s/^#[ \t]*([^\n]*)\n//s) {
- my $comment = $1;
- if ($comment =~ m/^([a-zA-Z0-9_-]+):\s*([^\n]+)$/) {
- $headers{$1} = $2;
- }
- }
- return %headers;
- }
-
- sub ParseTo
- {
- my $body = shift;
- my %To = ();
-
- while ($body =~ s/#[ \t]*([^\n]*)\n//s) {
- my $comment = $1;
- if ($comment =~ s/^##[ \t]*\[(?:\*|x)\][ \t]*([^:]*):[ \t]*([^\n]*)$//s) {
- $To{$1} = $2;
- }
- }
- return %To;
- }
-
- sub RemoveHeaders
- {
- my $body = shift;
- # First remove comments
- 1 while $body =~ s/^#[^\n]*\n//s;
- # Optional empty lines
- $body =~ s/^\s+//s;
- return $body;
- }
-
- sub DropNonASCII {
- my $text = shift;
- $text =~ s/[\x80-\xff]/?/g;
- return $text;
- }
-
- sub ReadFile
- {
- my $file = shift;
- local $/ = undef;
- open(FILE, "< $file")
- or die ("Couldn't read $file: $!\nExiting!\n");
- my $body = <FILE>;
- close(FILE)
- or die ("Couldn't close $file: $!\nExiting!\n");
- return $body;
- }
-
- ## Handle invalid arguments
- sub Help_InvalidOption
- {
- print STDERR "Try `${PROGRAM} --help' for more information.\n";
- exit 1;
- }
-
- ## Print the usage message and exit
- sub Help_PrintHelp
- {
- print <<_EOF_;
-
- Usage: ${PROGRAM} [OPTIONS]
- Send outdated debconf PO files to the last translators.
-
- Options:
- --help display this help and exit
- --version display version information and exit
- -v, --verbose display additional information
- --noverbose
- -f, --force send the email without confirmation
- --noforce
- --utf8 send the mail in UTF-8
- --noutf8
- --podir=DIRECTORY specify where are located the PO files
- --smtp=SERVER specify SMTP server for mailing (default localhost)
- --template=TEMPLATE specify file to use it as template for the emails
- --notemplate
- --default don't open the editor and use the template as is
- --nodefault
- --gzip compress PO files with gzip
- --nogzip
- --package=PACKAGE specify the name of the package
- --from=MAINTAINER specify the name and the email address of the sender
- --deadline=DEADLINE specify the deadline for receiving the updated
- translations
- --langs=LANGUAGES restrict sending emails only to these languages
- --languageteam send the email also to the Language Team
- --nolanguageteam
- --summary send a status report to the maintainer with the list
- of emails sent to translators
- --nosummary
- --submit send a bug report against the package with a report
- of the outdated debconf translations
- --bts=BUGNUMBER specify the Debian bug number to set as reply-to
- --call[=LIST] send a call for translations to the LIST (or to
- the Debian I18N mailing list by default
- --potfile=FILE when used with --call, specifies the POT file to
- attach to the call for translations
-
- _EOF_
- exit 0;
- }
-
- ## Print the version text and exit
- sub Help_PrintVersion
- {
- print <<_EOF_;
- ${PROGRAM} $VERSION
- Copyright (C) 2004-2006 Fabio Tranchitella and Denis Barbier.
- This is free software; see the source for copying conditions. There is NO
- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- _EOF_
- exit 0;
- }
-
- sub Verbose
- {
- my $msg = shift;
- return unless $VERBOSE_ARG;
- $msg =~ s/^/**${PROGRAM}: /mg;
- print STDERR $msg."\n";
- }
-