#!/usr/bin/perl -w # # MAIN ADMINISTRATIVE DATABASE UPDATE TOOL # # Usage: # ./update-master-info [-d RSYNCDESTDIR] [-O OCEAN ... | -a] # # Usual usages: # # After editing source-info.txt to add commodities, or # changing db-idempotent-update (eg to change the schema): # ./update-master-info -d ~ftp/users/ijackson/yarrg/ # This will update everything except the ocean topologies. # # To take account of new islands, or to fix a mistake in # assigning island(s) to archipelago(es), or to add support # for a new ocean: # ./update-master-info -d ~ftp/users/ijackson/yarrg/ -O Midnight # # After a fix to a mistake on a YPPedia chart page, correcting # only inter-island-distances: # ./update-master-info -O Midnight # # After changing the algorithms for topology determination # or YPPedia scraping: # ./update-master-info -a # and check that nothing unexpected changes. # # To just make backups of the databases into the rsync directory: # ./update-master-info -b -d ~ftp/users/ijackson/yarrg/ -a # ./update-master-info -b -d ~ftp/users/ijackson/yarrg/ -O ... # 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. use strict (qw(vars)); use DBI; use Commods; use CommodsDatabase; use File::Copy; $ENV{'LC_CTYPE'}= 'en_GB.UTF-8'; sub full ($) { my ($ocean) = @_; quick($ocean); print "## updating topology of $ocean\n"; system('./yppedia-chart-parser',$ocean); die "$ocean $?" if $?; print "\n"; } sub quick ($) { my ($ocean) = @_; print STDERR "## updating schema and commodities for $ocean\n"; system('./db-idempotent-populate',$ocean); die $? if $?; } my $rsyncdir; sub process_some_info ($$$) { my ($v,$df,$sfn) = @_; my $sf= new IO::File $sfn or die "$sfn $!"; my $h; while (<$sf>) { chomp; s/\s+$//; next if m/^\s*\#/ || !m/\S/; if (m/^\S.*/) { $h= $&; } die "$_ ?" unless defined $h; if ($h =~ m/^commods|^\%[a-z]\b/) { s/\t.*//; } if ($v<2) { next if $h =~ m/^nocommods/; } next if $sfn =~ m/source-info/ && $h =~ m/^ocean\b/; next if $h =~ m/^client|^vessels|^shot\b/; print $df $_, "\n" or die $!; } $sf->error and die $!; } sub update_master_info () { foreach my $v (1..$masterinfoversion) { my $dfnl= sprintf "master-info%s.txt", ($v>1 ? "-v$v" : ''); print STDERR "installing new $dfnl...\n"; my $dfn= "$rsyncdir/$dfnl"; my $df= new IO::File "$dfn.tmp", 'w' or die "$dfn.tmp $!"; process_some_info($v,$df, 'source-info.txt'); foreach my $ocean (sort keys %oceans) { process_some_info($v,$df, '_ocean-'.(lc $ocean).'.txt'); } close $df or die $!; rename "$dfn.tmp", "$dfn" or die $!; } } my @specoceans; my $alloceans; my $backup; sub optarg () { return $_ if length; die unless @ARGV; return scalar shift @ARGV; } while (@ARGV && $ARGV[0] =~ m/^-/) { $_= shift @ARGV; last if m/^--?$/; while (m/^-./) { if (s/^-d//) { die if defined $rsyncdir; $rsyncdir= optarg(); } elsif (s/^-O//) { push @specoceans, optarg(); } elsif (s/^-b/-/) { die if $backup; $backup=1; } elsif (s/^-a/-/) { die if $alloceans; $alloceans=1; } else { die "$_ ?"; } } } die if @ARGV; die if @specoceans && $alloceans; die if $backup && !$alloceans && !@specoceans; parse_info_serverside(); if ($backup) { my @oceans= $alloceans ? (sort keys %oceans) : @specoceans; foreach my $ocean (@oceans) { print "## database backup for $ocean\n"; db_setocean($ocean); db_writer(); db_connect(); $dbh->selectall_arrayref("SELECT * FROM commods WHERE commodid=1"); my $src= db_filename(); my $dst= $src; $dst =~ s,.*/,,; $dst= "$rsyncdir/$dst"; copy($src,"$dst.tmp") or die "$src -> $dst.tmp $!"; rename("$dst.tmp",$dst) or die "$dst.tmp -> $dst $!"; $dbh->rollback(); } } elsif (@specoceans) { print "### full update of specified oceans ...\n"; foreach my $ocean (@specoceans) { die "$ocean ?" unless defined $oceans{$ocean}; full($ocean); } } elsif ($alloceans) { print "### full (inc.topology) update of all oceans ...\n"; foreach my $ocean (sort keys %oceans) { full($ocean); } } else { print "### quick (no topology) update only (of all oceans) ...\n"; foreach my $ocean (sort keys %oceans) { quick($ocean); } } if (defined $rsyncdir and !$backup) { print "### master-info update ...\n"; update_master_info(); }