#!/usr/bin/perl -w # # This script is invoked to process an email sent by the # commod-update-receiver Perl script. # This is part of ypp-sc-tools, a set of third-party tools for assisting # players of Yohoho Puzzle Pirates. # # Copyright (C) 2009 Ian Jackson # # 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 3 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, see . # # Yohoho and Puzzle Pirates are probably trademarks of Three Rings and # are used without permission. This program is not endorsed or # sponsored by Three Rings. # Emails are: # multipart/mixed, containing # text/plain; name="metadata"; charset="utf-8" # Content-Disposition: inline; filename="metadata" # ocean\t canonical mixed case # island\t canonical mixed case # timestamp\t time_t (non-leap secs since start of 1970 UTC) # clientname\t may contain spaces # clientversion\t may contain spaces # clientfixes\t space-delimited list # clientspec\t \t\t # servername\t may contain spaces # serverversion\t may contain spaces # serverfixes\t space-delimited list # serverspec\t \t\t # application/octet-stream; name="deduped.tsv.gz" # Content-Disposition: attachment; filename="deduped.tsv.gz" # use strict (qw(vars)); use POSIX; use MIME::Parser; use Commods; setlocale(LC_CTYPE, "en_GB.UTF-8"); my $parser= new MIME::Parser; our $entity; sub find_part ($$$) { my ($filename, $type, $accepter) = @_; foreach my $part ($entity->parts()) { my $h= $part->head(); next unless $h->recommended_filename() eq $filename; next unless $h->mime_type() eq $type; next unless $part->effective_type() eq $type; next if defined $accepter and !&$accepter($h); return $part; } die "no appropriate part with name $filename and type $type"; } sub bad_data_fail ($) { die $_[0]; } sub main () { $parser->extract_nested_messages(0); $parser->ignore_errors(0); $entity= $parser->parse(\*STDIN); my $eff_type= $entity->effective_type(); die "effective type $eff_type" unless $eff_type eq 'multipart/mixed'; my $mdpart= find_part('metadata', 'text/plain', sub { my $charset= $_[0]->mime_attr('content-type.charset'); return 1 if grep { $_ eq $charset } qw(utf-8 us-ascii); }); my $mdh= $mdpart->open('r') or die; my %md; while (defined($_= $mdh->getline())) { m/^([a-z]+)\t(.*)$/ or next; $md{$1}= $2; } my $tsvpart= find_part('deduped.tsv.gz', 'application/octet-stream', undef); my $tsv= pipethrough_prep(); $tsvpart->bodyhandle()->print($tsv); my $pt= pipethrough_run_along($tsv,undef, 'gunzip','gunzip'); while (<$pt>) { my @v= check_tsv_line($_, \&bad_data_fail); print "[",join('|',@v),"]\n"; } pipethrough_run_finish($pt); } my $ok= eval { main(); 1; }; my $err= $@; $parser->filer->purge(); if (!$ok) { print STDERR "PROCESSING FAILED\n $@\n"; exit 1; }