module Sequencer

Constants

NUMBERS_AT_END
VERSION

Public Instance Methods

entries(of_dir) click to toggle source

Detects sequences in the passed directory (same as Dir.entries but returns Sequence objects). Single files will be upgraded to single-frame Sequences

# File lib/sequencer.rb, line 33
def entries(of_dir)
  # Remove all dotfiles and directories
  actual_files = Dir.entries(of_dir).reject do |e|
    e =~ /^\./
  end.reject do | e |
    File.directory?(File.join(of_dir, e))
  end
  
  from_enumerable(actual_files, of_dir)
end
from_enumerable(enum, assume_directory = '') click to toggle source

Groups the names in the passed Enumerable into Sequence objects and returns them

# File lib/sequencer.rb, line 9
def from_enumerable(enum, assume_directory = '')
  # Remove all dotfiles, ensure files are presorted
  actual_files = enum.reject{|e| e =~ /^\./ }.sort
  
  groups = {}
  
  actual_files.each do | e |
    if e =~ NUMBERS_AT_END
      base = e[0...-([$1, $2].join.length)]
      key = [base, $2]
      groups[key] ||= []
      groups[key] << e
    else
      groups[e] = [e]
    end
  end
  
  groups.map do | key, filenames |
    Sequence.new(assume_directory, filenames)
  end
end
from_glob(glob_pattern) click to toggle source

Detect multiple sequences from a glob result

# File lib/sequencer.rb, line 72
def from_glob(glob_pattern)
  dirs_of_matched_files = Dir.glob(glob_pattern).map(&File.method(:dirname)).uniq
  dirs_of_matched_files.map(&method(:entries)).flatten
end
from_single_file(path_to_single_file) click to toggle source

Detect a Sequence from a single file and return a handle to it

# File lib/sequencer.rb, line 60
def from_single_file(path_to_single_file)
  #File.stat(path_to_single_file)
  
  frame_number = path_to_single_file.scan(NUMBERS_AT_END).flatten.shift
  if frame_number =~ /^0/ # Assume that the input is padded and take the glob path
    sequence_via_glob(path_to_single_file)
  else # Take the slower path by pattern-matching on entries
    sequence_via_patterns(path_to_single_file)
  end
end
glob_and_padding_for(path) click to toggle source

Get a glob pattern and padding offset for a file in a sequence

# File lib/sequencer.rb, line 78
def glob_and_padding_for(path)
  plen = 0
  glob_pattern = path.gsub(NUMBERS_AT_END) do
    plen = $1.length
    ('[0-9]' * plen) + $2.to_s
  end
  return nil if glob_pattern == path
  
  [glob_pattern, plen]
end
recursive_entries(of_dir) click to toggle source

Detects sequences in the passed directory and all of it's subdirectories It will skip all the entries starting with a dot TODO: fix symlink handling

# File lib/sequencer.rb, line 47
def recursive_entries(of_dir)
  detected_sequences = entries(of_dir)
  possible_subdirs = Dir.entries(of_dir)
  possible_subdirs.each do | possible_subdir |
    next if possible_subdir =~ /^\./
    
    dirpath = File.join(of_dir, possible_subdir)
    detected_sequences += recursive_entries(dirpath) if File.directory?(dirpath)
  end
  detected_sequences.sort
end

Private Instance Methods

sequence_via_glob(path_to_single_file) click to toggle source
# File lib/sequencer.rb, line 91
def sequence_via_glob(path_to_single_file)
  glob, padding = glob_and_padding_for(path_to_single_file)
  seq_glob = File.join(File.dirname(path_to_single_file), File.basename(glob))
  files = Dir.glob(seq_glob).map {|f| File.basename(f) }
  
  Sequence.new(File.expand_path(File.dirname(path_to_single_file)), files)
end
sequence_via_patterns(path_to_single_file) click to toggle source
# File lib/sequencer.rb, line 99
def sequence_via_patterns(path_to_single_file)
  base_glob_pattern = path_to_single_file.gsub(NUMBERS_AT_END, '*')
  closing_element = $2
  matching_paths = Dir.glob(base_glob_pattern).select do | p |
    number, closer = p.scan(NUMBERS_AT_END).flatten
    closer == closing_element
  end
  files = matching_paths.map {|f| File.basename(f) }
  Sequence.new(File.expand_path(File.dirname(path_to_single_file)), files)
end