tracksperanto 3.3.0.pre → 3.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/DEVELOPER_DOCS.rdoc CHANGED
@@ -3,31 +3,37 @@
3
3
  === Tests
4
4
 
5
5
  Tracksperanto is heavily tested. Please use the Github checkout to also receive some 17+ megabytes of test files that the test suite
6
- can chew on. If you implement fixes or new features having tests for them is NOT OPTIONAL. We are not in crunchtime shot delivery mode
7
- here but we are sharing an essential pipeline tool that has to be robust day in day out, year to year. Mmmkay?
8
-
9
- So please do not underestimate tests.
6
+ can chew on. Contributions or patches without tests will be rejected at sight.
10
7
 
11
8
  === Development environment
12
9
 
13
- Tracksperanto is currently being developed on Ruby 1.9.3 but it should also work fine on 1.8.7. What you will need is everything mentioned
14
- in the Gemfile plus Bundler. Please develop against the git repo checkout since we no longer package the test fixtures with the gem.
10
+ Tracksperanto is currently being developed on Ruby 1.9.3 but it should also work fine on 1.8.7.
11
+ What you will need is everything mentioned in the Gemfile plus Bundler.
12
+ Development should be done agains the git checkout because the gem does not contain the test files
13
+ (various example files in different formats that are used for verifying all the import and export modules).
14
+
15
+ The test corpus on Tracksperanto is HUGE at the moment, and it makes no sense to ship it with the gem.
15
16
 
17
+ So, to get started:
18
+
19
+ * Make sure you have Ruby and Bundler (+sudo gem install bundler+ if unsure)
16
20
  * Checkout the repo at http://github.com/guerilla-di/tracksperanto
17
- * Run `bundle install' and `bundle exec rake' to run the tests
18
- * Carry your development, in your own branch or feature branch
19
- * File a pull request or send a patch to info at guerilla-di.org
21
+ * Run +bundle install+ and +bundle exec rake+ to run the tests
22
+ * Do your thing, in a separate branch
23
+ * File a pull request or send a patch to +me at julik dot nl+
20
24
 
21
25
  === Internal tracker representation
22
26
 
23
27
  The trackers are represented by Tracker objects, which work like addressable hashes per frame number. The Tracker objects
24
28
  contain Keyframe objects, and those in turn contain coordinates. The coordinates are stored in absolute pixels, relative to
25
- the zero coordinate in the lower left corner. The absolute left/bottom of the image has coordinates 0,0 (at the lower left corner of the
26
- first pixel) and 0.5x0.5 in the middle of the leftmost lower pixel.
29
+ the zero coordinate in the lower left corner.
30
+
31
+ Note on subpixel precision: the absolute left/bottom of the image has coordinates 0,0
32
+ (at the lower left corner of the leftmost bottommost pixel) and 0.5x0.5 in the middle of that pixel.
27
33
 
28
34
  === Importing your own formats
29
35
 
30
- You can easily write a Tracksperanto import module - refer to Tracksperanto::Import::Base
36
+ To write an import module refer to Tracksperanto::Import::Base
31
37
  docs. Your importer will be configured with width and height of the comp that it is importing, and will get an IO
32
38
  object with the file that you are processing. You should then yield parsed trackers within the each method (tracker objects should
33
39
  be Tracksperanto::Tracker objects or compatibles)
@@ -44,7 +50,7 @@ You probably want to write a Tool (consult the Tracksperanto::Tool::Base docs) i
44
50
  or their data. A Tool is just like an export module, except that instead it sits between the exporter and the exporting routine. Tools wrap export
45
51
  modules or each other, so you can stack different tool modules together (like "scale first, then move").
46
52
 
47
- === Writing your own processing routines
53
+ === Writing your own processing pipelines from start to finish
48
54
 
49
55
  You probably want to write a descendant of Tracksperanto::Pipeline::Base. This is a class that manages a conversion from start to finish, including detecting the
50
56
  input format, allocating output files and building a chain of Tools to process the export. If you want to make a GUI for Tracksperanto you will likely need
@@ -70,7 +76,7 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
70
76
  # This importer needs to know width and height
71
77
  some_importer.width = 1024
72
78
  some_importer.height = 576
73
- some_importer.io = File.open("source_file.fmt")
79
+ some_importer.io = File.open("source_file.shk")
74
80
 
75
81
  # The importer responds to each() so if your file is not too big you can just load all the trackers
76
82
  # as an array. If you expect to have alot of trackers investigate a way to buffer them on disk
@@ -89,6 +95,8 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
89
95
 
90
96
  # Now when we send export commands to the Slipper it will play them through
91
97
  # to the Scaler and the Scaler in turn will send commands to the exporter.
98
+ # As you can see when you run export commands you do not have to use the Tracker
99
+ # objects, you just have to stream the right arguments in the right sequence
92
100
  slipper.start_export(1024, 576)
93
101
  trackers.each do | t |
94
102
  slipper.start_tracker_segment(t.name)
@@ -99,4 +107,4 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
99
107
  end
100
108
  slipper.end_export
101
109
 
102
- # And we are done!
110
+ # And we are done!
data/Gemfile CHANGED
@@ -1,24 +1,27 @@
1
1
  # -*- ruby -*-
2
2
  source :rubygems
3
3
 
4
+ gem "bundler"
5
+
4
6
  gem "obuf", "~> 1.1"
5
- gem "tickly", "~> 2.0"
6
- gem "bychar"
7
+ gem "tickly", "~> 2.1"
8
+ gem "bychar", "~> 2"
7
9
  gem "progressive_io", "~> 1.0"
8
10
  gem "flame_channel_parser", "~> 4.0"
11
+
9
12
  gem "progressbar", "0.10.0"
10
13
  gem "update_hints", "~> 1.0"
11
14
 
12
-
13
15
  group :development do
14
16
  gem "approximately"
15
17
  gem "jeweler"
16
18
  gem "rake"
19
+ gem "linebyline"
17
20
 
18
21
  if RUBY_VERSION > "1.8"
19
- gem "flexmock", "~> 1.3"
22
+ gem "flexmock", "~> 1.3", :require => %w( flexmock flexmock/test_unit )
20
23
  else
21
- gem "flexmock", "~> 0.8"
24
+ gem "flexmock", "~> 0.8", :require => %w( flexmock flexmock/test_unit )
22
25
  end
23
26
 
24
27
  gem "cli_test", "~>1.0"
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 3.3.6
2
+
3
+ * Shake out the latest Bundler integration issues
4
+
5
+ === 3.3.0
6
+
7
+ * Require dependencies using Bundler
8
+ * Update to newer Tickly that has a faster parser
9
+
1
10
  === 3.2.2
2
11
 
3
12
  * Bump a whole array of dependencies to speed up and simplify Nuke and Shake parsers
