Makefile: add pickrand
[cmccabe-bin] / names_to_numbers.rb
1 #!/usr/bin/ruby -w
2
3 #
4 # names_to_numbers.rb
5 #
6 # Renames all the files in a directory with the given file extension.
7 # The renamed files will just have numbers.
8 #
9 # Colin Mccabe
10 #
11
12 require 'fileutils'
13 require 'optparse'
14 require 'ostruct'
15
16 class MyOptions
17   def self.parse(args)
18     opts = OpenStruct.new
19     opts.dry_run = false
20     opts.num_digits = 2
21     opts.extension = nil
22     opts.starting_number = 1
23     opts.prefix_counter_increment = 1
24     $fu_args = { :verbose => true }
25     opts.preserve_names = false
26
27     # Fill in $opts values
28     parser = OptionParser.new do |myparser|
29       myparser.banner = "Usage: #{ File.basename($0) } [opts]"
30       myparser.separator("Specific options:")
31       myparser.on("--num-digits DIGITS", "-D",
32               "Set the number of digits in the numbering scheme.") do |d|
33         opts.num_digits = d.to_i
34       end
35       myparser.on("--dry-run", "-d",
36               "Show what would be done, without doing it.") do |d|
37         $fu_args = { :verbose => true, :noop => true }
38         opts.dry_run = true
39       end
40       myparser.on("--file-extension EXTENSION", "-e",
41               "The file extension for the files to rename.") do |e|
42         opts.extension = e
43       end
44       myparser.on("--preserve-names", "-p",
45               "Preserve the names while changing the numbers.") do |e|
46         opts.preserve_names = true
47       end
48       myparser.on("--starting-number NUMBER", "-N",
49               "The starting number (defaults to 1)") do |e|
50         opts.starting_number = e.to_i
51       end
52       myparser.on("--glob GLOB", "-g",
53               "Specify the glob expression to use.  Example: '*/*.mp3'.") do |d|
54         opts.glob = d
55       end
56       myparser.on("--prefix-counter-increment NUMBER", "-I",
57               "The increment to use (defaults to 1)") do |e|
58         opts.prefix_counter_increment = e.to_i
59       end
60     end
61
62     parser.parse!(args)
63     raise "invalid num_digits: #{opts.num_digits}" unless
64       opts.num_digits > 0
65     raise "must specify an extension" unless opts.extension != nil
66     if (opts.glob == nil) then
67       opts.glob = "*.#{opts.extension}"
68     end
69     return opts
70   end
71 end
72
73 def pow(x, y)
74   ret = 1
75   (0...y).each do |z|
76     ret = ret * x
77   end
78   return ret
79 end
80 def file_iter
81   Dir.glob($opts.glob).sort.each do |f|
82     yield f
83   end
84 end
85
86 def count_files(file)
87   $total_files = $total_files + 1
88 end
89
90 def get_file_name(num)
91   return sprintf("%0#{$opts.num_digits}d", num)
92 end
93
94 def rename_files(file)
95   dst="#{get_file_name($prefix_counter)}.#{$opts.extension}"
96   if (file != dst) then
97     FileUtils.mv(file, dst, $fu_args)
98   end
99   $prefix_counter = $prefix_counter + $opts.prefix_counter_increment
100 end
101
102 def rename_files_keep_names(file)
103   proper_file = ""
104   if (file =~ /^[0-9. -]*(.*)$/) then
105     proper_file = $1
106   else
107     raise "can't find proper name for #{file}"
108   end
109   full_name = "#{get_file_name($prefix_counter)} - #{proper_file}"
110   FileUtils.mv(file, full_name, $fu_args)
111   $prefix_counter = $prefix_counter + $opts.prefix_counter_increment
112 end
113
114 # MAIN
115 begin
116   $opts = MyOptions.parse(ARGV)
117 rescue Exception => msg
118   $stderr.print("#{msg}.\nType --help to see usage information.\n")
119   exit 1
120 end
121
122 # make sure there aren't too many files
123 $total_files = 0
124 max_total_files = pow(10, $opts.num_digits) - 1
125 file_iter { |f| count_files(f) }
126 if ($total_files > max_total_files) then
127   raise "With #{$opts.num_digits} digit(s), we can only have at most \
128 #{max_total_files} files-- but there are #{$total_files} files in the \
129 #directory. Try setting a higher value for num_digits, using -D."
130 end
131
132 # rename files
133 $prefix_counter = $opts.starting_number
134 if ( $opts.preserve_names ) then
135   file_iter { |f| rename_files_keep_names(f) }
136 else
137   file_iter { |f| rename_files(f) }
138 end
139
140 exit 0