sequencer 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/History.txt CHANGED
@@ -1,6 +1,14 @@
1
+ === 1.0.5 / 2011-07-07
2
+
3
+ * Dicking around with testing frameworks that become obsolete is the worst thing ever.
4
+
5
+ === 1.0.4 / 2010-10-26
6
+
7
+ * Add rseqrename binary that batch-renames sequences
8
+
1
9
  === 1.0.3 / 2010-10-26
2
10
 
3
- * Add rseqpad binary that zero-pads filenames
11
+ * Add rseqpad binary that zero-pads sequences
4
12
 
5
13
  === 1.0.2 / 2010-05-06
6
14
 
data/Manifest.txt CHANGED
@@ -1,9 +1,10 @@
1
1
  .autotest
2
2
  History.txt
3
3
  Manifest.txt
4
- README.txt
4
+ README.rdoc
5
5
  Rakefile
6
6
  bin/rseqls
7
7
  bin/rseqpad
8
+ bin/rseqrename
8
9
  lib/sequencer.rb
9
10
  test/test_sequencer.rb
@@ -6,18 +6,34 @@
6
6
 
7
7
  Simplifies working with image sequences
8
8
 
9
- == FEATURES/PROBLEMS:
9
+ == FEATURES:
10
10
 
11
11
  * List all sequences in a directory interspersed with other file entries
12
12
  * Detect sequence from single file
13
13
 
14
14
  == SYNOPSIS:
15
15
 
16
- require "sequencer"
17
- s = Sequencer.from_single_file("/RAID/Film/CONFORM.092183.dpx")
18
- s.file_count #=> 3201
19
- s.gaps? #=> true
20
- s.missing_frames #=> 15, somebody was careless
16
+ From the terminal - go to a directory, and then:
17
+
18
+ $rseqls
19
+
20
+ Fussball_Shot[1..1, 3..3].sni
21
+ FinalLichtUitValSec_Shot1.[1..128].jpg
22
+ Fussball_Shot3_v02.sni
23
+ FinalLichtUitValSec_Shot1.0001.ifl
24
+ FinalLichtUitValSec.0001.ifl
25
+ FinalLichtUitValSec.[1..185].jpg
26
+
27
+ You also have <tt>rseqpad</tt> and <tt>rseqrename</tt> :-)
28
+
29
+ From code:
30
+
31
+ require "sequencer"
32
+ s = Sequencer.from_single_file("/RAID/Film/CONFORM.092183.dpx")
33
+ s.file_count #=> 3201
34
+ s.gaps? #=> true
35
+ s.missing_frames #=> 15, somebody was careless
36
+ s.pattern #=> "CONFORM.%06d.dpx", usable with printf right away
21
37
 
22
38
  == INSTALL:
23
39
 
data/Rakefile CHANGED
@@ -3,10 +3,11 @@ require 'rubygems'
3
3
  require 'hoe'
4
4
  require File.dirname(__FILE__) + "/lib/sequencer"
5
5
 
6
+ Hoe::RUBY_FLAGS.gsub!(/^-w/, '')
6
7
  Hoe.spec 'sequencer' do | s |
7
- s.version = Sequencer::VERSION
8
+ s.readme_file = 'README.rdoc'
9
+ s.extra_rdoc_files = FileList['*.rdoc']
8
10
  s.developer('Julik Tarkhanov', 'me@julik.nl')
9
- s.extra_dev_deps = {"test-spec" => ">=0"}
10
11
  end
11
12
 
12
13
  # vim: syntax=ruby
data/bin/rseqrename ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + "/../lib/sequencer"
4
+
5
+ one_file, base_pattern = ARGV.shift, ARGV.shift
6
+ Sequencer.from_single_file(one_file).bulk_rename(base_pattern)
data/lib/sequencer.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Sequencer
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.5'
3
3
  NUMBERS_AT_END = /(\d+)([^\d]+)?$/
4
4
 
5
5
  extend self
@@ -30,7 +30,8 @@ module Sequencer
30
30
 
31
31
  # Detect a Sequence from a single file and return a handle to it
32
32
  def from_single_file(path_to_single_file)
33
- File.stat(path_to_single_file)
33
+ #File.stat(path_to_single_file)
34
+
34
35
  frame_number = path_to_single_file.scan(NUMBERS_AT_END).flatten.shift
35
36
  if frame_number =~ /^0/ # Assume that the input is padded and take the glob path
36
37
  sequence_via_glob(path_to_single_file)
@@ -86,7 +87,7 @@ module Sequencer
86
87
  attr_reader :directory
87
88
 
88
89
  def initialize(directory, filenames)
