fogged 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +34 -0
- data/app/controllers/fogged/resources_controller.rb +259 -0
- data/app/jobs/fogged/resources/zencoder_poll_job.rb +39 -0
- data/app/models/fogged/resource.rb +153 -0
- data/app/models/fogged/resources/aws_encoder.rb +64 -0
- data/app/models/fogged/resources/encoder.rb +13 -0
- data/app/serializers/fogged/resource_serializer.rb +35 -0
- data/config/locales/en.yml +6 -0
- data/config/locales/fr.yml +6 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20141103143408_create_fogged_resources.rb +20 -0
- data/lib/fogged.rb +46 -0
- data/lib/fogged/acts_as_having_many_resources.rb +30 -0
- data/lib/fogged/acts_as_having_one_resource.rb +34 -0
- data/lib/fogged/engine.rb +50 -0
- data/lib/fogged/version.rb +3 -0
- data/lib/tasks/fogged_tasks.rake +4 -0
- data/test/controllers/fogged/resources_controller/confirm_test.rb +56 -0
- data/test/controllers/fogged/resources_controller/create_test.rb +56 -0
- data/test/controllers/fogged/resources_controller/destroy_test.rb +29 -0
- data/test/controllers/fogged/resources_controller/show_test.rb +35 -0
- data/test/controllers/fogged/resources_controller/update_test.rb +31 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/images_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/image.rb +3 -0
- data/test/dummy/app/models/movie.rb +4 -0
- data/test/dummy/app/models/movie_fogged_resource.rb +4 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/delayed_job +5 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +78 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/fog.rb +1 -0
- data/test/dummy/config/initializers/fogged.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20141104135257_create_images.rb +10 -0
- data/test/dummy/db/migrate/20141104152227_create_movies.rb +9 -0
- data/test/dummy/db/migrate/20141104152345_create_movie_fogged_resources.rb +10 -0
- data/test/dummy/db/migrate/20141105073909_create_delayed_jobs.rb +22 -0
- data/test/dummy/db/schema.rb +72 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +234 -0
- data/test/dummy/log/test.log +20250 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test/controllers/resources_controller/index_test.rb +56 -0
- data/test/dummy/test/models/image_test.rb +24 -0
- data/test/dummy/test/models/movie_test.rb +26 -0
- data/test/fixtures/fogged/resources.yml +31 -0
- data/test/fixtures/images.yml +5 -0
- data/test/fixtures/movie_fogged_resources.yml +19 -0
- data/test/fixtures/movies.yml +8 -0
- data/test/fogged_test.rb +7 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/jobs/fogged/resources/zencoder_poll_job_test.rb +92 -0
- data/test/models/fogged/resource_test.rb +97 -0
- data/test/models/fogged/resources/aws_encoder_test.rb +54 -0
- data/test/models/fogged/resources/encoder_test.rb +18 -0
- data/test/support/concerns/json_test_helper.rb +43 -0
- data/test/support/concerns/resource_test_helper.rb +28 -0
- data/test/test_helper.rb +59 -0
- metadata +354 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 117c0db8e6eced45592f16bb7cbb19aadb026dba
|
4
|
+
data.tar.gz: 5e52387b1f5338038bf2c378d7b4a7ff9217f0a0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 29213f2ad1476ea58e24a488e8c2a422950b27008e596d497714f9d8f65e9ce1f73ead680b7d33ea0c2ce7ae1380ce05172b5777c71c49c4d40607c752643cd1
|
7
|
+
data.tar.gz: 3bff3cc1207dc3f9f28057044ed731cdec712ffed320a14de4896eb5cc0730571e91d70755d90f07b8fe2a3aecf638d4aa5468cf81f51dcf9b78460539debd47
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 Gatemedia.ch
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Fogged'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,259 @@
|
|
1
|
+
# The Resource API. This API has only 3 methods: create, confirm and destroy.
|
2
|
+
#
|
3
|
+
# To create a new resource, call the create method with a filename and a
|
4
|
+
# content_type, you will get a resource as a result. This resource has an
|
5
|
+
# upload_url you can use to put your content. Caution, this url is valid only
|
6
|
+
# for 2 minutes.
|
7
|
+
#
|
8
|
+
# When uploading a resource, two http headers are *mandatory*:
|
9
|
+
# * Content-Type, which *must* be the same value as the one used to create the
|
10
|
+
# resource
|
11
|
+
# * Set the acl to public read. Eg. on AWS send the x-amz-acl header set to
|
12
|
+
# "public-read". This ensures that the resource is publicly readable.
|
13
|
+
#
|
14
|
+
# The upload can fail if these two flags/settings are missing.
|
15
|
+
#
|
16
|
+
# Once you finished uploading the resource, you can confirm it with the method
|
17
|
+
# confirm. You MUST confirm a resource in order to use it elsewhere (eg. in the
|
18
|
+
# Event api). Once confirmed, a resource can't be updated. For example, if you
|
19
|
+
# want to update the resource content, create a new one. A resource has these
|
20
|
+
# fields:
|
21
|
+
#
|
22
|
+
# id - the resource's id
|
23
|
+
# name - the resource's name
|
24
|
+
# upload_url - the secured url where you can upload your content. This link has
|
25
|
+
# already all the correct parameters for S3. Do not change them.
|
26
|
+
# url - the public url where you can read the content
|
27
|
+
# h264_url - the url of the h264 file. Only for video resources
|
28
|
+
# mpeg_url - the url of the mpeg file. Only for video resources
|
29
|
+
# webm_url - the url of the webm file. Only for video resources
|
30
|
+
# thumbnail_urls - the urls of the thumbnails. Only for video resources
|
31
|
+
# encoding_progress - the progress of the encoding in %. Only for video
|
32
|
+
# resources
|
33
|
+
#
|
34
|
+
# Examples
|
35
|
+
#
|
36
|
+
# {
|
37
|
+
# "resource": {
|
38
|
+
# "id": 1,
|
39
|
+
# "upload_url": "https:...",
|
40
|
+
# "url": "https:..."
|
41
|
+
# }
|
42
|
+
# }
|
43
|
+
#
|
44
|
+
# {
|
45
|
+
# "resource": {
|
46
|
+
# "id": 42145,
|
47
|
+
# "name": "Resource 6",
|
48
|
+
# "url": "https://...",
|
49
|
+
# "h264_url": "https://...",
|
50
|
+
# "mpeg_url": "https://...",
|
51
|
+
# "webm_url": "https://...",
|
52
|
+
# "thumbnail_urls": [
|
53
|
+
# "https://...",
|
54
|
+
# "https://...",
|
55
|
+
# "https://...",
|
56
|
+
# "https://...",
|
57
|
+
# "https://..."
|
58
|
+
# ],
|
59
|
+
# "encoding_progress": 0
|
60
|
+
# }
|
61
|
+
# }
|
62
|
+
module Fogged
|
63
|
+
class ResourcesController < Fogged.parent_controller.constantize
|
64
|
+
before_action :select_resourceables, :only => :index
|
65
|
+
before_action :select_resource, :only => %i(confirm destroy show update)
|
66
|
+
|
67
|
+
# List all resources. Parameter type is mandatory. It indicates in which
|
68
|
+
# "context" you want all resources. You can refine the search, using
|
69
|
+
# using parameters type_id or type_ids, which will select the context
|
70
|
+
# objects before retrieving the resources. Pagination options are
|
71
|
+
# available. Search options are available.
|
72
|
+
#
|
73
|
+
# type - the context/type in which the resources search is done. Mandatory
|
74
|
+
# type_id - the specific type id
|
75
|
+
# type_ids - the specific type ids
|
76
|
+
# query - text search (insensitive) on the resource's name
|
77
|
+
#
|
78
|
+
# Example
|
79
|
+
#
|
80
|
+
# GET /api/v1/resources?type=group&ids[]=2&ids[]=3
|
81
|
+
# GET /api/v1/resources?type=group
|
82
|
+
#
|
83
|
+
# Returns an array of Resources found
|
84
|
+
# Raises 400 if the given type is unknown
|
85
|
+
# Raises 500 if an error occurs
|
86
|
+
def index
|
87
|
+
resources = @resourceables.map do |resourceable|
|
88
|
+
resourceable.resources.search(params)
|
89
|
+
end
|
90
|
+
|
91
|
+
render :json => paginate(resources.flatten.uniq),
|
92
|
+
:meta => @meta,
|
93
|
+
:each_serializer => ResourceSerializer
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get the resource.
|
97
|
+
#
|
98
|
+
# id - the resource's id
|
99
|
+
#
|
100
|
+
# Example
|
101
|
+
#
|
102
|
+
# GET /api/v1/resources/123
|
103
|
+
#
|
104
|
+
# Returns the Resource
|
105
|
+
# Raises 404 if the Resource is not found
|
106
|
+
# Raises 500 if an error occurs
|
107
|
+
def show
|
108
|
+
render :json => @resource,
|
109
|
+
:serializer => ResourceSerializer
|
110
|
+
end
|
111
|
+
|
112
|
+
# Create a new resource. You must provide a filename (example: foo.png)
|
113
|
+
# and a content_type (example: "image/png"). This content_type must be the
|
114
|
+
# same as the one used with the upload_url.
|
115
|
+
#
|
116
|
+
# resource - a hash with a name (optional), a filename and a content_type
|
117
|
+
#
|
118
|
+
#
|
119
|
+
# Examples
|
120
|
+
#
|
121
|
+
# POST /api/v1/resources
|
122
|
+
# {
|
123
|
+
# "resource": {
|
124
|
+
# "name": "The ultimate ruby"
|
125
|
+
# "filename": "ruby.png"
|
126
|
+
# "content_type": "image/png"
|
127
|
+
# }
|
128
|
+
# }
|
129
|
+
#
|
130
|
+
# Return the created resource which will be marked as uploading.
|
131
|
+
# Raises 400 if resource params are not valid.
|
132
|
+
# Raises 500 if an error occurs.
|
133
|
+
def create
|
134
|
+
resource = Resource.create!(
|
135
|
+
:name => resource_params.require(:name),
|
136
|
+
:extension => extension(resource_params.require(:filename)),
|
137
|
+
:content_type => resource_params.require(:content_type),
|
138
|
+
:uploading => true
|
139
|
+
)
|
140
|
+
|
141
|
+
render :json => resource,
|
142
|
+
:serializer => ResourceSerializer,
|
143
|
+
:include_upload_url => true
|
144
|
+
end
|
145
|
+
|
146
|
+
# Update a Resource. You can update the name of a Resource or its context
|
147
|
+
# object
|
148
|
+
#
|
149
|
+
# id - the resource's id
|
150
|
+
# resource - the resource params
|
151
|
+
#
|
152
|
+
# Example
|
153
|
+
#
|
154
|
+
# PUT /api/v1/resources/1
|
155
|
+
# {
|
156
|
+
# "resource": {
|
157
|
+
# "name": "Updated"
|
158
|
+
# }
|
159
|
+
# }
|
160
|
+
#
|
161
|
+
# Returns the updated Resource
|
162
|
+
# Raises 400 if the parameters are invalid
|
163
|
+
# Raises 404 if the resource or the context object can't be found
|
164
|
+
# Raises 500 if an error occurs
|
165
|
+
def update
|
166
|
+
@resource.update!(resource_params.permit(:name))
|
167
|
+
|
168
|
+
show
|
169
|
+
end
|
170
|
+
|
171
|
+
# Confirm a resource. You MUST confirm a resource before using it.
|
172
|
+
#
|
173
|
+
# id - the resource id
|
174
|
+
#
|
175
|
+
# Examples
|
176
|
+
#
|
177
|
+
# PUT /api/v1/resources/1/confirm
|
178
|
+
#
|
179
|
+
# Return the confirmed resource. Note that the upload_url will not be
|
180
|
+
# present in the response.
|
181
|
+
# Raises 500 if a server errors occurs
|
182
|
+
def confirm
|
183
|
+
@resource.process!
|
184
|
+
@resource.update!(:uploading => false)
|
185
|
+
show
|
186
|
+
end
|
187
|
+
|
188
|
+
# Destroy a resource. You can choose to destroy a resource. This
|
189
|
+
# will also destroy the content on S3.
|
190
|
+
#
|
191
|
+
# id - the resource id
|
192
|
+
#
|
193
|
+
# Examples
|
194
|
+
#
|
195
|
+
# DELETE /api/v1/resources/1
|
196
|
+
#
|
197
|
+
# Return an empty response with 204(No content)
|
198
|
+
# Raises 500 if a server errors occurs
|
199
|
+
def destroy
|
200
|
+
@resource.destroy!
|
201
|
+
head :no_content
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def select_resourceables
|
207
|
+
ids = params[:type_id] || params[:type_ids]
|
208
|
+
ids = [ids] unless ids.respond_to?(:to_ary)
|
209
|
+
@resourceables = resourceable_clazz.all
|
210
|
+
@resourceables = resourceable_clazz.where(:id => ids) if ids.try(:any?)
|
211
|
+
end
|
212
|
+
|
213
|
+
def resourceable_clazz
|
214
|
+
@_resourceable_clazz ||= resource_type_param.try(:classify)
|
215
|
+
.try(:safe_constantize)
|
216
|
+
unless @_resourceable_clazz
|
217
|
+
fail(ArgumentError, "Unknown resourceable type: #{params[:type]}")
|
218
|
+
end
|
219
|
+
@_resourceable_clazz
|
220
|
+
end
|
221
|
+
|
222
|
+
def resource_type_param
|
223
|
+
params.require(:type)
|
224
|
+
end
|
225
|
+
|
226
|
+
def select_resource
|
227
|
+
@resource = Resource.find(params[:id])
|
228
|
+
end
|
229
|
+
|
230
|
+
def resource_params
|
231
|
+
params.require(:resource).permit(:name, :filename, :content_type)
|
232
|
+
end
|
233
|
+
|
234
|
+
def extension(filename)
|
235
|
+
extension = File.extname(filename)
|
236
|
+
extension.tap { |e| e.slice!(0) }
|
237
|
+
end
|
238
|
+
|
239
|
+
def paginate(result)
|
240
|
+
page = Integer(params[:page] || 1)
|
241
|
+
count = Integer(params[:count] || 50).to_i
|
242
|
+
offset = (page - 1) * count
|
243
|
+
total = result.size
|
244
|
+
@meta = {
|
245
|
+
:pagination => {
|
246
|
+
:total => total,
|
247
|
+
:remaining => [total - offset - count, 0].max
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
case result
|
252
|
+
when Array
|
253
|
+
result.slice(offset, count)
|
254
|
+
else
|
255
|
+
result.limit(count).offset(offset)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Fogged
|
2
|
+
module Resources
|
3
|
+
class ZencoderPollJob < Struct.new(:resource_id)
|
4
|
+
def perform
|
5
|
+
@resource = Fogged::Resource.find(resource_id)
|
6
|
+
update_encoding_progress
|
7
|
+
|
8
|
+
return if @resource.encoding_progress == 100
|
9
|
+
|
10
|
+
frequency = Fogged.zencoder_polling_frequency
|
11
|
+
Delayed::Job.enqueue(self, :run_at => frequency.seconds.from_now)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def update_encoding_progress
|
17
|
+
job = Zencoder::Job.progress(@resource.encoding_job_id)
|
18
|
+
|
19
|
+
case job.body["state"]
|
20
|
+
when "finished"
|
21
|
+
job = Zencoder::Job.details(@resource.encoding_job_id)
|
22
|
+
f = job.body["job"]["output_media_files"][0]
|
23
|
+
@resource.update!(
|
24
|
+
:encoding_progress => 100,
|
25
|
+
:width => f["width"],
|
26
|
+
:height => f["height"],
|
27
|
+
:duration => f["duration_in_ms"].to_f / 1000.0
|
28
|
+
)
|
29
|
+
when "processing", "waiting"
|
30
|
+
@resource.update!(
|
31
|
+
:encoding_progress => job.body["progress"].to_i
|
32
|
+
)
|
33
|
+
else
|
34
|
+
fail(ArgumentError, "Unknown Zencoder job state #{job.body["state"]}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Fogged
|
2
|
+
class Resource < ActiveRecord::Base
|
3
|
+
validates :extension, :content_type, :presence => true
|
4
|
+
|
5
|
+
before_save :ensure_token
|
6
|
+
after_destroy :destroy_fogged_file
|
7
|
+
|
8
|
+
def self.search(params)
|
9
|
+
results = all
|
10
|
+
|
11
|
+
if params[:query]
|
12
|
+
results = results.where(
|
13
|
+
"#{table_name}.name LIKE :query",
|
14
|
+
:query => "%#{params[:query].to_s.downcase}%"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
results
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload_url
|
22
|
+
fogged_file.service.put_object_url(
|
23
|
+
Fogged.resources.key,
|
24
|
+
fogged_file.key,
|
25
|
+
2.minutes.from_now,
|
26
|
+
"Content-Type" => content_type,
|
27
|
+
"x-amz-acl" => "public-read"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def url
|
32
|
+
storage = Fogged.resources
|
33
|
+
storage.service.try(
|
34
|
+
:request_url,
|
35
|
+
:bucket_name => storage.key,
|
36
|
+
:object_name => fogged_name
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def h264_url
|
41
|
+
return unless video?
|
42
|
+
url.gsub(fogged_name, fogged_name_for(:h264))
|
43
|
+
end
|
44
|
+
|
45
|
+
def mpeg_url
|
46
|
+
return unless video?
|
47
|
+
url.gsub(fogged_name, fogged_name_for(:mpeg))
|
48
|
+
end
|
49
|
+
|
50
|
+
def webm_url
|
51
|
+
return unless video?
|
52
|
+
url.gsub(fogged_name, fogged_name_for(:webm))
|
53
|
+
end
|
54
|
+
|
55
|
+
def thumbnail_urls
|
56
|
+
return unless video?
|
57
|
+
5.times.map do |n|
|
58
|
+
url.gsub(fogged_name, fogged_name_for(:thumbnails, n))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def video?
|
63
|
+
content_type.start_with?("video/")
|
64
|
+
end
|
65
|
+
|
66
|
+
def image?
|
67
|
+
content_type.start_with?("image/")
|
68
|
+
end
|
69
|
+
|
70
|
+
def encoding?
|
71
|
+
return false unless video? && encoding_progress.present?
|
72
|
+
encoding_progress < 100
|
73
|
+
end
|
74
|
+
|
75
|
+
def process!
|
76
|
+
find_size! if image?
|
77
|
+
encode! if video?
|
78
|
+
end
|
79
|
+
|
80
|
+
def write(content)
|
81
|
+
fogged_file.body = content
|
82
|
+
fogged_file.save
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def find_size!
|
88
|
+
if Fogged.test_enabled
|
89
|
+
update!(
|
90
|
+
:width => 800,
|
91
|
+
:height => 600
|
92
|
+
)
|
93
|
+
else
|
94
|
+
size = FastImage.size(url)
|
95
|
+
update!(
|
96
|
+
:width => size.first,
|
97
|
+
:height => size.second
|
98
|
+
) unless size.blank?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def encode!
|
103
|
+
return unless Fogged.zencoder_enabled
|
104
|
+
Resources::Encoder.for(self).encode!
|
105
|
+
end
|
106
|
+
|
107
|
+
def ensure_token
|
108
|
+
self.token = generate_token if token.blank?
|
109
|
+
end
|
110
|
+
|
111
|
+
def generate_token
|
112
|
+
loop do
|
113
|
+
a_token = SecureRandom.hex(16)
|
114
|
+
break a_token unless Resource.find_by(:token => a_token)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def fogged_file
|
119
|
+
return @fogged_file if defined?(@fogged_file)
|
120
|
+
|
121
|
+
files = Fogged.resources.files
|
122
|
+
@fogged_file = files.get(fogged_name) || files.create(
|
123
|
+
:key => fogged_name,
|
124
|
+
:body => "",
|
125
|
+
:public => true,
|
126
|
+
:content_type => content_type
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def fogged_name
|
131
|
+
"#{token}.#{extension}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def fogged_name_for(type, number = 0)
|
135
|
+
case type
|
136
|
+
when :h264
|
137
|
+
"#{token}-h264.mp4"
|
138
|
+
when :mpeg
|
139
|
+
"#{token}-mpeg.mp4"
|
140
|
+
when :webm
|
141
|
+
"#{token}-webm.webm"
|
142
|
+
when :thumbnails
|
143
|
+
"#{token}-thumbnail-#{number}.png"
|
144
|
+
else
|
145
|
+
fail(ArgumentError, "Can't get fogged name of #{type}")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def destroy_fogged_file
|
150
|
+
fogged_file.destroy
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|