trecs 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
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