trecs 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ tmp/
2
+ doc/todo.org
3
+ /sandbox/*
4
+ /README.html
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.spec ADDED
File without changes
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 2.1.0
3
+ - 2.1.1
4
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
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
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
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
@@ -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,10 @@
1
+ module TRecs
2
+ class RecordingStrategy
3
+ def initialize(recorder:, **optionsx)
4
+ @recorder = recorder
5
+ end
6
+
7
+ private
8
+ attr_reader :recorder
9
+ end
10
+ 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,3 @@
1
+ module TRecs
2
+ VERSION = "0.0.1.alpha"
3
+ 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
@@ -0,0 +1 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
@@ -0,0 +1 @@
1
+ Lorem ipsum dolor sit amet.