data/README.rdoc CHANGED
@@ -9,6 +9,8 @@ Unfortunately, the UIs of these are all different and not very user-friendly. It
9
9
  that an app cannot solve a shot that another one will, but you usually have to redo your 2D
10
10
  tracks in each one of them.
11
11
 
12
+ === Efficiency when doing tracks
13
+
12
14
  Another problem with today's matchmoving apps is that they are vastly inefficient when
13
15
  doing 2D tracks. Almost all of them use OpenGL and want to load the whole frame into memory
14
16
  at once. When doing tracks of long shots at high resolutions (like 2K and HD), especially
@@ -27,31 +29,65 @@ which is not adequate for all of the features being tracked.
27
29
 
28
30
  So it's very natural to track in a modern compositing app that has selective image
29
31
  loading, and then export one single group of tracks into all of the matchmoving
30
- applications at once. Also, you can always escape into the 2D world if no 3D app proves
31
- to be adequate. If you need to move from one app to another, you won't have to retrack.
32
+ applications at once.
33
+
34
+ === Evaluating different camera solvers
35
+
36
+ Since your 2D tracking data is now freely interchangeable you can load the same tracks
37
+ into multiple 3D tracking applications and see which one gives you a better solve.
38
+ Should all the 3D camera trackers fail, you can still take your tracks into the 2D
39
+ compositing world to do the job.
40
+
41
+ === Processing 2D tracking data
42
+
43
+ Sometimes you need to offset your tracks in time, or resize them to a different pixel format.
44
+ Very few apps allow you to convert your tracks in one step from format to format - like doing
45
+ an unproportional scale on the tracks, or moving them a few pixels left and right. This comes
46
+ at a high cost if the footage you are tracking came cropped or in a wrong aspect - the only
47
+ way to solve the shot will be to retrack it from scratch.
48
+
49
+ To circumvent this, Tracksperanto allows you to apply transformations to the tracking data
50
+ that you export - and you can apply multiple transformations if desired.
51
+
52
+ == Using Tracksperanto from the command line
32
53
 
33
- Another issue with tracks is adjusting to formats. Very few apps allow you to convert your
34
- tracks in one step from format to format - like doing an unproportional scale on the
35
- tracks, or moving them a few pixels left and right. This comes at a high cost if the
36
- footage you are tracking came cropped or in a wrong aspect - the only way to solve the shot
37
- will be to retrack it from scratch. Tracksperanto allows you to work around this
38
- by applying simple transformations to the tracks.
54
+ To run on your own computer, make sure you have Ruby installed. Versions from 1.8.7
55
+ and up are supported.
56
+
57
+ $ ruby -v
58
+ ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin12.2.0]
39
59
 
40
- == Usage
60
+ Then install tracksperanto. It will be downloaded and unpacked automatically for you by the
61
+ RubyGems system:
41
62
 
42
- The main way to use Tracksperanto is with the the supplied "tracksperanto" binary, like so:
63
+ $ sudo gem install tracksperanto
43
64
 
44
- tracksperanto -w 1920 -h 1080 /Films/Blockbuster/Shots/001/script.shk
65
+ Then you will have a "tracksperanto" binary in your $PATH, which you can use like this:
45
66
 
46
- -w and -h stand for Width and Height and define the size of your comp (different tracking
47
- apps use different coordinate systems and we need to know the size of the comp to properly
48
- convert these). Some formats contain clear hints on the size of the comp, but most don't -
49
- for formats that do contain them you don't need to supply anything.
50
- You also have additional options like -xs, -ys and --slip - consult the usage info for the tracksperanto binary.
67
+ $ tracksperanto -w 1920 -h 1080 /Films/Blockbuster/Shots/001/script.shk
68
+
69
+ To see the supported options, run
70
+
71
+ $ tracksperanto --help | more
51
72
 
52
73
  The converted files will be saved in the same directory as the source, if resulting
53
74
  converted files already exist <b>they will be overwritten without warning</b>.
54
75
 
76
+ == Using Tracksperanto through the web
77
+
78
+ For situations where you cannot install anything on your machine, or you run a shitty OS that cannot
79
+ run Ruby decently, or you are in a locked-down environment, we offer a web-enabled version of
80
+ Tracksperanto at the following URL:
81
+
82
+ http://tracksperanto.guerilla-di.org/
83
+
84
+ This is a web-app which is always in lock-step with the main Tracksperanto in terms of versions,
85
+ features and bug fixes. As a matter of principle, we reserve the right to use anything you upload
86
+ to the web version for fixing bugs in Tracksperanto. Note that we usually scrub all the studio-specific
87
+ data (like script and footage paths) from the files before adding them to the repo.
88
+
89
+ If you want your own copy of the web application at your facility we can discuss that, but it's not free.
90
+
55
91
  == Format support
56
92
 
57
93
  ---
data/bin/tracksperanto CHANGED
@@ -10,11 +10,11 @@
10
10
  # == Author
11
11
  # Julik <me@julik.nl>
12
12
 
13
+ # Require the xperanto lib, which in turn requires Bundler and pulls in all the gems
13
14
  require File.dirname(__FILE__) + '/../lib/tracksperanto' unless defined?(Tracksperanto)
15
+ require 'update_hints'
14
16
  require 'optparse'
15
- require 'rubygems'
16
17
  require 'progressbar'
17
- require "update_hints"
18
18
 
19
19
  def disclaimer
20
20
  "Please consider a small donation to keep Tracksperanto going: http://guerilla-di.org/source-and-license/\n"+
@@ -100,6 +100,8 @@ op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String, toold("Crop")) do
100
100
  end
101
101
 
102
102
  op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :y_factor))
103
+ op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :x_factor))
104
+
103
105
  op.on(" -t", "--trim", Float, toold("StartTrim"), &tool("StartTrim")) # Before slip!
104
106
  op.on(" -s", "--slip FRAMES", Integer, toold("Slipper"), &tool("Slipper", :slip))
105
107
  op.on(" -g", "--golden", toold("Golden"), &tool("Golden"))
data/lib/export/base.rb CHANGED
@@ -64,13 +64,14 @@ class Tracksperanto::Export::Base
64
64
  # Called on tracker start, once for each tracker. Receives the name of the tracker.
65
65
  def start_tracker_segment(tracker_name)
66
66
  end
67
+
68
+ # Called for each tracker keyframe, with the Tracksperanto internal coordinates and frame numbers.
69
+ # The calls come after start_tracker_segment and before end_tracker_segment
70
+ def export_point(at_frame_i, abs_float_x, abs_float_y, float_residual)
71
+ end
67
72
 
68
73
  # Called on tracker end, once for each tracker
69
74
  def end_tracker_segment
70
75
  end
71
76
 
72
- # Called for each tracker keyframe, with the Tracksperanto internal coordinates and frame numbers.
73
- # The calls come after start_tracker_segment and before end_tracker_segment
74
- def export_point(at_frame_i, abs_float_x, abs_float_y, float_residual)
75
- end
76
77
  end
