6 # Moves all the files in a directory with the given file extension into a
7 # hierarchy. The maximum number of entries at each level is fixed.
9 # This is useful for arranging mp3s in a way that makes them easy to play on
10 # devices where large directories are impractical.
20 DEFAULT_FILES_PER_LEVEL = 10
25 opts.files_per_level = DEFAULT_FILES_PER_LEVEL
27 $fu_args = { :verbose => true }
28 opts.preserve_names = false
30 # Fill in $opts values
31 parser = OptionParser.new do |myparser|
32 myparser.banner = "Usage: #{ File.basename($0) } [opts]"
33 myparser.separator("Specific options:")
34 myparser.on("--files-per-level NFILES", "-L",
35 "Set the number of files per directory to use (default " +
36 DEFAULT_FILES_PER_LEVEL.to_s() + ").") do |d|
37 opts.files_per_level = d.to_i
39 myparser.on("--dry-run", "-d",
40 "Show what would be done, without doing it.") do |d|
41 $fu_args = { :verbose => true, :noop => true }
44 myparser.on("--file-extension EXTENSION", "-e",
45 "The file extension for the files to rename.") do |e|
51 raise "invalid number of files per level: #{opts.files_per_level}" unless
52 opts.files_per_level > 1
53 raise "must give an extension" unless opts.extension != nil
59 num_digits = Math.log10($opts.files_per_level + 1).ceil()
61 (0..idx.length - 2).each do |i|
63 path = path + "/" + (("%0" + num_digits.to_s + "d") % v)
68 def idx_increment(idx)
70 while (idx[i] > $opts.files_per_level)
79 $opts = MyOptions.parse(ARGV)
80 rescue Exception => msg
81 $stderr.print("#{msg}.\nType --help to see usage information.\n")
87 Dir.glob("*.#{$opts.extension}").sort.each do |f|
88 num_files = num_files + 1
91 raise "No files found in the current working directory with extension " +
94 num_levels = Math.log(num_files) / Math.log($opts.files_per_level)
95 num_levels = num_levels.ceil()
96 if ($fu_args[:verbose]) then
97 print "Number of files: " + num_files.to_s() + ". Number of levels: " +
98 num_levels.to_s() + "\n"
102 (1..num_levels).each { |n| idx.push(1) }
105 Dir.glob("*.#{$opts.extension}").sort.each do |f|
106 path = idx_to_path(idx)
107 FileUtils.mkdir_p(path, $fu_args)
108 FileUtils.mv(f, path + "/" + f, $fu_args)
109 idx[idx.length - 1] = idx[idx.length - 1] + 1
110 if (idx[idx.length - 1] > $opts.files_per_level)