Ticket #278: mythtv-mythlink.patch

File mythtv-mythlink.patch, 14.5 KB (added by mtdean@…, 14 years ago)
  • contrib/mythlink.pl

     
    2626    our ($db_host, $db_user, $db_name, $db_pass, $video_dir);
    2727    our ($hostname, $dbh, $sh);
    2828
     29# Default filename format
     30    $dformat = '%T - %Y-%m-%d, %g-%i %A - %S';
     31# Default separator character
     32    $dseparator_char = '-';
     33# Default replacement character
     34    $dreplacement_char = '-';
     35# Default space character
     36    $dspace_char = ' ';
     37
     38# Provide default values for GetOptions
     39    $format = $dformat;
     40    $separator_char = $dseparator_char;
     41    $replacement_char = $dreplacement_char;
     42    $space_char = $dspace_char;
     43
    2944# Load the destination directory, if one was specified
    30     GetOptions('dest|destination|path=s' => \$dest,
    31                'format=s'                => \$format,
    32                'usage|help|h'            => \$usage,
     45    GetOptions('dest|destination|path=s'    => \$dest,
     46               'format=s'                   => \$format,
     47               'sepchar|separator-char=s'   => \$separator_char,
     48               'repchar|replacement-char=s' => \$replacement_char,
     49               'space|space-char=s'         => \$space_char,
     50               'usage|help|h'               => \$usage,
    3351              );
    3452
    35 # Default filename format
    36     $format ||= '%T - %Y-%m-%d, %g-%i %A - %S';
     53# Check the separator, replacement, and space characters for illegal characters
     54    if ($separator_char =~ /(?:[\/\\:*?<>|"])/) {
     55      print "Illegal separator character specified.  Using default.\n";
     56      $separator_char = $dseparator_char;
     57    }
     58    if ($replacement_char =~ /(?:[\/\\:*?<>|"])/) {
     59      print "Illegal replacement character specified.  Using default.\n";
     60      $replacement_char = $dreplacement_char;
     61    }
     62    if ($space_char =~ /(?:[\/\\:*?<>|"])/) {
     63      print "Illegal space character specified.  Using default.\n";
     64      $space_char = $dspace_char;
     65    }
    3766
    3867# Print usage
    3968    if ($usage) {
     
    5180
    5281--format
    5382
    54     default:  $format
     83    default:  $dformat
    5584
    5685    \%T = title    (aka show name)
    5786    \%S = subtitle (aka episode name)
    5887    \%R = description
     88    \%C = category (as reported by grabber)
     89    \%U = recording group
     90    \%p = separator character
    5991    \%y = year, 2 digits
    6092    \%Y = year, 4 digits
    6193    \%n = month
     
    71103    \%a = am/pm
    72104    \%A = AM/PM
    73105
    74     * Illegal filename characters will be replaced with dashes.
     106    * For end time, prepend an "e" to the appropriate time/date format code
     107      above; i.e. "\%eG" gives the 24-hour hour for the end time.
     108
     109    * For original airdate, prepend an "o" to the year, month, or day format
     110      codes above; i.e. "\%oY" gives the year in which the episode was first
     111      aired.
     112
    75113    * A suffix of .mpg or .nuv will be added where appropriate.
    76114
     115--separator-char
     116
     117    The character used to separate sections of the link name.  Specifying the
     118    separator character allows trailing separators to be removed from the link
     119    name and multiple separators caused by missing data to be consolidated.
     120    Indicate the separator character in the format string using either a
     121    literal character or the '%p' specifier.
     122
     123    default:  '$dseparator_char'
     124
     125--replacement-char
     126
     127    Characters in the link name which are not legal on some filesystems will
     128    be replaced with the given character
     129
     130    default:  '$dreplacement_char'
     131
     132--space-char
     133
     134    Use the specified character instead of space in the link name
     135
     136    default:  '$dspace_char'
     137
    77138--help
    78139
    79140    Show this help text.
     
    165226    }
    166227
    167228# Prepare a database query
    168     $sh = $dbh->prepare('SELECT title, subtitle, description FROM recorded WHERE chanid=? AND starttime=? AND endtime=?');
     229    $sh = $dbh->prepare('SELECT title, subtitle, description, recgroup, category, originalairdate FROM recorded WHERE chanid=? AND starttime=? AND endtime=?');
    169230
    170231# Create symlinks for the files on this machine
    171232    foreach my $file (<$video_dir/*.nuv>) {
     
    182243    # Query the desired info about this recording
    183244        $sh->execute($channel, "$syear$smonth$sday$shour$sminute$ssecond", "$eyear$emonth$eday$ehour$eminute$esecond")
    184245            or die "Could not execute ($q):  $!\n\n";
    185         my ($title, $subtitle, $description) = $sh->fetchrow_array;
     246        my ($title, $subtitle, $description, $recgroup, $category, $oad) = $sh->fetchrow_array;
    186247    # Format some fields we may be parsing below
     248        # Start time
    187249        my $meridian = ($shour > 12) ? 'AM' : 'PM';
    188250        my $hour = ($shour > 12) ? $shour - 12 : $shour;
    189251        if ($hour < 10) {
     
    192254        elsif ($hour < 1) {
    193255            $hour = 12;
    194256        }
     257        # End time
     258        my $emeridian = ($ehour > 12) ? 'AM' : 'PM';
     259        my $ethour = ($ehour > 12) ? $ehour - 12 : $ehour;
     260        if ($ethour < 10) {
     261            $ethour = "0$ethour";
     262        }
     263        elsif ($ethour < 1) {
     264            $ethour = 12;
     265        }
     266        # Original airdate
     267        # Handle NULL values for original airdate.
     268        $oad ||= '0000-00-00';
     269        my ($oyear, $omonth, $oday) = split(/\-/, $oad, 3);
    195270    # Build a list of name format options
    196271        my %fields;
    197272        ($fields{'T'} = ($title       or '')) =~ s/%/%%/g;
    198273        ($fields{'S'} = ($subtitle    or '')) =~ s/%/%%/g;
    199274        ($fields{'R'} = ($description or '')) =~ s/%/%%/g;
     275        ($fields{'C'} = ($category    or '')) =~ s/%/%%/g;
     276        ($fields{'U'} = ($recgroup    or '')) =~ s/%/%%/g;
     277        $fields{'p'} = $separator_char;     # separator character
     278        # Start time
    200279        $fields{'y'} = substr($syear, 2);   # year, 2 digits
    201280        $fields{'Y'} = $syear;              # year, 4 digits
    202281        $fields{'n'} = int($smonth);        # month
     
    211290        $fields{'s'} = $ssecond;            # seconds
    212291        $fields{'a'} = lc($meridian);       # am/pm
    213292        $fields{'A'} = $meridian;           # AM/PM
     293        # End time
     294        $fields{'ey'} = substr($eyear, 2);  # year, 2 digits
     295        $fields{'eY'} = $eyear;             # year, 4 digits
     296        $fields{'en'} = int($emonth);       # month
     297        $fields{'em'} = $emonth;            # month, leading zero
     298        $fields{'ej'} = int($eday);         # day of month
     299        $fields{'ed'} = $eday;              # day of month, leading zero
     300        $fields{'eg'} = int($ethour);       # 12-hour hour
     301        $fields{'eG'} = int($ehour);        # 24-hour hour
     302        $fields{'eh'} = $ethour;            # 12-hour hour, with leading zero
     303        $fields{'eH'} = $ehour;             # 24-hour hour, with leading zero
     304        $fields{'ei'} = $eminute;           # minutes
     305        $fields{'es'} = $esecond;           # seconds
     306        $fields{'ea'} = lc($emeridian);     # am/pm
     307        $fields{'eA'} = $emeridian;         # AM/PM
     308        # Original Airdate
     309        $fields{'oy'} = substr($oyear, 2);  # year, 2 digits
     310        $fields{'oY'} = $oyear;             # year, 4 digits
     311        $fields{'on'} = int($omonth);       # month
     312        $fields{'om'} = $omonth;            # month, leading zero
     313        $fields{'oj'} = int($oday);         # day of month
     314        $fields{'od'} = $oday;              # day of month, leading zero
    214315    # Make the substitution
    215316        my $keys = join('', sort keys %fields);
    216317        my $name = $format;
    217         $name =~ s/(?<!%)(?:%([$keys]))/$fields{$1}/g;
     318        $name =~ s/(?<!%)(?:%([eo]?)([$keys]))/$fields{$1.$2}/g;
    218319        $name =~ s/%%/%/g;
    219320    # Some basic cleanup for illegal (windows) filename characters, etc.
    220         $name =~ tr/\ \t\r\n/ /s;
     321        $name =~ s/(?:[\/\\\:\*\?\<\>\|$replacement_char])+/$replacement_char/sg;
    221322        $name =~ tr/"/'/s;
    222         $name =~ s/(?:[\-\/\\:*?<>|]+\s*)+(?=[^\d\s])/- /sg;
    223         $name =~ tr/\/\\:*?<>|/-/;
    224         $name =~ s/^[\-\ ]+//s;
    225         $name =~ s/[\-\ ]+$//s;
     323        $name =~ s/[\s$space_char]+/$space_char/sg;
     324        $name =~ s/($space_char*)(?:$separator_char+($space_char*))+/$1$separator_char$2/sg;
     325        $name =~ s/^$space_char+//s;
     326        $name =~ s/$space_char*$separator_char+$space_char*$//s;
    226327    # Get a shell-safe version of the filename (yes, I know it's not needed in this case, but I'm anal about such things)
    227328        my $safe_file = $file;
    228329        $safe_file =~ s/'/'\\''/sg;
  • contrib/mythlink.sh

     
    66#
    77# mythlink.sh
    88#
    9 # Creates readable symlinks referring to MythTV recordings
    10 #
    11 # Based on the script mythlink.sh by Dale Gass
    12 #
    13 # Modified by Mike Dean
    14 #  - Provides multiple easily-configurable "views"
    15 #  - System specific information is specified as environment variables
    16 #  - Uses '-' to separate portions of the filename (instead of '_' since '_'
    17 #    is used to replace special characters (such as the space character))
    18 #  - Shows recording year
    19 #  - Shows end time
    20 #  - Separates date and time info
    21 #  - Removes trailing separator (i.e. for movies, which have no subtitle)
    22 #  - Adds an optional extension (for specifying filetype to Windows)
     9# Creates readable symlinks referring to MythTV recordings using the
     10# mythlink.pl script
    2311
    2412
    2513### Modify these values for your installation ###
    26 # The location of the MythTV Recordings (with "ugly" filenames)
    27 MYTH_RECORDINGS_PATH=/var/storage/mythtv
    2814# The path in which the views ("pretty" links) will be created
    29 VIEWS_PATH=/var/storage/mythtv/views
    30 # The extension added to the end of the links, including the period.
    31 # For no extension, specify '' for the value.
    32 EXTENSION='.mpg'
    33 # Enables output for debugging (set to 0 for no output)
    34 DEBUG=0
     15VIEWS_PATH=/var/video/views
    3516
     17# The location of the mythlink.pl script
     18# The default value assumes mythlink.pl is in the user's PATH
     19COMMAND=mythlink.pl
     20
     21
    3622### The following directory names and formats may be customized ###
    3723
    38 # Formats may consist of any combination of
    39 # ${title}, ${subtitle}
    40 # ${date}, ${starttime}, ${endtime}, ${originalairdate}
    41 # ${category}, ${recgroup}
     24# Formats may be constructed using the format specifiers listed in the
     25# output of "mythlink.pl --help"
    4226
    4327# Files will be sorted "alphabetically" so the appropriate fields on which you
    4428# would like to sort should be placed at the beginning of the format
    4529
    46 # Formats of the individual fields were chosen to minimize confusion caused by
    47 # use of different sorting algorithms by clients (i.e. alphabetically versus
    48 # alphanumerically).
    49 
    5030# To add a custom format, simply include a directory name and format in the
    51 # environment variables below.  (Whitespace separates the values.)
     31# environment variables below using the syntax shown below.
    5232
    5333# The names of the directories containing the views
    54 DIRECTORIES='time
    55              title
    56              group
    57              category
    58              original_airdate'
     34DIRECTORIES=(
     35             'time'
     36             'title'
     37             'group'
     38             'category'
     39             'original_airdate'
     40            )
    5941# The formats used for the respective directories specified above
    60 FORMATS='${date}-${starttime}-${endtime}-${title}-${subtitle}
    61          ${title}-${date}-${starttime}-${endtime}-${subtitle}
    62          ${recgroup}-${title}-${date}-${starttime}-${endtime}-${subtitle}
    63          ${category}-${title}-${date}-${starttime}-${endtime}-${subtitle}
    64          ${title}-${originalairdate}-${subtitle}'
     42FORMATS=(
     43         '%Y%m%d-%H%i-%eH%ei-%T-%S'
     44         '%T-%Y%m%d-%H%i-%eH%ei-%S'
     45         '%U-%T-%Y%m%d-%H%i-%eH%ei-%S'
     46         '%C-%T-%Y%m%d-%H%i-%eH%ei-%S'
     47         '%T-%oY%om%od-%S'
     48        )
    6549
     50# The character used to separate sections of the link name
     51SEPARATOR_CHAR='-'
    6652
    67 ### These values most likely do not need modification ###
    68 # The name of the MythTV database
    69 MYTH_DB=mythconverg
    70 # The database username and password
    71 MYTH_DB_USER=mythtv
    72 MYTH_DB_PASSWD=mythtv
     53# The character used to replace illegal characters in the filename
     54REPLACEMENT_CHAR='_'
    7355
     56# The character used to replace space characters in the filename
     57# (Use ' ' to allow spaces in filenames)
     58SPACE_CHAR='_'
    7459
    75 export MYTH_RECORDINGS_PATH VIEWS_PATH EXTENSION DEBUG DIRECTORIES FORMATS
    7660
    77 
    78 for dir in ${DIRECTORIES}
    79   do
    80   rm -rf ${VIEWS_PATH}/${dir}/*
     61# Make the links by calling mythlink.pl with the appropriate arguments
     62last_index=$(( ${#DIRECTORIES[@]} - 1 ))
     63for directory in `seq 0 $last_index`; do
     64  ${COMMAND} --separator-char $SEPARATOR_CHAR \
     65             --replacement-char $REPLACEMENT_CHAR \
     66             --space-char $SPACE_CHAR \
     67             --dest ${VIEWS_PATH}/${DIRECTORIES[$directory]} \
     68             --format ${FORMATS[$directory]}
    8169done
    82 mysql -u${MYTH_DB_USER} -p${MYTH_DB_PASSWD} ${MYTH_DB} -B --exec "select chanid,starttime,endtime,title,subtitle,recgroup,category,originalairdate from recorded;" >/tmp/mythlink.$$
    83 perl -w -e '
    84   my $mythpath=$ENV{"MYTH_RECORDINGS_PATH"};
    85   my $viewspath=$ENV{"VIEWS_PATH"};
    86   my $extension=$ENV{"EXTENSION"};
    87   my $debug=$ENV{"DEBUG"};
    88   my $dirs=$ENV{"DIRECTORIES"};
    89   my $fmts=$ENV{"FORMATS"};
    90   my @directories=split(/\s+/,$dirs);
    91   my @formats=split(/\s+/,$fmts);
    92   if (!-d ${viewspath}) {
    93     mkdir ${viewspath} or die "Failed to make directory: ${viewspath}\n";
    94   }
    95   foreach (@directories) {
    96     if (!-d "${viewspath}/$_") {
    97       mkdir "${viewspath}/$_" or die "Failed to make directory: ${viewspath}/$_\n";
    98     }
    99   }
    100   <>;
    101   while (<>) {
    102     chomp;
    103     my ($chanid,$start,$end,$title,$subtitle,$recgroup,$category,$originalairdate) = split /\t/;
    104     $start =~ s/[^0-9]//g;
    105     $end =~ s/[^0-9]//g;
    106     $subtitle = "" if(!defined $subtitle);
    107     my $filename = "${chanid}_${start}_${end}.nuv";
    108     do { print "Skipping ${mythpath}/${filename}\n"; next } unless -e "${mythpath}/${filename}";
    109     $end =~ /^........(....)/;
    110     my $endtime = $1;
    111     $start =~ /^(........)(....)/;
    112     my $date = $1;
    113     my $starttime = $2;
    114     $originalairdate =~ s/[^0-9]//g;
    115     $originalairdate = "00000000" if(($originalairdate eq ""));
    116     for ($i = 0; $i < @directories; $i++) {
    117       my $directory = $directories[$i];
    118       my $link=$formats[$i];
    119       $link =~ s/(\${\w+})/$1/gee;
    120       $link =~ s/-$//;
    121       $link =~ s/ /_/g;
    122       $link =~ s/&/+/g;
    123       $link =~ s/[^+0-9a-zA-Z_-]+/_/g;
    124       $link = $link . $extension;
    125       print "Creating $link\n" if ($debug);
    126       unlink "${viewspath}/${directory}/${link}" if(-e "${viewspath}/${directory}/${link}");
    127       symlink "${mythpath}/${filename}", "${viewspath}/${directory}/${link}" or die "Failed to create symlink ${viewspath}/${directory}/${link}: $!";
    128     }
    129   }
    130 ' /tmp/mythlink.$$
    131 rm /tmp/mythlink.$$
    13270
    133