trecs 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,5 +18,9 @@ module TRecs
18
18
 
19
19
  def stop
20
20
  end
21
+
22
+ def inspect
23
+ "<#{self.class}: frames: #{frames}>"
24
+ end
21
25
  end
22
26
  end
@@ -25,7 +25,7 @@ module TRecs
25
25
  frame = data_array[-height..-1].join
26
26
 
27
27
  frame = @prev_frame + curr_data
28
-
28
+
29
29
  @first_timestamp ||= [ sec, usec ].join('.').to_f
30
30
  curr_timestamp = [ sec, usec ].join('.').to_f
31
31
  offset = ((curr_timestamp - @first_timestamp)*1000).to_i
@@ -41,39 +41,3 @@ module TRecs
41
41
  end
42
42
  end
43
43
  end
44
-
45
- # module TRecs
46
- # class TtyrecStrategy
47
- # attr_accessor :recorder
48
-
49
- # def initialize(options={})
50
- # file = options.fetch(:input_file)
51
- # @file = File.new(file)
52
- # @frames = []
53
- # @full_output = ""
54
- # @height = options.fetch(:height) { 24 }
55
- # @width = options.fetch(:width) { 80 }
56
- # end
57
-
58
- # def perform
59
- # @prev_timestamp = 0
60
- # while !@file.eof?
61
- # sec, usec, len = @file.read(12).unpack('VVV')
62
- # @full_output << @file.read(len)
63
-
64
- # data_array = @full_output.each_line.to_a
65
- # height = data_array.size > @height ? @height : 0
66
- # frame = data_array[-height..-1].join
67
-
68
- # @first_timestamp ||= [ sec, usec ].join('.').to_f
69
- # curr_timestamp = [ sec, usec ].join('.').to_f
70
- # offset = ((curr_timestamp - @first_timestamp)*1000).to_i
71
-
72
- # if curr_timestamp > @prev_timestamp
73
- # recorder.current_frame(time: offset, content: frame)
74
- # @prev_timestamp = curr_timestamp
75
- # end
76
- # end
77
- # end
78
- # end
79
- # end
@@ -0,0 +1,106 @@
1
+ require 'json'
2
+ require "fileutils"
3
+ require "zlib"
4
+ require 'archive/tar/minitar'
5
+ require "tmpdir"
6
+ require "pathname"
7
+ require "yaml"
8
+
9
+ module TRecs
10
+ class TgzSource
11
+ include Archive::Tar
12
+
13
+ attr_reader :trecs_file
14
+
15
+ def initialize(options={})
16
+ @trecs_file = options.fetch(:trecs_file)
17
+ end
18
+
19
+ def create_recording
20
+ in_tmp_dir do
21
+ @tgz = Zlib::GzipWriter.new(File.open(trecs_file, 'wb'))
22
+
23
+ yield self
24
+
25
+ create_file('manifest.yaml') do |f|
26
+ f.write manifest.to_yaml
27
+ end
28
+
29
+ Minitar.pack(@files_to_add.flatten, @tgz)
30
+ end
31
+ end
32
+
33
+ def reader(options={})
34
+ reader = nil
35
+ options[:source] = self
36
+ read do |source|
37
+ @manifest = YAML.load(source.read_file("manifest.yaml"))
38
+
39
+ format = manifest["format"]
40
+ reader_file = "readers/#{format}_reader"
41
+ require reader_file
42
+ reader_class_name = [
43
+ "TRecs::",
44
+ format.split(/[-_\s]/).map(&:capitalize),
45
+ "Reader"
46
+ ].join
47
+ reader_class = reader_class_name.split("::").reduce(Object) { |a, e| a.const_get e }
48
+ reader = reader_class.new(options)
49
+ end
50
+ reader
51
+ end
52
+
53
+ def read
54
+ in_tmp_dir do
55
+ tgz = Zlib::GzipReader.new(File.open(trecs_file, 'rb'))
56
+ Minitar.unpack(tgz, "./")
57
+
58
+ yield self
59
+ end
60
+ end
61
+
62
+ def in_tmp_dir
63
+ Dir.mktmpdir("trecs_record") do |dir|
64
+ Dir.chdir(dir) do
65
+ yield
66
+ end
67
+ end
68
+ end
69
+
70
+ def read_file(file_name)
71
+ File.read(file_name)
72
+ end
73
+
74
+ def create_file(file_name)
75
+ File.open(file_name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
76
+ yield f
77
+ end
78
+ add_file(file_name)
79
+ end
80
+
81
+ def add_file(file_name)
82
+ @files_to_add ||= []
83
+ @files_to_add << file_name
84
+ end
85
+
86
+ def add_audio_file(file_name)
87
+ Dir.mkdir("audio") unless File.exist? "audio"
88
+
89
+ orig_file = file_name
90
+ file_name = "./audio/" + Pathname(file_name).basename.to_s
91
+ FileUtils.symlink(orig_file, file_name)
92
+ add_file(file_name)
93
+ end
94
+
95
+ def []=(key, value)
96
+ manifest[key.to_s] = value
97
+ end
98
+
99
+ private
100
+
101
+ def manifest
102
+ @manifest ||= {}
103
+ end
104
+
105
+ end
106
+ end
data/lib/trecs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module TRecs
2
- VERSION = "0.1.11"
2
+ VERSION = "0.1.12"
3
3
  end
@@ -1,15 +1,19 @@
1
- require 'json'
2
- require "fileutils"
1
+ require "sources/tgz_source"
3
2
 
4
3
  module TRecs
5
4
  class JsonWriter
6
5
  attr_accessor :recorder
6
+
7
7
  attr_reader :frames
8
- attr_reader :file
8
+ attr_reader :audio_files
9
+ attr_reader :source
9
10
 
10
11
  def initialize(options={})
11
- @file = options.fetch(:trecs_file)
12
- FileUtils.rm(@file, force: true)
12
+ trecs_file = options.fetch(:trecs_file)
13
+ @source = TgzSource.new(trecs_file: trecs_file)
14
+
15
+ @audio_files = options.fetch(:audio_files) { [] }
16
+ @audio_files = Array(@audio_files)
13
17
  end
14
18
 
15
19
  def setup
@@ -23,11 +27,26 @@ module TRecs
23
27
  end
24
28
 
25
29
  def render
26
- json_string = frames.to_json
27
-
28
- File.open(file, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
29
- f.write(json_string)
30
+ source.create_recording do |source|
31
+ source[:format] = "json"
32
+
33
+ json_string = frames.to_json
34
+
35
+ source.create_file('frames.json') do |f|
36
+ f.write json_string
37
+ end
38
+
39
+ audio_files.each do |file|
40
+ source.add_audio_file(file)
41
+ end
42
+ if audio_files.any?
43
+ source[:defailt_audio] = audio_files.first
44
+ end
30
45
  end
31
46
  end
47
+
48
+ def add_audio_file(file_name)
49
+ audio_files << file_name
50
+ end
32
51
  end
33
52
  end
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+ require "frame"
3
+
4
+ module TRecs
5
+ describe Frame do
6
+ context "content" do
7
+ context "initializer" do
8
+ Given(:frame) { Frame.new("THE CONTENT") }
9
+ Then { frame.content == "THE CONTENT" }
10
+ end
11
+ context "set aftewards" do
12
+ Given(:frame) { Frame.new }
13
+ When { frame.content = "THE NEW CONTENT" }
14
+ Then { frame.content == "THE NEW CONTENT" }
15
+ end
16
+ end
17
+
18
+ context "width" do
19
+ context "one line" do
20
+ Given(:frame) { Frame.new("123456") }
21
+ Then { frame.width == 6 }
22
+ end
23
+ context "multiple lines" do
24
+ Given(:frame) { Frame.new(<<FRAME
25
+ 123
26
+ 12345
27
+ 12
28
+ FRAME
29
+ ) }
30
+ Then { frame.width == 5 }
31
+ end
32
+ end
33
+
34
+ context "height" do
35
+ context "one line" do
36
+ Given(:frame) { Frame.new("LINE 1") }
37
+ Then { frame.height == 1 }
38
+ end
39
+ context "multiple lines" do
40
+ Given(:frame) { Frame.new(<<FRAME
41
+ LINE 1
42
+ LINE 2
43
+ LINE 3
44
+ FRAME
45
+ ) }
46
+ Then { frame.height == 3 }
47
+ end
48
+ end
49
+
50
+ context "each" do
51
+ Given(:content) { "a\nb\nc\n" }
52
+ Given(:frame) { Frame.new(content) }
53
+ Then {
54
+ frame.each
55
+ .zip(content.each_line)
56
+ .all?{ |actual, expected|
57
+ actual == expected
58
+ }
59
+ }
60
+ Then { frame.is_a? Enumerable }
61
+ end
62
+
63
+ context "#to_s" do
64
+ Given(:frame) { Frame.new("FRAME CONTENT") }
65
+ Then { frame.to_s == "FRAME CONTENT" }
66
+ end
67
+ end
68
+ end
@@ -76,7 +76,7 @@ module TRecs
76
76
  context "content at time" do
77
77
  Given(:screen) { double.as_null_object }
78
78
  Given(:ticker) { OpenStruct.new }
79
- Given(:reader) { CustomReader.new(0 => "a", 100 => "b", 200 => "c") }
79
+ Given(:reader) { CustomReader.new(100 => "b", 0 => "a", 200 => "c") }
80
80
 
81
81
  Given(:player) {
82
82
  Player.new(reader: reader, ticker: ticker, screen: screen)
@@ -3,6 +3,6 @@ require "readers/json_reader"
3
3
 
4
4
  module TRecs
5
5
  describe JsonReader do
6
- Then { skip("Test JsonReader") }
6
+ skip("Test JsonReader")
7
7
  end
8
8
  end
@@ -3,6 +3,6 @@ require "readers/yaml_store_reader"
3
3
 
4
4
  module TRecs
5
5
  describe YamlStoreReader do
6
- Then { skip("Test YamlStoreReader") }
6
+ skip("Test YamlStoreReader")
7
7
  end
8
8
  end
@@ -207,44 +207,63 @@ module TRecs
207
207
  end
208
208
 
209
209
  context "Offset" do
210
+ context "initialization" do
211
+ context "from constructor" do
212
+ Given(:recorder) { Recorder.new(offset: 10, writer: OpenStruct.new, strategy: OpenStruct.new) }
213
+ Then { recorder.offset == 10 }
214
+ end
215
+
216
+ context "setter" do
217
+ Given(:recorder) { Recorder.new(offset: 10, writer: OpenStruct.new, strategy: OpenStruct.new) }
218
+ When { recorder.offset = 30 }
219
+ Then { recorder.offset == 30 }
220
+ end
221
+ end
222
+
210
223
  Given { Spy.clear }
211
224
  Given(:writer) { Spy.new("Writer").ignore(:recorder=, :setup, :render) }
212
225
  Given(:strategy) { CustomStrategy.new }
213
226
 
214
227
  Given(:recorder) {
215
- Recorder.new(writer: writer, strategy: strategy, offset: 7)
228
+ Recorder.new(offset: 7, writer: writer, strategy: strategy, step: 10)
216
229
  }
217
230
 
218
- context "setting current frame and time with content duplicates" do
219
- When {
220
- strategy.action = -> {
221
- recorder.current_frame(time: 0, content: "CONTENT")
222
- recorder.current_frame(time: 10, content: "CONTENT 2")
223
- recorder.current_frame(time: 12, content: "CONTENT 3")
224
- }
225
- recorder.record
226
- }
227
-
228
- Then {
229
- writer.calls[1] == [
230
- :create_frame,
231
- [ { time: 7, content: "CONTENT" } ]
232
- ]
233
- }
234
- Then {
235
- writer.calls[2] == [
236
- :create_frame,
237
- [ { time: 17, content: "CONTENT 2" } ]
238
- ]
239
- }
240
- Then {
241
- writer.calls[3] == [
242
- :create_frame,
243
- [ { time: 19, content: "CONTENT 3" } ]
244
- ]
231
+ When {
232
+ strategy.action = -> {
233
+ recorder.current_frame(time: 0, content: "CONTENT")
234
+ recorder.current_frame(time: 10, content: "CONTENT 2")
235
+ recorder.current_frame(time: 12, content: "CONTENT 3")
236
+ recorder.current_frame( content: "CONTENT 4")
245
237
  }
246
- end
238
+ recorder.record
239
+ }
247
240
 
241
+ Then {
242
+ writer.calls[1] == [
243
+ :create_frame,
244
+ [ { time: 7, content: "CONTENT" } ]
245
+ ]
246
+ }
247
+ Then {
248
+ writer.calls[2] == [
249
+ :create_frame,
250
+ [ { time: 17, content: "CONTENT 2" } ]
251
+ ]
252
+ }
253
+ Then {
254
+ writer.calls[3] == [
255
+ :create_frame,
256
+ [ { time: 19, content: "CONTENT 3" } ]
257
+ ]
258
+ }
259
+ Then { recorder.current_time == 22 }
260
+ Then {
261
+ writer.calls[4] == [
262
+ :create_frame,
263
+ [ { time: 29, content: "CONTENT 4" } ]
264
+ ]
265
+ }
248
266
  end
267
+
249
268
  end
250
269
  end
@@ -0,0 +1,129 @@
1
+ require "spec_helper"
2
+ require "recording_strategies/config_strategy"
3
+ require "recorder"
4
+ require "recording_strategies/hash_strategy"
5
+ require "writers/in_memory_writer"
6
+
7
+ module TRecs
8
+ describe ConfigStrategy do
9
+ context "options" do
10
+
11
+ context "set values" do
12
+
13
+ Given(:options) {
14
+ {
15
+ step: 40,
16
+ format: "yaml_store",
17
+ strategies: [],
18
+ spureous_option: "something spureous",
19
+ }
20
+ }
21
+
22
+ Given(:strategy) { ConfigStrategy.new(options) }
23
+
24
+ Then { strategy.step == 40 }
25
+ Then { strategy.format == "yaml_store" }
26
+ Then { strategy.strategies == [] }
27
+ end
28
+
29
+ context "default values" do
30
+ Given(:strategy) { ConfigStrategy.new }
31
+
32
+ Then { strategy.step == 100 }
33
+ Then { strategy.format == "json" }
34
+ Then { strategy.strategies == [] }
35
+ end
36
+ end
37
+
38
+ context "strategies" do
39
+ context "adding strategies" do
40
+ Given(:strategy) { ConfigStrategy.new(strategies: [first_strategy]) }
41
+ Given(:first_strategy) { Object.new }
42
+ Given(:second_strategy) { Object.new }
43
+ Given(:third_strategy) { Object.new }
44
+
45
+ context "just one" do
46
+ Then { strategy.strategies == [first_strategy] }
47
+ end
48
+
49
+ context "adding later" do
50
+ context "one by one" do
51
+ When { strategy << second_strategy }
52
+ When { strategy << third_strategy }
53
+
54
+ Then { strategy.strategies == [
55
+ first_strategy,
56
+ second_strategy,
57
+ third_strategy,
58
+ ] }
59
+ end
60
+
61
+ context "in bulk" do
62
+ When { strategy << [second_strategy, third_strategy] }
63
+
64
+ Then { strategy.strategies == [
65
+ first_strategy,
66
+ second_strategy,
67
+ third_strategy,
68
+ ] }
69
+ end
70
+ end
71
+
72
+ context "#perform" do
73
+ Given(:writer) { InMemoryWriter.new }
74
+ Given(:recorder) { Recorder.new(strategy: strategy, writer: writer) }
75
+
76
+ When { strategy.recorder = recorder }
77
+ When { recorder.record }
78
+
79
+ context "one strategy" do
80
+ Given(:s) { HashStrategy.new(
81
+ {
82
+ 0 => "A",
83
+ 100 => "B",
84
+ 200 => "C",
85
+ }
86
+ ) }
87
+
88
+ Given(:strategy) { ConfigStrategy.new(strategies: [s]) }
89
+
90
+ Then { writer.frames[0] == "A" }
91
+ Then { writer.frames[100] == "B" }
92
+ Then { writer.frames[200] == "C" }
93
+ end
94
+
95
+ context "two strategies" do
96
+ Given(:s1) { HashStrategy.new(
97
+ {
98
+ 0 => "A",
99
+ 10 => "B",
100
+ 20 => "C",
101
+ }
102
+ )
103
+ }
104
+
105
+ Given(:s2) { HashStrategy.new(
106
+ {
107
+ 0 => "D",
108
+ 15 => "E",
109
+ 30 => "F",
110
+ }
111
+ )
112
+ }
113
+
114
+ Given(:strategy) { ConfigStrategy.new(strategies: [s1, s2]) }
115
+
116
+ Then { writer.frames[0] == "A" }
117
+ Then { writer.frames[10] == "B" }
118
+ Then { writer.frames[20] == "C" }
119
+
120
+ Then { writer.frames[120] == "D" }
121
+ Then { writer.frames[135] == "E" }
122
+ Then { writer.frames[150] == "F" }
123
+ end
124
+
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end