media_magick 0.1.0 → 0.1.1
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/.gitignore +2 -1
- data/.travis.yml +7 -3
- data/CHANGELOG.md +92 -1
- data/README.md +1 -1
- data/app/assets/javascripts/media_magick/plupload_it.js +30 -9
- data/app/controllers/media_magick/attach_controller.rb +16 -28
- data/app/helpers/media_magick/application_helper.rb +46 -5
- data/app/views/_file.html.erb +2 -2
- data/app/views/_image.html.erb +3 -3
- data/app/views/_upload.html.erb +3 -10
- data/app/views/_video.html.erb +8 -0
- data/gemfiles/mongoid-3.0.gemfile +7 -0
- data/lib/media_magick.rb +1 -5
- data/lib/media_magick/controller/helpers.rb +20 -0
- data/lib/media_magick/engine.rb +1 -1
- data/lib/media_magick/model.rb +41 -48
- data/lib/media_magick/version.rb +1 -1
- data/lib/media_magick/video/parser.rb +62 -0
- data/media_magick.gemspec +8 -4
- data/spec/controllers/media_magick/attach_controller_spec.rb +12 -11
- data/spec/dummy/app/assets/javascripts/application.js +5 -0
- data/spec/dummy/app/assets/javascripts/posts.js +2 -0
- data/spec/dummy/app/assets/stylesheets/posts.css +4 -0
- data/spec/dummy/app/controllers/posts_controller.rb +83 -0
- data/spec/dummy/app/helpers/posts_helper.rb +2 -0
- data/spec/dummy/app/models/album.rb +3 -1
- data/spec/dummy/app/models/post.rb +10 -0
- data/spec/dummy/app/models/track.rb +1 -0
- data/spec/dummy/app/uploaders/post_uploader.rb +17 -0
- data/spec/dummy/app/views/posts/_form.html.erb +47 -0
- data/spec/dummy/app/views/posts/edit.html.erb +6 -0
- data/spec/dummy/app/views/posts/index.html.erb +25 -0
- data/spec/dummy/app/views/posts/new.html.erb +5 -0
- data/spec/dummy/app/views/posts/show.html.erb +15 -0
- data/spec/dummy/app/views/users/index.html.erb +1 -1
- data/spec/dummy/config/mongoid.yml +65 -17
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/helpers/media_magick/application_helper_spec.rb +90 -27
- data/spec/integration/images_spec.rb +1 -1
- data/spec/lib/media_magick/controller/helper_spec.rb +37 -0
- data/spec/lib/media_magick/model_spec.rb +41 -9
- data/spec/lib/media_magick/video/parser_spec.rb +67 -0
- data/spec/spec_helper.rb +11 -8
- data/spec/views/_upload.html.erb_spec.rb +26 -0
- metadata +76 -21
- data/.rvmrc +0 -1
- data/spec/dummy/app/helpers/users_helper.rb +0 -2
data/lib/media_magick/model.rb
CHANGED
@@ -1,84 +1,77 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
require 'carrierwave/mongoid'
|
3
3
|
require 'media_magick/attachment_uploader'
|
4
|
+
require 'media_magick/video/parser'
|
4
5
|
|
5
6
|
module MediaMagick
|
6
7
|
module Model
|
7
8
|
extend ActiveSupport::Concern
|
8
9
|
|
9
10
|
module ClassMethods
|
10
|
-
def
|
11
|
-
|
12
|
-
attaches_many(name, options, &block)
|
13
|
-
end
|
11
|
+
def attaches_many(name, options = {})
|
12
|
+
attaches_block = block_given? ? Proc.new : nil
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
# * refactor these methods to remove duplication
|
18
|
-
#
|
19
|
-
def attaches_many(name, options = {}, &block)
|
20
|
-
klass = Class.new do
|
21
|
-
include Mongoid::Document
|
22
|
-
extend CarrierWave::Mount
|
14
|
+
name_camelcase = create_attaches_class(name, options, attaches_block) do
|
15
|
+
create_video_methods(name) if options[:allow_videos]
|
23
16
|
|
24
17
|
field :priority, type: Integer, default: 0
|
18
|
+
|
25
19
|
default_scope asc(:priority)
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
embedded_in :attachmentable, polymorphic: true
|
31
|
-
end
|
21
|
+
embedded_in(:attachmentable, polymorphic: true)
|
22
|
+
end
|
32
23
|
|
33
|
-
|
24
|
+
embeds_many(name, :as => :attachmentable, class_name: "#{self}#{name_camelcase}")
|
25
|
+
end
|
34
26
|
|
35
|
-
|
36
|
-
|
27
|
+
def attaches_one(name, options = {})
|
28
|
+
attaches_block = block_given? ? Proc.new : nil
|
37
29
|
|
38
|
-
|
30
|
+
name_camelcase = create_attaches_class(name, options, attaches_block) do
|
31
|
+
create_video_methods(name) if options[:allow_videos]
|
39
32
|
|
40
|
-
|
41
|
-
return self.send(self.class::ATTACHMENT).file.filename if method == :filename
|
42
|
-
self.send(self.class::ATTACHMENT).send(method)
|
43
|
-
end
|
33
|
+
embedded_in(name)
|
44
34
|
end
|
45
35
|
|
46
|
-
name_camelcase
|
47
|
-
|
36
|
+
embeds_one(name, class_name: "#{self}#{name_camelcase}", cascade_callbacks: true)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
48
40
|
|
49
|
-
|
50
|
-
|
41
|
+
def create_attaches_class(name, options, attaches_block, &block)
|
42
|
+
klass = Class.new do
|
43
|
+
include Mongoid::Document
|
44
|
+
extend CarrierWave::Mount
|
51
45
|
|
52
|
-
|
46
|
+
field :type, type: String, default: options[:as] || 'image'
|
53
47
|
|
54
|
-
|
48
|
+
def self.create_video_methods(name)
|
49
|
+
field :video, type: String
|
50
|
+
|
51
|
+
def video=(url)
|
52
|
+
self.type = 'video'
|
53
|
+
super
|
54
|
+
|
55
|
+
video = MediaMagick::Video::Parser.new(url)
|
56
|
+
|
57
|
+
send(self.class::ATTACHMENT).store!(video.to_image) if video.valid?
|
58
|
+
end
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
def source(options = {})
|
61
|
+
video = MediaMagick::Video::Parser.new(self.video)
|
58
62
|
|
59
|
-
|
60
|
-
"#{self.class}#{name_camelcase}".constantize.find(id).update_attributes(attachmentable: self)
|
63
|
+
video.to_html(options) if video.valid?
|
61
64
|
end
|
62
65
|
end
|
63
|
-
else
|
64
|
-
embeds_many(name, :as => :attachmentable, class_name: "#{self}#{name_camelcase}")
|
65
|
-
end
|
66
|
-
end
|
67
66
|
|
68
|
-
|
69
|
-
klass = Class.new do
|
70
|
-
include Mongoid::Document
|
71
|
-
extend CarrierWave::Mount
|
67
|
+
class_eval(&block) if block_given?
|
72
68
|
|
73
|
-
embedded_in name
|
74
69
|
mount_uploader name.to_s.singularize, (options[:uploader] || AttachmentUploader)
|
75
70
|
|
76
|
-
accepts_nested_attributes_for name.to_s.singularize
|
77
|
-
|
78
71
|
self.const_set "TYPE", options[:type] || :image
|
79
72
|
self.const_set "ATTACHMENT", name.to_s.singularize
|
80
73
|
|
81
|
-
class_eval(&
|
74
|
+
class_eval(&attaches_block) if attaches_block
|
82
75
|
|
83
76
|
def method_missing(method, args = nil)
|
84
77
|
return self.send(self.class::ATTACHMENT).file.filename if method == :filename
|
@@ -89,7 +82,7 @@ module MediaMagick
|
|
89
82
|
name_camelcase = name.to_s.camelcase
|
90
83
|
Object.const_set "#{self}#{name_camelcase}", klass
|
91
84
|
|
92
|
-
|
85
|
+
return name_camelcase
|
93
86
|
end
|
94
87
|
end
|
95
88
|
end
|
data/lib/media_magick/version.rb
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module MediaMagick
|
5
|
+
module Video
|
6
|
+
class Parser
|
7
|
+
def initialize(url)
|
8
|
+
@url = url
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
youtube_regex = /((https?)?:\/\/)?(www.)?(youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/watch\?feature=player_embedded&v=)([A-Za-z0-9_-]*)(\&\S+)?(\S)*/
|
13
|
+
vimeo_regex = /((https?):\/\/)?(www.)?vimeo\.com\/([A-Za-z0-9._%-]*)((\?|#)\S+)?/
|
14
|
+
|
15
|
+
if @url.match(youtube_regex)
|
16
|
+
@id = @url.match(youtube_regex)[5]
|
17
|
+
@service = 'youtube'
|
18
|
+
true
|
19
|
+
else
|
20
|
+
if @url.match(vimeo_regex)
|
21
|
+
@id = @url.match(vimeo_regex)[4]
|
22
|
+
@service = 'vimeo'
|
23
|
+
true
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_image
|
31
|
+
id = @id if valid?
|
32
|
+
|
33
|
+
case @service
|
34
|
+
when 'youtube'
|
35
|
+
image_url = "http://img.youtube.com/vi/#{id}/0.jpg"
|
36
|
+
when 'vimeo'
|
37
|
+
uri = URI.parse("http://vimeo.com/api/v2/video/#{id}.json")
|
38
|
+
resp = Net::HTTP.get_response(uri)
|
39
|
+
image_url = JSON.parse(resp.body)[0]["thumbnail_large"]
|
40
|
+
end
|
41
|
+
|
42
|
+
uri = URI.parse(image_url)
|
43
|
+
response = Net::HTTP.get_response(uri)
|
44
|
+
|
45
|
+
File.new("/tmp/#{id}.jpg", "w+").tap do |file|
|
46
|
+
file.write(response.body.force_encoding('UTF-8'))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_html(options = {})
|
51
|
+
valid?
|
52
|
+
|
53
|
+
case @service
|
54
|
+
when 'youtube'
|
55
|
+
"<iframe width=\"#{ options[:width] || 560}\" height=\"#{ options[:height] || 315 }\" src=\"http://www.youtube.com/embed/#{@id}\" frameborder=\"0\" allowfullscreen></iframe>"
|
56
|
+
when 'vimeo'
|
57
|
+
"<iframe src=\"http://player.vimeo.com/video/#{@id}?title=0&byline=0&portrait=0#{ "&#{options[:url_options]}" if options[:url_options] }#{ "&player_id=#{ options[:player_id] }" if options[:player_id] }\" width=\"#{ options[:width] || 500 }\" height=\"#{ options[:height] || 341 }\" frameborder=\"0\" #{ "id=\"#{ options[:player_id] }\"" if options[:player_id] }webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/media_magick.gemspec
CHANGED
@@ -16,13 +16,17 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = MediaMagick::VERSION
|
17
17
|
|
18
18
|
gem.add_dependency 'carrierwave', '~> 0.6.0'
|
19
|
-
gem.add_dependency 'mongoid', '
|
19
|
+
gem.add_dependency 'mongoid', '>= 2.4'
|
20
20
|
gem.add_dependency 'plupload-rails', '~> 1.0.6'
|
21
21
|
gem.add_dependency 'rails', '~> 3.2.0'
|
22
22
|
|
23
|
-
gem.add_development_dependency 'bson_ext', '~> 1.
|
23
|
+
gem.add_development_dependency 'bson_ext', '~> 1.7.0'
|
24
24
|
gem.add_development_dependency 'mini_magick', '~> 3.4'
|
25
25
|
gem.add_development_dependency 'rake', '~> 0.9'
|
26
|
-
gem.add_development_dependency 'rspec-rails', '~> 2.
|
27
|
-
gem.add_development_dependency 'simplecov', '~> 0.
|
26
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.11.0'
|
27
|
+
gem.add_development_dependency 'simplecov', '~> 0.7.0'
|
28
|
+
|
29
|
+
#gems for code analyses
|
30
|
+
gem.add_development_dependency 'flog', '~> 3.0.0.b2'
|
31
|
+
gem.add_development_dependency 'flay', '~> 2.0.0.b1'
|
28
32
|
end
|
@@ -17,6 +17,18 @@ describe MediaMagick::AttachController do
|
|
17
17
|
response.body.should =~ /nu.jpg/m
|
18
18
|
end
|
19
19
|
|
20
|
+
it "creates a new video" do
|
21
|
+
album = Album.create
|
22
|
+
|
23
|
+
expect {
|
24
|
+
post :create, { model: 'Album', id: album.id, relation: 'photos_and_videos', video: 'youtube.com/watch?v=FfUHkPf9D9k' }
|
25
|
+
}.to change { album.reload.photos_and_videos.count }.by(1)
|
26
|
+
|
27
|
+
response.should render_template('_image')
|
28
|
+
|
29
|
+
response.body.should =~ /FfUHkPf9D9k/m
|
30
|
+
end
|
31
|
+
|
20
32
|
it "creates a new photo for embedded models" do
|
21
33
|
album = Album.create
|
22
34
|
track = album.tracks.create
|
@@ -35,17 +47,6 @@ describe MediaMagick::AttachController do
|
|
35
47
|
post :create, { model: 'Album', id: album.id, relation: 'photos', partial: 'albums/photo', file: fixture_file_upload("#{File.expand_path('../../..', __FILE__)}/support/fixtures/nu.jpg") }
|
36
48
|
response.should render_template('albums/_photo')
|
37
49
|
end
|
38
|
-
|
39
|
-
it 'creates a new photo without parent' do
|
40
|
-
album = Album.new
|
41
|
-
album_files = AlbumFiles.create(file: File.new("#{File.expand_path('../../..', __FILE__)}/support/fixtures/nu.jpg"))
|
42
|
-
|
43
|
-
AlbumFiles.should_receive(:create!).and_return(album_files)
|
44
|
-
|
45
|
-
post :create, { model: 'Album', id: album.id, relation: 'files', file: fixture_file_upload("#{File.expand_path('../../..', __FILE__)}/support/fixtures/nu.jpg") }
|
46
|
-
|
47
|
-
response.body.should =~ /nu.jpg/m
|
48
|
-
end
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
# GET /posts
|
3
|
+
# GET /posts.json
|
4
|
+
def index
|
5
|
+
@posts = Post.all
|
6
|
+
|
7
|
+
respond_to do |format|
|
8
|
+
format.html # index.html.erb
|
9
|
+
format.json { render json: @posts }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /posts/1
|
14
|
+
# GET /posts/1.json
|
15
|
+
def show
|
16
|
+
@post = Post.find(params[:id])
|
17
|
+
|
18
|
+
respond_to do |format|
|
19
|
+
format.html # show.html.erb
|
20
|
+
format.json { render json: @post }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# GET /posts/new
|
25
|
+
# GET /posts/new.json
|
26
|
+
def new
|
27
|
+
@post = Post.new
|
28
|
+
|
29
|
+
respond_to do |format|
|
30
|
+
format.html # new.html.erb
|
31
|
+
format.json { render json: @post }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# GET /posts/1/edit
|
36
|
+
def edit
|
37
|
+
@post = Post.find(params[:id])
|
38
|
+
end
|
39
|
+
|
40
|
+
# POST /posts
|
41
|
+
# POST /posts.json
|
42
|
+
def create
|
43
|
+
@post = Post.new(params[:post])
|
44
|
+
|
45
|
+
respond_to do |format|
|
46
|
+
if @post.save
|
47
|
+
format.html { redirect_to @post, notice: 'Post was successfully created.' }
|
48
|
+
format.json { render json: @post, status: :created, location: @post }
|
49
|
+
else
|
50
|
+
format.html { render action: "new" }
|
51
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# PUT /posts/1
|
57
|
+
# PUT /posts/1.json
|
58
|
+
def update
|
59
|
+
@post = Post.find(params[:id])
|
60
|
+
|
61
|
+
respond_to do |format|
|
62
|
+
if @post.update_attributes(params[:post])
|
63
|
+
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
|
64
|
+
format.json { head :no_content }
|
65
|
+
else
|
66
|
+
format.html { render action: "edit" }
|
67
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# DELETE /posts/1
|
73
|
+
# DELETE /posts/1.json
|
74
|
+
def destroy
|
75
|
+
@post = Post.find(params[:id])
|
76
|
+
@post.destroy
|
77
|
+
|
78
|
+
respond_to do |format|
|
79
|
+
format.html { redirect_to posts_url }
|
80
|
+
format.json { head :no_content }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -5,7 +5,7 @@ class Album
|
|
5
5
|
embeds_many :tracks
|
6
6
|
|
7
7
|
attaches_many :photos
|
8
|
-
attaches_many :files, :relation => :referenced
|
8
|
+
attaches_many :files, :relation => :referenced, type: 'file'
|
9
9
|
attaches_many :compound_name_files
|
10
10
|
|
11
11
|
attaches_many :images do
|
@@ -13,4 +13,6 @@ class Album
|
|
13
13
|
end
|
14
14
|
|
15
15
|
attaches_many :pictures, uploader: PictureUploader
|
16
|
+
|
17
|
+
attaches_many :photos_and_videos, as: 'photo', uploader: PictureUploader, allow_videos: true
|
16
18
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Post
|
2
|
+
include Mongoid::Document
|
3
|
+
include MediaMagick::Model
|
4
|
+
|
5
|
+
field :title, :type => String
|
6
|
+
field :text, :type => String
|
7
|
+
|
8
|
+
attaches_many :files, :type => 'file'
|
9
|
+
attaches_many :images, :type => 'image', :uploader => PostUploader, :allow_videos => true
|
10
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class PostUploader < CarrierWave::Uploader::Base
|
4
|
+
include CarrierWave::MiniMagick
|
5
|
+
|
6
|
+
storage :file
|
7
|
+
|
8
|
+
def store_dir
|
9
|
+
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
10
|
+
end
|
11
|
+
|
12
|
+
process :resize_to_fill => [50, 50]
|
13
|
+
version :thumb do
|
14
|
+
process :resize_to_fit => [300, 300]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<%= form_for(@post) do |f| %>
|
2
|
+
<% if @post.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @post.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= f.label :title %><br />
|
16
|
+
<%= f.text_field :title %>
|
17
|
+
</div>
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :text %><br />
|
20
|
+
<%= f.text_area :text %>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<h3>uploads</h3>
|
24
|
+
<div class="field" style="overflow: hidden;">
|
25
|
+
<label>imagens and videos</label>
|
26
|
+
<%- if @post.new_record? -%>
|
27
|
+
create first
|
28
|
+
<%- else -%>
|
29
|
+
<%= attachment_container_for_video(@post, :images) %>
|
30
|
+
<br /><br />
|
31
|
+
<%= attachment_container @post, :images %>
|
32
|
+
<%- end -%>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="field">
|
36
|
+
<label>files</label>
|
37
|
+
<%- if @post.new_record? -%>
|
38
|
+
create first
|
39
|
+
<%- else -%>
|
40
|
+
<%= attachment_container @post, :files, :as => "file" %>
|
41
|
+
<%- end -%>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="actions">
|
45
|
+
<%= f.submit %>
|
46
|
+
</div>
|
47
|
+
<% end %>
|