89
- raise "Can't sequence nothingness" if filenames.empty?
90
+ raise "Cannot create a Sequence with no files" if filenames.empty?
90
91
  @directory, @filenames = directory, natural_sort(filenames)
91
92
  @directory.freeze
92
93
  @filenames.freeze
@@ -202,9 +203,17 @@ module Sequencer
202
203
  end
203
204
 
204
205
  # Apply a bulk rename
205
- def bulk_rename(with_pattern)
206
- rename_map = filenames.inject({}) do | filename, map |
206
+ def bulk_rename(with_pattern, into_directory = nil, &operation)
207
+ # Check if the pattern includes a number. If it doesnt, add one and the
208
+ # extension
209
+ unless with_pattern.include?("%")
210
+ padz = last_frame_no.to_s.length
211
+ with_pattern = [with_pattern, ".%0#{padz}d", File.extname(pattern)].join
212
+ end
213
+
214
+ rename_map = @filenames.inject({}) do | map, filename |
207
215
  frame_no = filename.scan(NUMBERS_AT_END).flatten.shift.to_i
216
+
208
217
  map.merge(filename => (with_pattern % frame_no))
209
218
  end
210
219
 
@@ -217,15 +226,19 @@ module Sequencer
217
226
  raise "This would overwrite old files with the renamed ones (#{error[0..1]}.join(',')..)"
218
227
  end
219
228
 
220
- if (error = (Dir.entries(@directory) % rename_map.values)).any?
229
+ if (error = (Dir.entries(@directory) & rename_map.values)).any?
221
230
  raise "Files that will be created by the rename are already in place (#{error[0..1]}.join(',')..)"
222
231
  end
223
232
 
233
+ destination = into_directory || directory
224
234
 
225
- end
226
-
227
- def bulk_rename!(with_pattern)
228
- replace(bulk_rename(with_pattern))
235
+ rename_map.each_pair do | from_path, to_path |
236
+ src, dest = File.join(directory, from_path), File.join(destination, to_path)
237
+ File.rename(src, dest)
238
+ #yield(src, dest)
239
+ end
240
+
241
+ self.class.new(destination, rename_map.values)
229
242
  end
230
243
 
231
244
  private
@@ -1,10 +1,9 @@
1
1
  require 'test/unit'
2
- require 'rubygems'
3
- require 'test/spec'
2
+ require 'set'
4
3
  require 'fileutils'
5
4
  require File.dirname(__FILE__) + '/../lib/sequencer'
6
5
 
7
- TEST_DIR = File.dirname(__FILE__) + "/tmp"
6
+ TEST_DIR = File.expand_path(File.dirname(__FILE__)) + "/tmp"
8
7
 
9
8
  def emit_test_dirs
10
9
  start_f = 123
@@ -59,131 +58,166 @@ def teardown_test_dirs
59
58
  FileUtils.rm_rf(TEST_DIR)
60
59
  end
61
60
 
62
- context "Sequencer.glob_and_padding_for should" do
61
+ class Test_glob_and_padding_for < Test::Unit::TestCase
63
62
 
64
- specify "return proper glob pattern and padding for a path with extension" do
63
+ def test_returns_proper_glob_pattern_padding_for_a_path_with_extension
65
64
  glob, pad = Sequencer.glob_and_padding_for("file.00001.gif")
66
- glob.should.equal "file.[0-9][0-9][0-9][0-9][0-9].gif"
67
- pad.should.equal 5
65
+ assert_equal "file.[0-9][0-9][0-9][0-9][0-9].gif", glob
66
+ assert_equal 5, pad
68
67
  end
69
-
70
- specify "return proper glob pattern and padding for a path without extension" do
68
+
69
+ def test_returns_proper_glob_pattern_and_padding_for_a_path_without_extension
71
70
  glob, pad = Sequencer.glob_and_padding_for("file.00001")
72
- glob.should.equal "file.[0-9][0-9][0-9][0-9][0-9]"
73
- pad.should.equal 5
71
+ assert_equal "file.[0-9][0-9][0-9][0-9][0-9]", glob
72
+ assert_equal 5, pad
74
73
  end
75
74
 
76
- specify "return nil for a file that is not a sequence" do
75
+ def return_nil_for_a_file_that_is_not_in_the_sequence
77
76
  glob, pad = Sequencer.glob_and_padding_for("file")
78
- glob.should.be.nil
77
+ assert_nil glob
79
78
  end
80
79
  end
81
80
 