@@ -1,4 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'flame_channel_parser'
3
+
2
4
  class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
3
5
 
4
6
  # Flame setups contain clear size indications
@@ -1,4 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
+
2
3
  require 'tickly'
3
4
 
4
5
  class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
@@ -1,4 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
+
2
3
  require 'bychar'
3
4
 
4
5
  module Tracksperanto::ShakeGrammar
@@ -27,13 +28,13 @@ module Tracksperanto::ShakeGrammar
27
28
  # that will cache in chunks, and then read from there byte by byte. This yields a substantial speedup (4.9 seconds for the test
28
29
  # as opposed to 7.9 without this). We do check for the proper class only once so that when we use nested lexers
29
30
  # we only wrap the passed IO once, and only if necessary.
30
- with_io = Bychar::Reader.new(with_io) unless with_io.respond_to?(:read_one_byte)
31
+ with_io = Bychar.wrap(with_io) unless with_io.respond_to?(:read_one_char!)
31
32
  @io, @stack, @buf, @sentinel, @limit_to_one_stmt, @stack_depth = with_io, [], '', sentinel, limit_to_one_stmt, stack_depth
32
33
 
33
34
  catch(STOP_TOKEN) do
34
35
  begin
35
36
  loop { parse }
36
- rescue Bychar::EOFError
37
+ rescue Bychar::EOF
37
38
  end
38
39
  end
39
40
 
@@ -53,7 +54,7 @@ module Tracksperanto::ShakeGrammar
53
54
 
54
55
  def parse
55
56
 
56
- c = @io.read_one_byte!
57
+ c = @io.read_one_char!
57
58
 
58
59
  if @buf.length > MAX_BUFFER_SIZE # Wrong format and the buffer is filled up, bail
59
60
  raise WrongInputError, "Atom buffer overflow at #{MAX_BUFFER_SIZE} bytes, this is definitely not a Shake script"
data/lib/pipeline/base.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  # -*- encoding : utf-8 -*-
2
+
3
+ require 'progressive_io'
4
+ require 'obuf'
5
+
2
6
  module Tracksperanto::Pipeline
3
7
 
4
8
  class EmptySourceFileError < RuntimeError
@@ -213,9 +217,9 @@ module Tracksperanto::Pipeline
213
217
  # Setup output files and return a single output
214
218
  # that replays to all of them
215
219
  def setup_outputs_for(input_file_path)
216
- file_name = File.basename(input_file_path).gsub(EXTENSION, '')
220
+ file_name_without_extension = File.basename(input_file_path, '.*')
217
221
  outputs = (exporters || Tracksperanto.exporters).map do | exporter_class |
218
- export_name = [file_name, exporter_class.desc_and_extension].join("_")
222
+ export_name = [file_name_without_extension, exporter_class.desc_and_extension].join("_")
219
223
  export_path = File.join(File.dirname(input_file_path), export_name)
220
224
  exporter_class.new(open_owned_export_file(export_path))
221
225
  end
data/lib/tracksperanto.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding : utf-8 -*-
2
- %w( stringio delegate tempfile flame_channel_parser obuf progressive_io ).map(&method(:require))
2
+ %w( stringio delegate tempfile ).map(&method(:require))
3
3
 
4
4
  module Tracksperanto
5
5
  PATH = File.expand_path(File.dirname(__FILE__))
6
- VERSION = '3.2.2'
6
+ VERSION = '3.3.6'
7
7
 
8
8
  module Import; end
9
9
  module Export; end
@@ -47,6 +47,8 @@ class FlameStabilizerCornerpinExportTest < Test::Unit::TestCase
47
47
  x = Tracksperanto::Export::FlameStabilizerCornerpin.new(s)
48
48
  x.just_export(trackers, 1920, 1080)
49
49
 
50
+ s.rewind
51
+
50
52
  assert_same_buffer(File.open(P2), s)
51
53
  end
52
54
 
@@ -63,6 +65,8 @@ class FlameStabilizerCornerpinExportTest < Test::Unit::TestCase
63
65
  x = Tracksperanto::Export::FlameStabilizerCornerpin.new(s)
64
66
  x.just_export(trackers, 1920, 1080)
65
67
 
68
+ s.rewind
69
+
66
70
  assert_same_buffer(File.open(P3), s)
67
71
  end
68
72
  end
data/test/helper.rb CHANGED
@@ -2,17 +2,18 @@
2
2
  require "rubygems"
3
3
  require File.dirname(__FILE__) + '/../lib/tracksperanto' unless defined?(Tracksperanto)
4
4
  require 'test/unit'
5
- require 'flexmock'
6
- require 'flexmock/test_unit'
7
- require 'approximately'
8
5
  require 'fileutils'
9
6
 
7
+ require 'bundler'
8
+ Bundler.require :development
9
+
10
10
  unless File.exist?(File.dirname(__FILE__) + "/import/samples")
11
11
  puts "Please run tests on a git checkout from http://github.com/guerilla-di/tracksperanto"
12
12
  puts "so that you also have the 17-something megs of the test corpus to test against. Aborting."
13
13
  exit 1
14
14
  end
15
15
 
16
+ # We are limited to flexmock 0.8 on Ruby 1.8
16
17
  # http://redmine.ruby-lang.org/issues/4882
17
18
  # https://github.com/jimweirich/flexmock/issues/4
18
19
  # https://github.com/julik/flexmock/commit/4acea00677e7b558bd564ec7c7630f0b27d368ca
@@ -22,6 +23,22 @@ class FlexMock::PartialMockProxy
22
23
  end
23
24
  end
24
25
 
26
+ class Test::Unit::TestCase
27
+ # Runs the block with a temporary directory. The directory will be removed
28
+ # when the block completes. The path to the directory will be yielded to the block
29
+ def in_temp_dir
30
+ old_dir = Dir.pwd
31
+ begin
32
+ Dir.mktmpdir do | where |
33
+ Dir.chdir(where)
34
+ yield(where)
35
+ end
36
+ ensure
37
+ Dir.chdir(old_dir)
38
+ end
39
+ end
40
+ end
41
+
25
42
  # This module creates ideal parabolic tracks for testing exporters. The two trackers
26
43
  # will start at opposite corners of the image and traverse two parabolic curves, touching
27
44
  # the bounds of the image at the and and in the middle. On the middle frame they will vertically
@@ -94,21 +111,9 @@ module ParabolicTracks
94
111
  flunk "The test output was overwritten, so this test is meaningless"
95
112
  end
96
113
 
