User:Mannyack/multizip

From DPWiki
Jump to navigation Jump to search

multizip.pl: Software to Create the Slices for BEGIN Projects

Version 1.04 of multizip is a rewrite into perl. There is a major performance enhancement, as there are no longer temporary disk files. Thumbs.db is ignored if present in pngs or images. -- mannyack June 2021

The ruby version of Multizip was written by rfrank in 2008.

To create mulitzip.pl on your computer, copy the following text, starting with

#!/usr/bin/perl

through

print "Done.\n";

Copy all of that to a flat text file, in a program like Notepad or Notepad++; Guiguts would even work. Save the file as multizip.pl and then follow the instructions which follow.

#!/usr/bin/perl

#usage:

#

#   multizip projname nslices

#

#   this program is used to create upload zips for newcomer's only

#   projects at DP. It requires the directories: text, pngs, images

#   

#   multizip projname   --> generates balanced zips with projname as basename

#

#version 1.03: minor mod to the slicing logic to even out the slice sizes, instead of a larger

#              slice at the end containing the remainder of the files.

#mannyack--December 2020.

#version 1.04: convert to perl

#              ignore thumbs.db in pngs and images

#              don't create temporary directories on disk, go straight to zip file

#              create another zip file containing all .txt and .png files (for GWL/BWL creation)

#mannyack--June 2021.

use strict;

use warnings;

use Archive::Zip;

my $codeversion = '1.04';

print "multizip.pl version $codeversion\n";

#*******************************#

#get command line parameters

unless(scalar @ARGV == 2){

   print "Usage: multizip projname num_slices\n";

   exit;

}

my $projname = $ARGV[0];

my $nslices = $ARGV[1];

unless($projname =~ /^[a-zA-Z][a-zA-Z0-9]*$/){

   print "Project name must start with an alphabetic character and the rest alphanumeric\n";

   exit;

}

unless($nslices =~ /^[\d]+$/){

   print "Number of slices must be numeric\n";

   exit;

}

#*******************************#

#Read text directory and push files onto list (sorted)

my $textdirname = 'text';

my @textfiles = ();

my $file;

unless(-e -d $textdirname){

   print "Text directory missing\n";

   exit;

}

opendir (TEXTDIR, $textdirname) or die "Text: $!";

while ($file = readdir TEXTDIR){

   #only take files of the form *.txt

   if($file =~ /\.txt$/){

       push(@textfiles, $file);

   }

}

closedir TEXTDIR;

my $ntextfiles = scalar @textfiles;

if ($ntextfiles == 0){

   print "Text directory empty\n";

   exit;

}

@textfiles = sort @textfiles;

print "Processing $ntextfiles text files\n";

#*******************************#

#Read pngs directory and push files onto list (sorted)

my $pngsdirname = 'pngs';

my @pngfiles = ();

unless(-e -d $pngsdirname){

   print "Pngs directory missing\n";

   exit;

}

opendir (PNGSDIR, $pngsdirname) or die "Pngs: $!";

while ($file = readdir PNGSDIR){

   #only take files of the form *.png (no '.' or thumbs.db)

   if($file =~ /\.png$/){

       push(@pngfiles,$file);

   }

}

closedir PNGSDIR;

my $npngfiles = scalar @pngfiles;

if ($npngfiles == 0){

   print "Pngs directory empty\n";

   exit;

}

@pngfiles = sort @pngfiles;

print "Processing $npngfiles png files\n";

#*******************************#

#images directory must exist, warning if empty

my $imagedirname = 'images';

my @imagefiles = ();

unless(-e -d $imagedirname){

   print "Images directory missing\n";

   exit;

}

opendir (IMGDIR, $imagedirname) or die "Images: $!";

while ($file = readdir IMGDIR){

   #ignore files whose name starts with '.' and thumbs.db

   unless ($file =~ /^\./  or $file eq 'thumbs.db'){

       push(@imagefiles,$file);

   }

}

my $nimagefiles = scalar @imagefiles;

if($nimagefiles == 0){

   print "Warning: Images directory empty\n";

}else{

   print "Processing $nimagefiles illustration files\n";

}