82
- context "Sequencer.entries should" do
83
- before { emit_test_dirs }
84
- after { teardown_test_dirs }
85
- specify "return entries for every sequence in a directory" do
81
+ class Sequencer_entries_should < Test::Unit::TestCase
82
+ def setup; emit_test_dirs; end
83
+ def teardown; teardown_test_dirs; end
84
+
85
+ def test_returns_entries_for_every_sequence_in_a_directory
86
86
  entries = Sequencer.entries(TEST_DIR + "/many_seqs")
87
+ flunk "this test is not finished"
87
88
  end
88
89
  end
89
90
 
90
- context "A Sequence created from unpadded files should" do
91
- before { emit_test_dirs }
92
- after { teardown_test_dirs }
91
+ class A_Sequence_created_from_unpadded_files_should < Test::Unit::TestCase
92
+ def setup; emit_test_dirs; end
93
+ def teardown; teardown_test_dirs; end
93
94
 
94
- specify "be properly created" do
95
+ def test_properly_created
95
96
  s = Sequencer.from_single_file(TEST_DIR + "/natural_numbering/somefiles 5545168.png")
96
- s.should.not.be.nil
97
- s.expected_frames.should.equal 30
98
- s.file_count.should.equal 30
99
- s.pattern.should.equal "somefiles %07d.png"
97
+ assert_not_nil s
98
+ assert_equal 30, s.expected_frames
99
+ assert_equal 30, s.file_count
100
+ assert_equal "somefiles %07d.png", s.pattern
101
+ end
102
+ end
103
+
104
+ class A_Sequence_created_from_a_file_that_has_no_numbering_slot_should
105
+ def setup; @single = Sequencer::Sequence.new("/tmp", ["foo.tif"]); end
106
+
107
+ def test_report_a_pattern_that_is_the_name_as_filename
108
+ assert_equal 'foo.tif', @single.pattern
109
+ assert @single.single_file?
110
+ assert_equal 1, @single.expected_frames
111
+ assert_equal "#<foo.tif>", @single.inspect
100
112
  end
101
113
  end
102
114
 
103
- context "A Sequence created from a file that has no numbering slot should" do
104
- before { @single = Sequencer::Sequence.new("/tmp", ["foo.tif"]) }
115
+ class Sequencer_bulk_rename_should < Test::Unit::TestCase
116
+ def setup
117
+ emit_test_dirs
118
+ @with_gaps = Sequencer.from_single_file(TEST_DIR + "/sequence_and_sole_file/broken_seq.000245.tif")
119
+ end
120
+
121
+ def teardown
122
+ teardown_test_dirs
123
+ end
105
124
 
106
- specify "report a pattern that is the same as filename" do
107
- @single.pattern.should.equal "foo.tif"
108
- @single.should.be.single_file?
109
- @single.expected_frames.should.equal 1
110
- @single.inspect.should.equal "#<foo.tif>"
125
+ def test_return_a_new_Sequencer_with_right_parameters
126
+ res = @with_gaps.bulk_rename("another_base")
127
+ assert_equal @with_gaps.length, res.length
128
+ assert_equal @with_gaps.directory, res.directory
129
+ assert_equal "another_base.%03d.tif", res.pattern
130
+
131
+ assert File.exist?(res.to_paths[0])
132
+ assert File.exist?(res.to_paths[-1])
111
133
  end
112
134
  end
113
135
 
114
- context "A Sequence created from pad-numbered files should" do
115
- before do
136
+ class A_Sequence_created_from_pad_numbered_files_should < Test::Unit::TestCase
137
+ def setup
116
138
  emit_test_dirs
117
139
  @gapless = Sequencer.from_single_file(TEST_DIR + "/sequence_and_sole_file/seq1.000245.tif")
118
140
  @with_gaps = Sequencer.from_single_file(TEST_DIR + "/sequence_and_sole_file/broken_seq.000245.tif")
119
141
  @single = Sequencer.from_single_file(TEST_DIR + "/sequence_and_sole_file/single_file.002123154.tif")
120
142
  end
121
143
 
122
- after { teardown_test_dirs }
144
+ def teardown
145
+ teardown_test_dirs
146
+ end
123
147
 
124
- specify "initialize itself from one path to a file in the sequence without gaps" do
125
- @gapless.should.not.be.nil
126
- @gapless.should.be.kind_of(Sequencer::Sequence)
127
- @gapless.should.respond_to(:gaps?)
128
- @gapless.should.not.be.single_file?
148
+ def test_initialize_itself_from_one_path_to_a_file_in_the_sequence_without_gaps
149
+ assert_not_nil @gapless
150
+ assert_kind_of Sequencer::Sequence, @gapless
151
+ assert_respond_to @gapless, :gaps?
152
+ assert !@gapless.single_file?
129
153
 
