trecs 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c70e79d4e4e1ea582f79bf7bcec4b07c9a7f58ab
4
- data.tar.gz: f39499ec8e9709e515436d5138a1744165726c27
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGY1NWJjMWVhZmIyZjkzMjIwMmNmZjU0N2JlMmU5ZWYwODY3YjFhNw==
5
+ data.tar.gz: !binary |-
6
+ MDMyNTg1YTYyOGIxYjRiYTVlOGM3ZWEzNzA0ZTQyYzlmZjZlZGNkNg==
5
7
  SHA512:
6
- metadata.gz: f075f2ba5d1e44ff73dc7c6057e611f89fabe6f1c788fc5d90e97586e952c24fe0bad6c8e5fd2ab9756a6db73b0275e21a644e99c5a9fe02e92c9b3bae777261
7
- data.tar.gz: 97faa57c7ea63c15ef2976984c21e5e4709db60741b1926ee099b3784c9934606984e7683a295544aea706f053062e9b4f000e3ba3af06053deb52b1d0df85b3
8
+ metadata.gz: !binary |-
9
+ YTMzNzQ4ZGFkZDYzNGI4MTRlNTdhYjhmNTFjOGZlZDhhNmU4NWUxNjVmN2Q5
10
+ NTc4ZmNiY2YwZTkzODM1NTBhMTZlYjMyOGE0MjQzZDYxM2FlMWIwMTAxNGM2
11
+ MzhjNDllNDhjYWNkYTk2YWE1MjNmMjA3OTFkMzI2Zjg2ZWIyYzM=
12
+ data.tar.gz: !binary |-
13
+ MDdhYTMwODk1NWMwNzQ1MThkMDEzODQzZjlhMjdkM2U5NGYyYzQ2NDNjNTdk
14
+ YjJmYzZiNmZmZjkzYmRkNjlkZmEyYjA2NGQ5MTRjMGMxY2FkYmNkNDdmZDg5
15
+ YWQ4YzdkNGM2OGVhZTg2Y2JjZTFjYWZiNDBhYmRiOWQzM2JlOWM=
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trecs (0.1.11)
4
+ trecs (0.1.12)
5
+ minitar (~> 0.5.4)
5
6
  trollop (~> 2.0)
6
7
 
7
8
  GEM
@@ -10,6 +11,7 @@ GEM
10
11
  diff-lcs (1.2.5)
11
12
  given_core (3.5.4)
12
13
  sorcerer (>= 0.3.7)
14
+ minitar (0.5.4)
13
15
  rake (10.3.2)
14
16
  rspec (2.99.0)
15
17
  rspec-core (~> 2.99.0)
data/bin/trecs CHANGED
@@ -3,75 +3,55 @@
3
3
  $:.unshift(File.expand_path("../../lib", __FILE__))
4
4
  require "trecs"
5
5
  require "player"
6
+ require "sources/tgz_source"
7
+
6
8
  require "trollop"
7
9
 
10
+ def finish(opts)
11
+ puts "Finished"
12
+ puts "Replay with:"
13
+ puts "trecs #{opts[:trecs_file]}"
14
+ end
15
+
16
+ trap "SIGINT" do
17
+ finish(opts)
18
+ exit rescue nil
19
+ end
8
20
 
9
21
  opts = Trollop::options do
10
22
  version TRecs::VERSION
11
23
 
12
- opt :step, "Time in ms between frames", short: 's', default: 100
13
- opt :format, "File format", type: String, default: "json"
14
- opt :ticker, "Ticker", type: String, default: "clock"
24
+ opt :step, "Time in ms between frames", short: 's', default: 100
25
+ opt :ticker, "Ticker", type: String, default: "clock"
15
26
 
16
- opt :from, "Play from", type: Integer, default: 0
17
- opt :to, "Play to", type: Integer, default: 0
18
- opt :speed, "Playinx speed", type: Float, default: 1.0
27
+ opt :from, "Play from", type: Integer, default: 0
28
+ opt :to, "Play to", type: Integer, default: 0
29
+ opt :speed, "Playing speed", type: Float, default: 1.0
19
30
 
20
- opt :ticker_file, "File to watch", type: String, default: "/tmp/ticker"
21
-
22
- opt :audio, "Play with audio", type: String
31
+ opt :ticker_file, "File to watch", type: String, default: "/tmp/ticker"
23
32
  end
24
33
  opts[:trecs_file] = ARGV[0]