97
- def assert_same_buffer(ref_buffer, actual_buffer, message = "The line should be identical")
98
- [ref_buffer, actual_buffer].each{|io| io.rewind }
99
-
100
- # There are subtle differences in how IO is handled on dfferent platforms (Darwin)
101
- lineno = 0
102
- begin
103
- loop do
104
- return if ref_buffer.eof? && actual_buffer.eof?
105
- lineno += 1
106
- ref_line, actual_line = ref_buffer.readline, actual_buffer.readline
107
- assert_equal ref_line, actual_line, "Mismatch on line #{lineno}:"
108
- end
109
- rescue EOFError
110
- flunk "One of the buffers was too short at #{lineno}"
111
- end
114
+ # for assert_same_buffer
115
+ def self.included(into)
116
+ into.send(:include, LineByLine::Assertions)
112
117
  end
113
118
 
114
119
  def ensure_same_output(exporter_klass, reference_path, message = "The line should be identical")
@@ -118,6 +123,7 @@ module ParabolicTracks
118
123
  create_reference_output(exporter_klass, reference_path) do | x |
119
124
  yield(x) if block_given?
120
125
  end
126
+ flunk
121
127
  return
122
128
  end
123
129
 
@@ -126,6 +132,8 @@ module ParabolicTracks
126
132
  yield(x) if block_given?
127
133
  export_parabolics_with(x)
128
134
 
135
+ io.rewind
136
+
129
137
  assert_same_buffer(File.open(reference_path, "r"), io, message)
130
138
  end
131
139
 
data/test/test_cli.rb CHANGED
@@ -4,16 +4,15 @@ require "set"
4
4
  require "cli_test"
5
5
 
6
6
  class TestCli < Test::Unit::TestCase
7
- TEMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp")
8
7
  BIN_P = File.expand_path(File.dirname(__FILE__) + "/../bin/tracksperanto")
9
8
 
10
- def setup
11
- Dir.mkdir(TEMP_DIR) unless File.exist?(TEMP_DIR)
12
- FileUtils.cp(File.dirname(__FILE__) + "/import/samples/flame_stabilizer/fromCombustion_fromMidClip_wSnap.stabilizer", TEMP_DIR + "/flm.stabilizer")
13
- end
14
-
15
- def teardown
16
- FileUtils.rm_rf(TEMP_DIR)
9
+ # Wraps in_temp_dir but sneaks a prefab file into it
10
+ def with_stabilizer_in_temp_dir
11
+ test_f = File.expand_path(File.dirname(__FILE__)) + "/import/samples/flame_stabilizer/fromCombustion_fromMidClip_wSnap.stabilizer"
12
+ in_temp_dir do | where |
13
+ FileUtils.cp(test_f, where + "/flm.stabilizer")
14
+ yield(where)
15
+ end
17
16
  end
18
17
 
19
18
  # Run the tracksperanto binary with passed options, and return [exit_code, stdout_content, stderr_content]
@@ -28,43 +27,52 @@ class TestCli < Test::Unit::TestCase
28
27
  end
29
28
 
30
29
  def test_cli_with_nonexisting_file
31
- status, o, e = cli(TEMP_DIR + "/nonexisting.file")
32
- assert_equal 1, status
33
- assert_match /Input file #{TEMP_DIR + "/nonexisting.file"} does not exist/, e
30
+ with_stabilizer_in_temp_dir do
31
+ status, o, e = cli("nonexisting.file")
32
+ assert_equal 1, status
33
+ assert_match /file does not exist/, e
34
+ end
34
35
  end
35
36
 
36
37
  def test_basic_cli
37
- status, o, e = cli(TEMP_DIR + "/flm.stabilizer")
38
- assert_equal 0, status, "Should exit with a normal status"
39
- fs = %w(. ..
40
- flm.stabilizer flm_3de_v3.txt flm_3de_v4.txt flm_boujou_text.txt flm_flame.stabilizer
41
- flm_matchmover.rz2 flm_mayalive.txt flm_nuke.nk flm_pftrack_2011_pfmatchit.txt flm_pftrack_v4.2dt
42
- flm_pftrack_v5.2dt flm_shake_trackers.txt flm_syntheyes_2dt.txt flm_flame_cornerpin.stabilizer
43
- flm_tracksperanto_ruby.rb flm_mayaLocators.ma flm_createNulls.jsx flm_xsi_nulls.py flm_nuke_cam_trk_autotracks.txt flm_3dsmax_nulls.ms
44
- )
45
- assert_match /Found and converted 1 trackers with 232 keyframes\./, o, "Should have output coversion statistics"
46
- assert_same_set fs, Dir.entries(TEMP_DIR)
38
+ with_stabilizer_in_temp_dir do | d |
39
+ status, o, e = cli("flm.stabilizer")
40
+ assert_equal 0, status, "Should exit with a normal status (error was #{e})"
41
+ fs = %w(. ..
42
+ flm.stabilizer flm_3de_v3.txt flm_3de_v4.txt flm_boujou_text.txt flm_flame.stabilizer
43
+ flm_matchmover.rz2 flm_mayalive.txt flm_nuke.nk flm_pftrack_2011_pfmatchit.txt flm_pftrack_v4.2dt
44
+ flm_pftrack_v5.2dt flm_shake_trackers.txt flm_syntheyes_2dt.txt flm_flame_cornerpin.stabilizer
45
+ flm_tracksperanto_ruby.rb flm_mayaLocators.ma flm_createNulls.jsx flm_xsi_nulls.py flm_nuke_cam_trk_autotracks.txt flm_3dsmax_nulls.ms
46
+ )
47
+ assert_match /Found and converted 1 trackers with 232 keyframes\./, o, "Should have output coversion statistics"
48
+ assert_same_set fs, Dir.entries(d)
49
+ end
47
50
  end
48
51
 
49
52
  def test_cli_with_nonexisting_only_exporter_prints_proper_error_message
50
- status, o, e = cli("--only microsoftfuckingword " + TEMP_DIR + "/flm.stabilizer")
51
- assert_not_equal 0, status, "Should exit with abnormal state"
52
- assert e.include?("Unknown exporter \"microsoftfuckingword\"")
53
- assert e.include?("The following export modules are available")
53
+ with_stabilizer_in_temp_dir do
54
+ status, o, e = cli("--only microsoftfuckingword flm.stabilizer")
55
+ assert_not_equal 0, status, "Should exit with abnormal state"
56
+ assert e.include?("Unknown exporter \"microsoftfuckingword\"")
57
+ assert e.include?("The following export modules are available")
58
+ end
54
59
  end
55
60
 
56
61
  def test_cli_with_nonexisting_importer_prints_proper_error_message
57
- status, o, e = cli("--from microsoftfuckingword " + TEMP_DIR + "/flm.stabilizer")
58
- assert_not_equal 0, status, "Should exit with abnormal state"
59
- assert e.include?("Unknown importer \"microsoftfuckingword\"")
60
- assert e.include?("The following import modules are available")
62
+ with_stabilizer_in_temp_dir do
63
+ status, o, e = cli("--from microsoftfuckingword flm.stabilizer")
64
+ assert_not_equal 0, status, "Should exit with abnormal state"
65
+ assert e.include?("Unknown importer \"microsoftfuckingword\"")
66
+ assert e.include?("The following import modules are available")
67
+ end
61
68
  end
