has_media 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,6 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
6
+ generators/**/*.rb
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2009 AF83
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = has_media
2
+
3
+ Media Managment Library for ActiveRecord and Carrierwave
4
+
5
+ Easy way to link media (ie image, audio, pdf for now) on other activerecords models
6
+
7
+ === Create migrations
8
+
9
+ ./script/generate has_media
10
+
11
+ == Usage
12
+
13
+ has_one_medium :image, :only => :image
14
+ has_many_media :images, :only => :image
15
+
16
+ has_one_medium :audio, :only => :audio
17
+ has_many_media :audios, :only => :audio
18
+
19
+ has_one_medium :image_no_encode, :only => :image, :encode => false
20
+
21
+ has_one_medium :pdf, :encode => false
22
+
23
+ == TODO
24
+
25
+ * Add a video class
26
+
27
+ == Contributors
28
+
29
+ klacointe, spk, shingara, nono
30
+
31
+ == Copyright
32
+
33
+ Copyright (c) 2009 AF83. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "has_media"
8
+ gem.summary = %Q{Media Managment Library for ActiveRecord and Carrierwave}
9
+ gem.description = %Q{Media Managment Library for ActiveRecord and Carrierwave}
10
+ gem.email = "kevinlacointe@gmail.com"
11
+ gem.homepage = "http://github.com/AF83/has_media"
12
+ gem.authors = ["klacointe", "spk"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency('carrierwave', '>=0.4.2')
15
+ gem.add_dependency('activerecord', '>=2.3.4')
16
+ gem.add_dependency('activesupport', '>=2.3.4')
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "has_media #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
@@ -0,0 +1,8 @@
1
+ class HasMediaGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template('create_media.rb', 'db/migrate', :migration_file_name => 'create_media')
5
+ m.migration_template('create_media_links.rb', 'db/migrate', :migration_file_name => 'create_media_links')
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ class CreateMedia < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :media do |t|
4
+ t.integer :width
5
+ t.integer :height
6
+ t.integer :size
7
+ t.string :content_type # required
8
+ t.string :url
9
+ t.string :filename # required
10
+ t.string :thumbnail
11
+ t.integer :encode_status # required
12
+ t.string :type # required
13
+ t.string :status
14
+ t.string :context # required
15
+ t.timestamps
16
+ end
17
+ add_index :media, :encode_status
18
+ add_index :media, [:type, :context]
19
+ end
20
+
21
+ def self.down
22
+ drop_table :media
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ class CreateMediaLinks < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :media_links do |t|
4
+ t.integer :medium_id # required
5
+ t.integer :mediated_id # required
6
+ t.string :mediated_type # required
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :media_links, :medium_id
11
+ add_index :media_links, [:mediated_id, :mediated_type]
12
+ end
13
+
14
+ def self.down
15
+ drop_table :media_links
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ class HasMediaGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template('create_media.rb', 'db/migrate', :migration_file_name => 'create_media')
5
+ m.migration_template('create_media_links.rb', 'db/migrate', :migration_file_name => 'create_media_links')
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class Audio < Medium
2
+ set_table_name 'media'
3
+
4
+ mount_uploader :file, AudioUploader
5
+
6
+ def self.handle_content_type?(content_type)
7
+ content_type.starts_with? 'audio/'
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class Image < Medium
2
+ set_table_name 'media'
3
+
4
+ mount_uploader :file, ImageUploader
5
+
6
+ def self.handle_content_type?(content_type)
7
+ content_type.starts_with? 'image/'
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class MediaLink < ActiveRecord::Base
2
+ belongs_to :medium, :dependent => :destroy
3
+ end
4
+
@@ -0,0 +1,166 @@
1
+ class Medium < ActiveRecord::Base
2
+ set_table_name 'media'
3
+
4
+ has_many :media_links, :foreign_key => :medium_id, :dependent => :destroy
5
+ has_many :mediated, :through => :media_links
6
+
7
+ mount_uploader :file, MediumUploader
8
+
9
+ validates_presence_of :context
10
+
11
+ attr_accessible :label, :description
12
+
13
+ ENCODE_WAIT = 0
14
+ ENCODE_ENCODING = 1
15
+ ENCODE_SUCCESS = 2
16
+ ENCODE_FAILURE = 3
17
+ ENCODE_NOT_READY = 4
18
+ NO_ENCODING = 5
19
+
20
+ EXTENSIONS = {
21
+ :image => 'png',
22
+ :audio => 'mp3',
23
+ :pdf => 'pdf',
24
+ }
25
+
26
+ # Allowed MIME types for upload
27
+ # need custom configuration
28
+ # TODO: add errors if not type of file
29
+ @@mime_types = {
30
+ :video => ['video/mpeg', 'video/mp4', 'video/quicktime', 'video/x-ms-wmv', 'video/x-flv', 'video/x-msvideo'],
31
+ :image => HasMedia.images_content_types,
32
+ :audio => ['audio/mpeg', 'audio/x-ms-wma', 'audio/x-wav'],
33
+ :flash => ['application/x-shockwave-flash'],
34
+ :pdf => ['application/pdf'],
35
+ }
36
+
37
+ # TODO : check that carrierwave destroy files on after detroy hook
38
+ after_destroy :remove_file_from_fs
39
+ after_initialize :set_default_encoding_status
40
+
41
+
42
+ named_scope :with_context, lambda {|context|
43
+ { :conditions => { :context => context.to_s} }
44
+ }
45
+
46
+ def self.sanitize(name)
47
+ name = name.gsub("\\", "/") # work-around for IE
48
+ name = File.basename(name)
49
+ name = name.gsub(/[^a-zA-Z0-9\.\-\+_]/,"_")
50
+ name = "_#{name}" if name =~ /\A\.+\z/
51
+ name = "unnamed" if name.size == 0
52
+ return name.downcase
53
+ end
54
+
55
+ def self.new_from_value(object, value, context, encode, only)
56
+ only ||= ""
57
+ medium_types = [Image, Audio, Pdf]
58
+ if only != "" and klass = Kernel.const_get(only.capitalize)
59
+ medium_types = [klass]
60
+ end
61
+ klass = medium_types.find do |k|
62
+ if k.respond_to?(:handle_content_type?)
63
+ k.handle_content_type?(value.content_type)
64
+ end
65
+ end
66
+ if klass.nil?
67
+ object.media_errors = [HasMedia.errors_messages[:type_error]]
68
+ return
69
+ end
70
+ medium = klass.new
71
+ medium.filename = self.sanitize(value.original_filename)
72
+ medium.file = value
73
+ medium.content_type = value.content_type
74
+ medium.context = context
75
+ medium.encode_status = (encode == "false" ? NO_ENCODING : ENCODE_WAIT)
76
+ medium.save
77
+ medium
78
+ end
79
+
80
+ ##
81
+ # Is this medium encoding?
82
+ #
83
+ def encoding?
84
+ encode_status == ENCODE_ENCODING
85
+ end
86
+
87
+ ##
88
+ # Is this medium ready?
89
+ #
90
+ def ready?
91
+ encode_status == ENCODE_SUCCESS
92
+ end
93
+
94
+ ##
95
+ # Has the encoding failed for this medium
96
+ #
97
+ def failed?
98
+ encode_status == ENCODE_FAILURE
99
+ end
100
+
101
+ ##
102
+ # Delete media file(s) from disk
103
+ #
104
+ def unlink_files
105
+ file = self.full_filename
106
+ File.unlink(file) if File.exists? file
107
+ end
108
+
109
+ # Public path to the file originally uploaded.
110
+ def original_file_path
111
+ File.join(directory_path, self.filename)
112
+ end
113
+
114
+ # Http uri to the originally file
115
+ def original_file_uri
116
+ File.join(directory_uri, self.filename)
117
+ end
118
+
119
+ # System directory to store files
120
+ def directory_path
121
+ self.file.store_dir
122
+ end
123
+ # system path for a medium
124
+ def file_path(thumbnail = nil)
125
+ final_name = filename.gsub /\.[^.]+$/, '.' + file_extension
126
+ final_name[-4,0] = "_#{thumbnail}" if thumbnail
127
+ File.join(directory_path, final_name)
128
+ end
129
+
130
+ # http uri for a medium
131
+ def file_uri(thumbnail = nil)
132
+ final_name = filename.gsub /\.[^.]+$/, '.' + file_extension
133
+ final_name[-4,0] = "_#{thumbnail}" if thumbnail
134
+ File.join(directory_uri, final_name)
135
+ end
136
+ # http uri of directory which stores media
137
+ def directory_uri
138
+ File.join(HasMedia.directory_uri,
139
+ ActiveSupport::Inflector.underscore(self.type),
140
+ self.id.to_s)
141
+ end
142
+
143
+ def file_exists?(thumbnail = nil)
144
+ File.exist?(File.join(Rails.root, 'public', file_uri(thumbnail)))
145
+ end
146
+
147
+ def file_extension
148
+ EXTENSIONS[type.downcase.to_sym]
149
+ end
150
+
151
+ private
152
+
153
+ ##
154
+ # Set encode_status value to notify the encoder of a new file
155
+ def set_default_encoding_status
156
+ self.encode_status = ENCODE_NOT_READY if filename_changed?
157
+ end
158
+
159
+ ##
160
+ # Unlink the folder containing the files
161
+ # TODO : remove all files, not only the original one
162
+ def remove_file_from_fs
163
+ require 'fileutils'
164
+ FileUtils.rm_rf(self.original_file_path)
165
+ end
166
+ end
@@ -0,0 +1,9 @@
1
+ class Pdf < Medium
2
+ set_table_name 'media'
3
+
4
+ mount_uploader :file, PdfUploader
5
+
6
+ def self.handle_content_type?(content_type)
7
+ content_type.include?('pdf')
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class AudioUploader < MediumUploader
4
+
5
+ # Choose what kind of storage to use for this uploader
6
+ storage :file
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class ImageUploader < MediumUploader
4
+
5
+ # Choose what kind of storage to use for this uploader
6
+ storage :file
7
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ class MediumUploader < CarrierWave::Uploader::Base
4
+
5
+ # Choose what kind of storage to use for this uploader
6
+ storage :file
7
+ # storage :s3
8
+
9
+ # Override the directory where uploaded files will be stored
10
+ # This is a sensible default for uploaders that are meant to be mounted:
11
+ def store_dir
12
+ type = ActiveSupport::Inflector.underscore(model.class.to_s)
13
+ "#{HasMedia.directory_path}/#{type}/#{model.id}"
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ class PdfUploader < MediumUploader
4
+ storage :file
5
+
6
+ # Add a white list of extensions which are allowed to be uploaded
7
+ def extension_white_list
8
+ %w(pdf)
9
+ end
10
+ end
data/lib/has_media.rb ADDED
@@ -0,0 +1,195 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'active_support'
4
+ require 'carrierwave'
5
+
6
+ module HasMedia
7
+
8
+ VERSION = "0.0.1"
9
+
10
+ @@store_dir = '/tmp'
11
+ @@directory_uri = ''
12
+ @@errors_messages = {:type_error => 'Wrong type'}
13
+ @@images_content_types = [
14
+ 'image/jpeg',
15
+ 'image/pjpeg',
16
+ 'image/jpg',
17
+ 'image/gif',
18
+ 'image/png',
19
+ 'image/x-png',
20
+ 'image/jpg',
21
+ 'image/x-ms-bmp',
22
+ 'image/bmp',
23
+ 'image/x-bmp',
24
+ 'image/x-bitmap',
25
+ 'image/x-xbitmap',
26
+ 'image/x-win-bitmap',
27
+ 'image/x-windows-bmp',
28
+ 'image/ms-bmp',
29
+ 'application/bmp',
30
+ 'application/x-bmp',
31
+ 'application/x-win-bitmap',
32
+ 'application/preview',
33
+ 'image/jp_',
34
+ 'application/jpg',
35
+ 'application/x-jpg',
36
+ 'image/pipeg',
37
+ 'image/vnd.swiftview-jpeg',
38
+ 'image/x-xbitmap',
39
+ 'application/png',
40
+ 'application/x-png',
41
+ 'image/gi_',
42
+ 'image/x-citrix-pjpeg'
43
+ ]
44
+
45
+ def self.directory_path=(value)
46
+ @@store_dir = value
47
+ end
48
+ def self.directory_path
49
+ @@store_dir
50
+ end
51
+ def self.directory_uri=(value)
52
+ @@directory_uri = value
53
+ end
54
+ def self.directory_uri
55
+ @@directory_uri
56
+ end
57
+ # taken from http://github.com/technoweenie/attachment_fu/blob/master/lib/technoweenie/attachment_fu.rb
58
+ def self.images_content_types
59
+ @@images_content_types
60
+ end
61
+ def self.errors_messages
62
+ @@errors_messages
63
+ end
64
+ def self.errors_messages=(h)
65
+ @@errors_messages.merge!(h)
66
+ end
67
+
68
+ def self.included(mod)
69
+ mod.extend ClassMethods
70
+ end
71
+
72
+ module ClassMethods
73
+
74
+ def has_one_medium(context, options = {})
75
+ set_relations(context, :has_one)
76
+ set_general_methods
77
+ create_one_accessors(context, options)
78
+ end
79
+
80
+ def has_many_media(context, options = {})
81
+ set_relations(context, :has_many)
82
+ set_general_methods
83
+ create_many_accessors(context, options)
84
+ end
85
+
86
+ def set_general_methods
87
+ @methods_present ||= false
88
+ unless @methods_present
89
+ set_media_links_relation
90
+ set_attributes
91
+ set_validate_methods
92
+ set_callbacks
93
+ end
94
+ @methods_present = true
95
+ end
96
+
97
+ def set_relations(context, relation)
98
+ @contexts ||= {}
99
+ @contexts[relation] ||= []
100
+ @media_relation_set ||= []
101
+ if @contexts[relation].include?(context)
102
+ raise Exception.new("You should NOT use same context identifier for several has_one or has_many relation to media")
103
+ end
104
+ @contexts[relation] << context
105
+ return if @media_relation_set.include? self
106
+ has_many :media, :through => :media_links, :dependent => :destroy
107
+
108
+ @media_relation_set << self
109
+ end
110
+
111
+ def set_callbacks
112
+ validate :merge_media_errors
113
+ before_save :remove_old_media
114
+ end
115
+ def set_attributes
116
+ attr_accessor :media_errors
117
+ end
118
+ def set_validate_methods
119
+ module_eval <<-"end;", __FILE__, __LINE__
120
+ def merge_media_errors
121
+ self.media_errors ||= []
122
+ self.media_errors.each do |error|
123
+ self.errors.add_to_base(error)
124
+ end
125
+ end
126
+ end;
127
+ end
128
+
129
+ def set_media_links_relation
130
+ has_many :media_links, :as => :mediated, :dependent => :destroy
131
+ end
132
+
133
+ def create_one_accessors(context, options)
134
+ #check_conditions = ''
135
+ #check_conditions << "return unless medium.is_a? #{options[:only].to_s.capitalize}" if options.has_key? :only
136
+
137
+ define_method(context) do
138
+ media.with_context(context.to_sym).first
139
+ end
140
+
141
+ module_eval <<-"end;", __FILE__, __LINE__
142
+ def #{context}=(value)
143
+ return if value.blank?
144
+ medium = Medium.new_from_value(self, value, "#{context}", "#{options[:encode]}", "#{options[:only]}")
145
+ if medium
146
+ @old_media ||= []
147
+ @old_media += media.with_context("#{context}")
148
+ media << medium
149
+ end
150
+ end
151
+ end;
152
+ end
153
+
154
+ def create_many_accessors(context, options)
155
+ #check_conditions = ''
156
+ #check_conditions << "return unless medium.is_a? #{options[:only].to_s.capitalize}" if options.has_key? :only
157
+
158
+ define_method(context.to_s.pluralize) do
159
+ media.with_context(context.to_sym).uniq
160
+ end
161
+
162
+ module_eval <<-"end;", __FILE__, __LINE__
163
+ def #{context}=(values)
164
+ return if values.blank?
165
+ Array(values).each do |value|
166
+ next if value.nil?
167
+ medium = Medium.new_from_value(self, value, "#{context}", "#{options[:encode]}", "#{options[:only]}")
168
+ media << medium if medium
169
+ end
170
+ end
171
+ end;
172
+ end
173
+ end
174
+
175
+ def remove_old_media
176
+ (@old_media || []).each do |medium|
177
+ medium.destroy if medium
178
+ end
179
+ end
180
+
181
+ end
182
+
183
+ class ActiveRecord::Base
184
+ include HasMedia
185
+ end
186
+
187
+ require File.dirname(__FILE__) + '/has_media/uploaders/medium_uploader'
188
+ Dir.glob(File.dirname(__FILE__) + '/has_media/uploaders/*.rb').each do |uploader|
189
+ require uploader
190
+ end
191
+
192
+ require File.dirname(__FILE__) + '/has_media/models/medium'
193
+ Dir.glob(File.dirname(__FILE__) + '/has_media/models/*.rb').each do |model|
194
+ require model
195
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,166 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "HasMedia" do
4
+
5
+ before :all do
6
+ class MediumRelatedTest < ActiveRecord::Base
7
+ include HasMedia
8
+ has_one_medium :image, :only => :image
9
+ has_many_media :images, :only => :image
10
+ has_one_medium :audio, :only => :audio
11
+ has_many_media :audios, :only => :audio
12
+ has_one_medium :image_no_encode, :only => :image, :encode => false
13
+ has_one_medium :pdf, :encode => false
14
+ end
15
+ HasMedia.directory_path = 'tmp'
16
+ HasMedia.directory_uri = '/media'
17
+ end
18
+
19
+ before :each do
20
+ @medium = MediumRelatedTest.new
21
+ @image = ActionController::TestUploadedFile.new('spec/fixtures/media/image.jpg', 'image/jpeg')
22
+ @audio = ActionController::TestUploadedFile.new('spec/fixtures/media/audio.wav', 'audio/wav')
23
+ @image_bis = ActionController::TestUploadedFile.new('spec/fixtures/media/image_bis.jpg', 'image/jpeg')
24
+ @pdf = ActionController::TestUploadedFile.new('spec/fixtures/media/Conversational_Capital _Explained.pdf', 'application/pdf')
25
+ end
26
+
27
+ it 'should not have 2 has_one_medium with same context' do
28
+ lambda {
29
+ class Prout < ActiveRecord::Base
30
+ include HasMedia
31
+ has_one_medium :prout, :only => :image
32
+ has_one_medium :prout, :only => :audio
33
+ end
34
+ }.should raise_error(Exception)
35
+ end
36
+
37
+ it "should define accessors" do
38
+ @medium.methods.should include("image")
39
+ @medium.methods.should include("images")
40
+ @medium.methods.should include("audio")
41
+ @medium.methods.should include("audios")
42
+ @medium.methods.should include("pdf")
43
+ end
44
+
45
+ it "should define setters" do
46
+ @medium.methods.should include("image=")
47
+ @medium.methods.should include("images=")
48
+ @medium.methods.should include("audio=")
49
+ @medium.methods.should include("audios=")
50
+ @medium.methods.should include("pdf=")
51
+ end
52
+
53
+ it "should associate image to mediated object" do
54
+ @medium.image = @image
55
+ @medium.save!
56
+ @medium.image.should_not be_nil
57
+ @medium.image.class.should == Image
58
+ end
59
+
60
+ it "should associate audio to mediated object" do
61
+ @medium.audio = @audio
62
+ @medium.save!
63
+ @medium.audio.should_not be_nil
64
+ @medium.audio.class.should == Audio
65
+ end
66
+
67
+ it "should associate pdf to mediated object" do
68
+ @medium.pdf = @pdf
69
+ @medium.save!
70
+ @medium.pdf.should_not be_nil
71
+ @medium.pdf.class.should == Pdf
72
+ end
73
+
74
+ it "should add both audio and image " do
75
+ @medium.image = @image
76
+ @medium.audio = @audio
77
+ @medium.save!
78
+ @medium.audio.should_not be_nil
79
+ @medium.audio.class.should == Audio
80
+ @medium.audio.filename.should == @audio.original_filename
81
+ @medium.audio.content_type.should == "audio/wav"
82
+ @medium.audio
83
+ @medium.image.should_not be_nil
84
+ @medium.image.class.should == Image
85
+ @medium.image.filename.should == @image.original_filename
86
+ @medium.image.content_type.should == "image/jpeg"
87
+ end
88
+
89
+ it "should replace media when in has_one_medium relations" do
90
+ @medium.image = @image_bis
91
+ @medium.save
92
+ @medium.image.filename.should == @image_bis.original_filename
93
+ @medium.image = @image
94
+ @medium.save
95
+ @medium.image.filename.should == @image.original_filename
96
+ end
97
+
98
+ it "should destroy files from fs when Related Model is destroyed" do
99
+ @medium.image = @image
100
+ @medium.save!
101
+ path = @medium.image.original_file_path
102
+ File.exist?(path).should be_true
103
+ @medium.destroy
104
+ File.exist?(path).should be_false
105
+ end
106
+
107
+ [:encoding?, :ready?, :failed?].each do |method|
108
+ [:image, :audio, :images, :audios].each do |context|
109
+ class_eval %{
110
+ it "should responds to #{context}.#{method}" do
111
+ @medium.send("#{context}=", @#{context})
112
+ @medium.save!
113
+ media = @medium.send("#{context}")
114
+ if media.is_a? Array
115
+ media.each do |medium|
116
+ [true, false].include?(medium.send("#{method}"))
117
+ end
118
+ else
119
+ [true, false].include?(media.send("#{method}"))
120
+ end
121
+ end
122
+ }
123
+ end
124
+ end
125
+
126
+ it "should add several has_many_media for the same context" do
127
+ @medium.images = [@image, @image_bis]
128
+ @medium.save!
129
+ @medium.media.size.should == 2
130
+ end
131
+
132
+ it "should have the right encode status" do
133
+ @medium.image_no_encode = @image
134
+ @medium.save!
135
+ @medium.image_no_encode.encode_status.should == Medium::NO_ENCODING
136
+ @medium.image = @image_bis
137
+ @medium.save!
138
+ @medium.image.encode_status.should == Medium::ENCODE_WAIT
139
+ end
140
+
141
+ it "should have an original uri" do
142
+ @medium.image = @image
143
+ @medium.save!
144
+ @medium.image.original_file_uri.should == File.join(HasMedia.directory_uri,
145
+ ActiveSupport::Inflector.underscore(@medium.image.type),
146
+ @medium.image.id.to_s,
147
+ @medium.image.filename)
148
+ end
149
+
150
+ it "pdf should exist" do
151
+ @medium.pdf = @pdf
152
+ @medium.save!
153
+ path = @medium.pdf.file_path
154
+ File.exist?(path).should be_true
155
+ end
156
+
157
+ it "should add errors on parent model if type is not allowed" do
158
+ @image = ActionController::TestUploadedFile.new('spec/fixtures/media/image.jpg', 'image/jpeg')
159
+ @medium.audio = @image
160
+ @medium.valid?
161
+ @medium.should_not be_valid
162
+ @medium.save.should be_false
163
+ @medium.errors.full_messages.include?(HasMedia.errors_messages[:type_error])
164
+ end
165
+
166
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --backtrace
@@ -0,0 +1,53 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'spec'
4
+ require 'spec/autorun'
5
+ require 'rubygems'
6
+ require 'action_controller'
7
+ require 'action_controller/test_process'
8
+ require 'has_media'
9
+
10
+ dbconfig = {
11
+ :adapter => 'sqlite3',
12
+ :database => ':memory:',
13
+ # :database => 'has_media.sqlite'
14
+ }
15
+
16
+ ActiveRecord::Base.establish_connection(dbconfig)
17
+ ActiveRecord::Migration.verbose = false
18
+ #ActiveRecord::Base.logger = Logger.new(STDOUT)
19
+ class TestMigration < ActiveRecord::Migration
20
+ def self.up
21
+ create_table :medium_related_tests, :force => true do |t|
22
+ t.string :name
23
+ end
24
+ create_table :prouts, :force => true do |t|
25
+ t.string :name
26
+ end
27
+ create_table :media, :force => true do |t|
28
+ t.string :context
29
+ t.string :content_type
30
+ t.string :filename
31
+ t.integer :encode_status
32
+ t.string :type
33
+ t.timestamps
34
+ end
35
+ create_table :media_links, :force => true do |t|
36
+ t.integer :medium_id
37
+ t.integer :mediated_id
38
+ t.string :mediated_type
39
+ t.timestamps
40
+ end
41
+ end
42
+ def self.down
43
+ drop_table :medium_related_tests
44
+ drop_table :media
45
+ drop_table :media_links
46
+ end
47
+ end
48
+
49
+ Spec::Runner.configure do |config|
50
+ config.before(:all) { TestMigration.up }
51
+ config.after(:all) { TestMigration.down }
52
+ config.after(:each) { Medium.destroy_all; MediaLink.destroy_all; MediumRelatedTest.destroy_all; }
53
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: has_media
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - klacointe
8
+ - spk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-01-08 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.2.9
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: carrierwave
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.4.2
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: activerecord
38
+ type: :runtime
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.3.4
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ type: :runtime
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.3.4
55
+ version:
56
+ description: Media Managment Library for ActiveRecord and Carrierwave
57
+ email: kevinlacointe@gmail.com
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ extra_rdoc_files:
63
+ - LICENSE
64
+ - README.rdoc
65
+ files:
66
+ - .document
67
+ - .gitignore
68
+ - LICENSE
69
+ - README.rdoc
70
+ - Rakefile
71
+ - VERSION
72
+ - generators/has_media/has_media_generator.rb
73
+ - generators/has_media/templates/create_media.rb
74
+ - generators/has_media/templates/create_media_links.rb
75
+ - generators/has_media_generator.rb
76
+ - lib/has_media.rb
77
+ - lib/has_media/models/audio.rb
78
+ - lib/has_media/models/image.rb
79
+ - lib/has_media/models/media_link.rb
80
+ - lib/has_media/models/medium.rb
81
+ - lib/has_media/models/pdf.rb
82
+ - lib/has_media/uploaders/audio_uploader.rb
83
+ - lib/has_media/uploaders/image_uploader.rb
84
+ - lib/has_media/uploaders/medium_uploader.rb
85
+ - lib/has_media/uploaders/pdf_uploader.rb
86
+ - spec/fixtures/media/Conversational_Capital _Explained.pdf
87
+ - spec/fixtures/media/audio.wav
88
+ - spec/fixtures/media/image.jpg
89
+ - spec/fixtures/media/image_bis.jpg
90
+ - spec/fixtures/media/lc_pdf_overview_format.pdf
91
+ - spec/has_media_spec.rb
92
+ - spec/spec.opts
93
+ - spec/spec_helper.rb
94
+ has_rdoc: true
95
+ homepage: http://github.com/AF83/has_media
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options:
100
+ - --charset=UTF-8
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ version:
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: "0"
114
+ version:
115
+ requirements: []
116
+
117
+ rubyforge_project:
118
+ rubygems_version: 1.3.5
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Media Managment Library for ActiveRecord and Carrierwave
122
+ test_files:
123
+ - spec/spec_helper.rb
124
+ - spec/has_media_spec.rb