class FileName
The class to create filename that is not duplicated. We select type of additional part of filename: number or time.
Constants
- OPTIONS_CREATE
- VERSION
Attributes
Public Class Methods
# File lib/filename.rb, line 341 def self.configuration(*args) self.manage.configuration(*args) end
Executing FileName.new
and FileName.create
, we get new filename. The same options of FileName.new
are available.
# File lib/filename.rb, line 330 def self.create(basepath, *rest) self.new(basepath, *rest).create end
# File lib/filename.rb, line 315 def self.load(str) filename = Marshal.load(str) if key = filename.configuration_key opts = self.manage.configuration_setting(key) filename.format = opts[:format] end filename end
# File lib/filename.rb, line 324 def self.load_from(path) self.load(File.read(path)) end
# File lib/filename.rb, line 336 def self.manage @@manage = FileName::Manage.new unless @@manage @@manage end
The options are following:
- :start (Fixnum)
-
If ID string type is number, the ID starts from the specified number.
- :digit (Fixnum)
-
When we create additional part of a filename, we use a string of ID number with specified digit.
- :delimiter (String)
-
We use specified string for delimiter between base name and additional part. Default is ‘.’ if position is suffix. Otherwise, ‘_’.
- :type (:number or :time)
-
We specify type of additional part: :number or :time. Default is :number.
- :format (String or Proc)
-
We specify format string of additional part or proc object to create additional part. If type is :time, the format string is used by Time#strftime. For :number type, the string is a farst argument of sprintf(format, number). Proc object takes an object of Time or Integer for respective types.
- :position (:prefix, :suffix, or :middle)
-
We specify of position of additional part of filename.
- :path
-
We sepecify if path created by
FileName#create
is absolute or relative. Default is absolute. - :data
-
We specify hash expressing instance variables for evaluation of format proc, which is set by an option :format. If we set { :a => 1, :b => 2 } for :data option, we can use @a and @b in proc object set by :format option.
- :filter
-
We specify filters :before and :after for basename without suffix, which is got by File.basename(path, “.*”)
- :extension
-
Default value of the option of
FileName#create
. - :add
-
Default value of the option of
FileName#create
. - :directory
-
Default value of the option of
FileName#create
. - :file
-
Default value of the option of
FileName#create
.
# File lib/filename.rb, line 65 def initialize(basepath, *rest) if Hash === rest[-1] opts = rest.delete_at(-1) else opts = {} end path = File.join(basepath, *rest) @relative_path_p = (opts[:path] == :relative) if @relative_path_p @basepath = path else @basepath = File.expand_path(path) end @number = opts[:start] || 0 @digit = opts[:digit] || 2 if @digit < 1 raise ArgumentError, "Number of digit must be positive." end @type = opts[:type] || :number @position = opts[:position] || :suffix @delimiter = opts[:delimiter] || (@position == :suffix ? '.' : '_') @format = opts[:format] @last_addition = nil @default_create = {} opts.each do |key, val| if OPTIONS_CREATE.include?(key) @default_create[key] = val end end @configuration_key = nil @data = Object.new if opts[:data] opts[:data].each do |key, val| @data.instance_variable_set("@#{key}", val) end end @filter = opts[:filter] || {} end
Public Instance Methods
The options are following:
- :extension (String of extension)
-
If we want to change extension, we set the value of the option. Note that if we specify “txt” as :extension option, generated filesame is the format “SOME_STRING.txt”; that is, this method adds “.” + (specified extension).
- :add (:always, :auto, or :prohibit)
-
We specify if the additional part is used.
-
:always - We always add.
-
:auto - If the file exists, we add.
-
:prohibit - Even if the file exists, we do not add.
-
- :directory (:self, :parent, or nil)
-
If the value is :self, we make directory of created filename. If the value is :parent, we make parent directory of created filename. If the value is nil, we do nothing.
- :file
-
If the value is :overwrite, we create a new empty file. If the value is :write and the file does not exist, we create an empty file. If the value is nil, we do nothing.
# File lib/filename.rb, line 264 def create(opts = {}) basepath = @basepath if @filter[:before] basepath = filter_exec(@filter[:before], basepath) end base = get_basepath(basepath, get_option_create(opts, :extension)) opt_add = get_option_create(opts, :add) if addition = get_addition(opt_add, base) path = add_addition(base, addition) while File.exist?(path) if addition = get_addition(opt_add, base) path = add_addition(base, addition) else raise "Can not create new filename." end end path else path = base end if @filter[:after] path = filter_exec(@filter[:after], path) end create_directory(path, get_option_create(opts, :directory)) write_file(path, get_option_create(opts, :file)) path end
If @format is a Proc object, we can not dump a FileName
object. But, even if @format is Proc object, the object created from configuration can be dumped.
# File lib/filename.rb, line 295 def dump if not Proc === @format dumped = Marshal.dump(self) elsif @configuration_key tmp = @format @format = nil dumped = Marshal.dump(self) @format = tmp else raise "Can not dump." end dumped end
# File lib/filename.rb, line 119 def relative_path? @relative_path_p end
# File lib/filename.rb, line 309 def save_to(path) open(path, 'w') do |f| f.print dump end end
Private Instance Methods
# File lib/filename.rb, line 170 def add_addition(filename, addition) case @position when :prefix dir, base = File.split(filename) dir + '/' + addition + @delimiter + base when :middle dir, base = File.split(filename) ext = File.extname(base) if ext.size > 0 filename.sub(Regexp.new("\\#{ext}$"), @delimiter + addition + ext) else filename + @delimiter + addition end else # :suffix filename + @delimiter + addition end end
# File lib/filename.rb, line 194 def create_directory(base, dir_opt) if dir_opt case dir_opt when :self dir = base when :parent dir = File.dirname(base) else raise ArgumentError, "Invalid directory option." end FileUtils.mkdir_p(dir) end end
# File lib/filename.rb, line 135 def create_number_addition(number) case @format when String sprintf(@format, number) when Proc @data.instance_exec(number, &@format) else sprintf("%0#{@digit}d", number) end end
# File lib/filename.rb, line 123 def create_time_addition(t) case @format when String t.strftime(@format) when Proc @data.instance_exec(t, &@format) else t.strftime("%Y%m%d_%H%M%S_") + sprintf("%06d", t.usec) end end
# File lib/filename.rb, line 231 def filter_exec(filter, path) dir, basename = File.split(path) extname = File.extname(basename) basename_new = filter.call(basename.sub(/#{extname}$/, "")) + extname if relative_path? && dir == "." basename_new else File.join(dir, basename_new) end end
# File lib/filename.rb, line 147 def get_addition(add, filename) if add != :prohibit && (add == :always || File.exist?(filename)) case @type when :time s = create_time_addition(Time.now) when :number s = create_number_addition(@number) @number += 1 else raise "Invalid type of addition." end if s.size == 0 || s.include?(' ') || s.include?('/') raise "Invalid additional part of filename: #{s.inspect}" elsif @last_addition == s raise "Create same addition: #{s.inspect}" end @last_addition = s return s end nil end
# File lib/filename.rb, line 104 def get_basepath(basepath, extension = nil) if extension extension = '.' + extension unless extension[0] == '.' oldext = File.extname(basepath) if oldext.size > 0 basepath.sub(Regexp.new("\\#{oldext}$"), extension) else basepath + extension end else basepath end end
# File lib/filename.rb, line 189 def get_option_create(opts, key) opts.has_key?(key) ? opts[key] : @default_create[key] end
# File lib/filename.rb, line 209 def touch_file(path) FileUtils.mkdir_p(File.dirname(path)) open(path, 'w') {} end
# File lib/filename.rb, line 215 def write_file(path, file_opt) if file_opt case file_opt when :write unless File.exist?(path) touch_file(path) end when :overwrite touch_file(path) else raise ArgumentError, "Invalid file option." end end end