62
69
 
63
70
  def test_cli_with_only_option
64
- FileUtils.cp(File.dirname(__FILE__) + "/import/samples/flame_stabilizer/fromCombustion_fromMidClip_wSnap.stabilizer", TEMP_DIR + "/flm.stabilizer")
65
- cli("#{BIN_P} --only syntheyes #{TEMP_DIR}/flm.stabilizer")
66
- fs = %w(. .. flm.stabilizer flm_syntheyes_2dt.txt )
67
- assert_same_set fs, Dir.entries(TEMP_DIR)
71
+ with_stabilizer_in_temp_dir do | d |
72
+ cli("#{BIN_P} --only syntheyes flm.stabilizer")
73
+ fs = %w(. .. flm.stabilizer flm_syntheyes_2dt.txt )
74
+ assert_same_set fs, Dir.entries(d)
75
+ end
68
76
  end
69
77
 
70
78
  # TODO: This currently hangs in testing
@@ -74,20 +82,21 @@ class TestCli < Test::Unit::TestCase
74
82
  # end
75
83
 
76
84
  def test_cli_reformat
77
- FileUtils.cp(File.dirname(__FILE__) + "/import/samples/flame_stabilizer/fromCombustion_fromMidClip_wSnap.stabilizer", TEMP_DIR + "/flm.stabilizer")
78
- cli("--reformat-x 1204 --reformat-y 340 --only flamestabilizer #{TEMP_DIR}/flm.stabilizer")
79
-
80
- p = Tracksperanto::Import::FlameStabilizer.new(:io => File.open(TEMP_DIR + "/flm_flame.stabilizer"))
81
- items = p.to_a
82
- assert_equal 1204, p.width, "The width of the converted setup should be that"
83
- assert_equal 340, p.height, "The height of the converted setup should be that"
85
+ with_stabilizer_in_temp_dir do | d |
86
+ cli("--reformat-x 1204 --reformat-y 340 --only flamestabilizer flm.stabilizer")
87
+ p = Tracksperanto::Import::FlameStabilizer.new(:io => File.open(d + "/flm_flame.stabilizer"))
88
+ items = p.to_a
89
+ assert_equal 1204, p.width, "The width of the converted setup should be that"
90
+ assert_equal 340, p.height, "The height of the converted setup should be that"
91
+ end
84
92
  end
85
93
 
86
94
  def test_cli_trim
87
- FileUtils.cp(File.dirname(__FILE__) + "/import/samples/flame_stabilizer/fromCombustion_fromMidClip_wSnap.stabilizer", TEMP_DIR + "/flm.stabilizer")
88
- results = cli("--slip -8000 --trim --only flamestabilizer #{TEMP_DIR}/flm.stabilizer")
89
- assert_not_equal 0, results[0] # status
90
- assert_match /There were no trackers exported/, results[-1] # STDERR
95
+ with_stabilizer_in_temp_dir do | d |
96
+ results = cli("--slip -8000 --trim --only flamestabilizer flm.stabilizer")
97
+ assert_not_equal 0, results[0] # status
98
+ assert_match /There were no trackers exported/, results[-1] # STDERR
99
+ end
91
100
  end
92
101
 
93
102
  # We use this instead of assert_equals for arrays of file names since different filesystems
@@ -3,14 +3,8 @@ require File.expand_path(File.dirname(__FILE__)) + '/helper'
3
3
 
4
4
  class TestPipeline < Test::Unit::TestCase
5
5
 
6
- def setup
7
- @old_dir = Dir.pwd
8
- Dir.chdir(File.dirname(__FILE__))
9
- super
10
- end
11
-
12
6
  def create_stabilizer_file
13
- @stabilizer = "./input.stabilizer"
7
+ @stabilizer = "input.stabilizer"
14
8
  trackers = %w( Foo Bar Baz).map do | name |
15
9
  t = Tracksperanto::Tracker.new(:name => name)
16
10
  t.keyframe!(:frame => 3, :abs_x => 100, :abs_y => 200)
@@ -25,144 +19,166 @@ class TestPipeline < Test::Unit::TestCase
25
19
  end
26
20
  end
27
21
 
28
- def teardown
29
- Dir.glob("./input*.*").each(&File.method(:unlink))
30
- Dir.chdir(@old_dir)
31
- super
32
- end
33
-
34
22
  def test_supports_block_init
35
23
  pipeline = Tracksperanto::Pipeline::Base.new(:tool_tuples => [:a, :b])
36
24
  assert_equal [:a, :b], pipeline.tool_tuples
37
25
  end
38
26
 
39
27
  def test_run_with_autodetected_importer_and_size_without_progress_block
40
- create_stabilizer_file
41
- pipeline = Tracksperanto::Pipeline::Base.new
42
- assert_nothing_raised { pipeline.run(@stabilizer) }
43
- assert_equal 3, pipeline.converted_points
44
- assert_equal 9, pipeline.converted_keyframes, "Should report conversion of 9 keyframes"
28
+ in_temp_dir do
29
+ create_stabilizer_file
30
+ pipeline = Tracksperanto::Pipeline::Base.new
31
+ assert_nothing_raised { pipeline.run(@stabilizer) }
32
+ assert_equal 3, pipeline.converted_points
33
+ assert_equal 9, pipeline.converted_keyframes, "Should report conversion of 9 keyframes"
34
+ end
45
35
  end
46
36
 
47
37
  def test_run_with_error_picks_up_known_snags_from_importer
48
- create_stabilizer_file
49
- pipeline = Tracksperanto::Pipeline::Base.new
50
- flexmock(Tracksperanto::Import::ShakeScript).should_receive(:known_snags).times(1)
51
- assert_raise(Tracksperanto::Pipeline::NoTrackersRecoveredError) do
52
- pipeline.run(@stabilizer, :importer => "ShakeScript", :width => 2910, :height => 1080)
38
+ in_temp_dir do
39
+ create_stabilizer_file
40
+ pipeline = Tracksperanto::Pipeline::Base.new
41
+ flexmock(Tracksperanto::Import::ShakeScript).should_receive(:known_snags).times(1)
42
+ assert_raise(Tracksperanto::Pipeline::NoTrackersRecoveredError) do
43
+ pipeline.run(@stabilizer, :importer => "ShakeScript", :width => 2910, :height => 1080)
44
+ end
53
45
  end
54
46
  end
55
47
 
56
48
  def test_run_with_autodetected_importer_and_size_with_progress_block
57
- create_stabilizer_file
58
- processing_log = ""
59
- accum = lambda do | percent, message |
60
- processing_log << ("%d -> %s\n" % [percent, message])
61
- end
49
+ in_temp_dir do
50
+ create_stabilizer_file
51
+ processing_log = ""
52
+ accum = lambda do | percent, message |
53
+ processing_log << ("%d -> %s\n" % [percent, message])
54
+ end
62
55
 
