enigmamachine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.document +5 -0
  2. data/.gitignore +26 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +32 -0
  5. data/Rakefile +57 -0
  6. data/VERSION +1 -0
  7. data/bin/enigmamachine +15 -0
  8. data/lib/enigmamachine/config.ru +9 -0
  9. data/lib/enigmamachine/encoding_queue.rb +29 -0
  10. data/lib/enigmamachine/models/encoder.rb +54 -0
  11. data/lib/enigmamachine/models/encoding_task.rb +19 -0
  12. data/lib/enigmamachine/models/video.rb +37 -0
  13. data/lib/enigmamachine/public/default.css +233 -0
  14. data/lib/enigmamachine/public/images/Enigma-logo.jpg +0 -0
  15. data/lib/enigmamachine/public/images/bg01.jpg +0 -0
  16. data/lib/enigmamachine/public/images/bg02.jpg +0 -0
  17. data/lib/enigmamachine/public/images/bg03.jpg +0 -0
  18. data/lib/enigmamachine/public/images/bg04.jpg +0 -0
  19. data/lib/enigmamachine/public/images/img02.gif +0 -0
  20. data/lib/enigmamachine/public/images/img03.gif +0 -0
  21. data/lib/enigmamachine/public/images/img04.gif +0 -0
  22. data/lib/enigmamachine/public/images/img05.gif +0 -0
  23. data/lib/enigmamachine/public/images/img06.jpg +0 -0
  24. data/lib/enigmamachine/public/images/spacer.gif +0 -0
  25. data/lib/enigmamachine/views/encoders/edit.erb +20 -0
  26. data/lib/enigmamachine/views/encoders/encoder.erb +10 -0
  27. data/lib/enigmamachine/views/encoders/encoding_task.erb +10 -0
  28. data/lib/enigmamachine/views/encoders/form.erb +5 -0
  29. data/lib/enigmamachine/views/encoders/index.erb +12 -0
  30. data/lib/enigmamachine/views/encoders/new.erb +19 -0
  31. data/lib/enigmamachine/views/encoders/show.erb +19 -0
  32. data/lib/enigmamachine/views/encoding_tasks/edit.erb +23 -0
  33. data/lib/enigmamachine/views/encoding_tasks/form.erb +12 -0
  34. data/lib/enigmamachine/views/encoding_tasks/new.erb +23 -0
  35. data/lib/enigmamachine/views/index.erb +13 -0
  36. data/lib/enigmamachine/views/layout.erb +67 -0
  37. data/lib/enigmamachine/views/videos/form.erb +11 -0
  38. data/lib/enigmamachine/views/videos/index.erb +36 -0
  39. data/lib/enigmamachine/views/videos/new.erb +19 -0
  40. data/lib/enigmamachine/views/videos/video.erb +6 -0
  41. data/lib/enigmamachine.rb +179 -0
  42. data/lib/enigmamachine.sqlite3 +0 -0
  43. data/lib/ext/array_ext.rb +8 -0
  44. data/lib/ext/partials.rb +28 -0
  45. data/lib/init.rb +75 -0
  46. data/test/helper.rb +49 -0
  47. data/test/support/afile.mpg +0 -0
  48. data/test/support/blueprints.rb +29 -0
  49. data/test/test_encoder.rb +80 -0
  50. data/test/test_encoder_queue.rb +34 -0
  51. data/test/test_enigmamachine.rb +536 -0
  52. data/test/test_video.rb +84 -0
  53. metadata +141 -0
