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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/app/controllers/fogged/resources_controller.rb +259 -0
  5. data/app/jobs/fogged/resources/zencoder_poll_job.rb +39 -0
  6. data/app/models/fogged/resource.rb +153 -0
  7. data/app/models/fogged/resources/aws_encoder.rb +64 -0
  8. data/app/models/fogged/resources/encoder.rb +13 -0
  9. data/app/serializers/fogged/resource_serializer.rb +35 -0
  10. data/config/locales/en.yml +6 -0
  11. data/config/locales/fr.yml +6 -0
  12. data/config/routes.rb +4 -0
  13. data/db/migrate/20141103143408_create_fogged_resources.rb +20 -0
  14. data/lib/fogged.rb +46 -0
  15. data/lib/fogged/acts_as_having_many_resources.rb +30 -0
  16. data/lib/fogged/acts_as_having_one_resource.rb +34 -0
  17. data/lib/fogged/engine.rb +50 -0
  18. data/lib/fogged/version.rb +3 -0
  19. data/lib/tasks/fogged_tasks.rake +4 -0
  20. data/test/controllers/fogged/resources_controller/confirm_test.rb +56 -0
  21. data/test/controllers/fogged/resources_controller/create_test.rb +56 -0
  22. data/test/controllers/fogged/resources_controller/destroy_test.rb +29 -0
  23. data/test/controllers/fogged/resources_controller/show_test.rb +35 -0
  24. data/test/controllers/fogged/resources_controller/update_test.rb +31 -0
  25. data/test/dummy/Rakefile +6 -0
  26. data/test/dummy/app/assets/javascripts/application.js +13 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/controllers/images_controller.rb +5 -0
  30. data/test/dummy/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy/app/models/image.rb +3 -0
  32. data/test/dummy/app/models/movie.rb +4 -0
  33. data/test/dummy/app/models/movie_fogged_resource.rb +4 -0
  34. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  35. data/test/dummy/bin/bundle +3 -0
  36. data/test/dummy/bin/delayed_job +5 -0
  37. data/test/dummy/bin/rails +4 -0
  38. data/test/dummy/bin/rake +4 -0
  39. data/test/dummy/config.ru +4 -0
  40. data/test/dummy/config/application.rb +23 -0
  41. data/test/dummy/config/boot.rb +5 -0
  42. data/test/dummy/config/database.yml +25 -0
  43. data/test/dummy/config/environment.rb +5 -0
  44. data/test/dummy/config/environments/development.rb +37 -0
  45. data/test/dummy/config/environments/production.rb +78 -0
  46. data/test/dummy/config/environments/test.rb +39 -0
  47. data/test/dummy/config/initializers/assets.rb +8 -0
  48. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/test/dummy/config/initializers/fog.rb +1 -0
  52. data/test/dummy/config/initializers/fogged.rb +7 -0
  53. data/test/dummy/config/initializers/inflections.rb +16 -0
  54. data/test/dummy/config/initializers/mime_types.rb +4 -0
  55. data/test/dummy/config/initializers/session_store.rb +3 -0
  56. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  57. data/test/dummy/config/locales/en.yml +23 -0
  58. data/test/dummy/config/routes.rb +4 -0
  59. data/test/dummy/config/secrets.yml +22 -0
  60. data/test/dummy/db/development.sqlite3 +0 -0
  61. data/test/dummy/db/migrate/20141104135257_create_images.rb +10 -0
  62. data/test/dummy/db/migrate/20141104152227_create_movies.rb +9 -0
  63. data/test/dummy/db/migrate/20141104152345_create_movie_fogged_resources.rb +10 -0
  64. data/test/dummy/db/migrate/20141105073909_create_delayed_jobs.rb +22 -0
  65. data/test/dummy/db/schema.rb +72 -0
  66. data/test/dummy/db/test.sqlite3 +0 -0
  67. data/test/dummy/log/development.log +234 -0
  68. data/test/dummy/log/test.log +20250 -0
  69. data/test/dummy/public/404.html +67 -0
  70. data/test/dummy/public/422.html +67 -0
  71. data/test/dummy/public/500.html +66 -0
  72. data/test/dummy/public/favicon.ico +0 -0
  73. data/test/dummy/test/controllers/resources_controller/index_test.rb +56 -0
  74. data/test/dummy/test/models/image_test.rb +24 -0
  75. data/test/dummy/test/models/movie_test.rb +26 -0
  76. data/test/fixtures/fogged/resources.yml +31 -0
  77. data/test/fixtures/images.yml +5 -0
  78. data/test/fixtures/movie_fogged_resources.yml +19 -0
  79. data/test/fixtures/movies.yml +8 -0
  80. data/test/fogged_test.rb +7 -0
  81. data/test/integration/navigation_test.rb +10 -0
  82. data/test/jobs/fogged/resources/zencoder_poll_job_test.rb +92 -0
  83. data/test/models/fogged/resource_test.rb +97 -0
  84. data/test/models/fogged/resources/aws_encoder_test.rb +54 -0
  85. data/test/models/fogged/resources/encoder_test.rb +18 -0
  86. data/test/support/concerns/json_test_helper.rb +43 -0
  87. data/test/support/concerns/resource_test_helper.rb +28 -0
  88. data/test/test_helper.rb +59 -0
  89. metadata +354 -0
