Handig perl script om zaken van de humax te halen

Status
Niet open voor verdere reacties.

gctwnl

Forum Gebruiker
Berichten
13
Ik heb tijden geleden een erg handig perl script gemaakt om films van de 5050C te downloaden/verwijderen/etc.

Dit is de handleiding:
hermione:Humax gerben$ ./downloadhumax --usage
This is the downloadhumax script. You can use this script to download
and/or remove recorded movies from your Humac-5050C PVR.

To use this script, just run it. As it is a perl script, you either need
to make this script executable and make sure the first line contains the
correct location of your perl executable, or you call perl explicitely as
in
perl downloadhumax
on a unix-like PC (like a Mac or a Linux machine). Note, this script
has been tested only on a Mac running Mac OS X 10.6. Differences in ftp
behaviour may require tweaking of this script on other environments.

Without arguments, the script will download everything on your Humax
without deleting. It will not redownload what is already there, but it
will re-download if the local file has a size different than the file
on the humax (which is what may occur if you abort the script during
a download).

The following flags may be given with the following results:
--targetdir=s Write the downloaded files in directory s
--machine=s The name or IP address of your Humax 5050C
--pin=i The PIN code of your Humax 5050C
--dryrun Do not download or delete anything, but only
write what the script would do (very handy this)
--redownloadpartial Overwrite downloaded files if their size does not match
what is on the Humax 5050C
--pattern=s Only download/delete files if their name matches this
pattern. E.g., with a pattern like
-pattern='^(No|Z)'
on a Unix machine, it woul donly download/delete
files that start with 'No' or 'Z' and leave the rest
alone. The pattern is a perl regular expression.
--delete Delete the file on the Humax 5050C after a successful
download (or if the file already has been downloaded
earlier, which for the script means "there is a local
file with the same name and the same size")
--forcedelete Delete the file irregardless of it being successfully
downloaded. Do not download. Very handy to clean your
Humax 5050C without using the cumbersome GUI for this
--debug Print out debug messages
--usage Print out this message and exit
--license Print out the license and exit

Examples:
./downloadhumax
Download everything, do not delete everything
./downloadhumax --delete
Download everything and delete everything on the Humax 5050C
that has been downloaded
./downloadhumax --pattern='^House' --delete
Download all files of which the name starts with 'House' and
delete those from the Humax
./downloadhumax --redownloadpartial --delete
Download everything that has not been fully downloaded yet and
delete everything from the Humax 5050C
./downloadhumax --pattern='^House' --forcedelete
Delete all files on the Humax 5050C of which the name starts
with 'House'. Do not download.

No warranty, use at your own risk. Please read the license by running the
script with the --license flag or reading the license in the code below.

This program is distributed as open source under a BSD-style license.

En hier is de code:
Code:
#!/usr/bin/perl
# Change these deafults if need be:
$HUMAXDIR='/Users/Shared/Humax';# Where you want the .ts files to go
$HUMAXADDRESS='192.168.1.x';	# What the DNS name or IP address is of your Humax
$HUMAXPIN=0000;			# What the pin code is of your humax (0000 is default)
$REDOWNLOADPARTIAL=1;		# If local file has different size than file
				# on Humax, overwrite? (nonzero = overwrite)
$DELETEIFDOWNLOADED=0;		# If file has been succesfully downloaded
				# delete on Humax? (nonzero = delete)
$DRYRUN=0;			# If set to 1, do not download or delete,
				# just show
$PATTERN='.*';			# only get those matching the pattern

# Do not change anything below this line

use Getopt::Long;
my $targetdir = $HUMAXDIR;
my $humaxaddress = $HUMAXADDRESS;
my $pin = $HUMAXPIN;
my $dryrun = $DRYRUN;
my $redownloadpartial = $REDOWNLOADPARTIAL;
my $pattern = $PATTERN;
my $delete = $DELETEIFDOWNLOADED;
my $forcedelete = 0;
my $debug = 0;
my $usage = 0;
my $license = 0;
$result = GetOptions( "targetdir=s"	    => \$targetdir,
		      "machine=s"	    => \$humaxaddress,
		      "pin=i"		    => \$pin,
		      "dryrun"		    => \$dryrun,
		      "redownloadpartial"   => \$redownloadpartial,
		      "pattern=s"	    => \$pattern,
		      "forcedelete"	    => \$forcedelete,
		      "debug"		    => \$debug,
		      "license"		    => \$license,
		      "usage"		    => \$usage,
		      "delete"		    => \$delete);

$HUMAXUSER='humaxftp';
$DATE=`/bin/date "+%Y-%m-%d-%H%M%S"`;
chomp($DATE);
$TMPNETRC="/tmp/.netrc-downloadhumax-${DATE}";
$TMPDIRLIST="/tmp/.dirlist-downloadhumax-${DATE}";
$TMPFTPCOMMANDS="/tmp/.ftpcmds-downloadhumax-${DATE}";

if ($usage) {
print <<_EOF_USAGE;
    This is the downloadhumax script. You can use this script to download
    and/or remove recorded movies from your Humac-5050C PVR.

    To use this script, just run it. As it is a perl script, you either need
    to make this script executable and make sure the first line contains the
    correct location of your perl executable, or you call perl explicitely as
    in
	perl downloadhumax
    on a unix-like PC (like a Mac or a Linux machine). Note, this script
    has been tested only on a Mac running Mac OS X 10.6. Differences in ftp
    behaviour may require tweaking of this script on other environments.

    Without arguments, the script will download everything on your Humax
    without deleting. It will not redownload what is already there, but it
    will re-download if the local file has a size different than the file
    on the humax (which is what may occur if you abort the script during
    a download).

    The following flags may be given with the following results:
    --targetdir=s	Write the downloaded files in directory s
    --machine=s		The name or IP address of your Humax 5050C
    --pin=i		The PIN code of your Humax 5050C
    --dryrun		Do not download or delete anything, but only
			write what the script would do (very handy this)
    --redownloadpartial	Overwrite downloaded files if their size does not match
			what is on the Humax 5050C
    --pattern=s		Only download/delete files if their name matches this
			pattern. E.g., with a pattern like
			    -pattern='^(No|Z)'
			on a Unix machine, it woul donly download/delete
			files that start with 'No' or 'Z' and leave the rest
			alone. The pattern is a perl regular expression.
    --delete		Delete the file on the Humax 5050C after a successful
			download (or if the file already has been downloaded
			earlier, which for the script means "there is a local
			file with the same name and the same size")
    --forcedelete	Delete the file irregardless of it being successfully
			downloaded. Do not download. Very handy to clean your
			Humax 5050C without using the cumbersome GUI for this
    --debug		Print out debug messages
    --usage		Print out this message and exit
    --license		Print out the license and exit

    Examples:
	./downloadhumax
		Download everything, do not delete everything
	./downloadhumax --delete
		Download everything and delete everything on the Humax 5050C
		that has been downloaded
	./downloadhumax --pattern='^House' --delete
		Download all files of which the name starts with 'House' and
		delete those from the Humax
	./downloadhumax --redownloadpartial --delete
		Download everything that has not been fully downloaded yet and
		delete everything from the Humax 5050C
	./downloadhumax --pattern='^House' --forcedelete
		Delete all files on the Humax 5050C of which the name starts
		with 'House'. Do not download.

    No warranty, use at your own risk. Please read the license by running the
    script with the --license flag or reading the license in the code below.

    This program is distributed as open source under a BSD-style license.

_EOF_USAGE
    exit 0 unless $license;
}

if ($license) {
print <<_EOF_LICENSE;

Copyright (c) 2011, Gerben Wierda, R&A
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

Neither the name of R&A nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

_EOF_LICENSE
    exit 0;
}

open( NETRC, ">${TMPNETRC}") or die "Cannot create ${TMPNETRC}: $!";
print( NETRC "machine ${humaxaddress}\n");
print( NETRC "login ${HUMAXUSER}\n");
print( NETRC "password ${pin}\n");
close( NETRC);
system( "chmod 600 ${TMPNETRC}")==0 or die "Cannot chmod ${TMPNETRC}: $!";

sub humaxdirlist
{
    my $humaxsubdir = shift;

    open( FTP_IN, ">${TMPFTPCOMMANDS}") or die "Cannot create ${FTPCOMMANDS}: $!";
    print( FTP_IN "cd \"$humaxsubdir\"\n");
    print( FTP_IN "dir\n");
    print( FTP_IN "quit\n");
    close( FTP_IN);

    if ($debug) {
	print "***** DEBUG START humaxdirlist\n";
	system( "/bin/cat \"${TMPFTPCOMMANDS}\"");
	print "***** DEBUG STOP\n";
    }

    system( "/usr/bin/ftp -N ${TMPNETRC} ${humaxaddress} <${TMPFTPCOMMANDS} >${TMPDIRLIST}");

    open( DIRLIST, "<${TMPDIRLIST}") or die "Cannot read ${TMPDRLIST}: $!";
    my @dirlist = <DIRLIST>;
    close( DIRLIST);

    if ($debug) {
	print "***** DEBUG START humaxdirlist\n";
	system( "/bin/cat \"${TMPDIRLIST}\"");
	print "***** DEBUG STOP\n";
    }

    return @dirlist;
}

my %completed;
my %tsfiles;
foreach my $dirline (&humaxdirlist( "Video")) {
    next if $dirline=~/^Command/;
    next if $dirline=~/\s(\.)?\.$/;
    next if $dirline=~/\s0.n?ts$/;
    my ($pre, $size, $mid, $name) = $dirline=~/^(\S+\s+){4}(\S+)\s+(\S+\s+){3}(.+)$/;
    # print $dirline;
    # print "$name = $size\n";
    if ($name =~ /^\.(.+)/) {
	my $basename = $1;
	#print "Completed recording: $basename\n";
	$completed{$basename} = $size;
    }
    if ($name =~ /^(.+)\.ts$/) {
	my $basename = $1;
	#print "TS File: $basename.ts\n";
	if ($basename =~ /$pattern/) {
	    $tsfiles{$basename} = $size;
	}
	else {
	    print "Skipping $basename\n";
	}
    }
}

# Weed out uncompleted recordings on Humax
foreach my $key (keys %tsfiles) {
    delete $tsfiles{$key} unless exists $completed{$key};
}

die "Can't cd to ${targetdir}: $!\n" unless chdir( "${targetdir}");

foreach my $key (keys %tsfiles) {
    my $download = 0;
    # print "Completed $key = $tsfiles{$key}\n";
    my $localsize = -s "$key.ts";
    # print "$key: L:$localsize R:$tsfiles{$key}\n";
    if (not $forcedelete) {
	if ($localsize) {
	    if ($localsize == $tsfiles{$key}) {
		print( "Skipping \"$key\", file already completely downloaded.\n") unless $dryrun;
	    }
	    elsif ($localsize > 0) {
		warn( "Found \"$key\" with different size. Incomplete download?\n");
		$download = $redownloadpartial;
	    }
	}
	else {
	    $download = 1;
	}
    }
    if ($download and not $forcedelete) {
	if ($dryrun) {
	    print( "dryrun: /usr/bin/ftp -A -N ${TMPNETRC} \"ftp://humaxftp\@humax/Video/$key.ts\"\n");
	}
	else {
	    system( "/usr/bin/ftp -A -N ${TMPNETRC} \"ftp://humaxftp\@humax/Video/$key.ts\"");
	}
    }
    if ($forcedelete or $delete) {
	# Check if downloaded file has same size as original, if so
	# delete foo.ts, foo.hmt, foo.nts and .foo subdirectory with contents
	my $newlocalsize = -s "$key.ts";
	if ($forcedelete or $newlocalsize or $dryrun) {
	    if ($forcedelete or ($newlocalsize == $tsfiles{$key}) or $dryrun) {
		print( "Deleting \"$key\" from Humax.\n") unless $dryrun;
		my @subdirlist = &humaxdirlist( "Video/.$key");
		open( FTP_IN, ">${TMPFTPCOMMANDS}") or die "Cannot create ${FTPCOMMANDS}: $!";
		print( FTP_IN "cd \"Video/.$key\"\n");
		foreach my $subdirline (@subdirlist) {
		    # print "SUBDIRLINE: $subdirline";
		    next if $subdirline=~/^Command/;
		    next if $subdirline=~/\s(\.)?\.$/;
		    my ($pre, $size, $mid, $name) = $subdirline=~/^(\S+\s+){4}(\S+)\s+(\S+\s+){3}(.+)$/;
		    print( FTP_IN "del \"$name\"\n");
		}	
		print( FTP_IN "cd ..\n");
		print( FTP_IN "rmdir \".$key\"\n");
		print( FTP_IN "del \"$key.ts\"\n");
		print( FTP_IN "del \"$key.nts\"\n");
		print( FTP_IN "del \"$key.hmt\"\n");
		print( FTP_IN "quit\n");
		close( FTP_IN);
		if ($debug) {
		    print "***** DEBUG START\n";
		    system( "/bin/cat \"${TMPFTPCOMMANDS}\"");
		    print "***** DEBUG STOP\n";
		}
		if ($dryrun) {
		    print( "dryrun: Not executing delete commands for \"$key\"\n");
		}
		else {
		    system( "/usr/bin/ftp -N ${TMPNETRC} ${humaxaddress} <${TMPFTPCOMMANDS}");
		}
	    }
	    elsif (not ($forcedelete or $dryrun)) {
		warn( "Downloaded file \"$key.ts\" is incomplete. Download must have aborted. Not deleting original.\n");
	    }
	    else {
		# $forcedelete so original has been deleted or $dryrun and nothing has happened
	    }
	}
	elsif (not ($forcedelete or $dryrun)) {
	    warn( "Downloaded file \"$key.ts\"is missing. Download must have failed. Not deleting original.\n");
	}
	else{
	    # $forcedelete so original has been deleted or $dryrun and nothing has happened
	}
    }
}

if (not $debug) {
    unlink( "${TMPNETRC}");
    unlink( "${TMPFTPCOMMANDS}");
    unlink( "${TMPFTPCOMMANDS}-subdir");
    unlink( "${TMPDIRLIST}");
}
 
Status
Niet open voor verdere reacties.
Bovenaan