63
- pipeline = Tracksperanto::Pipeline::Base.new(:progress_block => accum)
64
- assert_nothing_raised { pipeline.run(@stabilizer) }
65
- assert processing_log.include?("Parsing the file")
66
- assert processing_log.include?("Parsing channel \"tracker1/ref/y\"")
56
+ pipeline = Tracksperanto::Pipeline::Base.new(:progress_block => accum)
57
+ assert_nothing_raised { pipeline.run(@stabilizer) }
58
+ assert processing_log.include?("Parsing the file")
59
+ assert processing_log.include?("Parsing channel \"tracker1/ref/y\"")
60
+ end
67
61
  end
68
62
 
69
63
  def test_run_returns_the_number_of_trackers_and_keyframes_processed
70
- create_stabilizer_file
71
- pipeline = Tracksperanto::Pipeline::Base.new
72
- result = pipeline.run(@stabilizer)
73
- assert_equal [3, 9], result
64
+ in_temp_dir do
65
+ create_stabilizer_file
66
+ pipeline = Tracksperanto::Pipeline::Base.new
67
+ result = pipeline.run(@stabilizer)
68
+ assert_equal [3, 9], result
69
+ end
74
70
  end
75
71
 
76
72
  def test_run_crashes_with_empty_file
77
- empty_file_path = "./input_empty.stabilizer"
78
- f = File.open(empty_file_path, "w"){|f| f.write('') }
79
- pipeline = Tracksperanto::Pipeline::Base.new
80
- assert_raise(Tracksperanto::Pipeline::EmptySourceFileError) { pipeline.run(empty_file_path) }
73
+ in_temp_dir do
74
+ empty_file_path = "input_empty.stabilizer"
75
+ f = File.open(empty_file_path, "w"){|f| f.write('') }
76
+ pipeline = Tracksperanto::Pipeline::Base.new
77
+ assert_raise(Tracksperanto::Pipeline::EmptySourceFileError) { pipeline.run(empty_file_path) }
78
+ end
81
79
  end
82
80
 
83
81
  def test_run_crashes_with_no_trackers
84
- empty_file_path = "./input_empty.stabilizer"
85
- f = File.open(empty_file_path, "w"){|f| f.write('xx') }
86
- pipeline = Tracksperanto::Pipeline::Base.new
87
- assert_raise(Tracksperanto::Pipeline::NoTrackersRecoveredError) { pipeline.run(empty_file_path) }
82
+ in_temp_dir do
83
+ empty_file_path = "input_empty.stabilizer"
84
+ f = File.open(empty_file_path, "w"){|f| f.write('xx') }
85
+ pipeline = Tracksperanto::Pipeline::Base.new
86
+ assert_raise(Tracksperanto::Pipeline::NoTrackersRecoveredError) { pipeline.run(empty_file_path) }
87
+ end
88
88
  end
89
89
 
90
90
  def test_tool_initialization_from_tuples
91
- create_stabilizer_file
91
+ in_temp_dir do
92
+ create_stabilizer_file
92
93
 
93
- pipeline = Tracksperanto::Pipeline::Base.new
94
- pipeline.tool_tuples = [
95
- ["Bla", {:foo=> 234}]
96
- ]
94
+ pipeline = Tracksperanto::Pipeline::Base.new
95
+ pipeline.tool_tuples = [
96
+ ["Bla", {:foo=> 234}]
97
+ ]
97
98
 
98
- mock_mux = flexmock("MUX")
99
- mock_lint = flexmock("LINT")
100
- flexmock(Tracksperanto::Export::Mux).should_receive(:new).and_return(mock_mux)
101
- flexmock(Tracksperanto::Tool::Lint).should_receive(:new).with(mock_mux).and_return(mock_lint)
99
+ mock_mux = flexmock("MUX")
100
+ mock_lint = flexmock("LINT")
101
+ flexmock(Tracksperanto::Export::Mux).should_receive(:new).and_return(mock_mux)
102
+ flexmock(Tracksperanto::Tool::Lint).should_receive(:new).with(mock_mux).and_return(mock_lint)
102
103
 
103
- m = flexmock("tool object")
104
- mock_tool_class = flexmock("tool class")
104
+ m = flexmock("tool object")
105
+ mock_tool_class = flexmock("tool class")
105
106
 
106
- flexmock(Tracksperanto).should_receive(:get_tool).with("Bla").once.and_return(mock_tool_class)
107
- mock_tool_class.should_receive(:new).with(mock_lint, {:foo => 234}).once
107
+ flexmock(Tracksperanto).should_receive(:get_tool).with("Bla").once.and_return(mock_tool_class)
108
+ mock_tool_class.should_receive(:new).with(mock_lint, {:foo => 234}).once
108
109
 
109
- assert_raise(NoMethodError) { pipeline.run(@stabilizer) }
110
+ assert_raise(NoMethodError) { pipeline.run(@stabilizer) }
111
+ end
110
112
  end
111
113
 
112
114
  def test_run_with_autodetected_importer_that_requires_size
113
- FileUtils.cp("./import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "./input.shk")
114
- pipeline = Tracksperanto::Pipeline::Base.new
115
- assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("./input.shk") }
115
+ in_temp_dir do
116
+ FileUtils.cp( File.dirname(__FILE__) + "/import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "input.shk")
117
+ pipeline = Tracksperanto::Pipeline::Base.new
118
+ assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("input.shk") }
119
+ end
116
120
  end
117
121
 
118
122
  def test_run_with_autodetected_importer_that_requires_size_when_size_supplied
