Load asciicast data via ajax

This commit is contained in:
Marcin Kulik 2012-03-03 18:38:11 +01:00
parent a16c10009a
commit b3e8fbb7df
10 changed files with 64 additions and 28 deletions

View File

@ -9,6 +9,7 @@ gem 'confstruct'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-github'
gem 'bzip2-ruby'
# Gems used only for assets and not required
# in production environments by default.

View File

@ -33,6 +33,7 @@ GEM
arel (3.0.0)
awesome_print (0.4.0)
builder (3.0.0)
bzip2-ruby (0.2.7)
capybara (1.1.2)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@ -204,6 +205,7 @@ PLATFORMS
DEPENDENCIES
awesome_print
bzip2-ruby
capybara
carrierwave
coffee-rails

View File

@ -0,0 +1,4 @@
class AsciiIo.Asciicast extends Backbone.Model
url: ->
"/asciicasts/#{@get('id')}.json"

View File

@ -2,13 +2,20 @@ class AsciiIo.Movie
MIN_DELAY: 0.01
SPEED: 1.0
constructor: (@data, @timing) ->
constructor: (@model) ->
@frameNo = 0
@dataIndex = 0
@currentTime = 0
@processedFramesTime = 0
_.extend(this, Backbone.Events)
isLoaded: ->
@model.get('escaped_stdout_data') != undefined
load: ->
@model.fetch
success: => @play()
play: ->
@nextFrame()
@ -21,13 +28,22 @@ class AsciiIo.Movie
seek: (percent) ->
# TODO
timing: ->
@model.get('stdout_timing_data')
data: ->
unless @_data
@_data = eval "'" + @model.get('escaped_stdout_data') + "'"
@_data
nextFrame: () ->
# return if @currentData.length > 100
if frame = @timing[@frameNo++] # @frameNo += 1
if frame = @timing()[@frameNo++] # @frameNo += 1
[delay, count] = frame
frameData = @data.slice(@dataIndex, @dataIndex + count)
frameData = @data().slice(@dataIndex, @dataIndex + count)
@dataIndex += count
if delay <= @MIN_DELAY

View File

@ -1,7 +1,9 @@
class AsciiIo.PlayerView extends Backbone.View
initialize: (options) ->
@movie = new AsciiIo.Movie(options.data, options.timing)
@movie = new AsciiIo.Movie(@model)
@movie.load()
@terminalView = new AsciiIo.TerminalView(
cols: this.options.cols
lines: this.options.lines
@ -39,4 +41,5 @@ class AsciiIo.PlayerView extends Backbone.View
@terminalView.stopCursorBlink()
play: ->
@movie.play()
if @movie.isLoaded()
@movie.play()

View File

@ -1,4 +1,5 @@
class AsciicastsController < ApplicationController
respond_to :html, :json
def index
@asciicasts = Asciicast.order("created_at DESC")
@ -6,6 +7,7 @@ class AsciicastsController < ApplicationController
def show
@asciicast = Asciicast.find(params[:id])
respond_with @asciicast
end
end

View File

@ -1,31 +1,14 @@
module AsciicastsHelper
def player_data(asciicast)
data = `bzip2 -d -c #{asciicast.stdout.path}`
time = `bzip2 -d -c #{asciicast.stdout_timing.path}`
data_hex_array = data.bytes.map { |b| '\x' + format('%02x', b) }
var_data = "'#{data_hex_array.join}'"
time_lines = time.lines.map do |line|
delay, n = line.split
"[#{delay.to_f}, #{n.to_i}]"
end
var_time = "[#{time_lines.join(',')}]"
<<EOS.html_safe
def player_script(asciicast)
return <<EOS.html_safe
<script>
var data = #{var_data};
var time = #{j var_time};
var cols = #{asciicast.terminal_columns};
var lines = #{asciicast.terminal_lines};
$(function() {
window.player = new AsciiIo.PlayerView({
el: $('.player'),
cols: cols,
lines: lines,
data: data,
timing: time
cols: #{asciicast.terminal_columns},
lines: #{asciicast.terminal_lines},
model: new AsciiIo.Asciicast({ id: #{asciicast.id} })
});
window.player.play();

View File

@ -20,4 +20,27 @@ class Asciicast < ActiveRecord::Base
self.terminal_columns = data['term']['columns']
self.terminal_type = data['term']['type']
end
def as_json(opts = {})
super :methods => [:escaped_stdout_data, :stdout_timing_data]
end
def escaped_stdout_data
if data = stdout.read
Bzip2.uncompress(data).bytes.map { |b| '\x' + format('%02x', b) }.join
else
nil
end
end
def stdout_timing_data
if data = stdout_timing.read
Bzip2.uncompress(data).lines.map do |line|
delay, n = line.split
[delay.to_f, n.to_i]
end
else
nil
end
end
end

View File

@ -13,4 +13,4 @@
<p>But like anything else with Vim, there are always multiple ways of accomplishing the very same thing, so I make no guarantees that there arent simpler ways of getting this done — but I can say that this way gets the job done, and is pretty easy to get working on your own system.</p>
</div>
<%= player_data(@asciicast) %>
<%= player_script(@asciicast) %>

View File

@ -54,3 +54,5 @@ module AsciiIo
config.assets.version = '1.0'
end
end
ActiveRecord::Base.include_root_in_json = false