Use tsm gem for snapshot generation

openid
Marcin Kulik 11 years ago
parent 4e1f01dc99
commit a81d9dadb3

@ -17,6 +17,7 @@ gem 'thin', '~> 1.5.0'
gem 'open4', '~> 1.3.0'
gem 'redcarpet', '~> 2.2.2'
gem 'slim'
gem 'tsm', :git => 'git://github.com/sickill/tsm.git'
# Gems used only for assets and not required
# in production environments by default.

@ -1,3 +1,10 @@
GIT
remote: git://github.com/sickill/tsm.git
revision: 193fc4382e2b295e5be74a8ccfc0b862346b7d4b
specs:
tsm (0.0.1)
ffi (~> 1.8)
GEM
remote: http://rubygems.org/
specs:
@ -348,5 +355,6 @@ DEPENDENCIES
simplecov (~> 0.7.1)
slim
thin (~> 1.5.0)
tsm!
uglifier (>= 1.0.3)
unicorn (~> 4.6.2)

@ -1,105 +1,71 @@
require 'tempfile'
class SnapshotWorker
def perform(asciicast_id)
begin
@asciicast = Asciicast.find(asciicast_id)
prepare_files
convert_to_typescript
attr_reader :asciicast
delay = (@asciicast.duration / 2).to_i
delay = 30 if delay > 30
snapshot = capture_terminal(delay)
def perform(asciicast_id)
@asciicast = Asciicast.find(asciicast_id)
@asciicast.snapshot = snapshot
@asciicast.save!
delay = (asciicast.duration / 2).to_i
delay = 30 if delay > 30
rescue ActiveRecord::RecordNotFound
# oh well...
asciicast.snapshot = create_snapshot(delay)
asciicast.save!
ensure
cleanup
end
rescue ActiveRecord::RecordNotFound
# oh well...
end
def prepare_files
log "preparing files..."
if RUBY_VERSION < '1.9'
in_data_file = Tempfile.new('asciiio-data')
else
in_data_file = Tempfile.new('asciiio-data', :encoding => 'ascii-8bit')
end
in_data_file.write(@asciicast.stdout.read)
in_data_file.close
@in_data_path = in_data_file.path
if RUBY_VERSION < '1.9'
in_timing_file = Tempfile.new('asciiio-timing')
else
in_timing_file = Tempfile.new('asciiio-timing', :encoding => 'ascii-8bit')
end
in_timing_file.write(@asciicast.stdout_timing.read)
in_timing_file.close
@in_timing_path = in_timing_file.path
@out_data_path = @in_data_path + '.ts'
@out_timing_path = @in_timing_path + '.ts'
def create_snapshot(delay)
data = get_data_to_feed(delay)
screen = TSM::Screen.new(asciicast.terminal_columns,
asciicast.terminal_lines)
vte = TSM::Vte.new(screen)
vte.input(data)
screen.snapshot.to_s
end
def convert_to_typescript
log "converting to typescript..."
def get_data_to_feed(delay)
timing = get_timing
stdout = get_stdout
i = 0
time = 0
bytes_to_feed = 0
while time < delay
time += timing[i][0]
bytes_to_feed += timing[i][1]
i += 1
end
system "bash -c './script/convert-to-typescript.sh " +
"#{@in_data_path} #{@in_timing_path} " +
"#{@out_data_path} #{@out_timing_path}'"
raise "Can't convert asciicast ##{@asciicast.id} to typescript" if $? != 0
stdout.bytes.take(bytes_to_feed)
end
def capture_terminal(delay)
log "capturing terminal output..."
def get_timing
lines = unbzip(asciicast.stdout_timing.file.read).lines
capture_command =
"scriptreplay #{@out_timing_path} #{@out_data_path}; sleep 10"
command = "bash -c 'ASCIICAST_ID=#{@asciicast.id} " +
"COLS=#{@asciicast.terminal_columns} " +
"LINES=#{@asciicast.terminal_lines} " +
"COMMAND=\"#{capture_command}\" " +
"DELAY=#{delay} ./script/capture.sh'"
lines = []
pid, stdin, stdout, stderr = open4(command)
while !stdout.eof?
lines << stdout.readline
end
Process.waitpid pid
status = $?.exitstatus
if status != 0
log "Error capturing output: #{lines.join.inspect}", :error
raise "Can't capture output of asciicast ##{@asciicast.id}"
timing = lines.map do |line|
delay, n = line.split
delay = delay.to_f
n = n.to_i
[delay, n]
end
lines.join('')
end
def cleanup
log "cleaning up..."
FileUtils.rm_f([
@in_data_path,
@in_timing_path,
@out_data_path,
@out_timing_path
].compact)
def get_stdout
unbzip(asciicast.stdout.file.read)
end
private
def unbzip(compressed_data)
f = IO.popen "bzip2 -d", "r+"
f.write(compressed_data)
f.close_write
uncompressed_data = f.read
f.close
uncompressed_data
end
def log(text, level = :info)
Rails.logger.send(level, "SnapshotWorker: #{text}")
end

@ -1,17 +0,0 @@
#!/bin/bash
# Usage:
# ASCIICAST_ID=666 COLS=80 LINES=20 COMMAND="df; df; df; sleep 10"
# DELAY=1 ./tmux-save.sh
set -e
unset TMUX
SESSION_NAME=asciiio-thumb-$ASCIICAST_ID-`date +'%s'`
tmux new -s $SESSION_NAME -d -x $COLS -y $LINES "$COMMAND"
sleep $DELAY
tmux capture-pane -t $SESSION_NAME
tmux save-buffer -
tmux kill-session -t $SESSION_NAME &>/dev/null

@ -1,12 +0,0 @@
#!/bin/bash
in_data_file="$1"
in_timing_file="$2"
out_data_file="$3"
out_timing_file="$4"
echo '# Foo' >$out_data_file
bzip2 -c -d $in_data_file >>$out_data_file
(echo 0.0; bzip2 -c -d $in_timing_file | awk '{ print $2; print $1 }' | head -n -1) | xargs -L 2 echo >$out_timing_file

BIN
vendor/bin/tmux vendored

Binary file not shown.

@ -0,0 +1 @@
libtsm.so.1.0.0

@ -0,0 +1 @@
libtsm.so.1.0.0

Binary file not shown.
Loading…
Cancel
Save