has_media 0.0.4

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.
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