Module: Sequencer

Extended by:
Sequencer
Included in:
Sequencer
Defined in:
lib/sequencer.rb,
lib/sequencer/version.rb

Defined Under Namespace

Classes: Padder, Sequence

Constant Summary collapse

NUMBERS_AT_END =
/(\d+)([^\d]+)?$/
VERSION =
'1.3.1'

Instance Method Summary collapse

Instance Method Details

#entries(of_dir) ⇒ Object

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



33
34
35
36
37
38
39
40
41
42
# 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 = '') ⇒ Object

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



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 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) ⇒ Object

Detect multiple sequences from a glob result



72
73
74
75
# 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) ⇒ Object

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



60
61
62
63
64
65
66
67
68
69
# 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) ⇒ Object

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



78
79
80
81
82
83
84
85
86
87
# 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) ⇒ Object

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



47
48
49
50
51
52
53
54
55
56
57
# 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