Sign up here and you can log into the forum!

fast linksheet script

Everything (else) to do with Movie Sheets and homebrew firmware on the WDTV(s), including how the %*#^ do I get them working?

Re: fast linksheet script   

Postby Chris Bone » Wed Jan 25, 2012 6:16 am

Oh, recliq, you mentioned a linksheet test setup... would that be in the form of a script that creates a dummy heirarchy of files and then runs linksheet against it in various modes and with a catalogue of expected results?... if so, perhaps you can send that to me so I can test against that and handle any issues up until such time as you guys are happy with it.

Cheers
Chris
Chris Bone
n00b
 
Posts: 14
Joined: Fri Nov 04, 2011 4:43 am

Re: fast linksheet script   

Postby recliq » Wed Jan 25, 2012 7:47 am

Yea, quite like that, different filenames for the possible naming conventions and sheet types but with fake media files, so you can browse it just like a real media collection but you can't play the videos.
If I find my test-setup i will share it with you, or even make it public as example for naming conventions.
It's based on an archive b-rad once made, I just updated it to check for more combinations that are possible and valid.

If I can't find it I'm probably going to create a new one...
­WDLXTV Project Maintainer
-:] If you like my contributions feel free to donate for a beer or a new flash drive. ...and always remember: RTFM! (README, FAQ, WIKI) [:-
User avatar
recliq
WDLXTV Team
 
Posts: 5022
Joined: Thu Apr 15, 2010 8:09 am
Location: Kiel, Germany

Re: fast linksheet script   

Postby Chris Bone » Wed Jan 25, 2012 9:26 am

A setup for regression testing could be quite useful for this kind of thing.. it's the classic kind of code that breaks when some other thing is fixed so keeping a comprehensive suite of input and a way to generate the linksheet output in a diff-able way sounds right... I'll add an optional 3rd arg to the script that can set somewhere other than /msheets as the target. This way we can run:

linksheet_old /tmp/test_data 0 /tmp/msheet_orig
linksheet_new /tmp/test_data 0 /tmp/msheet_new
diff -r /tmp/msheet_orig /tmp/msheet_new

And the only diffs should be bug fixes or new mappings.

Cheers
Chris
Chris Bone
n00b
 
Posts: 14
Joined: Fri Nov 04, 2011 4:43 am

Re: fast linksheet script   

Postby recliq » Wed Jan 25, 2012 12:11 pm

sounds good to me :)
­WDLXTV Project Maintainer
-:] If you like my contributions feel free to donate for a beer or a new flash drive. ...and always remember: RTFM! (README, FAQ, WIKI) [:-
User avatar
recliq
WDLXTV Team
 
Posts: 5022
Joined: Thu Apr 15, 2010 8:09 am
Location: Kiel, Germany

Re: fast linksheet script   

Postby Chris Bone » Thu Jan 26, 2012 10:18 am

Here is what I hope is the final version. It corrects the incorrect folder sheet bug and is also a fair amount faster. The incorrect
folder sheet bug was caused by the fact that every sheet would get linked in as the folder sheet, you'd only get the correct result
if the proper folder sheet was the very last one processed. The bug is fixed by holding back all the in-exact name matches in a
list and only create them if nothing else created the link... so now it doesn't matter what order things were created in you get a
deterministic result given well formed input... this provides a speed win because spurious links are not being created/destroyed.

I also skipped creation of sheets for folders whose names start with a '.' because those are hidden anyway, they don't need sheets.

Cheers
Chris

Code: Select all
#!/usr/bin/perl

### Copyright 2012 b-rad.cc
### http://wdlxtv.com & http://b-rad.cc & http://nextdimension.cc
### GPLv3 - full license located @ /usr/share/LICENSE
### Stipulations:
### - the full copyright notices in /osd/setup_about.xml must be left intact, as it is the publicly displayed copyright portion of this software as dictated by the GPLv3
### - this entire header must be left intact

## linksheets <location> <mode> [/msheets]
##  recursively searches and symlinks movie sheets into /msheets
##  /msheets is joined with /osd via unionfs
##  -- if <mode>  is 1 or 2 then max-levels=<mode>
##  if [/msheets] is provided then that's where the links are created (for testing)
##
## valid types
##  video thumb view:
##  audio thumb view:
##  list mode:
##   - STD
##   - SHEET
##   - WALL
##

use strict;
use File::Basename;
use Cwd 'realpath';

# utility function for controlling the led
sub set_power_led{
    my $mode = shift;
    open(my $fh, ">>", "/proc/led");
    print $fh "power led $mode\n";
    close($fh);
}

# test to see if a string starts with a '.'
sub starts_with_dot{
    $_ = shift;
    if ( /^\./ ) {
        return 1;
    }
    return 0;
}

if ( ! -e $ARGV[0] ) {
    print ("PATH: " . $ARGV[0] . " does not exist!\n");
    system("logger -t linksheets \"$ARGV[0] not found, exiting immediately!!!\"");
    exit 2
}

my $MODE = $ARGV[1];

if ( -e '/tmp/STOP_DMARENDER' ) {
    print "stop\n";
    system("logger -t linksheets \"/tmp/STOP_DMARENDER exists, exiting immediately!!!\"");
    exit 55
}

# parse config file into environment (so that it augments env)
open(my $fh, "<", "/conf/config");
while (!eof($fh)) {
    my $inline = readline($fh);
    if ($inline =~ /LISTNUM/ ||
        $inline =~ /GENTHUMBS/ ||
        $inline =~ /THUMBRESO/ ||
        $inline =~ /MSHEET/ ||
        $inline =~ /DEFAULTSHEET/) {
        chomp($inline);
        (my $var, my $val) = split("=", $inline);
        $val =~ s/'//g;
        #print ($var . "=" . $val . "\n");
        $ENV{$var} = $val
    }
}
close($fh);

# now extract the parameters from the augmented environment
my $MSHEETMODE   = $ENV{'MSHEETMODE'};
my $GENMSHEET    = $ENV{'GENMSHEET'};
my $VIDMSHEET    = $ENV{'VIDMSHEET'};
my $LISTMSHEET   = $ENV{'LISTMSHEET'};
my $DEFAULTSHEET = $ENV{'DEFAULTSHEET'};
my $LDEBUG       = $ENV{'LDEBUG'};

# check that MSHEETMODE is legal
if ( $MSHEETMODE ne "wall" && $MSHEETMODE ne "sheet" && $MSHEETMODE ne "std" ) {
    print "illegal MSHEETMODE\n";
    system("logger -t linksheets \"illegal MSHEETMODE $MSHEETMODE, exiting immediately!!!\"");
    exit 3;
}

# check that one of the sheet modes is active
if ( $GENMSHEET ne "ON" && $VIDMSHEET ne "ON" && $LISTMSHEET ne "ON" && $MODE ne "5" ) {
    print "no generation mode selected\n";
    system("logger -t linksheets \"no generation mode selected, exiting immediately!!!\"");
    exit 3;
}

# configure the per-mode sheet pattern
my $SEARCHSTRING = ".*_sheet.$MSHEETMODE.jpg";

# setup the 'find' argument that will control the depth of it's recursive search
my $DEPTH = "";
if ( $MODE eq "1" || $MODE eq "2" ) {
    $DEPTH = "-maxdepth " . $MODE;
}

system("logger -t linksheets \"Generating MovieSheets for " . $ARGV[0] . ", mode " . $ARGV[1] . "\"");

set_power_led('blink on');

if ( $DEFAULTSHEET ne "" && ! -l "/tmp/defaultsheet.jpg" ) {
    # if the valut of DEFAULTSHEET starts with a / then it's
    # a full path and we want to use it exactly, otherwise
    # assume it's a path relative to /osd/
    $_ = $DEFAULTSHEET;
    if ( /^\// ) {
        symlink($DEFAULTSHEET, "/tmp/defaultsheet.jpg");
    } else {
        symlink("/osd/" . $DEFAULTSHEET, "/tmp/defaultsheet.jpg");
    }
}

# for testing, allow setting of a location to generate the links
if ( $#ARGV == 2 ) {
    chdir($ARGV[2]);
} else {
    chdir("/msheets");
}

# keep track of things we'll only link as a last resort
my %soft_links;

# make sure the link replaces the thing it currently points to
sub force_symlink{
    my $src = shift;
    my $dst = shift;
    my $dbg = shift;
    if ( -e $dst ) {
   my $curr = realpath($dst);
   if ( $curr eq $src ) {
       return;
   }
   if ( $LDEBUG ne "" ) {
       # for the purposes of logging, don't mention it if the files
       # have the same size, ie: assume the user's name space does
       # this for a sane reason
       (my $src_dev,my $src_ino,my $src_mode,my $src_nlink,
        my $src_uid,my $src_gid,my $src_rdev,my $src_size,
        my $src_atime,my $src_mtime,my $src_ctime,
        my $src_blksize,my $src_blocks) = stat($src);
       (my $curr_dev,my $curr_ino,my $curr_mode,my $curr_nlink,
        my $curr_uid,my $curr_gid,my $curr_rdev,my $curr_size,
        my $curr_atime,my $curr_mtime,my $curr_ctime,
        my $curr_blksize,my $curr_blocks) = stat($curr);
       if ($src_size == $curr_size) {
      # assume it's the same image
       } else {
      print "change mind: " . $src . "\n";
      print "           : " . $curr . "\n";
      print "           : " . $dst . "\n";
       }
   }
        unlink($dst);
    }
    symlink($src, $dst);
}

my $find_cmd = "find $ARGV[0]/ -type f $DEPTH ";
$find_cmd .= "-regextype posix-egrep ";
$find_cmd .= "-iregex \".*_sheet.jpg|.*wd_tv.jpg|" . $SEARCHSTRING . "\"";
open(my $fh, $find_cmd . " 2>/dev/null |");
while (!eof($fh)) {
    my $msheet = readline($fh);
    chomp($msheet);
    my $basename_msheet = basename($msheet);
    if ( $MSHEETMODE ne "std" && ($basename_msheet eq "wd_tv.jpg" ||
                                  $basename_msheet eq ".wd_tv.jpg") ) {
        # special handling for [.]wd_tv.jpg:
        #    just link it as it's folder name
        my $DIRNAME = basename(dirname($msheet));
        if ( ! starts_with_dot($DIRNAME) ) {  # skip invisible dirs
            force_symlink($msheet, $DIRNAME,"l1 ");
            if ( $LDEBUG ne "" ) { print "l1  $msheet -> $DIRNAME\n"; }
        }
    } elsif ( $MSHEETMODE ne "std" && ($basename_msheet eq "folder.jpg_sheet.jpg" ||
                                       $basename_msheet eq ".folder.jpg_sheet.jpg" ) ) {
        # special handling for [.]folder.jpg_sheet.jpg
        #    just link it as it's folder name if there is no $MSHEETMODE.jpg form
        #    (as we intend to use that one in instead as the sheet for $DIRNAME)
        my $NOEXT = substr($msheet,0,-4);
        if ( ! -f "$NOEXT.$MSHEETMODE.jpg" ) {
            my $DIRNAME = basename(dirname($msheet));
            if ( ! starts_with_dot($DIRNAME) ) {  # skip invisible dirs
                force_symlink($msheet, $DIRNAME, "l2 ");
                if ( $LDEBUG ne "" ) { print "l2  $msheet -> $DIRNAME\n"; }
            }
        }
    } elsif ( substr($msheet,-10) eq "_sheet.jpg" ) {
        # handle all images that end in _sheet.jpg
        my $BASENAME = basename($msheet, "_sheet.jpg");
        $BASENAME =~ s/^\.//;   # remove leading '.' (if it exists)
        my $NOEXT = substr($msheet, 0, -4);
        my $DIRPATH = dirname($msheet);
        my $DIRNAME = basename($DIRPATH);
        if ( $MSHEETMODE eq "std" ) {
            # it is not clear what this is trying to do or if it makes any sense
            my $BASELINK = basename(realpath($DIRNAME));
            if ( $BASELINK ne "" && substr($BASELINK,0,-10) ne $DIRNAME ) {
                unlink($DIRNAME);
                if ( $LDEBUG ne "" ) { print "ul3 $msheet -> $DIRNAME\n"; }
            }
        } else {
            # link in as folder sheet if a more specialized form do not exist
            if ( starts_with_dot($DIRNAME) ) {
                # skip invisible dirs
            } elsif ( ! -f "$NOEXT.$MSHEETMODE.jpg" &&
                      ! -f "$DIRPATH/folder.jpg_sheet.jpg" &&
                      ! -f "$DIRPATH/folder.jpg_sheet.$MSHEETMODE.jpg" ) {
                if ( $BASENAME eq $DIRNAME ) {
                    # exact name match, do nothing, the 'l3a' link will pick it up
                } elsif ( ! -e $DIRNAME ) {
                    # inexact name match, record that we'll make the link
                    # but don't do so until all other possible matches
                    # have been attempted
                    $soft_links{$DIRNAME} = $msheet;
                }
            }
        }
        # link in as file sheet if a more specialized form do not exist
        if ( ! -f "$NOEXT.$MSHEETMODE.jpg" ) {
            force_symlink($msheet, $BASENAME, "l3a");
            if ( $LDEBUG ne "" ) { print "l3a $msheet -> $BASENAME\n"; }
        }
    } else {
        # handle all other images
        my $BASENAME = basename($msheet,"_sheet.$MSHEETMODE.jpg");
        $BASENAME =~ s/^\.//g;    # remove leading '.' (if it exists)
        my $DIRPATH = dirname($msheet);
        my $DIRNAME = basename($DIRPATH);
        if ( $MSHEETMODE eq "std" ) {
            # it is not clear what this is trying to do or if it makes any sense
            my $BASELINK = basename(realpath($DIRNAME));
            if ( $BASELINK ne "" && substr($BASELINK,0,-(11+length($MSHEETMODE))) ne $DIRNAME ) {
                unlink($DIRNAME);
                if ( $LDEBUG ne "" ) { print "ul4 $msheet -> $DIRNAME\n"; }
            }
        } else {
            # link in as folder sheet if a more specialized form do not exist
            if ( starts_with_dot($DIRNAME) ) {
                # skip invisible dirs
            } elsif ( ! -f "$DIRPATH/folder.jpg_sheet.jpg" &&
                      ! -f "$DIRPATH/folder.jpg_sheet.$MSHEETMODE.jpg" ) {
                if ( $BASENAME eq $DIRNAME ) {
                    # exact name match, do nothing, the 'l4a' link will pick it up
                } elsif ( ! -e $DIRNAME ) {
                    # inexact name match, record that we'll make the link
                    # but don't do so until all other possible matches
                    # have been attempted
                    $soft_links{$DIRNAME} = $msheet;
                }
            }
        }
        # link in as file sheet
        force_symlink($msheet, $BASENAME, "l4a");
        if ( $LDEBUG ne "" ) { print "l4a $msheet -> $BASENAME\n"; }
    }
    # check to see if we've been asked to stop
    if ( -f "/tmp/linksheets.stop.$MODE" ||
         -f "/tmp/linksheets.stop" ) {
        set_power_led('blink off');
        set_power_led('on');
        system("logger -t linksheets \"linksheets.stop found, exiting immediately!!!\"");
        exit 3;
    }
}

# now process any soft links, anything that gets
# logged indicates that the given folder does not
# have a properly named sheet
foreach my $DIRNAME (keys(%soft_links)) {
    if ( ! -e $DIRNAME ) {
   my $msheet = $soft_links{$DIRNAME};
        symlink($msheet, $DIRNAME);
   if ( $LDEBUG ne "" ) { print "l5  $msheet -> $DIRNAME\n"; }
    }
}

set_power_led('blink off');
set_power_led('on');
system("logger -t linksheets \"Done MovieSheets for " . $ARGV[0] . ", mode " . $ARGV[1] . "\"");
Chris Bone
n00b
 
Posts: 14
Joined: Fri Nov 04, 2011 4:43 am

Re: fast linksheet script   

Postby alexmineiro » Sat Apr 07, 2012 11:45 am

Hi,

how can i install this script on my wdlxtv because i don't want to wait till the new firmware will be out?

greets

alexm
alexmineiro
n00b
 
Posts: 11
Joined: Sun Jul 03, 2011 7:58 am

Re: fast linksheet script   

Postby dzebrys » Sat Apr 07, 2012 1:29 pm

alexmineiro wrote:how can i install this script on my wdlxtv because i don't want to wait till the new firmware will be out?


use this tutorial
User avatar
dzebrys
DLX'er
 
Posts: 130
Joined: Mon Feb 14, 2011 1:49 am
Location: poland

Re: fast linksheet script   

Postby alexmineiro » Sat Apr 07, 2012 2:25 pm

mmh i got this problem:

Image

Anyone knows a solution ?

oh i fixed it by myself.. it was a copy & paste problem with notepad++ .. thx for this script ...
alexmineiro
n00b
 
Posts: 11
Joined: Sun Jul 03, 2011 7:58 am

Re: fast linksheet script   

Postby derwildemann » Sun Jul 01, 2012 9:49 am

alexmineiro wrote:mmh i got this problem:

Image

Anyone knows a solution ?

oh i fixed it by myself.. it was a copy & paste problem with notepad++ .. thx for this script ...

hi alexmineiro (de Minas Gerais / Brasil?),

would you please be so kind to provide me the details to install this script? Like where do I install it? what are the requirements? Can I use it on my WD Player running FW 1.05.04 version 0.5.1.1?
I believe I have read that it could only be used with FW 1.02.21

cheers
DWM
derwildemann
DLX'er
 
Posts: 86
Joined: Fri Feb 04, 2011 4:55 am

Re: fast linksheet script   

Postby bcripps » Tue Jul 03, 2012 6:33 am

I as well would be greatful for more info on where to place the script and if it is compatable with 1.05.04_V-EXT3-Boot-Live-0.5.1.1 [non-flash]?

Also with the increased speed on the perl script is it nessessary to keep all the movie sheets in the MSHEETDIR? Or is the script based on that one directory? I would like to relocate my sheets back into the shared folders. Reason being is Sickbeard right now isn't capable of creating a unique season folder for my shows, so the moviesheets are getting jumbled if I have two shows with the same season number.
bcripps
n00b
 
Posts: 8
Joined: Tue Jul 03, 2012 6:24 am

PreviousNext

Return to Movie Sheet Support & Discussion

Who is online

Users browsing this forum: No registered users and 0 guests