119
- FileUtils.cp("./import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "./input.shk")
120
- pipeline = Tracksperanto::Pipeline::Base.new
121
- assert_nothing_raised { pipeline.run("./input.shk", :width => 720, :height => 576) }
123
+ in_temp_dir do
124
+ FileUtils.cp( File.dirname(__FILE__) + "/import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "input.shk")
125
+ pipeline = Tracksperanto::Pipeline::Base.new
126
+ assert_nothing_raised { pipeline.run("input.shk", :width => 720, :height => 576) }
127
+ end
122
128
  end
123
129
 
124
130
  def test_run_with_overridden_importer_and_no_size
125
- FileUtils.cp("./import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "./input.shk")
126
- pipeline = Tracksperanto::Pipeline::Base.new
127
- num_exporters = Tracksperanto.exporters.length
128
- assert_nothing_raised { pipeline.run("./input.shk", :importer => "ShakeScript", :width => 720, :height => 576) }
129
- assert_equal num_exporters, Dir.glob("./input_*").length, "#{num_exporters} files should be present for the input and outputs"
131
+ in_temp_dir do
132
+ FileUtils.cp( File.dirname(__FILE__) + "/import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "input.shk")
133
+ pipeline = Tracksperanto::Pipeline::Base.new
134
+ num_exporters = Tracksperanto.exporters.length
135
+ assert_nothing_raised { pipeline.run("input.shk", :importer => "ShakeScript", :width => 720, :height => 576) }
136
+ assert_equal num_exporters, Dir.glob("input_*").length, "#{num_exporters} files should be present for the input and outputs"
137
+ end
130
138
  end
131
139
 
132
140
  def test_run_with_overridden_importer_and_size_for_file_that_would_be_recognized_differently
133
- FileUtils.cp("./import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "./input.stabilizer")
134
- pipeline = Tracksperanto::Pipeline::Base.new
135
- assert_nothing_raised { pipeline.run("./input.stabilizer", :importer => "ShakeScript", :width => 720, :height => 576) }
141
+ in_temp_dir do
142
+ FileUtils.cp( File.dirname(__FILE__) + "/import/samples/shake_script/four_tracks_in_one_stabilizer.shk", "input.stabilizer")
143
+ pipeline = Tracksperanto::Pipeline::Base.new
144
+ assert_nothing_raised { pipeline.run("input.stabilizer", :importer => "ShakeScript", :width => 720, :height => 576) }
145
+ end
136
146
  end
137
147
 
138
148
  def test_run_with_unknown_format_raises
139
- File.open("./input.txt", "w"){|f| f.write("foo") }
149
+ in_temp_dir do
150
+ File.open("input.txt", "w"){|f| f.write("foo") }
140
151
 
141
- pipeline = Tracksperanto::Pipeline::Base.new
142
- assert_raise(Tracksperanto::Pipeline::UnknownFormatError) { pipeline.run("./input.txt") }
143
- assert_raise(Tracksperanto::Pipeline::UnknownFormatError) { pipeline.run("./input.txt", :width => 100, :height => 100) }
144
- assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("./input.txt", :importer => "Syntheyes") }
152
+ pipeline = Tracksperanto::Pipeline::Base.new
153
+ assert_raise(Tracksperanto::Pipeline::UnknownFormatError) { pipeline.run("input.txt") }
154
+ assert_raise(Tracksperanto::Pipeline::UnknownFormatError) { pipeline.run("input.txt", :width => 100, :height => 100) }
155
+ assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("input.txt", :importer => "Syntheyes") }
156
+ end
145
157
  end
146
158
 
147
159
  def test_importing_file_with_trackers_of_zero_length_does_not_accumulate_any_trackers
148
- pft_with_empty_trackers = "./import/samples/pftrack5/empty_trackers.2dt"
149
- i = Tracksperanto::Import::PFTrack.new(:io => File.open(pft_with_empty_trackers), :width => 1920, :height => 1080)
150
- tks = i.to_a
151
- assert_equal 3, tks.length
152
- assert_equal 0, tks[0].length, "The tracker should have 0 keyframes for this test to make sense"
160
+ in_temp_dir do
161
+ pft_with_empty_trackers = File.dirname(__FILE__) + "/import/samples/pftrack5/empty_trackers.2dt"
162
+ i = Tracksperanto::Import::PFTrack.new(:io => File.open(pft_with_empty_trackers), :width => 1920, :height => 1080)
163
+ tks = i.to_a
164
+ assert_equal 3, tks.length
165
+ assert_equal 0, tks[0].length, "The tracker should have 0 keyframes for this test to make sense"
153
166
 
154
- FileUtils.cp(pft_with_empty_trackers, "./input_empty.2dt")
167
+ FileUtils.cp(pft_with_empty_trackers, "input_empty.2dt")
155
168
 
156
- pipeline = Tracksperanto::Pipeline::Base.new
157
- num_t, num_k = pipeline.run("./input_empty.2dt", :width => 1920, :height => 1080)
158
- assert_equal 1, num_t, "Only one tracker should have been sent through the export"
169
+ pipeline = Tracksperanto::Pipeline::Base.new
170
+ num_t, num_k = pipeline.run("input_empty.2dt", :width => 1920, :height => 1080)
171
+ assert_equal 1, num_t, "Only one tracker should have been sent through the export"
172
+ end
159
173
  end
160
174
 
161
175
  def test_run_with_overridden_importer_and_size
162
- FileUtils.cp("./import/samples/3de_v4/3de_export_cube.txt", "./input.txt")
163
- pipeline = Tracksperanto::Pipeline::Base.new
164
- assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("./input.txt", :importer => "Equalizer4") }
165
- assert_nothing_raised { pipeline.run("./input.txt", :importer => "Equalizer4", :width => 720, :height => 576) }
176
+ in_temp_dir do
177
+ FileUtils.cp( File.dirname(__FILE__) + "/import/samples/3de_v4/3de_export_cube.txt", "input.txt")
178
+ pipeline = Tracksperanto::Pipeline::Base.new
179
+ assert_raise(Tracksperanto::Pipeline::DimensionsRequiredError) { pipeline.run("input.txt", :importer => "Equalizer4") }
180
+ assert_nothing_raised { pipeline.run("input.txt", :importer => "Equalizer4", :width => 720, :height => 576) }
181
+ end
166
182
  end
167
183
 
168
184
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "tracksperanto"
8
- s.version = "3.3.0.pre"
8
+ s.version = "3.3.6"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik Tarkhanov"]
12
- s.date = "2013-03-22"
12
+ s.date = "2013-04-04"
13
13
  s.description = "Converts 2D track exports between different apps like Flame, MatchMover, PFTrack..."
14
14
  s.email = "me@julik.nl"
15
15
  s.executables = ["tracksperanto"]
@@ -209,50 +209,53 @@ Gem::Specification.new do |s|
209
209
  s.specification_version = 3
210
210
 
211
211
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
212
+ s.add_runtime_dependency(%q<bundler>, [">= 0"])
212
213
  s.add_runtime_dependency(%q<obuf>, ["~> 1.1"])
213
- s.add_runtime_dependency(%q<tickly>, ["~> 2.0"])
214
- s.add_runtime_dependency(%q<bychar>, [">= 0"])
214
+ s.add_runtime_dependency(%q<tickly>, ["~> 2.1"])
215
+ s.add_runtime_dependency(%q<bychar>, ["~> 2"])
215
216
  s.add_runtime_dependency(%q<progressive_io>, ["~> 1.0"])
216
217
  s.add_runtime_dependency(%q<flame_channel_parser>, ["~> 4.0"])
217
218
  s.add_runtime_dependency(%q<progressbar>, ["= 0.10.0"])
218
219
  s.add_runtime_dependency(%q<update_hints>, ["~> 1.0"])
219
- s.add_runtime_dependency(%q<bundler>, [">= 0"])
220
220
  s.add_development_dependency(%q<approximately>, [">= 0"])
221
221
  s.add_development_dependency(%q<jeweler>, [">= 0"])
222
222
  s.add_development_dependency(%q<rake>, [">= 0"])
223
+ s.add_development_dependency(%q<linebyline>, [">= 0"])
223
224
  s.add_development_dependency(%q<flexmock>, ["~> 1.3"])
224
225
  s.add_development_dependency(%q<cli_test>, ["~> 1.0"])
225
226
  s.add_development_dependency(%q<rake-hooks>, [">= 0"])
226
227
  s.add_development_dependency(%q<ruby-prof>, [">= 0"])
227
228
  else
229
+ s.add_dependency(%q<bundler>, [">= 0"])
228
230
  s.add_dependency(%q<obuf>, ["~> 1.1"])
229
- s.add_dependency(%q<tickly>, ["~> 2.0"])
230
- s.add_dependency(%q<bychar>, [">= 0"])
231
+ s.add_dependency(%q<tickly>, ["~> 2.1"])
232
+ s.add_dependency(%q<bychar>, ["~> 2"])
231
233
  s.add_dependency(%q<progressive_io>, ["~> 1.0"])
232
234
  s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
233
235
  s.add_dependency(%q<progressbar>, ["= 0.10.0"])
234
236
  s.add_dependency(%q<update_hints>, ["~> 1.0"])
235
- s.add_dependency(%q<bundler>, [">= 0"])
236
237
  s.add_dependency(%q<approximately>, [">= 0"])
237
238
  s.add_dependency(%q<jeweler>, [">= 0"])
238
239
  s.add_dependency(%q<rake>, [">= 0"])
240
+ s.add_dependency(%q<linebyline>, [">= 0"])
239
241
  s.add_dependency(%q<flexmock>, ["~> 1.3"])
240
242
  s.add_dependency(%q<cli_test>, ["~> 1.0"])
241
243
  s.add_dependency(%q<rake-hooks>, [">= 0"])
242
244
  s.add_dependency(%q<ruby-prof>, [">= 0"])
243
245
  end
244
246
  else
247
+ s.add_dependency(%q<bundler>, [">= 0"])
245
248
  s.add_dependency(%q<obuf>, ["~> 1.1"])
246
- s.add_dependency(%q<tickly>, ["~> 2.0"])
247
- s.add_dependency(%q<bychar>, [">= 0"])
249
+ s.add_dependency(%q<tickly>, ["~> 2.1"])
250
+ s.add_dependency(%q<bychar>, ["~> 2"])
248
251
  s.add_dependency(%q<progressive_io>, ["~> 1.0"])
249
252
  s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
250
253
  s.add_dependency(%q<progressbar>, ["= 0.10.0"])
251
254
  s.add_dependency(%q<update_hints>, ["~> 1.0"])
252
- s.add_dependency(%q<bundler>, [">= 0"])
253
255
  s.add_dependency(%q<approximately>, [">= 0"])
254
256
  s.add_dependency(%q<jeweler>, [">= 0"])
255
257
  s.add_dependency(%q<rake>, [">= 0"])
258
+ s.add_dependency(%q<linebyline>, [">= 0"])
256
259
  s.add_dependency(%q<flexmock>, ["~> 1.3"])
257
260
  s.add_dependency(%q<cli_test>, ["~> 1.0"])
258
261
  s.add_dependency(%q<rake-hooks>, [">= 0"])
metadata CHANGED
@@ -1,16 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracksperanto
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0.pre
5
- prerelease: 6
4
+ version: 3.3.6
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Julik Tarkhanov
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-22 00:00:00.000000000 Z
12
+ date: 2013-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: obuf
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +50,7 @@ dependencies:
34
50
  requirements:
35
51
  - - ~>
36
52
  - !ruby/object:Gem::Version
37
- version: '2.0'
53
+ version: '2.1'
38
54
  type: :runtime
39
55
  prerelease: false
40
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,23 +58,23 @@ dependencies:
42
58
  requirements:
43
59
  - - ~>
44
60
  - !ruby/object:Gem::Version
45
- version: '2.0'
61
+ version: '2.1'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: bychar
48
64
  requirement: !ruby/object:Gem::Requirement
49
65
  none: false
50
66
  requirements:
51
- - - ! '>='
67
+ - - ~>
52
68
  - !ruby/object:Gem::Version
53
- version: '0'
69
+ version: '2'
54
70
  type: :runtime
55
71
  prerelease: false
56
72
  version_requirements: !ruby/object:Gem::Requirement
57
73
  none: false
58
74
  requirements:
59
- - - ! '>='
75
+ - - ~>
60
76
  - !ruby/object:Gem::Version
61
- version: '0'
77
+ version: '2'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: progressive_io
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -124,14 +140,14 @@ dependencies:
124
140
  - !ruby/object:Gem::Version
125
141
  version: '1.0'
126
142
  - !ruby/object:Gem::Dependency
127
- name: bundler
143
+ name: approximately
128
144
  requirement: !ruby/object:Gem::Requirement
129
145
  none: false
130
146
  requirements:
131
147
  - - ! '>='
132
148
  - !ruby/object:Gem::Version
133
149
  version: '0'
134
- type: :runtime
150
+ type: :development
135
151
  prerelease: false
136
152
  version_requirements: !ruby/object:Gem::Requirement
137
153
  none: false
@@ -140,7 +156,7 @@ dependencies:
140
156
  - !ruby/object:Gem::Version
141
157
  version: '0'
142
158
  - !ruby/object:Gem::Dependency
143
- name: approximately
159
+ name: jeweler
144
160
  requirement: !ruby/object:Gem::Requirement
145
161
  none: false
146
162
  requirements:
@@ -156,7 +172,7 @@ dependencies:
156
172
  - !ruby/object:Gem::Version
157
173
  version: '0'
158
174
  - !ruby/object:Gem::Dependency
159
- name: jeweler
175
+ name: rake
160
176
  requirement: !ruby/object:Gem::Requirement
161
177
  none: false
162
178
  requirements:
@@ -172,7 +188,7 @@ dependencies:
172
188
  - !ruby/object:Gem::Version
173
189
  version: '0'
174
190
  - !ruby/object:Gem::Dependency
175
- name: rake
191
+ name: linebyline
176
192
  requirement: !ruby/object:Gem::Requirement
177
193
  none: false
178
194
  requirements:
@@ -456,13 +472,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
456
472
  version: '0'
457
473
  segments:
458
474
  - 0
459
- hash: 506904342212099543
475
+ hash: -4545677537433489103
460
476
  required_rubygems_version: !ruby/object:Gem::Requirement
461
477
  none: false
462
478
  requirements:
463
- - - ! '>'
479
+ - - ! '>='
464
480
  - !ruby/object:Gem::Version
465
- version: 1.3.1
481
+ version: '0'
466
482
  requirements: []
467
483
  rubyforge_project:
468
484
  rubygems_version: 1.8.24