130
- @gapless.should.blaming("this is a gapless sequence").not.be.gaps?
131
- @gapless.file_count.should.blaming("actual file count in sequence").equal(446)
132
- @gapless.length.should.blaming("actual file count in sequence").equal(446)
133
- @gapless.expected_frames.should.blaming("expected frame count in sequence").equal(446)
134
- @gapless.inspect.should.blaming("inspect itself").equal('#<seq1.[123..568].tif>')
135
- @gapless.pattern.should.equal 'seq1.%06d.tif'
154
+ assert !@gapless.gaps?, "this is a gapless sequence"
155
+ assert_equal 446, @gapless.file_count, "actual file count in sequence"
156
+ assert_equal 446, @gapless.length, "actual file count in sequence"
157
+ assert_equal 446, @gapless.expected_frames, "expected frame count in sequence"
158
+ assert_equal '#<seq1.[123..568].tif>', @gapless.inspect
136
159
 
137
160
  files = @gapless.to_a
138
- files.length.should.equal 446
139
- files[0].should.equal 'seq1.000123.tif'
161
+ assert_equal 446, files.length
162
+ assert_equal 'seq1.000123.tif', files[0]
140
163
 
141
164
  paths = @gapless.to_paths
142
- paths.length.should.equal 446
143
- paths[0].should.equal(File.dirname(__FILE__) + "/tmp/sequence_and_sole_file/seq1.000123.tif")
165
+ assert_equal 446, paths.length
166
+ assert_equal File.expand_path(File.dirname(__FILE__)) + "/tmp/sequence_and_sole_file/seq1.000123.tif", paths[0]
144
167
  end
145
168
 
146
- specify "initialize itself from one path to a file in the sequence with gaps" do
147
- @with_gaps.should.not.be.nil
148
- @with_gaps.should.be.kind_of(Sequencer::Sequence)
149
- @with_gaps.should.not.be.single_file?
169
+ def test_initialize_itself_from_one_path_to_a_file_in_the_sequence_with_gaps
170
+ assert_not_nil @with_gaps
171
+ assert_kind_of Sequencer::Sequence, @with_gaps
172
+ assert !@with_gaps.single_file?
150
173
 
151
- @with_gaps.should.be.gaps?
152
- @with_gaps.gap_count.should.equal 1
153
- @with_gaps.segment_count.should.equal 2
154
- @with_gaps.missing_frames.should.equal(9)
155
- @with_gaps.inspect.should.blaming("inspect itself").equal('#<broken_seq.[123..568, 578..702].tif>')
156
- @with_gaps.should.include("broken_seq.000123.tif")
157
- @with_gaps.should.not.include("bogus.123.tif")
174
+ assert @with_gaps.gaps?
175
+ assert_equal 1, @with_gaps.gap_count
176
+ assert_equal 2, @with_gaps.segment_count
177
+ assert_equal 9, @with_gaps.missing_frames
178
+ assert_equal '#<broken_seq.[123..568, 578..702].tif>', @with_gaps.inspect
179
+ assert @with_gaps.include?("broken_seq.000123.tif")
180
+ assert !@with_gaps.include?("bogus.123.tif")
158
181
  end
159
182
 
160
- specify "return subsequences without gaps" do
183
+ def test_return_subsequences_without_gaps
161
184
  subseqs = @with_gaps.to_sequences
162
- subseqs[0].should.be.kind_of(Sequencer::Sequence)
163
- subseqs[1].should.be.kind_of(Sequencer::Sequence)
185
+ assert_kind_of Sequencer::Sequence, subseqs[0]
186
+ assert_kind_of Sequencer::Sequence, subseqs[1]
164
187
 
165
188
  first_seq, second_seq = subseqs
166
- first_seq.first_frame_no.should.equal 123
167
- first_seq.last_frame_no.should.equal 568
168
- second_seq.first_frame_no.should.equal 578
169
- second_seq.last_frame_no.should.equal 702
189
+ assert_equal 123, first_seq.first_frame_no
190
+ assert_equal 568, first_seq.last_frame_no
191
+ assert_equal 578, second_seq.first_frame_no
192
+ assert_equal 702, second_seq.last_frame_no
170
193
 
171
- first_seq.directory.should.equal second_seq.directory
172
- first_seq.directory.should.equal @with_gaps.directory
194
+ assert_equal second_seq.directory, first_seq.directory
195
+ assert_equal @with_gaps.directory, first_seq.directory
173
196
  end
174
197
 
175
- specify "list all sequences in directory and subdirectories using the pattern" do
198
+ def test_list_all_sequences_in_directory_and_subdirectories_using_the_pattern
176
199
  s = Sequencer.from_glob(TEST_DIR + "/**/*.tif")
