Load asciicast data via ajax
This commit is contained in:
parent
a16c10009a
commit
b3e8fbb7df
1
Gemfile
1
Gemfile
@ -9,6 +9,7 @@ gem 'confstruct'
|
|||||||
gem 'omniauth'
|
gem 'omniauth'
|
||||||
gem 'omniauth-twitter'
|
gem 'omniauth-twitter'
|
||||||
gem 'omniauth-github'
|
gem 'omniauth-github'
|
||||||
|
gem 'bzip2-ruby'
|
||||||
|
|
||||||
# Gems used only for assets and not required
|
# Gems used only for assets and not required
|
||||||
# in production environments by default.
|
# in production environments by default.
|
||||||
|
@ -33,6 +33,7 @@ GEM
|
|||||||
arel (3.0.0)
|
arel (3.0.0)
|
||||||
awesome_print (0.4.0)
|
awesome_print (0.4.0)
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
|
bzip2-ruby (0.2.7)
|
||||||
capybara (1.1.2)
|
capybara (1.1.2)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
@ -204,6 +205,7 @@ PLATFORMS
|
|||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
awesome_print
|
awesome_print
|
||||||
|
bzip2-ruby
|
||||||
capybara
|
capybara
|
||||||
carrierwave
|
carrierwave
|
||||||
coffee-rails
|
coffee-rails
|
||||||
|
4
app/assets/javascripts/player/asciicast.js.coffee
Normal file
4
app/assets/javascripts/player/asciicast.js.coffee
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class AsciiIo.Asciicast extends Backbone.Model
|
||||||
|
|
||||||
|
url: ->
|
||||||
|
"/asciicasts/#{@get('id')}.json"
|
@ -2,13 +2,20 @@ class AsciiIo.Movie
|
|||||||
MIN_DELAY: 0.01
|
MIN_DELAY: 0.01
|
||||||
SPEED: 1.0
|
SPEED: 1.0
|
||||||
|
|
||||||
constructor: (@data, @timing) ->
|
constructor: (@model) ->
|
||||||
@frameNo = 0
|
@frameNo = 0
|
||||||
@dataIndex = 0
|
@dataIndex = 0
|
||||||
@currentTime = 0
|
@currentTime = 0
|
||||||
@processedFramesTime = 0
|
@processedFramesTime = 0
|
||||||
_.extend(this, Backbone.Events)
|
_.extend(this, Backbone.Events)
|
||||||
|
|
||||||
|
isLoaded: ->
|
||||||
|
@model.get('escaped_stdout_data') != undefined
|
||||||
|
|
||||||
|
load: ->
|
||||||
|
@model.fetch
|
||||||
|
success: => @play()
|
||||||
|
|
||||||
play: ->
|
play: ->
|
||||||
@nextFrame()
|
@nextFrame()
|
||||||
|
|
||||||
@ -21,13 +28,22 @@ class AsciiIo.Movie
|
|||||||
seek: (percent) ->
|
seek: (percent) ->
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
timing: ->
|
||||||
|
@model.get('stdout_timing_data')
|
||||||
|
|
||||||
|
data: ->
|
||||||
|
unless @_data
|
||||||
|
@_data = eval "'" + @model.get('escaped_stdout_data') + "'"
|
||||||
|
|
||||||
|
@_data
|
||||||
|
|
||||||
nextFrame: () ->
|
nextFrame: () ->
|
||||||
# return if @currentData.length > 100
|
# return if @currentData.length > 100
|
||||||
|
|
||||||
if frame = @timing[@frameNo++] # @frameNo += 1
|
if frame = @timing()[@frameNo++] # @frameNo += 1
|
||||||
[delay, count] = frame
|
[delay, count] = frame
|
||||||
|
|
||||||
frameData = @data.slice(@dataIndex, @dataIndex + count)
|
frameData = @data().slice(@dataIndex, @dataIndex + count)
|
||||||
@dataIndex += count
|
@dataIndex += count
|
||||||
|
|
||||||
if delay <= @MIN_DELAY
|
if delay <= @MIN_DELAY
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
class AsciiIo.PlayerView extends Backbone.View
|
class AsciiIo.PlayerView extends Backbone.View
|
||||||
|
|
||||||
initialize: (options) ->
|
initialize: (options) ->
|
||||||
@movie = new AsciiIo.Movie(options.data, options.timing)
|
@movie = new AsciiIo.Movie(@model)
|
||||||
|
@movie.load()
|
||||||
|
|
||||||
@terminalView = new AsciiIo.TerminalView(
|
@terminalView = new AsciiIo.TerminalView(
|
||||||
cols: this.options.cols
|
cols: this.options.cols
|
||||||
lines: this.options.lines
|
lines: this.options.lines
|
||||||
@ -39,4 +41,5 @@ class AsciiIo.PlayerView extends Backbone.View
|
|||||||
@terminalView.stopCursorBlink()
|
@terminalView.stopCursorBlink()
|
||||||
|
|
||||||
play: ->
|
play: ->
|
||||||
@movie.play()
|
if @movie.isLoaded()
|
||||||
|
@movie.play()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
class AsciicastsController < ApplicationController
|
class AsciicastsController < ApplicationController
|
||||||
|
respond_to :html, :json
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@asciicasts = Asciicast.order("created_at DESC")
|
@asciicasts = Asciicast.order("created_at DESC")
|
||||||
@ -6,6 +7,7 @@ class AsciicastsController < ApplicationController
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
@asciicast = Asciicast.find(params[:id])
|
@asciicast = Asciicast.find(params[:id])
|
||||||
|
respond_with @asciicast
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,31 +1,14 @@
|
|||||||
module AsciicastsHelper
|
module AsciicastsHelper
|
||||||
|
|
||||||
def player_data(asciicast)
|
def player_script(asciicast)
|
||||||
data = `bzip2 -d -c #{asciicast.stdout.path}`
|
return <<EOS.html_safe
|
||||||
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
|
|
||||||
<script>
|
<script>
|
||||||
var data = #{var_data};
|
|
||||||
var time = #{j var_time};
|
|
||||||
var cols = #{asciicast.terminal_columns};
|
|
||||||
var lines = #{asciicast.terminal_lines};
|
|
||||||
$(function() {
|
$(function() {
|
||||||
window.player = new AsciiIo.PlayerView({
|
window.player = new AsciiIo.PlayerView({
|
||||||
el: $('.player'),
|
el: $('.player'),
|
||||||
cols: cols,
|
cols: #{asciicast.terminal_columns},
|
||||||
lines: lines,
|
lines: #{asciicast.terminal_lines},
|
||||||
data: data,
|
model: new AsciiIo.Asciicast({ id: #{asciicast.id} })
|
||||||
timing: time
|
|
||||||
});
|
});
|
||||||
|
|
||||||
window.player.play();
|
window.player.play();
|
||||||
|
@ -20,4 +20,27 @@ class Asciicast < ActiveRecord::Base
|
|||||||
self.terminal_columns = data['term']['columns']
|
self.terminal_columns = data['term']['columns']
|
||||||
self.terminal_type = data['term']['type']
|
self.terminal_type = data['term']['type']
|
||||||
end
|
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
|
end
|
||||||
|
@ -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 aren’t 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>
|
<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 aren’t 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>
|
</div>
|
||||||
|
|
||||||
<%= player_data(@asciicast) %>
|
<%= player_script(@asciicast) %>
|
||||||
|
@ -54,3 +54,5 @@ module AsciiIo
|
|||||||
config.assets.version = '1.0'
|
config.assets.version = '1.0'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ActiveRecord::Base.include_root_in_json = false
|
||||||
|
Loading…
Reference in New Issue
Block a user