#!/usr/bin/perl
##
## Author: David McKeon <@bonzoli.com>
## URL: http://bonzoli.com
## Program: unrar
## Creation Date: Date: 2007/01/29 21:01:48 PST
## Last Revision: $Date$
## Version: v.5
##
#############################################################################
# David McKeon <@bonzoli.com> http://bonzoli.com #
# #
# Copyright (C) 2007-2007 David McKeon. All rights reserved. #
# #
# 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 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: #
# #
# Free Software Foundation, Inc. #
# 59 Temple Place - Suite 330 #
# Boston, MA 02111-1307, USA. #
# #
# Or you can find the full GNU GPL online at: http://www.gnu.org #
# #
#############################################################################
## Category: Perl
##
##
##
##
##
#
$| = 1;
use Getopt::Long; # get command option pm
use File::Path; # create paths/dirs
# Print basic Usage
if (!$ARGV[0])
{
print "Usage: unrar.pl or \n-h help\n-v version\n";
exit 1;
}
#---------------------------------------------------------------------------
# Directory to place part files that were used to assemble the final file
# We move them here to help keep the clutter down
my $DMDIR='deleteme';
# This makes the dir if it doesn't exist
make_dir($DMDIR);
# Unrar executable, I change unrar to unrar.bin and rename this file to "unrar" in its place
# This has been tested with UNRAR 3.51 for linux
$URC='/usr/local/bin/unrar.bin';
#---------------------------------------------------------------------------
# Parse Options
Getopt::Long::Configure("no_ignore_case");
GetOptions(
"h|help" => \$help,
"d|debug" => \$debug,
"t|test" => \$test,
"V|version" => \$vers,
);
#---------------------------------------------------------------------------
# Execute Subroutines for each option call
if($help){ exec("perldoc $0"); }
if($vers){ version(); }
if($test){ test(); }
if($debug){ debug(); }
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
sub version {
my($date) = "2007/01/29 21:01:48 PST";
my($rvsn) = ".5";
my($rcsd) = ".5";
$date =~ s/(.*: +)(.*?)(\s*$)/$2/g;
$rvsn =~ s/(.*: +)(.*?)(\s*$)/$2/g;
$rcsd =~ s/(.*: +)(.*?)(\s*$)/$2/g;
print <
URL: http://bonzoli.com
Creation Date: 2007/01/29 21:01:48 GMT
Last Revision: $date GMT
Revision: $rcsd
Copyright (C) 2007-2007 David McKeon. All rights reserved.
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 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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
Or you can find the full GNU GPL online at: http://www.gnu.org
EOF
exit;
}
sub test {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION test
# RECEIVES None
# RETURNS None
# EXPECTS None
# SETS None
# DOES This Does the test option
print "Test fuction place holder\n";
exit;
}
sub debug {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION debug
# RECEIVES None
# RETURNS None
# EXPECTS None
# SETS None
# DOES Does the Debug function
print "Debug fuction place holder\n";
exit;
}
sub shellify_string {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION shellify_string
# RECEIVES $string
# RETURNS $string
# DOES Going to make this line readable by shell, so mv's and copies work.
# add a backslash before unusual characters
my ( $file );
# shouldn't just shift work here?
$file = shift @_;
#print "my file is $file \n";
#If its not one of these characters put a \ in front of it.
$file =~ s|[^-a-zA-Z0-9_.,/]|\\$&|g;
# backslash newline gets ignored by sh, so we have to use quotes.
$file =~ s|\\\n|'\n'|g;
# make sure name doesn't have a leading -
$file =~ s|^-|./-|;
# null name is unprintable, make it '.'
if ($file eq '') {
$file = ".";
}
return $file;
}
sub sanitize_string {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION sanitize_string
# RECEIVES string
# RETURNS sanitized string
# DOES sanitize artist name (or filename fragment) for use as a dir name
my $string = shift;
return 'unsorted' unless $string;
$string = lc($string);
$string =~ s|\bthe\b||;
$string =~ s|_| |g;
$string =~ s|^ +||;
$string =~ s| +$||;
$string =~ s| +| |g;
$string =~ s|\/| |g;
$string =~ s|[,(){}\[\]]||g;
return $string;
}
sub make_dir {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION make_dir
# RECEIVES directory including full path
# DOES Makes the full path and dir needed for the deleteme files.
$NEWDIR=shift;
eval { mkpath("$NEWDIR", 1, 0755) };
if ($@) {
print "Couldn\'t create $NEWDIR: $@";
}
}
# Take remaining Args and use them
$FILE="$ARGV[0]";
$NEWDIR=$FILE;
$FILE = shellify_string($FILE);
$CMD = ("$URC lb $FILE |wc -l");
$COUNT=`$CMD`;
chomp $COUNT;
print "THE COUNT:$COUNT:\n";
$CMD="$URC x $FILE >/dev/null";
if ($COUNT > 1)
{
$NEWDIR=~ s/.part\d+.rar$//g;
$NEWDIR=~ s/.rar$//g;
$NEWDIR=~ s/\w$//g;
$NEWDIR=sanitize_string($NEWDIR);
$NEWDIR=~ s/ /_/g;
$CMD1 = ("$URC l $FILE ");
$_=`$CMD1`;
if (!/\.D\.\.\.\.\./)
{
print "File count > 1, but I didn't find an internal directory in the archive.\n";
eval { mkpath("$NEWDIR", 1, 0755) };
if ($@)
{
print "Couldn\'t create $NEWDIR: $@";
exit;
}
print "Made a new directory, \nextracting rar in this directory\n-->:$NEWDIR:\n";
$NEWDIR=shellify_string($NEWDIR);
$CMD="$URC x $FILE $NEWDIR >/tmp/unrar.output";
}
print "$CMD\n";
system($CMD) == (0) or die "system $CMD failed: $?";
}
else
{
print "$CMD\n";
system($CMD) == (0) or die "system $CMD failed: $?";
}
if ( -d $MVDIR )
{
$FILE =~ s/\d+.rar$/\*/g;
$CMD="mv $FILE $MVDIR";
print "$CMD\n";
system($CMD) == (0) or die "system $CMD failed: $?";
}
#---------------------------------------------------------------------------
##
## Use "perldoc unrar" to read the man page below.
#
__END__
=head1 NAME
B - script that wraps the unrar binary, to create a directory if
the first rar file of a set, or a single rar, contains more then 1 file and
no directory in the archive. This is to keep an extracted set of files from
cluttering up the place. When it finds this scenario this script creates a
directory, a directory with the same name, minus any wierd characters.
=head1 SYNOPSIS
B
S<[ B<-dhtv> ]>
S<[ I ]>
=head1 DESCRIPTION
B script that wraps the unrar binary, to create a directory if
the first rar file of a set, or a single rar, contains more then 1 file and
no directory in the archive. This is to keep an extracted set of files from
cluttering up the place. When it finds this scenario this script creates a
directory, a directory with the same name, minus any wierd characters.
After extracting the files from the rar, if no error was found, it moves the
archives to a deleteme directory. This could be changed in the script to the
trashcan directory also. I preffer this method, because if you have a set of
rar files, there could be 2-100 of them, which is a bit of clutter itself. If
the deleteme directory doesn't exist, non of the files will be moved.
When only 1 file is in the rar, or it creates 1 file, that file will be in the
same directory where the program was run from.
# This has been tested with UNRAR 3.51 for linux binary, which you will need.
=head1 QUICK START
The most common usage is as follows:
B (filename.rar) or (filename.partxx.rar)
=head1 STANDARD OPTIONS
B<-d --debug>
Enables debugging code.
B<-h --help>
Prints this information.
B<-t --test>
Prints what will happen without performing the operations.
B<-v --version>
Prints version information.
=head1 OPTIONS
=head1 EXAMPLE
The example below
B B<-t> I
=head1 BUGS
None yet.
=head1 SEE ALSO
unrar
=head1 AUTHOR AND COPYRIGHT
David McKeon <@bonzoli.com> http://bonzoli.com
Copyright (C) 2007-2007 David McKeon. All rights reserved.
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 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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
Or you can find the full GNU GPL online at: http://www.gnu.org
=head1 VERSION
Current Revision: $Revision$
Last Modification: $Date$
=pod SCRIPT CATEGORIES
UNIX/System_administration
=pod OSNAMES
Any