177
- inspected = '[#<single.tif>, #<seq1.[458..512].tif>, #<anotherS [228..312].tif>, #<in_subdir [445..471].tif>, #<seq1.[123..568].tif>, #<somefile.tif>, #<single_file.002123154.tif>, #<broken_seq.[123..568, 578..702].tif>]'
178
- s.inspect.should.equal inspected
179
- end
180
-
181
- specify "initialize itself from a single file" do
182
- @single.should.be.single_file?
183
- @single.inspect.should.equal '#<single_file.002123154.tif>'
184
- @single.should.not.be.gaps?
185
- @single.expected_frames.should.equal 1
186
- @single.file_count.should.equal 1
200
+ # Here we need to use a Set since Ruby does not
201
+ ref_set = Set.new([
202
+ "#<anotherS [228..312].tif>",
203
+ "#<seq1.[458..512].tif>",
204
+ "#<single.tif>",
205
+ "#<in_subdir [445..471].tif>",
206
+ "#<broken_seq.[123..568, 578..702].tif>",
207
+ "#<seq1.[123..568].tif>",
208
+ "#<single_file.002123154.tif>",
209
+ "#<somefile.tif>"
210
+ ])
211
+ output_sequences = Set.new(s.map{|sequence| sequence.inspect })
212
+ assert_equal ref_set, output_sequences
213
+ end
214
+
215
+ def test_initialize_itself_from_a_single_file
216
+ assert @single.single_file?
217
+ assert_equal '#<single_file.002123154.tif>', @single.inspect
218
+ assert !@single.gaps?
219
+ assert_equal 1, @single.expected_frames
220
+ assert_equal 1, @single.file_count
187
221
  end
188
222
 
189
223
  end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequencer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 3
10
- version: 1.0.3
4
+ prerelease:
5
+ version: 1.0.5
11
6
  platform: ruby
12
7
  authors:
13
8
  - Julik Tarkhanov
@@ -15,61 +10,45 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-10-26 00:00:00 +02:00
13
+ date: 2011-07-07 00:00:00 +02:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
22
- name: test-spec
17
+ name: hoe
23
18
  prerelease: false
24
19
  requirement: &id001 !ruby/object:Gem::Requirement
25
20
  none: false
26
21
  requirements:
27
- - - ">="
22
+ - - ~>
28
23
  - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
24
+ version: "2.10"
33
25
  type: :development
34
26
  version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: hoe
37
- prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 21
44
- segments:
45
- - 2
46
- - 6
47
- - 1
48
- version: 2.6.1
49
- type: :development
50
- version_requirements: *id002
51
27
  description: Simplifies working with image sequences
52
28
  email:
53
29
  - me@julik.nl
54
30
  executables:
55
31
  - rseqls
56
32
  - rseqpad
33
+ - rseqrename
57
34
  extensions: []
58
35
 
59
36
  extra_rdoc_files:
60
37
  - History.txt
61
38
  - Manifest.txt
62
- - README.txt
39
+ - README.rdoc
63
40
  files:
64
41
  - .autotest
65
42
  - History.txt
66
43
  - Manifest.txt
67
- - README.txt
44
+ - README.rdoc
68
45
  - Rakefile
69
46
  - bin/rseqls
70
47
  - bin/rseqpad
48
+ - bin/rseqrename
71
49
  - lib/sequencer.rb
72
50
  - test/test_sequencer.rb
51
+ - .gemtest
73
52
  has_rdoc: true
74
53
  homepage: http://guerilla-di.org/sequencer
75
54
  licenses: []
@@ -77,7 +56,7 @@ licenses: []
77
56
  post_install_message:
78
57
  rdoc_options:
79
58
  - --main
80
- - README.txt
59
+ - README.rdoc
81
60
  require_paths:
82
61
  - lib
83
62
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -85,23 +64,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
64
  requirements:
86
65
  - - ">="
87
66
  - !ruby/object:Gem::Version
88
- hash: 3
89
- segments:
90
- - 0
91
67
  version: "0"
92
68
  required_rubygems_version: !ruby/object:Gem::Requirement
93
69
  none: false
94
70
  requirements:
95
71
  - - ">="
96
72
  - !ruby/object:Gem::Version
97
- hash: 3
98
- segments:
99
- - 0
100
73
  version: "0"
101
74
  requirements: []
102
75
 
103
76
  rubyforge_project: sequencer
104
- rubygems_version: 1.3.7
77
+ rubygems_version: 1.6.2
105
78
  signing_key:
106
79
  specification_version: 3
107
80
  summary: Simplifies working with image sequences