fogged 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|