@@ -0,0 +1,23 @@
1
+ <div class="post">
2
+ <h1 class="title">Edit an encoding task</h1>
3
+ <div class="entry">
4
+
5
+ <% unless @encoding_task.errors.empty? %>
6
+ <div class="errors">
7
+ <h2>Errors on Encoding Task</h2>
8
+ <ul>
9
+ <% @encoding_task.errors.each do |error| %>
10
+ <li><%= error %></li>
11
+ <% end %>
12
+ </ul>
13
+ </div>
14
+ <% end %>
15
+
16
+ <form id="task-<%= @encoding_task.id%>-edit" action="/encoding_tasks/<%= @encoding_task.id %>" method="POST">
17
+ <input name="_method" value="PUT" type="hidden"></input>
18
+ <%= partial(:'encoding_tasks/form') %>
19
+ </form>
20
+
21
+ </div>
22
+ </div>
23
+
@@ -0,0 +1,12 @@
1
+ <p><strong>Name:</strong> e.g. <em>encode a 320x240 flv at 25 frames per second</em><br/>
2
+ <input name="encoding_task[name]" id="encoding_task_name" value="<%= @encoding_task.name %>" ></input></p>
3
+
4
+ <p><strong>Output file suffix:</strong> e.g. <em>.flv</em><br/>
5
+ <input name="encoding_task[output_file_suffix]" id="encoding_task_output_file_suffix" value="<%= @encoding_task.output_file_suffix %>" ></input></p>
6
+
7
+ <p><strong>Encoding command:</strong> e.g. <em>-ab 128 -ar 22050 -b 500000 -r 25 -s 320x240<br/>
8
+ <input name="encoding_task[command]" id="encoding_task_command" value="<%= @encoding_task.command %>" size="70"></input></p>
9
+
10
+ <input type="submit" value="Save"/>
11
+ <p><a href="/encoders/<%= @encoding_task.encoder.id %>">cancel</a></p>
12
+
@@ -0,0 +1,23 @@
1
+ <div class="post">
2
+ <h1 class="title">New encoding task</h1>
3
+ <div class="entry">
4
+
5
+
6
+ <% unless @encoding_task.errors.empty? %>
7
+ <div class="errors">
8
+ <h2>Errors on Encoding Task</h2>
9
+ <ul>
10
+ <% @encoding_task.errors.each do |error| %>
11
+ <li><%= error %></li>
12
+ <% end %>
13
+ </ul>
14
+ </div>
15
+ <% end %>
16
+
17
+ <p>Create a new encoding task for this encoder</p>
18
+ <form action="/encoding_tasks/<%= @encoding_task.encoder.id %>" method="POST">
19
+ <%= partial(:"encoding_tasks/form")%>
20
+ </form>
21
+
22
+ </div>
23
+ </div>
@@ -0,0 +1,13 @@
1
+ <div class="post">
2
+ <h1 class="title">Your enigma machine</h1>
3
+ <div class="entry">
4
+ <p>It is encoding some videos.</p>
5
+ <% unless @videos.empty? %>
6
+ <p>Here are the next videos which will be encoded:</p>
7
+ <ul>
8
+ <%= partial :'videos/video', :collection => @videos %>
9
+ </ul>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <!--
3
+ Design by Free CSS Templates
4
+ http://www.freecsstemplates.org
5
+ Released for free under a Creative Commons Attribution 2.5 License
6
+
7
+ Name : Unqualified
8
+ Description: A two-column, fixed-width design.
9
+ Version : 1.0
10
+ Released : 20071220
11
+
12
+ -->
13
+ <html xmlns="http://www.w3.org/1999/xhtml">
14
+ <head>
15
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
16
+ <title>Enigma Admin</title>
17
+ <meta name="keywords" content="" />
18
+ <meta name="description" content="" />
19
+ <link href="/default.css" rel="stylesheet" type="text/css" media="screen" />
20
+ </head>
21
+ <body>
22
+ <!-- start header -->
23
+ <div id="header">
24
+ <div id="logo">
25
+ <h1><a href="/">Enigma</a></h1>
26
+ <p>Admin</p>
27
+ </div>
28
+ <div id="menu">
29
+ <ul>
30
+ <li <%= 'class="active"' if request.path_info == "/" %>><a href="/">Home</a></li>
31
+ <li <%= 'class="active"' if request.path_info == "/encoders" %>><a href="/encoders">Available Encoders</a></li>
32
+ <li <%= 'class="active"' if request.path_info == "/encoders/new" %>><a href="/encoders/new">New Encoder</a></li>
33
+ <li <%= 'class="active"' if request.path_info == "/videos" %>><a href="/videos">Videos</a></li>
34
+ </ul>
35
+ </div>
36
+ </div>
37
+ <!-- end header -->
38
+ <!-- start page -->
39
+ <div id="page">
40
+ <!-- start content -->
41
+ <div id="content">
42
+
43
+ <%= yield %>
44
+
45
+ </div>
46
+ <!-- end content -->
47
+ <!-- start sidebar -->
48
+ <div id="sidebar">
49
+ <ul>
50
+ <li>
51
+ <h2>Future Chimp</h2>
52
+ <ul>
53
+ <li><a href="http://futurechimp.org">blog</a></li>
54
+ </ul>
55
+ </li>
56
+ </div>
57
+ <!-- end sidebar -->
58
+ </div>
59
+ <!-- end page -->
60
+
61
+
62
+ <div id="footer">
63
+ <p>Design by <a href="http://www.freecsstemplates.org/">Free CSS Templates</a> &nbsp;&bull;&nbsp; Icons by <a href="http://www.famfamfam.com/">FAMFAMFAM</a>.</p>
64
+ </div>
65
+ </body>
66
+ </html>
67
+
@@ -0,0 +1,11 @@
1
+
2
+ <p><strong>File location:</strong><br/>
3
+ <input name="video[file]" id="video_file" value="<%= @video.file %>" size="50"></input></p>
4
+ <select id="encoder_id" name="encoder_id">
5
+ <% @encoders.each do |e| %>
6
+ <option value="<%= e.id %>"><%= e.name %></option>
7
+ <% end %>
8
+ </select>
9
+ <input type="submit" value="Save"/>
10
+ <p><a href="/videos">cancel</a></p>
11
+
@@ -0,0 +1,36 @@
1
+ <div class="post">
2
+ <h1 class="title">Videos</h1>
3
+ <div class="entry">
4
+
5
+ <p><a href="/videos/new">New video</a></p>
6
+
7
+ <% unless @encoding_videos.empty? %>
8
+ <h2>Currently encoding</h2>
9
+ <ul>
10
+ <%= partial :"videos/video", :collection => @encoding_videos %>
11
+ </ul>
12
+ <% end %>
13
+
14
+ <% unless @unencoded_videos.empty? %>
15
+ <h2>Waiting to encode</h2>
16
+ <ul>
17
+ <%= partial :"videos/video", :collection => @unencoded_videos %>
18
+ </ul>
19
+ <% end %>
20
+
21
+ <% unless @completed_videos.empty? %>
22
+ <h2>Completed</h2>
23
+ <ul>
24
+ <%= partial :"videos/video", :collection => @completed_videos %>
25
+ </ul>
26
+ <% end %>
27
+
28
+ <% unless @videos_with_errors.empty? %>
29
+ <h2>Failed to encode</h2>
30
+ <ul>
31
+ <%= partial :"videos/video", :collection => @videos_with_errors %>
32
+ </ul>
33
+ <% end %>
34
+
35
+ </div>
36
+
@@ -0,0 +1,19 @@
1
+ <div class="post">
2
+ <h1 class="title">Create a new video</h1>
3
+ <div class="entry">
4
+ <% unless @video.errors.empty? %>
5
+ <div class="errors">
6
+ <h2>Errors on video</h2>
7
+ <ul>
8
+ <% @video.errors.each do |error| %>
9
+ <li><%= error %></li>
10
+ <% end %>
11
+ </ul>
12
+ </div>
13
+ <% end %>
14
+
15
+ <form action="/videos" method="POST">
16
+ <%= partial :"videos/form" %>
17
+ </form>
18
+ </div>
19
+
@@ -0,0 +1,6 @@
1
+ <% video = videos_video %>
2
+ <li>
3
+ <%=h video.file %> -
4
+ created at <%=h video.created_at.strftime("%m/%d/%Y at %H:%M:%S")%><br/>
5
+ </li>
6
+
@@ -0,0 +1,179 @@
1
+ require File.dirname(__FILE__) + '/init.rb'
2
+
3
+ # Shows the enigma status page.
4
+ #
5
+ get '/' do
6
+ @videos = Video.all(:limit => 50, :order => [:created_at.asc])
7
+ erb :index
8
+ end
9
+
10
+ # Displays a list of all available encoders.
11
+ #
12
+ get '/encoders' do
13
+ @encoders = Encoder.all
14
+ erb :'encoders/index'
15
+ end
16
+
17
+
18
+ # Displays a form to create a new encoder.
19
+ #
20
+ get '/encoders/new' do
21
+ @encoder = Encoder.new
22
+ erb :'encoders/new'
23
+ end
24
+
25
+
26
+ # Displays an encoder.
27
+ #
28
+ get '/encoders/:id' do |id|
29
+ @encoder = Encoder.get(id)
30
+ @encoding_task = EncodingTask.new
31
+ erb :'encoders/show'
32
+ end
33
+
34
+
35
+ # Displays an edit page for an encoder.
36
+ #
37
+ get '/encoders/:id/edit' do |id|
38
+ @encoder = Encoder.get(id)
39
+ erb :"encoders/edit"
40
+ end
41
+
42
+
43
+ # Creates an encoder.
44
+ #
45
+ post '/encoders' do
46
+ @encoder = Encoder.new(params[:encoder])
47
+ if @encoder.save
48
+ flash[:notice] = "Encoder created."
49
+ redirect "/encoders/#{@encoder.id}"
50
+ else
51
+ erb :'encoders/new'
52
+ end
53
+ end
54
+
55
+
56
+ # Updates an encoder
57
+ #
58
+ put '/encoders/:id' do |id|
59
+ @encoder = Encoder.get(id)
60
+ if @encoder.update(params[:encoder])
61
+ flash[:notice] = "Encoder updated."
62
+ redirect '/encoders'
63
+ else
64
+ erb :"encoders/edit"
65
+ end
66
+ end
67
+
68
+ delete '/encoders/:id' do |id|
69
+ @encoder = Encoder.get(id)
70
+ @encoder.destroy!
71
+ redirect '/encoders'
72
+ end
73
+
74
+
75
+ # Show a form to make a new encoding task
76
+ #
77
+ get '/encoding_tasks/new/:encoder_id' do |encoder_id|
78
+ @encoding_task = EncodingTask.new
79
+ @encoding_task.encoder = Encoder.get(encoder_id)
80
+ erb :'encoding_tasks/new'
81
+ end
82
+
83
+
84
+ # Creates an encoding task.
85
+ #
86
+ post '/encoding_tasks/:encoder_id' do |encoder_id|
87
+ @encoding_task = EncodingTask.new(params[:encoding_task])
88
+ @encoder = Encoder.get(encoder_id)
89
+ @encoding_task.encoder = @encoder
90
+ if @encoding_task.save
91
+ flash[:notice] = "Encoding task created."
92
+ redirect "/encoders/#{@encoding_task.encoder.id}"
93
+ else
94
+ erb :'encoding_tasks/new'
95
+ end
96
+ end
97
+
98
+
99
+ # Gets the edit form for an encoding task
100
+ #
101
+ get '/encoding_tasks/:id/edit' do |id|
102
+ @encoding_task = EncodingTask.get(id)
103
+ erb :'encoding_tasks/edit'
104
+ end
105
+
106
+
107
+ # Updates an encoding task
108
+ #
109
+ put '/encoding_tasks/:id' do |id|
110
+ @encoding_task = EncodingTask.get(id)
111
+ if @encoding_task.update(params[:encoding_task])
112
+ redirect "/encoders/#{@encoding_task.encoder.id}"
113
+ else
114
+ erb :'encoding_tasks/edit'
115
+ end
116
+ end
117
+
118
+ delete '/encoding_tasks/:id' do |id|
119
+ @encoding_task = EncodingTask.get(id)
120
+ @encoder = @encoding_task.encoder
121
+ @encoding_task.destroy!
122
+ redirect "/encoders/#{id}"
123
+ end
124
+
125
+ # Displays a list of available videos
126
+ #
127
+ get '/videos' do
128
+ @completed_videos = Video.complete
129
+ @encoding_videos = Video.encoding
130
+ @videos_with_errors = Video.with_errors
131
+ @unencoded_videos = Video.unencoded
132
+ erb :'videos/index'
133
+ end
134
+
135
+
136
+ # Displays a form for creating a new video
137
+ #
138
+ get '/videos/new' do
139
+ @video = Video.new
140
+ @encoders = Encoder.all
141
+ erb :'videos/new'
142
+ end
143
+
144
+
145
+ # Creates a new video
146
+ #
147
+ post '/videos' do
148
+ @video = Video.new(params[:video])
149
+ @encoder = Encoder.get(params[:encoder_id])
150
+ @video.encoder = @encoder
151
+ if @video.save
152
+ redirect '/videos'
153
+ else
154
+ @encoders = Encoder.all
155
+ erb :'videos/new'
156
+ end
157
+ end
158
+
159
+ def reset_encoding_videos
160
+ Video.encoding.each do |video|
161
+ video.state = "unencoded"
162
+ video.save!
163
+ end
164
+ end
165
+
166
+
167
+ # Starts the enigma encoding thread. The thread will be reabsorbed into the
168
+ # main Sinatra/thin thread once the periodic timer is added.
169
+ #
170
+ Thread.new do
171
+ until EM.reactor_running?
172
+ sleep 1
173
+ end
174
+ reset_encoding_videos
175
+ Log.info(":::: Starting encoder ::::")
176
+ queue = EncodingQueue.new
177
+ queue.start
178
+ end
179
+
Binary file
@@ -0,0 +1,8 @@
1
+
2
+ # Monkey patches
3
+ class Array
4
+ def extract_options!
5
+ last.is_a?(::Hash) ? pop : {}
6
+ end
7
+ end
8
+
@@ -0,0 +1,28 @@
1
+ # An implementation of partials for Sinatra.
2
+ #
3
+ # Can be used like: <%= partial(:foo) %>
4
+ #
5
+ # Unlike Rails partials, the .erb files for these partials do not start with a
6
+ # leading underscore, i.e. the file name should be foo.rb, not _foo.rb.
7
+ #
8
+ # Liberated from:
9
+ # http://github.com/cschneid/irclogger/blob/master/lib/partials.rb
10
+ #
11
+ module Sinatra
12
+ module Partials
13
+ def partial(template, *args)
14
+ options = args.extract_options!
15
+ options.merge!(:layout => false)
16
+ if collection = options.delete(:collection) then
17
+ collection.inject([]) do |buffer, member|
18
+ buffer << erb(template, options.merge(:layout =>
19
+ false, :locals => {template.to_s.gsub!("/", "_").to_sym => member}))
20
+ # check with template.to_s.split("/").last.to_sym => member
21
+ end.join("\n")
22
+ else
23
+ erb(template, options)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
data/lib/init.rb ADDED
@@ -0,0 +1,75 @@
1
+ # Gems
2
+ #
3
+ require 'rubygems'
4
+ require 'sinatra'
5
+ require 'datamapper'
6
+ require 'ruby-debug'
7
+ require 'eventmachine'
8
+ require 'rack-flash'
9
+ require 'logger'
10
+
11
+ # Enigma code
12
+ #
13
+ require File.dirname(__FILE__) + '/enigmamachine'
14
+ require File.dirname(__FILE__) + '/enigmamachine/models/encoder'
15
+ require File.dirname(__FILE__) + '/enigmamachine/models/encoding_task'
16
+ require File.dirname(__FILE__) + '/enigmamachine/models/video'
17
+ require File.dirname(__FILE__) + '/enigmamachine/encoding_queue'
18
+
19
+ # Database config
20
+ #
21
+ configure :production do
22
+ db = "sqlite3:///#{Dir.pwd}/enigmamachine.sqlite3"
23
+ DataMapper.setup(:default, db)
24
+ end
25
+
26
+ configure :development do
27
+ db = "sqlite3:///#{Dir.pwd}/enigmamachine.sqlite3"
28
+ DataMapper.setup(:default, db)
29
+ end
30
+
31
+ configure :test do
32
+ db = "sqlite3::memory:"
33
+ DataMapper.setup(:default, db)
34
+ end
35
+
36
+ Video.auto_migrate! unless Video.storage_exists?
37
+ Encoder.auto_migrate! unless Encoder.storage_exists?
38
+ EncodingTask.auto_migrate! unless EncodingTask.storage_exists?
39
+ DataMapper.auto_upgrade!
40
+
41
+ # Extensions to Sinatra
42
+ #
43
+ require File.dirname(__FILE__) + '/ext/partials'
44
+ require File.dirname(__FILE__) + '/ext/array_ext'
45
+
46
+ # Set the views to the proper path inside the gem
47
+ #
48
+ set :views, File.dirname(__FILE__) + '/enigmamachine/views'
49
+ set :public, File.dirname(__FILE__) + '/enigmamachine/public'
50
+
51
+
52
+ # Register helpers
53
+ #
54
+ helpers do
55
+ include Sinatra::Partials
56
+ alias_method :h, :escape_html
57
+ end
58
+
59
+
60
+ # Set up Rack authentication
61
+ #
62
+ use Rack::Auth::Basic do |username, password|
63
+ [username, password] == ['admin', 'admin']
64
+ end
65
+
66
+ # Include flash notices
67
+ #
68
+ use Rack::Session::Cookie
69
+ use Rack::Flash
70
+
71
+ configure do
72
+ Log = Logger.new("enigma.log")
73
+ Log.level = Logger::INFO
74
+ end
75
+
data/test/helper.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'rack/test'
4
+ require 'base64'
5
+ require 'machinist/data_mapper'
6
+ require 'faker'
7
+ require 'sham'
8
+ set :environment, :test
9
+ set :run, false
10
+ set :raise_errors, true
11
+ set :logging, false
12
+ require File.dirname(__FILE__) + '/../lib/init'
13
+ require File.dirname(__FILE__) + '/../lib/enigmamachine'
14
+ require File.expand_path(File.dirname(__FILE__) + "/support/blueprints")
15
+
16
+
17
+
18
+ module TestHelper
19
+
20
+ def app
21
+ # change to your app class if using the 'classy' style
22
+ Sinatra::Application.new
23
+ end
24
+
25
+ def body
26
+ last_response.body
27
+ end
28
+
29
+ def status
30
+ last_response.status
31
+ end
32
+
33
+ include Rack::Test::Methods
34
+
35
+ end
36
+
37
+ require 'test/unit'
38
+ require 'shoulda'
39
+
40
+ Test::Unit::TestCase.send(:include, TestHelper)
41
+
42
+ def basic_auth_creds(username = 'admin', password = 'admin')
43
+ {'HTTP_AUTHORIZATION'=> encode_credentials(username, password)}
44
+ end
45
+
46
+ def encode_credentials(username, password)
47
+ "Basic " + Base64.encode64("#{username}:#{password}")
48
+ end
49
+
Binary file
@@ -0,0 +1,29 @@
1
+ require 'machinist/data_mapper'
2
+ require 'faker'
3
+ require 'sham'
4
+
5
+ Encoder.blueprint do
6
+ name {"Blah encoder"}
7
+ end
8
+
9
+ Video.blueprint do
10
+ encoder
11
+ file { File.dirname(__FILE__) + "/afile.mpg" }
12
+ state { "unencoded" }
13
+ created_at DateTime.now
14
+ updated_at DateTime.now
15
+ end
16
+
17
+ EncodingTask.blueprint do
18
+ name { "320x240 flv"}
19
+ output_file_suffix { ".foo.flv" }
20
+ command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136 -y"}
21
+ end
22
+
23
+ EncodingTask.blueprint(:with_encoder) do
24
+ name { "320x240 flv"}
25
+ output_file_suffix { ".foo.flv" }
26
+ command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136 -y"}
27
+ encoder
28
+ end
29
+
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestEncoder < Test::Unit::TestCase
4
+
5
+ context "An Encoder instance" do
6
+
7
+ setup do
8
+ @encoder = ::Encoder.make
9
+ end
10
+
11
+ should "be invalid without a name" do
12
+ @encoder.name = ""
13
+ assert !@encoder.valid?
14
+ end
15
+
16
+ should "have an encoding_tasks association" do
17
+ assert @encoder.respond_to? "encoding_tasks"
18
+ end
19
+
20
+ should "allow encoding_tasks to be added" do
21
+ encoder = Encoder.make_unsaved
22
+ task = EncodingTask.make_unsaved
23
+ assert_nothing_raised do
24
+ encoder.encoding_tasks << task
25
+ end
26
+ end
27
+
28
+ context "hitting the ffmpeg method" do
29
+ context "for an encoder with 1 task" do
30
+ setup do
31
+ video = Video.make
32
+ task = EncodingTask.make
33
+ video.encoder.encoding_tasks << task
34
+ video.encoder.save
35
+ video.encoder.encode(video)
36
+ @id = video.id
37
+ sleep 1
38
+ end
39
+
40
+ should "mark the video as encoding" do
41
+ video = Video.get(@id)
42
+ assert_equal "encoding", video.state
43
+ end
44
+
45
+ should_eventually "mark the video as complete" do
46
+ sleep 5
47
+ video = Video.get(@id)
48
+ assert_equal "complete", video.state
49
+ end
50
+
51
+ end
52
+
53
+ context "for an encoder with 2 tasks" do
54
+ setup do
55
+ video = Video.make
56
+ task = EncodingTask.make
57
+ 2.times { video.encoder.encoding_tasks << EncodingTask.make }
58
+ video.encoder.save
59
+ video.encoder.encode(video)
60
+ @id = video.id
61
+ end
62
+
63
+ should "mark the video as encoding" do
64
+ sleep 1
65
+ video = Video.get(@id)
66
+ assert_equal "encoding", video.state
67
+ end
68
+
69
+ should_eventually "mark the video as complete" do
70
+ sleep 1
71
+ video = Video.get(@id)
72
+ assert_equal "complete", video.state
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+