@@ -0,0 +1,64 @@
1
+ module Fogged
2
+ module Resources
3
+ class AWSEncoder < Struct.new(:resource)
4
+ def encode!
5
+ encode_video if resource.video?
6
+ end
7
+
8
+ private
9
+
10
+ def encode_video
11
+ fail(ArgumentError, "Zencoder gem needed") unless defined?(Zencoder)
12
+ fail(ArgumentError, "Delayed Job gem needed") unless defined?(Delayed::Job)
13
+
14
+ job = Zencoder::Job.create(
15
+ :input => resource.url,
16
+ :region => "europe",
17
+ :download_connections => 5,
18
+ :output => output
19
+ )
20
+ resource.update!(
21
+ :encoding_job_id => job.body["id"].to_s,
22
+ :encoding_progress => 0
23
+ )
24
+
25
+ Delayed::Job.enqueue(ZencoderPollJob.new(resource.id))
26
+ end
27
+
28
+ def output
29
+ [
30
+ {
31
+ :url => "s3://#{bucket}/#{fogged_name_for(:h264)}",
32
+ :video_codec => "h264",
33
+ :public => 1,
34
+ :thumbnails => {
35
+ :number => 5,
36
+ :format => "png",
37
+ :base_url => "s3://#{bucket}",
38
+ :filename => "#{resource.token}-thumbnail-{{number}}",
39
+ :public => 1
40
+ }
41
+ },
42
+ {
43
+ :url => "s3://#{bucket}/#{fogged_name_for(:mpeg)}",
44
+ :video_codec => "mpeg4",
45
+ :public => 1
46
+ },
47
+ {
48
+ :url => "s3://#{bucket}/#{fogged_name_for(:webm)}",
49
+ :video_codec => "vp8",
50
+ :public => 1
51
+ }
52
+ ]
53
+ end
54
+
55
+ def bucket
56
+ resource.send(:fogged_file).directory.key
57
+ end
58
+
59
+ def fogged_name_for(type)
60
+ resource.send(:fogged_name_for, type)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ module Fogged
2
+ module Resources
3
+ class Encoder
4
+ def self.for(resource)
5
+ "Fogged::Resources::#{provider_for(resource)}Encoder".constantize.new(resource)
6
+ end
7
+
8
+ def self.provider_for(resource)
9
+ return :AWS if resource.send(:fogged_file).class.to_s.include?("AWS")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Fogged
2
+ class ResourceSerializer < ActiveModel::Serializer
3
+ attributes :id, :name, :upload_url, :url
4
+ attributes :h264_url, :mpeg_url, :webm_url, :thumbnail_urls
5
+ attributes :encoding_progress
6
+
7
+ def include_upload_url?
8
+ options[:include_upload_url]
9
+ end
10
+
11
+ def include_h264_url?
12
+ object.video?
13
+ end
14
+
15
+ def include_mpeg_url?
16
+ object.video?
17
+ end
18
+
19
+ def include_webm_url?
20
+ object.video?
21
+ end
22
+
23
+ def include_thumbnail_urls?
24
+ object.video?
25
+ end
26
+
27
+ def include_encoding_progress?
28
+ object.video?
29
+ end
30
+
31
+ def encoding_progress
32
+ object.encoding_progress || 0
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ en:
2
+ fogged:
3
+ resource:
4
+ still_uploading: is still uploading, please confirm it first
5
+ resources:
6
+ still_uploading: are still uploading, please confirm them first
@@ -0,0 +1,6 @@
1
+ en:
2
+ fogged:
3
+ resource:
4
+ still_uploading: est en cours d'upload, confirmez la resource!
5
+ resources:
6
+ still_uploading: sont en cours d'upload, confirmez les resources!
@@ -0,0 +1,4 @@
1
+ Fogged::Engine.routes.draw do
2
+ resources :resources
3
+ put "resources/:id/confirm" => "resources#confirm"
4
+ end
@@ -0,0 +1,20 @@
1
+ class CreateFoggedResources < ActiveRecord::Migration
2
+ def change
3
+ create_table :fogged_resources do |t|
4
+ t.string :name, :null => false
5
+ t.string :token, :null => false
6
+ t.integer :width
7
+ t.integer :height
8
+ t.string :extension, :null => false
9
+ t.boolean :uploading
10
+ t.string :content_type, :null => false
11
+ t.integer :encoding_progress
12
+ t.string :encoding_job_id
13
+ t.integer :duration
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :fogged_resources, :token
19
+ end
20
+ end
@@ -0,0 +1,46 @@
1
+ Gem.loaded_specs["fogged"].dependencies.select { |d| d.type == :runtime }.each do |d|
2
+ require d.name
3
+ end
4
+
5
+ require "fogged/engine"
6
+ require "fogged/acts_as_having_one_resource"
7
+ require "fogged/acts_as_having_many_resources"
8
+
9
+ module Fogged
10
+ mattr_accessor :provider
11
+ @@provider = nil
12
+
13
+ mattr_accessor :resources
14
+ @@resources = nil
15
+
16
+ mattr_accessor :test_enabled
17
+ @@test_enabled = false
18
+
19
+ # controller
20
+ mattr_accessor :parent_controller
21
+ @@parent_controller = "ApplicationController"
22
+
23
+ # aws
24
+ mattr_accessor :aws_key
25
+ @@aws_key = nil
26
+ mattr_accessor :aws_secret
27
+ @@aws_secret = nil
28
+ mattr_accessor :aws_bucket
29
+ @@aws_bucket = nil
30
+ mattr_accessor :aws_region
31
+ @@aws_region = nil
32
+
33
+ # zencoder
34
+ mattr_accessor :zencoder_enabled
35
+ @@zencoder_enabled = false
36
+ mattr_accessor :zencoder_polling_frequency
37
+ @@zencoder_polling_frequency = 10
38
+
39
+ def self.configure
40
+ yield self
41
+ end
42
+
43
+ def self.test_mode!
44
+ self.test_enabled = true
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module Fogged
2
+ module ActsAsHavingManyResources
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ DEFAULT_OPTIONS = {
7
+ :dependent => :destroy,
8
+ :class_name => "Fogged::Resource"
9
+ }
10
+
11
+ def acts_as_having_many_resources(*args)
12
+ options = args.extract_options!
13
+ unless options.include?(:through)
14
+ fail(ArgumentError, ":through option is mandatory")
15
+ end
16
+ has_many :resources, DEFAULT_OPTIONS.merge(options)
17
+ validate :_check_resources, :unless => "resources.empty?"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def _check_resources
24
+ return if resources.to_a.select(&:uploading).empty?
25
+ errors.add(:resources, I18n.t("fogged.resources.still_uploading"))
26
+ end
27
+ end
28
+ end
29
+
30
+ ActiveRecord::Base.send(:include, Fogged::ActsAsHavingManyResources)
@@ -0,0 +1,34 @@
1
+ module Fogged
2
+ module ActsAsHavingOneResource
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ DEFAULT_OPTIONS = {
7
+ :dependent => :destroy,
8
+ :class_name => "Fogged::Resource"
9
+ }
10
+
11
+ def acts_as_having_one_resource(*args)
12
+ belongs_to :resource, DEFAULT_OPTIONS.merge(args.extract_options!)
13
+ validate :_check_resource, :unless => "resource.blank?"
14
+
15
+ define_method(:resource_id) do
16
+ resource.try(:id)
17
+ end
18
+
19
+ define_method(:resource_id=) do |id|
20
+ self.resource = id.blank? ? nil : Resource.find(id)
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def _check_resource
28
+ return unless resource.uploading
29
+ errors.add(:resource, I18n.t("fogged.resource.still_uploading"))
30
+ end
31
+ end
32
+ end
33
+
34
+ ActiveRecord::Base.send(:include, Fogged::ActsAsHavingOneResource)
@@ -0,0 +1,50 @@
1
+ module Fogged
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Fogged
4
+ config.fogged = Fogged
5
+
6
+ initializer "fogged.detect_zencoder" do
7
+ if defined?(Zencoder) && defined?(Delayed::Job)
8
+ Fogged.zencoder_enabled = true
9
+ end
10
+ end
11
+
12
+ initializer "fogged.resources" do
13
+ unless Fogged.test_enabled
14
+ case Fogged.provider
15
+ when :aws
16
+ fail(ArgumentError, "AWS key is mandatory") unless Fogged.aws_key
17
+ fail(ArgumentError, "AWS secret is mandatory") unless Fogged.aws_secret
18
+ fail(ArgumentError, "AWS bucket is mandatory") unless Fogged.aws_bucket
19
+ storage_options = {
20
+ :provider => "AWS",
21
+ :aws_access_key_id => Fogged.aws_key,
22
+ :aws_secret_access_key => Fogged.aws_secret
23
+ }
24
+ storage_options.merge!(:region => Fogged.aws_region) if Fogged.aws_region
25
+ storage = Fog::Storage.new(storage_options)
26
+
27
+ Fogged.resources = storage.directories.get(Fogged.aws_bucket)
28
+ if Rails.env.test?
29
+ Fog.mock!
30
+ Fogged.resources = storage.directories.create(:key => Fogged.aws_bucket)
31
+ end
32
+ else
33
+ fail(ArgumentError, "Provider #{Fogged.config.provider} is not available!")
34
+ end
35
+ end
36
+ end
37
+
38
+ initializer "fogged.resources.test" do
39
+ if Fogged.test_enabled
40
+ Fog.mock!
41
+ storage = Fog::Storage.new(
42
+ :provider => "AWS",
43
+ :aws_access_key_id => "1234567890",
44
+ :aws_secret_access_key => "1234567890"
45
+ )
46
+ Fogged.resources = storage.directories.create(:key => "test")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module Fogged
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :fogged do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,56 @@
1
+ require "test_helper"
2
+
3
+ module Fogged
4
+ class ResourcesControllerConfirmTest < ActionController::TestCase
5
+ tests ResourcesController
6
+ include ResourceTestHelper
7
+
8
+ test "should confirm resource" do
9
+ resource = fogged_resources(:resource_png)
10
+ FastImage.expects(:size).once.returns([800, 600])
11
+
12
+ put :confirm, :id => resource, :use_route => :fogged
13
+
14
+ assert_json_resource(resource.reload)
15
+ assert_equal 800, resource.width
16
+ assert_equal 600, resource.height
17
+ refute resource.encoding?
18
+ end
19
+
20
+ test "should confirm video resource with zencoder enabled" do
21
+ in_a_fork do
22
+ require "zencoder"
23
+ require "delayed_job_active_record"
24
+
25
+ Fogged.zencoder_enabled = true
26
+
27
+ Zencoder::Job.expects(:create).returns(
28
+ OpenStruct.new(:body => create_output)
29
+ )
30
+ resource = fogged_resources(:resource_mov)
31
+
32
+ assert_difference("Delayed::Job.count") do
33
+ put :confirm, :id => resource, :use_route => :fogged
34
+ end
35
+
36
+ assert_json_resource(resource.reload)
37
+ assert resource.encoding_job_id
38
+ assert resource.encoding?
39
+ end
40
+ end
41
+
42
+ test "should not confirm resource with invalid id" do
43
+ assert_raise(ActiveRecord::RecordNotFound) do
44
+ put :confirm, :id => 123456, :use_route => :fogged
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def create_output
51
+ {
52
+ :id => 1234567890
53
+ }.with_indifferent_access
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ require "test_helper"
2
+
3
+ module Fogged
4
+ class ResourcesControllerCreateTest < ActionController::TestCase
5
+ tests ResourcesController
6
+ include ResourceTestHelper
7
+
8
+ def setup
9
+ super
10
+ @resource_params = {
11
+ :name => "Dummy",
12
+ :filename => "dummy.png",
13
+ :content_type => "image/png"
14
+ }
15
+ end
16
+
17
+ test "should create resource" do
18
+ assert_difference("Resource.count") do
19
+ post :create, :resource => @resource_params, :use_route => :fogged
20
+ end
21
+
22
+ assert_json_resource(Resource.last)
23
+ assert_equal "png", Resource.last.extension
24
+ end
25
+
26
+ test "should not create resource without resource parameter" do
27
+ assert_no_difference("Resource.count") do
28
+ assert_raise(ActionController::ParameterMissing) do
29
+ post :create, :use_route => :fogged
30
+ end
31
+ end
32
+ end
33
+
34
+ %i(filename content_type name).each do |field|
35
+ test "should not create resource without #{field}" do
36
+ assert_no_difference("Resource.count") do
37
+ assert_raise(ActionController::ParameterMissing) do
38
+ post :create,
39
+ :resource => @resource_params.merge(field => ""),
40
+ :use_route => :fogged
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ test "should not create resource with invalid filename" do
47
+ assert_no_difference("Resource.count") do
48
+ assert_raise(ActiveRecord::RecordInvalid) do
49
+ post :create,
50
+ :resource => @resource_params.merge(:filename => "bar"),
51
+ :use_route => :fogged
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end