On 01/23/2006 03:59 PM, Tom Lichti wrote:
Right. Have you tried my new and improved mythrename.pl? It finally works correctly, and most of my stuff made it into SVN.
As a matter of fact, I have. It's nice--especially the no LiveTV one. And, I've been meaning to do up a change for the one that hasn't yet made it into SVN, but never made time for it. So, your question provided the motivation I needed to finally get it done.

The implementation you used for #874 ( http://svn.mythtv.org/trac/ticket/874 ) was a good quick hack for starting off the subdirectory thing. However, there were a few things I thought we could improve upon. For example, it made promises about the future ("In the future you will be able to pick the field to sub on"); took a shortcut ("Any titles with spaces in the name will have the spaces changed to underscores to simplify deleting"--I didn't see how this simplifies deleting but I didn't look that deep into your code, but I hope you were talking about for your code); and only allows creating subs based on title, and, therefore, only one level deep.

To make it truly user-customizable, we need the directory names to be just another part of the format specifier. The hard part is the fact that we need to replace any "illegal" characters (those that are illegal) in directory names as well as filenames, that the path separator ("/") is illegal inside directory/file names (so would be replaced), and that the "%F" used for the format specifier could exist inside a generated name after expansion (so we can't "defer" replacement). Therefore, I used a "placeholder" for the path separators. The placeholder needed to be a character that could never exist inside the filename or that would be replaced (i.e. it can't be either a legal or illegal character). The only character that meets this criteria is the null character (which, technically is illegal (on Windows, and on most *nix filesystems is the *only* illegal character), but we aren't replacing it because it shouldn't be there).

Also, I removed the phrase, 'This assumes that recgroup = "LiveTV" for live tv recordings,' since the recgroup is *always* LiveTV for LiveTV recordings (it's not translated and the user does not have the option to change it), so there's no sense worrying the user with the message (if anything, it could be made a comment in the Perl source, but doesn't belong in the usage message). And the comment about including time for channel-surfers shouldn't be there, either. There's code to prevent problems with duplicate filenames (see code after "# Check for duplicates"), but based on your comment, I'm assuming it has a bug (but I didn't look into it)...

I'd appreciate your testing this patch and providing feedback (does it do everything yours does/work well for you/etc.). Once I hear from you, I can post it on #874, or feel free to do so yourself. In case you do it, I'm including some comments below for Trac.

Thanks,
Mike

This patch allows the user to create subdirectories within a directory of links to recordings by using a format specifier to separate directory and filenames. This allows the user to create directories based on any desired field or combination of fields as well as creating any number of subdirectory levels within the destination directory.

Note that /all/ links within the destination directory and its subdirectories (recursive) will be removed when creating links to recordings. Also, any empty directories beneath the destination directory will be removed when creating links.

If the user specifies the path separator format specifier ("%F") but is attempting to rename files, the path separator will be replaced with the replacement character ("%-"), thereby preventing the user from attempting to move files. This behavior is required because the Perl implementation of rename varies wildly and usually will not work across filesystem boundaries.

BTW, I used "%F" as an abbreviation of "folder" since "%d" (as in "directory") was already used (for day of month) and I thought it would be easier for most users to remember than "%P" for "path separator". However, I included all three terms in the field description just for safe measure. ;)
Index: contrib/mythrename.pl
===================================================================
--- contrib/mythrename.pl       (revision 8699)
+++ contrib/mythrename.pl       (working copy)
@@ -20,6 +20,8 @@
     use DBI;
     use Getopt::Long;
     use File::Path;
+    use File::Basename;
+    use File::Find;
 
 # Some variables we'll use here
     our ($dest, $format, $usage, $underscores, $live);
@@ -66,10 +68,12 @@
 
     /var/video/show_names/
 
+    WARNING: ALL symlinks within the destination directory and its
+    subdirectories (recursive) will be removed when using the --link option.
+
 --live
 
-    Include live tv recordings, affects both linking and renaming. This assumes
-    that recgroup = "LiveTV" for live tv recordings.
+    Include live tv recordings, affects both linking and renaming.
 
     default: do not link/rename live tv recordings
 
@@ -98,6 +102,7 @@
     \%a = am/pm
     \%A = AM/PM
     \%- = separator character
+    \%F = directory/folder (path separator)
 
     * For end time, prepend an "e" to the appropriate time/date format code
       above; i.e. "\%eG" gives the 24-hour hour for the end time.
@@ -108,6 +113,13 @@
 
     * A suffix of .mpg or .nuv will be added where appropriate.
 
+    * To separate links into subdirectories, include the \%F format specifier
+      between the appropriate fields.  For example, "\%T\%F\%S" would create
+      a directory for each title containing links for each recording named
+      by subtitle.  You may use any number of subdirectories in your format
+      specifier.  If used without the --link option, "\%F" will be replaced
+      with the "\%-" separator character.
+
 --separator
 
     The string used to separate sections of the link name.  Specifying the
@@ -240,10 +252,13 @@
     # Bad path
         die "$dest is not a directory.\n" unless (-d $dest);
     # Delete any old links
-        foreach my $file (<$dest/*>) {
-            next unless (-l $file);
-            unlink $file or die "Couldn't remove old symlink $file:  $!\n";
-        }
+        find sub { if (-l $_) {
+                       unlink $_ or die "Couldn't remove old symlink $_: $!\n";
+                   }
+                 }, $dest;
+    # Delete empty directories (should this be an option?)
+    # Let this fail silently for non-empty directories
+        finddepth sub { rmdir $_; }, $dest;
     }
 
 # Prepare a database queries
@@ -339,6 +354,7 @@
     # Literals
         $fields{'%'}  = '%';
         ($fields{'-'}  = $separator) =~ s/%/%%/g;
+        $fields{'F'} = $dest ? "\0" : "$separator";
     # Make the substitution
         my $keys = join('|', sort keys %fields);
         my $name = $format;
@@ -352,10 +368,14 @@
         $name =~ s/(?:(?:$safe_sep)+\s*)+(?=[^\d\s])/$separator /sg;
         $name =~ s/^($safe_sep|$safe_rep|\ )+//s;
         $name =~ s/($safe_sep|$safe_rep|\ )+$//s;
+        $name =~ s/\0($safe_sep|$safe_rep|\ )+/\0/s;
+        $name =~ s/($safe_sep|$safe_rep|\ )+\0/\0/s;
     # Underscores?
         if ($underscores) {
             $name =~ tr/ /_/s;
         }
+    # Folders
+        $name =~ s/\0/\//sg;
     # 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)
         my $safe_file = $info{'basename'};
         $safe_file =~ s/'/'\\''/sg;
@@ -375,6 +395,11 @@
             }
             $name .= $suffix;
         # Create the link
+            my $directory = dirname("$dest/$name");
+            unless (-e $directory) {
+                mkpath($directory, 0, 0755)
+                    or die "Failed to create $directory:  $!\n";
+            }
             symlink "$video_dir/".$info{'basename'}, "$dest/$name"
                 or die "Can't create symlink $dest/$name:  $!\n";
             if (defined($verbose)) {
_______________________________________________
mythtv-users mailing list
mythtv-users@mythtv.org
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-users

Reply via email to