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