#!/usr/bin/perl # Change hash size for an MGMapsCache folder by moving files around # script version 1.01 #Externals use POSIX; use File::Find; use Cwd; #OS Specific Variables $linuxDirDivider = "\/"; $linuxMoveCommand = "mv"; $linuxDeleteCommand = "rm"; $linuxRmdirCommand = "rmdir"; $linuxMkdirCommand = "mkdir -p"; $windowsDirDivider = "\\"; $windowsMoveCommand = "move"; $windowsDeleteCommand = "del"; $windowsRmdirCommand = "rd"; $windowsMkdirCommand = "md"; print "Detected OS: $^O\n\n"; if($^O ge "linux" || $^O ge "cygwin" ) { $systemDirDivider = $linuxDirDivider; $systemDirDividerRegex = $linuxDirDivider; $systemMoveCommand = $linuxMoveCommand; $systemDeleteCommand = $linuxDeleteCommand; $systemRmdirCommand = $linuxRmdirCommand; $systemMkdirCommand = $linuxMkdirCommand; } elsif($^O ge "MSWin") { $systemDirDivider = $windowsDirDivider; $systemDirDividerRegex = "$windowsDirDivider$windowsDirDivider"; $systemMoveCommand = $windowsMoveCommand; $systemDeleteCommand = $windowsDeleteCommand; $systemRmdirCommand = $windowsRmdirCommand; $systemMkdirCommand = $windowsMkdirCommand; } if($^O eq "darwin") { $systemDirDivider = $linuxDirDivider; $systemDirDividerRegex = $linuxDirDivider; $systemMoveCommand = $linuxMoveCommand; $systemDeleteCommand = $linuxDeleteCommand; $systemRmdirCommand = $linuxRmdirCommand; $systemMkdirCommand = $linuxMkdirCommand; } my $dn = ""; my $fn; $oldSize = 0; $newSize = 0; $file_CacheConf = "cache.conf"; while ($dn eq "") { # Read cache folder name print "Enter the name of the cache folder (default \"MGMapsCache\"): "; chomp($dn = <>); if ($dn eq "") { $dn = "MGMapsCache"; } # Open cache.conf $fn = $dn.$systemDirDivider.$file_CacheConf; if (!open(F, "<".$fn)) { print "$fn not found (invalid cache folder name).\n"; $dn = ""; next; } # Get old hash size while ($line = ) { @splits = split('=', $line); if (($splits[0] eq 'tiles_per_file') && (int($splits[1]) != 1)) { print "At this time you cannot re-hash cache folders with multiple tiles per file.\n"; exit 1; } if ($splits[0] eq 'hash_size') { $oldSize = int($splits[1]); } elsif (($splits[0] eq 'version') && (int($splits[1]) < 3)) { $oldSize = 97; } } close(F); if ($oldSize < 1 || $oldSize >= 100) { print "Unknown existing cache size, invalid $file_CacheConf file.\n"; exit 1; } } # Get new hash size while ($newSize < 1 || $newSize >= 100) { print "New hash size (examples: 11, 23, 47, 97 or 1 to disable hashing): "; chomp($newSize = <>); next if ($newSize eq ""); $newSize = int($newSize); if ($newSize < 1 || $newSize >= 100) { print "Please enter a number between 1 and 100 (the prime numbers above give best results).\n"; next; } } # Nothing to do? Actually we may have to move _some_ files but not all if downloaded with different tools. if ($oldSize == $newSize) { print "Warning: Old hash size is the same as new hash size, nothing to do.\n"; } # Get base directory $baseDir = getcwd().$systemDirDivider; if ($dn =~ /^$systemDirDividerRegex/) { $baseDir = ""; } # Do the rename/move around finddepth(\&recursiveMove, $dn); # Remove the unused folders finddepth(\&recursiveRmdir, $dn); # update the cache configuration file print "Moving $file_CacheConf to $file_CacheConf.old\n"; my $cmd = $systemMoveCommand." ".$fn." ".$fn.".old"; system($cmd); print "Updating $file_CacheConf\n"; open(F, "<".$fn.".old") or die("Cannot read $file_CacheConf.old"); open(F2, ">".$fn) or die("Cannot write $file_CacheConf"); $found = 0; print F2 "version=3\n"; while($line = ) { @splits = split('=', $line); if ($splits[0] eq 'hash_size') { print F2 "hash_size=".$newSize."\n"; $found = 1; } elsif ($splits[0] ne 'version') { print F2 $line; } } if ($found == 0) { print F2 "hash_size=".$newSize."\n"; } close(F2); close(F); print "Removing $file_CacheConf.old\n"; $cmd = $systemDeleteCommand." ".$fn.".old"; system($cmd); # done exit; sub recursiveMove { # only mgm files if (/^([0-9]+)_([0-9]+)\.mgm$/) { my $oldName = $File::Find::name; my $newName = $oldName; my $oldHashVal = ($1*256+$2) % $oldSize; my $newHashVal = ($1*256+$2) % $newSize; if ($oldSize > 1 && $newSize > 1) { $newName =~ s/\/$oldHashVal\/([0-9]+_[0-9]+\.mgm)$/\/$newHashVal\/$1/; } elsif ($oldSize == 1 && $newSize == 1) { } elsif ($oldSize == 1) { $newName =~ s/\/([0-9]+_[0-9]+\.mgm)$/\/$newHashVal\/$1/; } else { $newName =~ s/\/$oldHashVal\/([0-9]+_[0-9]+\.mgm)$/\/$1/; } # mkdir if needed if ($newSize > 1) { my $newDir = $newName; $newDir =~ s/\/[0-9]+_[0-9]+\.mgm$//; if (!(-d $baseDir.$newDir)) { print "Creating directory ".$newDir."\n"; my $cmd = $systemMkdirCommand." ".$baseDir.$newDir; system($cmd); } } if ($oldName ne $newName) { print "Moving ".$oldName." to ".$newName."\n"; my $cmd = $systemMoveCommand." ".$baseDir.$oldName." ".$baseDir.$newName; system($cmd); } else { print "Not moving ".$oldName."\n"; } } } sub recursiveRmdir { # only folders with names like numbers that are empty if (/^([0-9]+)$/) { opendir(DIR, $_); my @dir = readdir(DIR); closedir(DIR); # only . and .. if ($#dir < 2) { print "Removing directory ".$File::Find::name."\n"; my $cmd = $systemRmdirCommand." ".$baseDir.$File::Find::name; system($cmd); } } }