trecs 0.0.1.alpha
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 +7 -0
- data/.bundle/config +1 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.spec +0 -0
- data/.travis.yml +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +38 -0
- data/LICENCE.txt +22 -0
- data/README.org +44 -0
- data/Rakefile +7 -0
- data/bin/trecs +33 -0
- data/bin/trecs_message +20 -0
- data/bin/trecs_terminal +25 -0
- data/doc/steps.org +18 -0
- data/lib/player.rb +75 -0
- data/lib/players/zip_file_player.rb +56 -0
- data/lib/recorder.rb +68 -0
- data/lib/recorders/message_recorder.rb +18 -0
- data/lib/recorders/ttyrec_recorder.rb +13 -0
- data/lib/recorders/zip_file_recorder.rb +41 -0
- data/lib/recording_strategies/incremental_recording_strategy.rb +25 -0
- data/lib/recording_strategies/ttyrec_recording_strategy.rb +30 -0
- data/lib/recording_strategy.rb +10 -0
- data/lib/screens/terminal_screen.rb +22 -0
- data/lib/timestamps.rb +22 -0
- data/lib/trecs/version.rb +3 -0
- data/sandbox/create_recording.rb +28 -0
- data/sandbox/lipsum_end +1 -0
- data/sandbox/lipsum_start +1 -0
- data/sandbox/record +50 -0
- data/sandbox/record_diff +26 -0
- data/sandbox/record_script_file +45 -0
- data/spec/player_spec.rb +196 -0
- data/spec/recorder_spec.rb +248 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/timestamps_spec.rb +44 -0
- data/spec/trecs_message_spec.rb +125 -0
- data/spec/trecs_spec.rb +110 -0
- data/spec/zip_file_recorder_spec.rb +58 -0
- data/trecs.gemspec +31 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f6e8706df641c011fc594a3589b732af9903e583
|
4
|
+
data.tar.gz: 55584a0ad79f7860e323e92717158cecd52b495d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 87c2377954222bf2af45037321ff28fe74a9ab8a302d0b78e8f3391f08fc2d6a3d07b1e31e38e32c68d64869f73558ee58131470cce8142d704148221623b622
|
7
|
+
data.tar.gz: c4118a76ee41f5c279d0b911a19772fdb8953319c7f7d4b310fbd51e15855f793daab5486c44610b85d1bbd14d439a1b4287d4a08e66598488e1696aa544ccf7
|
data/.bundle/config
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--- {}
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.spec
ADDED
File without changes
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
trecs (0.0.1.alpha)
|
5
|
+
rubyzip (~> 1.0.0)
|
6
|
+
trollop (~> 2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.2.4)
|
12
|
+
given_core (3.5.4)
|
13
|
+
sorcerer (>= 0.3.7)
|
14
|
+
rake (10.3.2)
|
15
|
+
rspec (2.13.0)
|
16
|
+
rspec-core (~> 2.13.0)
|
17
|
+
rspec-expectations (~> 2.13.0)
|
18
|
+
rspec-mocks (~> 2.13.0)
|
19
|
+
rspec-core (2.13.1)
|
20
|
+
rspec-expectations (2.13.0)
|
21
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
22
|
+
rspec-given (3.5.4)
|
23
|
+
given_core (= 3.5.4)
|
24
|
+
rspec (>= 2.12)
|
25
|
+
rspec-mocks (2.13.1)
|
26
|
+
rubyzip (1.0.0)
|
27
|
+
sorcerer (1.0.2)
|
28
|
+
trollop (2.0)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler (~> 1.6)
|
35
|
+
rake
|
36
|
+
rspec (~> 2.12)
|
37
|
+
rspec-given (~> 3.5.4)
|
38
|
+
trecs!
|
data/LICENCE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Federico Iachetti
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.org
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#+TITLE: README.org
|
2
|
+
#+AUTHOR: Federico Martín Iachetti
|
3
|
+
#+EMAIL: iachetti.federico@gmail.com
|
4
|
+
#+LANGUAGE: en
|
5
|
+
#+OPTIONS: H:3 num:t toc:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
|
6
|
+
#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc
|
7
|
+
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
8
|
+
#+EXPORT_SELECT_TAGS: export
|
9
|
+
#+EXPORT_EXCLUDE_TAGS: noexport
|
10
|
+
|
11
|
+
#+BEGIN_EXAMPLE
|
12
|
+
__________
|
13
|
+
/ o \
|
14
|
+
| ____|
|
15
|
+
| |___
|
16
|
+
| ____/
|
17
|
+
_| |
|
18
|
+
_| |===E
|
19
|
+
/\ _| ===E
|
20
|
+
\ \___| |
|
21
|
+
\___ /
|
22
|
+
_____ ____ _/
|
23
|
+
|_ _| _ \ ___ ___ ___
|
24
|
+
| | | |_) / _ \/ __/ __|
|
25
|
+
| | | _ < __/ (__\__ \
|
26
|
+
|_| |_| \_\___|\___|___/
|
27
|
+
|
28
|
+
#+END_EXAMPLE
|
29
|
+
* T-Recs
|
30
|
+
Text Recordings.
|
31
|
+
|
32
|
+
Record screencasts in plain text.
|
33
|
+
|
34
|
+
** Just an Idea
|
35
|
+
The idea is to create a tool that allows to record text somehow and then reproduce it just as you would reproduce a video.
|
36
|
+
|
37
|
+
** Some specifications
|
38
|
+
|
39
|
+
- It should have controls (play, pause, ffw, rew, stop, rec)
|
40
|
+
- It should have some kind of timestamp, so it can be synchronized with other resources
|
41
|
+
- The other resources:
|
42
|
+
+ Audio track
|
43
|
+
+ Video track
|
44
|
+
+ Browser extension (so, if you are recording the development of a web page, you could see in a browser the current snapshot of the page)
|
data/Rakefile
ADDED
data/bin/trecs
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
+
|
5
|
+
require "trollop"
|
6
|
+
|
7
|
+
require "timestamps"
|
8
|
+
require "players/zip_file_player"
|
9
|
+
|
10
|
+
options = Trollop::options do
|
11
|
+
opt :file_name, "File to process", short: 'f', type: String
|
12
|
+
opt :time, "Frame at time", short: 't', type: String
|
13
|
+
opt :current_time, "Returns the current playback time", short: 'c'
|
14
|
+
opt :step, "Time im ms between frames", short: 's', default: 100
|
15
|
+
|
16
|
+
opt :timestamps, "Returns the list of existing frame timestamps"
|
17
|
+
|
18
|
+
opt :testing, "Ticks without waiting. Use this option only for testing purpuses"
|
19
|
+
end
|
20
|
+
|
21
|
+
file_name = options[:file_name]
|
22
|
+
if file_name
|
23
|
+
if File.exist?(file_name)
|
24
|
+
player = TRecs::ZipFilePlayer.new(options)
|
25
|
+
if options[:timestamps]
|
26
|
+
p player.timestamps
|
27
|
+
else
|
28
|
+
player.play
|
29
|
+
end
|
30
|
+
else
|
31
|
+
puts "File #{file_name} does not exist."
|
32
|
+
end
|
33
|
+
end
|
data/bin/trecs_message
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
+
|
5
|
+
require "trollop"
|
6
|
+
|
7
|
+
require "recorders/message_recorder"
|
8
|
+
|
9
|
+
options = Trollop::options do
|
10
|
+
opt :file_name, "File to process", short: 'f', type: String
|
11
|
+
opt :message, "Message to record", short: 'm', type: String
|
12
|
+
opt :step, "Time between frames in milliseconds", short: 's', default: 100
|
13
|
+
end
|
14
|
+
|
15
|
+
if options[:file_name]
|
16
|
+
recorder = TRecs::MessageRecorder.new(options)
|
17
|
+
recorder.record
|
18
|
+
else
|
19
|
+
puts "Please give a file name"
|
20
|
+
end
|
data/bin/trecs_terminal
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
+
|
5
|
+
require "trollop"
|
6
|
+
|
7
|
+
require "recorders/ttyrec_recorder"
|
8
|
+
|
9
|
+
options = Trollop::options do
|
10
|
+
# opt :input_file, "File to process", short: 'i', type: String
|
11
|
+
opt :output_file, "Output file", short: 'o', type: String
|
12
|
+
end
|
13
|
+
|
14
|
+
options[:input_file] ||= "/tmp/ttyrecord"
|
15
|
+
|
16
|
+
if options[:output_file] # && options[:input_file]
|
17
|
+
puts "Recording ..."
|
18
|
+
options[:height], options[:width] = `stty size`.split(" ").map(&:to_i)
|
19
|
+
system "ttyrec #{options[:input_file]}"
|
20
|
+
recorder = TRecs::TtyrecRecorder.new(options)
|
21
|
+
recorder.record
|
22
|
+
puts "Finish Recording ..."
|
23
|
+
else
|
24
|
+
puts "Please give an input and an output file file name"
|
25
|
+
end
|
data/doc/steps.org
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#+OPTIONS: H:3 num:t toc:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
|
2
|
+
#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc
|
3
|
+
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
4
|
+
|
5
|
+
* Crear el binario trecs
|
6
|
+
Ésto es para poder comenzar a testear con código que funcione de una
|
7
|
+
trecs reproduce un archivo *.trecs conformado por un zip y una serie de archivos que representan los frames
|
8
|
+
|
9
|
+
* Extraer Player en su propia clase
|
10
|
+
Hacer que el binario llame directamente a la clase
|
11
|
+
|
12
|
+
* Extraer todo lo relacionado con el formato en particular a una nueva clase
|
13
|
+
Extraer todo lo relacionado con el formato en particular a una nueva clase, dejando sólo lo relacionado con reproducir frames, timestamps en Player
|
14
|
+
|
15
|
+
* Crear clase Screen
|
16
|
+
Screen sería el lugar sonde va a ir a parar el frame para ser visualizado.
|
17
|
+
* Extraer todo lo posible del binario hacia player
|
18
|
+
Hacer que el binario sea una cáscara y que el player sea el verdadero "main"
|
data/lib/player.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "timestamps"
|
2
|
+
require "screens/terminal_screen"
|
3
|
+
|
4
|
+
module TRecs
|
5
|
+
class Player
|
6
|
+
attr_reader :output
|
7
|
+
|
8
|
+
def initialize(time: nil, step: 100, output: TerminalScreen.new, testing: false, **options)
|
9
|
+
@current_time = time
|
10
|
+
@step = step
|
11
|
+
@ticks = time ? Array(time.to_i) : ticks
|
12
|
+
@output = output
|
13
|
+
@testing = testing
|
14
|
+
end
|
15
|
+
|
16
|
+
def play
|
17
|
+
ticks.each do |time|
|
18
|
+
play_frame(time)
|
19
|
+
sleep(sleep_time) unless testing
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def tick(time=current_time)
|
24
|
+
self.current_time = time
|
25
|
+
get_frame(time)
|
26
|
+
end
|
27
|
+
|
28
|
+
def timestamps
|
29
|
+
@timestamps ||= get_timestamps.sort
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_ticks
|
33
|
+
ticks = [0]
|
34
|
+
curr = 0
|
35
|
+
while(curr < timestamps.last.to_i)
|
36
|
+
curr += step
|
37
|
+
ticks << curr
|
38
|
+
end
|
39
|
+
ticks
|
40
|
+
end
|
41
|
+
|
42
|
+
def ticks
|
43
|
+
@ticks ||= generate_ticks
|
44
|
+
end
|
45
|
+
|
46
|
+
def play_frame(time)
|
47
|
+
output.clear
|
48
|
+
output.puts tick(time_at(time))
|
49
|
+
end
|
50
|
+
|
51
|
+
def time_at(time)
|
52
|
+
Timestamps.new(timestamps).time_at(time)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
attr_accessor :current_time
|
57
|
+
attr_reader :step
|
58
|
+
attr_reader :testing
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
def get_timestamps
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_frame(time)
|
67
|
+
""
|
68
|
+
end
|
69
|
+
|
70
|
+
def sleep_time
|
71
|
+
# TODO: Fix this to use the current time
|
72
|
+
@sleep_time ||= (step/1000.0)*0.8
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "zip"
|
2
|
+
require "player"
|
3
|
+
|
4
|
+
module TRecs
|
5
|
+
class ZipFilePlayer < Player
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
def initialize(file_name: "", **options)
|
9
|
+
@file_name = file_name
|
10
|
+
|
11
|
+
create_directory
|
12
|
+
extract_file
|
13
|
+
|
14
|
+
super(**options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# this
|
18
|
+
def get_frame(time)
|
19
|
+
File.read(file_to_read(time))
|
20
|
+
end
|
21
|
+
|
22
|
+
# this
|
23
|
+
def get_timestamps
|
24
|
+
return [] unless file_name
|
25
|
+
Dir.glob("#{dir}/*").each.map do |line|
|
26
|
+
line[/\/(\d++)\Z/, 1].to_i
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
attr_reader :file_name
|
32
|
+
attr_reader :dir
|
33
|
+
|
34
|
+
def file_to_read(time)
|
35
|
+
file_array = []
|
36
|
+
file_array << @dir
|
37
|
+
file_array << "/"
|
38
|
+
file_array << time
|
39
|
+
file_to_read = file_array.join
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_directory
|
43
|
+
@dir = Dir.mktmpdir
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_file
|
47
|
+
Zip::File.open(file_name) do |file|
|
48
|
+
file.each do |f|
|
49
|
+
f.extract "#{dir}/#{f.name}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/recorder.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module TRecs
|
2
|
+
class Recorder
|
3
|
+
attr_writer :current_time
|
4
|
+
attr_reader :step
|
5
|
+
|
6
|
+
def initialize(step: 100, **options)
|
7
|
+
@step = step
|
8
|
+
end
|
9
|
+
|
10
|
+
def next_timestamp
|
11
|
+
@current_time = -step unless @current_time
|
12
|
+
@current_time += step
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_time(time=nil)
|
16
|
+
if time
|
17
|
+
@current_time = time
|
18
|
+
end
|
19
|
+
@current_time
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_content(content=nil)
|
23
|
+
if content
|
24
|
+
@current_content = content
|
25
|
+
end
|
26
|
+
@current_content
|
27
|
+
end
|
28
|
+
|
29
|
+
def current_frame(time: next_timestamp, content:)
|
30
|
+
current_time(time)
|
31
|
+
current_content(content)
|
32
|
+
|
33
|
+
if previous_content != content
|
34
|
+
create_frame
|
35
|
+
self.previous_content = content
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def record
|
40
|
+
start
|
41
|
+
perform_recording
|
42
|
+
finish
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
attr_accessor :recording
|
47
|
+
attr_accessor :previous_content
|
48
|
+
attr_reader :recording_strategy
|
49
|
+
|
50
|
+
def start
|
51
|
+
self.current_time = nil
|
52
|
+
self.recording = true
|
53
|
+
setup
|
54
|
+
end
|
55
|
+
|
56
|
+
def finish
|
57
|
+
render
|
58
|
+
self.recording = false
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_frame
|
62
|
+
end
|
63
|
+
|
64
|
+
def perform_recording
|
65
|
+
recording_strategy.perform
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "timestamps"
|
2
|
+
|
3
|
+
require "recorders/zip_file_recorder"
|
4
|
+
require "recording_strategies/incremental_recording_strategy"
|
5
|
+
|
6
|
+
|
7
|
+
module TRecs
|
8
|
+
class MessageRecorder < ZipFileRecorder
|
9
|
+
attr_reader :message
|
10
|
+
|
11
|
+
def initialize(message:, **options)
|
12
|
+
@message = message
|
13
|
+
@recording_strategy = IncrementalRecordingStrategy.new(recorder: self, message: message)
|
14
|
+
super(**options)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "timestamps"
|
2
|
+
|
3
|
+
require "recorders/zip_file_recorder"
|
4
|
+
require "recording_strategies/ttyrec_recording_strategy"
|
5
|
+
|
6
|
+
module TRecs
|
7
|
+
class TtyrecRecorder < ZipFileRecorder
|
8
|
+
def initialize(input_file:, output_file:, **options)
|
9
|
+
@recording_strategy = TtyrecRecordingStrategy.new(recorder: self, file: input_file, **options)
|
10
|
+
super(file_name: output_file, **options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "zip"
|
2
|
+
require "recorder"
|
3
|
+
|
4
|
+
module TRecs
|
5
|
+
class ZipFileRecorder < Recorder
|
6
|
+
include FileUtils
|
7
|
+
def initialize(file_name:, **options)
|
8
|
+
super(**options)
|
9
|
+
@file_name = file_name
|
10
|
+
delete_file
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
attr_reader :file_name
|
15
|
+
attr_reader :frames
|
16
|
+
|
17
|
+
# this
|
18
|
+
def setup
|
19
|
+
@frames = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def render
|
23
|
+
Zip::File.open(file_name, Zip::File::CREATE) do |trecs_file|
|
24
|
+
frames.each do |timestamp, content|
|
25
|
+
Tempfile.open(timestamp.to_s) do |temp_file|
|
26
|
+
temp_file.write(content)
|
27
|
+
trecs_file.add(timestamp.to_s, temp_file)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_frame
|
34
|
+
frames[current_time] = current_content
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_file
|
38
|
+
rm file_name if File.exists? file_name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "recording_strategy"
|
2
|
+
module TRecs
|
3
|
+
class IncrementalRecordingStrategy < RecordingStrategy
|
4
|
+
def initialize(message:, **options)
|
5
|
+
@message = message
|
6
|
+
super(**options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform
|
10
|
+
message.each_char.each_with_object("") do |current_char, current_msg|
|
11
|
+
current_msg << current_char
|
12
|
+
|
13
|
+
time = timestamp_for(current_msg)
|
14
|
+
content = current_msg.dup
|
15
|
+
recorder.current_frame(time: time, content: content)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
private
|
19
|
+
attr_reader :message
|
20
|
+
|
21
|
+
def timestamp_for(message)
|
22
|
+
(message.size - 1) * recorder.step
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "recording_strategy"
|
2
|
+
module TRecs
|
3
|
+
class TtyrecRecordingStrategy < RecordingStrategy
|
4
|
+
def initialize(file:, height: 24, width: 80, **options)
|
5
|
+
@file = File.new(file)
|
6
|
+
@frames = []
|
7
|
+
@full_output = ""
|
8
|
+
@height = height
|
9
|
+
@width = width
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform
|
14
|
+
while !@file.eof?
|
15
|
+
sec, usec, len = @file.read(12).unpack('VVV')
|
16
|
+
@full_output << @file.read(len)
|
17
|
+
|
18
|
+
data_array = @full_output.each_line.to_a
|
19
|
+
height = data_array.size > @height ? @height : 0
|
20
|
+
frame = data_array[-height..-1].join
|
21
|
+
|
22
|
+
prev_timestamp ||= [ sec, usec ].join('.').to_f
|
23
|
+
curr_timestamp = [ sec, usec ].join('.').to_f
|
24
|
+
offset = ((curr_timestamp - prev_timestamp)*1000).to_i
|
25
|
+
|
26
|
+
recorder.current_frame(time: offset, content: frame)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
module TRecs
|
4
|
+
class TerminalScreen < SimpleDelegator
|
5
|
+
def clear
|
6
|
+
puts "\e[H\e[2J"
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@obj = $stdout
|
11
|
+
super(@obj)
|
12
|
+
end
|
13
|
+
|
14
|
+
def __getobj__
|
15
|
+
@obj
|
16
|
+
end
|
17
|
+
|
18
|
+
def __setobj__(obj)
|
19
|
+
@obj = obj
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/timestamps.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class Timestamps
|
2
|
+
attr_reader :collection
|
3
|
+
|
4
|
+
def initialize(collection)
|
5
|
+
@collection = collection
|
6
|
+
end
|
7
|
+
|
8
|
+
def time_at(time=0)
|
9
|
+
time = time.to_s.to_i
|
10
|
+
return 0 if collection.empty?
|
11
|
+
return collection.first if time <= collection.first
|
12
|
+
return collection.last if time >= collection.last
|
13
|
+
collection.each_cons(2) do |a, b|
|
14
|
+
if b == time
|
15
|
+
return b
|
16
|
+
end
|
17
|
+
if b > time
|
18
|
+
return a
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require 'zip'
|
3
|
+
|
4
|
+
include FileUtils
|
5
|
+
def create_recording(file_name: "")
|
6
|
+
rm file_name if File.exists? file_name
|
7
|
+
recording_dir = "./frames"
|
8
|
+
rm_rf recording_dir
|
9
|
+
mkdir_p recording_dir
|
10
|
+
|
11
|
+
yield recording_dir
|
12
|
+
|
13
|
+
files_to_record = Dir.glob("#{recording_dir}/*")
|
14
|
+
|
15
|
+
Zip::File.open(file_name, Zip::File::CREATE) do |trecs_file|
|
16
|
+
files_to_record.each do |file_to_rec|
|
17
|
+
dest_file_name = File.basename(file_to_rec)
|
18
|
+
trecs_file.add(dest_file_name, file_to_rec)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
rm_rf Dir.glob("#{recording_dir}")
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_frame(content: "", time: 0)
|
25
|
+
File.open("./frames/#{time.to_i}", File::WRONLY|File::CREAT) do |f|
|
26
|
+
f << content
|
27
|
+
end
|
28
|
+
end
|
data/sandbox/lipsum_end
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
@@ -0,0 +1 @@
|
|
1
|
+
Lorem ipsum dolor sit amet.
|