#*******************************#

#Sanity checks

unless($ntextfiles == $npngfiles){

   print "Count disagrees: text=$ntextfiles pngs=$npngfiles\n";

   exit;

}

if ($ntextfiles < 2 * $nslices){

   print "Too many slices or too few files: slices=$nslices files=$ntextfiles\n";

   exit;

}

#*******************************#

#Create a zip file per slice

my $chunksize = int($ntextfiles/$nslices);

my $extra = $ntextfiles % $nslices;

if ($extra > 0){

   $chunksize += 1;

}

my $zip;

my $nextindex = 0;

my $slice = 1;

while ($nextindex < $ntextfiles){

   my $count = $chunksize;

   my $slicename = $projname . '-' . $slice . 'of' . $nslices;

   print "$slicename.zip","\n";

   $zip = Archive::Zip->new();

   while ($count > 0){

       $zip->addFile("$textdirname/$textfiles[$nextindex]");

       $zip->addFile("$pngsdirname/$pngfiles[$nextindex]");

       $nextindex += 1;

       $count -= 1;

   }

   #put the illustrations in the first slice

   if ( $slice == 1 && $nimagefiles > 0){

       foreach(@imagefiles){

           $zip->addFile("$imagedirname/$_");

       }

   }

   $zip->writeToFileNamed("$slicename.zip");

   if ($slice == $extra){

       $chunksize -= 1;

   }

   $slice += 1;

}

#*******************************#

#Create a zip file of all .txt and .png to populate GWL and BWL

print "$projname-all.zip\n";

$zip = Archive::Zip->new();

foreach(@textfiles){

   $zip->addFile("$textdirname/$_");

}

foreach(@pngfiles){

   $zip->addFile("$pngsdirname/$_");

}

$zip->writeToFileNamed("$projname-all.zip");

print "Done.\n";

Installing Perl

This version of multizip was written on Windows 10 and tested with Strawberry Perl. If you have already installed Strawberry Perl for Guiguts or Guiprep, you have already done all that is needed in terms of installing Perl.

For anyone who has not installed Strawberry Perl, go to their web-site, download the package appropriate to your computer and follow their install instructions.

Guiguts and Guiprep require some CPAN modules. The only module used by multizip is ARCHIVE::ZIP. I did not have to install this through CPAN, it appeared to have been part of the base Strawberry Perl installation.

How to Use multizip

These instructions work for Multizip once you installed Perl successfully.

You can download the current version of multizip.pl (1.04) from the common dpscans folder (mannyack_multizip104) on the DP web-site. The file is less than 3k. Unzip the file and place it in the parent directory of your project directories.

Now you are ready to slice up some projects.


Slicing

You have prepped the project and you have the usual folders: text, pngs, images within a project folder.


1. Open a command prompt on your computer and navigate to your project directory, the one that contains pngs, text and images.

2. Multizip should be in the parent of this directory, so invoke it with the following command:

 perl ..\multizip.pl file_name_you_want number_of_parts_you_want
  • file name is whatever you want multizip to call your zipped up slice files
  • number of parts is how many slices you want to end up with

Multizip doesn’t allow you to specify how many pages you want to have in a single slice, only how many slices you want to end up with.

So if you type:

 perl ..\multizip.pl mybook 5

you will end up with five zip files named: mybook-1of5.zip, mybook-2of5.zip, etc., and mybook-all.zip.


3. Upload these zip files to your own dpscan folder, not BEGIN. (BEGIN can find your dpscans when you create the projects.)

mybook-all.zip is created so you can upload it to the first slice, create the GWL and BWL entries for the entire project and then delete all the project files and load the first slice zip.

Multizip will put your illustration files into the first zip file. If you don't put your "images" folder into the slicing directory, multizip will object. (If images is empty, it will complain, but proceed.)

If the number of pages in your project doesn't divide neatly into even sized slices, multizip will even out the slice sizes so that no slice is more than one page larger than any other slice. Multizip doesn't destroy your folders so you can experiment until you are happy with the result.