25
34
 
26
- reader_file = "readers/#{opts[:format]}_reader"
27
- require reader_file
28
- reader_class = Kernel.const_get([
29
- "TRecs::",
30
- opts[:format].split(/[-_\s]/).map(&:capitalize),
31
- "Reader"
32
- ].join
33
- )
34
-
35
+ source = TRecs::TgzSource.new(trecs_file: opts.fetch(:trecs_file))
36
+ reader = source.reader(opts)
35
37
 
36
- ticker_separator = '_' unless opts[:ticker] == ''
37
- ticker_file = "tickers/#{opts[:ticker]}#{ticker_separator}ticker"
38
+ ticker_file = "tickers/#{opts[:ticker]}_ticker"
38
39
  require ticker_file
39
- ticker_class = Kernel.const_get([
40
+ ticker_class_name = [
40
41
  "TRecs::",
41
42
  opts[:ticker].split(/[-_\s]/).map(&:capitalize),
42
43
  "Ticker"
43
44
  ].join
44
- )
45
-
46
- ########## AUDIO ##########
47
- def start_sound_player(file_name='sound.ogg')
48
- return unless File.exist?(file_name)
49
- # at_exit { system('stty echo') }
50
- STDOUT.puts "=> Starting sound player..."
51
- @sox_pid = fork do
52
- `play #{file_name} 2>&1`
53
- end
54
- end
55
-
56
- def stop_sound_player
57
- return unless File.exist?(file_name)
58
- STDOUT.puts "=> Stopping sound player..."
59
- Process.waitpid(@sox_pid)
60
- end
61
- ######## END AUDIO ########
62
-
45
+ ticker_class = ticker_class_name.split("::").reduce(Object) { |a, e| a.const_get e }
46
+ ticker = ticker_class.new(opts)
63
47
 
64
48
  player_options = {
65
- reader: reader_class.new(opts),
66
- ticker: ticker_class.new(opts),
49
+ reader: reader,
50
+ ticker: ticker,
67
51
  step: opts[:step],
68
52
  }
69
53
 
70
54
  player = TRecs::Player.new(player_options)
71
-
72
- opts[:audio] && start_sound_player(opts[:audio])
73
55
  player.play
74
56
 
75
- puts "Finished"
76
- puts "Replay with:"
77
- puts "trecs #{opts[:trecs_file]}"
57
+ finish(opts)
data/bin/trecs_record CHANGED
@@ -9,40 +9,31 @@ require "trollop"
9
9
  opts = Trollop::options do
10
10
  version TRecs::VERSION
11
11
 
12
- opt :step, "Time in ms between frames", short: 's', default: 100
13
- opt :format, "File format", type: String, default: "json"
14
- opt :strategy, "Strategy", type: String, default: "incremental"
12
+ opt :step, "Time in ms between frames", short: 's', default: 100
13
+ opt :strategy, "Strategy", type: String, default: "incremental"
15
14
 
16
- opt :message, "Message to record", type: String, default: "TRecs!"
17
- opt :width, "Width", type: Integer, default: 10
18
- opt :command, "Command" , short: "c", type: String
19
- opt :input_file, "File to record", type: String, default: ""
20
- opt :terminal, "Launch terminal", default: true
21
- opt :color, "Record colors", default: true
22
-
23
- opt :audio, "Record audio", type: String
15
+ opt :message, "Message to record", type: String, default: "TRecs!"
16
+ opt :width, "Width", type: Integer, default: 10
17
+ opt :command, "Command" , short: "c", type: String
18
+ opt :input_file, "File to record", type: String, default: ""
19
+ opt :terminal, "Launch terminal", default: true
20
+ opt :color, "Record colors", default: true
24
21
 
22
+ opt :audio, "Record audio", type: String
25
23
  end
26
24
  opts[:trecs_file] = ARGV[0]
27
25
 
28
- writer_file = "writers/#{opts[:format]}_writer"
29
- require writer_file
30
- writer_class = Kernel.const_get([
31
- "TRecs::",
32
- opts[:format].split(/[-_\s]/).map(&:capitalize),
33
- "Writer"
34
- ].join
35
- )
36
-
26
+ require "writers/json_writer"
27
+ writer_class = TRecs::JsonWriter
37
28
 
38
29
  strategy_file = "recording_strategies/#{opts[:strategy]}_strategy"
39
30
  require strategy_file
40
- strategy_class = Kernel.const_get([
31
+ strategy_class_name = [
41
32
  "TRecs::",
42
33
  opts[:strategy].split(/[-_\s]/).map(&:capitalize),
43
34
  "Strategy"
44
35
  ].join
45
- )
36
+ strategy_class = strategy_class_name.split("::").reduce(Object) { |a, e| a.const_get e }
46
37
 
47
38
  ########## AUDIO ##########
48
39
  def start_sound_recording(file_name='sound.ogg')
@@ -66,32 +57,37 @@ end
66
57
 
67
58
  ######## END AUDIO ########
68
59
 
60
+ if strategy_class.to_s == "TRecs::TmuxSessionStrategy" && !ENV['TMUX']
61
+ puts "You need to be inside a tmux session to use the Tmux Session Strategy"
62
+ exit(0)
63
+ end
69
64
 
70
65
  puts "Recording ..."
71
66
 
72
-
73
- if strategy_class.to_s == "TRecs::TtyrecStrategy"
67
+ if strategy_class.to_s == "TRecs::TtyrecStrategy" || strategy_class.to_s == "TRecs::TmuxSessionStrategy"
74
68
  opts[:height], opts[:width] = `stty size`.split(" ").map(&:to_i)
75
69
  opts[:audio] && start_sound_recording(opts[:audio])
70
+
76
71
  system "ttyrec #{opts[:input_file]}" if opts[:terminal]
77
72
  end
78
73
 
74
+ opts[:audio_files] = [opts[:audio]] if opts[:audio]
75
+
79
76
  recorder_options = {
80
77
  writer: writer_class.new(opts),
81
78
  strategy: strategy_class.new(opts),
82
79
  step: opts[:step],
83
80
  }
84
81
 
85
- opts[:audio] && stop_sound_recording
86
82
  RECORDER = TRecs::Recorder.new(recorder_options)
87
83
 
88
84
  trap "SIGINT" do
85
+ opts[:audio] && stop_sound_recording
89
86
  RECORDER.stop
90
87
  end
91
88
 
92
-
93
89
  RECORDER.record
94
90
 
95
91
  puts "Recording finished"
96
92
  puts "Play with:"
97
- puts " trecs #{opts[:trecs_file]}"
93
+ puts "trecs #{opts[:trecs_file]}"
@@ -0,0 +1,37 @@
1
+ module TRecs
2
+ class Frame
3
+ include Enumerable
4
+ attr_accessor :content
5
+ def initialize(content="")
6
+ @content = content
7
+ end
8
+
9
+ def width
10
+ content.each_line.map { |line|
11
+ line.chomp.size
12
+ }.max
13
+ end
14
+
15
+ def height
16
+ content.lines.count
17
+ end
18
+
19
+ def each
20
+ content.each_line
21
+ end
22
+
23
+ def to_s
24
+ content
25
+ end
26
+ alias :to_str :to_s
27
+ end
28
+
29
+ def Frame(value)
30
+ case value
31
+ when Frame then value
32
+ else
33
+ Frame.new(value.to_str)
34
+ end
35
+ end
36
+ module_function :Frame
37
+ end
data/lib/trecs/player.rb CHANGED
@@ -40,7 +40,7 @@ module TRecs
40
40
  end
41
41
 
42
42
  def timestamps
43
- @timestamps ||= reader.timestamps
43
+ @timestamps ||= reader.timestamps.sort
44
44
  end
45
45
 
46
46
  def time_to_play(time)
@@ -1,25 +1,31 @@
1
- require 'json'
2
- require "pathname"
1
+ require "sources/tgz_source"
3
2
 
4
3
  module TRecs
5
4
  class JsonReader
6
5
  attr_accessor :player
7
6
  attr_reader :frames
8
- attr_reader :file
9
7
  attr_reader :timestamps
8
+ attr_reader :source
10
9
 
11
10
  def initialize(options={})
12
- @file = options.fetch(:trecs_file)
13
- json_string = File.read(@file)
14
- @frames = {}
15
- parsed_json = JSON.parse(json_string)
16
- parsed_json.each do |time, content|
17
- @frames[Integer(time)] = content
18
- end
19
-
11
+ trecs_file = options.fetch(:trecs_file)
12
+ @source = options.fetch(:source)
13
+ @frames = get_frames
20
14
  @timestamps = @frames.keys
21
15
  end
22
16
 
17
+ def get_frames
18
+ frames = {}
19
+ source.read do
20
+ json_string = source.read_file("frames.json")
21
+ parsed_json = JSON.parse(json_string)
22
+ parsed_json.each do |time, content|
23
+ frames[Integer(time)] = content
24
+ end
25
+ end
26
+ frames
27
+ end
28
+
23
29
  def setup
24
30
  true
25
31
  end
@@ -32,5 +38,6 @@ module TRecs
32
38
  "<#{self.class}>"
33
39
  end
34
40
  alias :inspect :to_s
41
+
35
42
  end
36
43
  end
@@ -3,42 +3,43 @@ module TRecs
3
3
  attr_reader :writer
4
4
  attr_reader :strategy
5
5
  attr_reader :step
6
- attr_reader :offset
7
6
  attr_reader :recording
8
7
  attr_reader :current_time
9
8
  attr_reader :current_content
10
9
 
10
+ attr_accessor :offset
11
11
 
12
12
  def initialize(options={})
13
- @writer = options.fetch(:writer)
14
- @writer.recorder = self
13
+ @writer = options.fetch(:writer)
14
+ @writer.recorder = self
15
15
 
16
- @strategy = options.fetch(:strategy)
16
+ @strategy = options.fetch(:strategy)
17
17
  @strategy.recorder = self
18
18
 
19
- @step = options.fetch(:step) { 100 }
19
+ @step = options.fetch(:step) { 100 }
20
20
  @offset = options.fetch(:offset) { 0 }
21
- @recording = false
21
+
22
+ @recording = false
22
23
  @current_time = nil
23
24
  end
24
25
 
25
26
  def record
26
- self.current_time = nil
27
- self.recording = true
28
- writer.setup
29
- strategy.perform
30
- writer.render
31
- self.recording = false
27
+ do_record do
28
+ writer.setup
29
+ strategy.perform
30
+ writer.render
31
+ end
32
32
  end
33
33
 
34
34
  def current_frame(options={})
35
- time = options.fetch(:time) { next_timestamp }
35
+ time = options.fetch(:time) { next_timestamp }
36
36
  content = options.fetch(:content)
37
- @current_time = time
37
+
38
+ @current_time = time
38
39
  @current_content = content
39
40
 
40
41
  if @previous_content != content
41
- new_current_time = current_time + offset
42
+ new_current_time = current_time + offset
42
43
  writer.create_frame(time: new_current_time, content: current_content)
43
44
  @previous_content = content
44
45
  end
@@ -58,5 +59,12 @@ module TRecs
58
59
  attr_writer :current_time
59
60
  attr_writer :current_content
60
61
 
62
+ def do_record
63
+ self.current_time = nil
64
+ self.recording = true
65
+ yield
66
+ self.recording = false
67
+ end
68
+
61
69
  end
62
70
  end
@@ -0,0 +1,31 @@
1
+ require "recording_strategies/strategy"
2
+
3
+ module TRecs
4
+ class ConfigStrategy
5
+ include Strategy
6
+ attr_reader :step
7
+ attr_reader :format
8
+ attr_reader :strategies
9
+
10
+ def initialize(options={})
11
+ @step = options.fetch(:step) { 100 }
12
+ @format = options.fetch(:format) { "json" }
13
+ @strategies = options.fetch(:strategies) { [] }
14
+ end
15
+
16
+ def <<(strategies)
17
+ Array(strategies).each do |strategy|
18
+ @strategies << strategy
19
+ end
20
+ end
21
+
22
+ def perform
23
+ strategies.each do |strategy|
24
+ strategy.recorder = recorder
25
+ strategy.perform
26
+ recorder.offset = recorder.next_timestamp
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require "recording_strategies/strategy"
2
+ module TRecs
3
+ class FileFramesStrategy
4
+ include Strategy
5
+ attr_accessor :frames
6
+
7
+ def initialize(dirname)
8
+ @frames = Dir.entries(dirname)
9
+ .select { |d| d =~ /\d+/}
10
+ .each_with_object(Hash.new) do |filename, h|
11
+ h[filename.to_i] = File.read(dirname + "/" + filename)
12
+ end
13
+ end
14
+
15
+ def perform
16
+ @frames.each do |time, content|
17
+ current_time(time)
18
+ current_content(content)
19
+ save_frame
20
+ end
21
+ end
22
+
23
+ def stop
24
+ end
25
+
26
+ def inspect
27
+ "<#{self.class}: frames: #{frames}>"
28
+ end
29
+ end
30
+ end