assetable 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +181 -0
  4. data/Rakefile +23 -0
  5. data/app/assets/images/assetable/icon-upload.png +0 -0
  6. data/app/assets/images/assetable/icons/icon-ai.png +0 -0
  7. data/app/assets/images/assetable/icons/icon-css.png +0 -0
  8. data/app/assets/images/assetable/icons/icon-desmos.png +0 -0
  9. data/app/assets/images/assetable/icons/icon-doc.png +0 -0
  10. data/app/assets/images/assetable/icons/icon-document.png +0 -0
  11. data/app/assets/images/assetable/icons/icon-docx.png +0 -0
  12. data/app/assets/images/assetable/icons/icon-eps.png +0 -0
  13. data/app/assets/images/assetable/icons/icon-flash.png +0 -0
  14. data/app/assets/images/assetable/icons/icon-html.png +0 -0
  15. data/app/assets/images/assetable/icons/icon-jpg.png +0 -0
  16. data/app/assets/images/assetable/icons/icon-js.png +0 -0
  17. data/app/assets/images/assetable/icons/icon-mov.png +0 -0
  18. data/app/assets/images/assetable/icons/icon-mp3.png +0 -0
  19. data/app/assets/images/assetable/icons/icon-mp4.png +0 -0
  20. data/app/assets/images/assetable/icons/icon-pdf.png +0 -0
  21. data/app/assets/images/assetable/icons/icon-php.png +0 -0
  22. data/app/assets/images/assetable/icons/icon-png.png +0 -0
  23. data/app/assets/images/assetable/icons/icon-ppt.png +0 -0
  24. data/app/assets/images/assetable/icons/icon-pptx.png +0 -0
  25. data/app/assets/images/assetable/icons/icon-txt.png +0 -0
  26. data/app/assets/images/assetable/icons/icon-xls.png +0 -0
  27. data/app/assets/images/assetable/icons/icon-xlsx.png +0 -0
  28. data/app/assets/images/assetable/icons/icon-xml.png +0 -0
  29. data/app/assets/javascripts/assetable/asset_gallery.js.coffee +74 -0
  30. data/app/assets/javascripts/assetable/assetable_uploader.js.coffee +204 -0
  31. data/app/assets/javascripts/assetable/gallery.js.coffee +33 -0
  32. data/app/assets/javascripts/assetable/uploader.js.coffee +10 -0
  33. data/app/assets/javascripts/vendor/bootstrap-modal.js +246 -0
  34. data/app/assets/javascripts/vendor/jquery-ui-1.10.3.custom.js +2252 -0
  35. data/app/assets/stylesheets/assetable/_assetable.css.sass +9 -0
  36. data/app/assets/stylesheets/assetable/_bootstrap.css.sass +5 -0
  37. data/app/assets/stylesheets/assetable/components/_buttons.css.sass +99 -0
  38. data/app/assets/stylesheets/assetable/components/_close.css.sass +28 -0
  39. data/app/assets/stylesheets/assetable/components/_forms.css.sass +219 -0
  40. data/app/assets/stylesheets/assetable/components/_gallery.css.sass +118 -0
  41. data/app/assets/stylesheets/assetable/components/_modals.css.sass +116 -0
  42. data/app/assets/stylesheets/assetable/components/_progress.css.sass +91 -0
  43. data/app/assets/stylesheets/assetable/components/_uploader.css.sass +175 -0
  44. data/app/assets/stylesheets/assetable/core/_mixins.css.sass +754 -0
  45. data/app/assets/stylesheets/assetable/core/_utilities.css.sass +5 -0
  46. data/app/assets/stylesheets/assetable/core/_variables.css.sass +165 -0
  47. data/app/controllers/assetable/assets_controller.rb +38 -0
  48. data/app/controllers/assetable/external_services_controller.rb +36 -0
  49. data/app/models/asset.rb +53 -0
  50. data/app/models/asset_attachment.rb +4 -0
  51. data/app/models/document.rb +5 -0
  52. data/app/models/external_service.rb +14 -0
  53. data/app/models/gallery.rb +7 -0
  54. data/app/models/image.rb +5 -0
  55. data/app/models/video.rb +5 -0
  56. data/app/uploaders/document_uploader.rb +50 -0
  57. data/app/uploaders/image_uploader.rb +67 -0
  58. data/app/uploaders/video_uploader.rb +40 -0
  59. data/app/views/assetable/assets/_asset.html.haml +20 -0
  60. data/app/views/assetable/assets/_gallery.html.haml +12 -0
  61. data/app/views/assetable/external_services/new.html.haml +31 -0
  62. data/config/initializers/carrierwave.rb +6 -0
  63. data/config/initializers/gallery_input.rb +37 -0
  64. data/config/initializers/uploader_input.rb +80 -0
  65. data/config/routes.rb +8 -0
  66. data/db/migrate/20131122232735_create_assets.rb +19 -0
  67. data/db/migrate/20131123172825_create_asset_attachments.rb +15 -0
  68. data/db/migrate/20131125200943_create_galleries.rb +14 -0
  69. data/lib/assetable.rb +18 -0
  70. data/lib/assetable/config.rb +23 -0
  71. data/lib/assetable/core.rb +41 -0
  72. data/lib/assetable/engine.rb +15 -0
  73. data/lib/assetable/version.rb +3 -0
  74. data/lib/tasks/assetable_tasks.rake +4 -0
  75. data/test/fixtures/asset_attachments.yml +11 -0
  76. data/test/fixtures/assets.yml +11 -0
  77. data/test/fixtures/images.yml +11 -0
  78. data/test/fixtures/videos.yml +11 -0
  79. data/test/models/asset_attachment_test.rb +7 -0
  80. data/test/models/asset_test.rb +7 -0
  81. data/test/models/image_test.rb +7 -0
  82. data/test/models/video_test.rb +7 -0
  83. metadata +371 -0
@@ -0,0 +1,40 @@
1
+ class VideoUploader < CarrierWave::Uploader::Base
2
+
3
+ storage Assetable.storage
4
+
5
+ # Override the directory where uploaded files will be stored.
6
+ # This is a sensible default for uploaders that are meant to be mounted:
7
+ def store_dir
8
+ if model.present?
9
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
10
+ else
11
+ "uploads/#{mounted_as}"
12
+ end
13
+ end
14
+
15
+ # Create an MP4 version
16
+ # version :mp4 do
17
+ # process :encode_video => [:mp4, resolution: "1280x720", custom: "-preset medium"]
18
+ # end
19
+
20
+ # version :ogv, :from_version => :mp4 do
21
+ # process :encode_ogv => [resolution: :same]
22
+ # end
23
+
24
+ # # Create a thumbnail
25
+ # version :gallery_thumb do
26
+ # process thumbnail: [{format: 'jpg', quality: 10, size: "100x100", strip: true, logger: Rails.logger}]
27
+ # def full_filename for_file
28
+ # png_name for_file, version_name
29
+ # end
30
+ # end
31
+
32
+ def png_name for_file, version_name
33
+ %Q{#{version_name}_#{for_file.chomp(File.extname(for_file))}.jpg}
34
+ end
35
+
36
+ def default_url
37
+ ActionController::Base.helpers.asset_path("assetable/" + [version_name, "video.png"].compact.join('_'))
38
+ end
39
+
40
+ end
@@ -0,0 +1,20 @@
1
+ .uploader-preview
2
+
3
+ = link_to asset.filename.to_s, target: "_blank" do
4
+ - if asset.image?
5
+ = image_tag asset.filename.preview.to_s, class: "uploader-preview"
6
+ - elsif asset.document?
7
+ = image_tag "assetable/icons/icon-#{asset.extension}.png", class: "uploader-preview"
8
+ - elsif asset.video?
9
+ = image_tag "assetable/icons/icon-mp4.png", class: "uploader-preview"
10
+ - elsif asset.external_service?
11
+ = image_tag "assetable/icons/icon-document.png", class: "uploader-preview"
12
+
13
+ %span.uploader-name= asset.name
14
+ .uploader-size-and-actions
15
+ %span.uploader-size= number_to_human_size(asset.file_size)
16
+ .uploader-actions
17
+ = link_to "delete", "#", class: "btn-uploader btn-uploader-remove-asset"
18
+ = link_to "edit", "#", class: "btn-uploader btn-uploader-edit-asset"
19
+
20
+ = hidden_field_tag(fieldname, asset.id)
@@ -0,0 +1,12 @@
1
+ .assetable-gallery-header
2
+ %h3 Gallery
3
+ = link_to "&times;".html_safe, "#", class: "pull-right btn-close-assetable-gallery"
4
+
5
+ .assetable-gallery
6
+ = render partial: 'asset', collection: assets, locals: {fieldname: fieldname}
7
+
8
+ .assetable-gallery-footer
9
+ .assetable-gallery-paginate.pull-left
10
+ = paginate assets, remote: true
11
+ .pull-right
12
+ = link_to "insert asset", "#", class: "btn btn-primary btn-insert-asset"
@@ -0,0 +1,31 @@
1
+ .assetable-external-services.assetable-modal.modal.fade
2
+ .modal-dialog
3
+ .modal-content
4
+ = form_for [:assetable, @external_service], remote: true do |f|
5
+ .modal-header
6
+ %button.close{"aria-hidden" => "true", "data-dismiss" => "modal", type: "button"} ×
7
+ %h4.modal-title Third Party Service
8
+ .modal-body
9
+
10
+ = hidden_field_tag :fieldname, params[:fieldname]
11
+
12
+ .form-group
13
+ = f.label :name
14
+ = f.text_field :name, class: "form-control inpu-fluid", required: true
15
+ .form-group
16
+ = f.label :content_type
17
+ = f.select :content_type, ExternalService.possible_content_types
18
+ .form-group
19
+ = f.label :body
20
+ = f.text_area :body, class: "form-control input-fluid", required: true
21
+ .form-group.row
22
+ .col-xs-6
23
+ = f.label :width
24
+ = f.number_field :width, class: "form-control input-fluid"
25
+ .col-xs-6
26
+ = f.label :height
27
+ = f.number_field :height, class: "form-control input-fluid"
28
+
29
+ .modal-footer
30
+ = button_tag "Cancel", class: "btn btn-default", :'data-dismiss' => "modal", type: "button"
31
+ = f.submit "Add Third Party Service", class: "btn btn-primary"
@@ -0,0 +1,6 @@
1
+ if Rails.env.test? or Rails.env.cucumber?
2
+ CarrierWave.configure do |config|
3
+ config.storage = :file
4
+ config.enable_processing = false
5
+ end
6
+ end
@@ -0,0 +1,37 @@
1
+ class ActionView::Helpers::FormBuilder
2
+
3
+ include ActionView::Helpers::Tags
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Helpers::FormTagHelper
6
+ include ActionView::Helpers::FormOptionsHelper
7
+ include ActionView::Helpers::CaptureHelper
8
+ include ActionView::Helpers::AssetTagHelper
9
+ include ActionView::Helpers::NumberHelper
10
+
11
+ def gallery method, options = {}
12
+ # Build the association
13
+ @object.send("build_#{method}") unless @object.present? and @object.send(method).present?
14
+ # ID of the input wrapper
15
+ options[:id] = field_id(method, options[:index])
16
+ # The fieldname for the association
17
+ fieldname = @object_name + "[#{method}_attributes][asset_ids][]"
18
+
19
+ # Add the asset preview or the empty preview div
20
+ if gallery = @object.send(method)
21
+ asset_preview = ""
22
+ gallery.assets.each do |a|
23
+ asset_preview += asset_html(a, fieldname)
24
+ end
25
+ else
26
+ asset_preview = content_tag(:div, "", class: "uploader-preview")
27
+ end
28
+
29
+ # Uploader HTML with the asset previews and actions
30
+ uploader_html = content_tag(:div, (asset_preview.html_safe), class: "uploadar-data-wrapper")
31
+
32
+ # Wrap the previews and uploader in a div
33
+ uploader_wrapper = content_tag(:div, uploader_html, class: "gallery-uploader", id: options[:id], :'data-uploader-input-name' => fieldname)
34
+ return uploader_wrapper
35
+ end
36
+
37
+ end
@@ -0,0 +1,80 @@
1
+ class ActionView::Helpers::FormBuilder
2
+
3
+ include ActionView::Helpers::TagHelper
4
+ include ActionView::Helpers::FormTagHelper
5
+ include ActionView::Helpers::FormOptionsHelper
6
+ include ActionView::Helpers::CaptureHelper
7
+ include ActionView::Helpers::AssetTagHelper
8
+ include ActionView::Helpers::NumberHelper
9
+
10
+ def uploader method, options = {}
11
+ # add an ID to the options
12
+ options[:id] = field_id(method, options[:index]) unless options[:id].present?
13
+
14
+ # Set the fieldname
15
+ fieldname = @object_name + "[#{method}_association_attributes][asset_id]"
16
+
17
+ # Create the uploader
18
+ value = @object.nil? ? nil : @object.send(method)
19
+
20
+ # Add the asset preview or the empty preview div
21
+ if asset = asset_record(method)
22
+ asset_preview = asset_html(asset, fieldname)
23
+ else
24
+ asset_preview = content_tag(:div, "", class: "uploader-preview")
25
+ end
26
+
27
+ # uploaer html with preview and input
28
+ uploader_html = content_tag(:div, (asset_preview), class: "uploader-data-wrapper")
29
+
30
+ # Create and return the uploader html
31
+ uploader_wrapper = content_tag(:div, uploader_html, class: "uploader #{'uploader-has-asset' if asset} #{options[:class]}", id: options[:id], :'data-uploader-input-name' => fieldname)
32
+ return uploader_wrapper
33
+ end
34
+
35
+
36
+ # Convenience method to create the asset html
37
+ def asset_html asset, fieldname
38
+ image_tag = asset_preview_image(asset)
39
+ asset_name = content_tag(:span, asset.name.to_s, class: "uploader-name")
40
+ asset_size = content_tag(:span, number_to_human_size(asset.file_size.to_s), class: "uploader-size")
41
+ asset_size_and_actions = content_tag(:div, (asset_size + asset_actions), class: "uploader-size-and-actions")
42
+ field = hidden_field_tag(fieldname, (asset.id))
43
+ return content_tag(:div, (image_tag + asset_name + asset_size_and_actions + field), class: "uploader-preview")
44
+ end
45
+
46
+ # Asset preview image or fallback to a content type image
47
+ def asset_preview_image asset
48
+ if asset.image?
49
+ preview_image_tag = image_tag(asset.filename.preview.to_s, class: "uploader-preview")
50
+ elsif asset.document?
51
+ preview_image_tag = image_tag(ActionController::Base.helpers.asset_path("assetable/icons/icon-#{asset.extension}.png"), class: "uploader-preview")
52
+ elsif asset.video?
53
+ preview_image_tag = image_tag(ActionController::Base.helpers.asset_path("assetable/icons/icon-mp4.png"), class: "uploader-preview")
54
+ elsif asset.external_service?
55
+ preview_image_tag = image_tag(ActionController::Base.helpers.asset_path("assetable/icons/icon-document.png"), class: "uploader-preview")
56
+ end
57
+
58
+ return link_to preview_image_tag, asset.filename.to_s, target: "_blank"
59
+ end
60
+
61
+ # Asset actions, i.e.e remove and edit buttons
62
+ def asset_actions
63
+ remove_btn = link_to "delete", "#", class: "btn-uploader btn-uploader-remove-asset"
64
+ edit_btn = link_to "edit", "#", class: "btn-uploader btn-uploader-edit-asset"
65
+ content_tag(:div, (remove_btn + edit_btn), class: "uploader-actions")
66
+ end
67
+
68
+ # Get the asset record, if it's a belongs_to assocation, then we
69
+ # can grab the actual record
70
+ def asset_record method
71
+ @object.send(method) rescue nil
72
+ end
73
+
74
+ # Get the field id
75
+ def field_id label, index=nil
76
+ output = index ? "_#{index}" : ''
77
+ return @object_name + output + "_#{label}"
78
+ end
79
+
80
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ Rails.application.routes.draw do
2
+
3
+ namespace :assetable do
4
+ resources :assets
5
+ resources :external_services
6
+ end
7
+
8
+ end
@@ -0,0 +1,19 @@
1
+ class CreateAssets < ActiveRecord::Migration
2
+ def change
3
+ create_table :assets do |t|
4
+ t.string :type
5
+ t.string :name
6
+ t.text :body
7
+ t.string :filename
8
+ t.string :checksum
9
+ t.string :path
10
+ t.string :content_type
11
+ t.integer :file_size
12
+ t.integer :width
13
+ t.integer :height
14
+ t.integer :duration
15
+ t.integer :bit_rate
16
+ t.timestamps
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ class CreateAssetAttachments < ActiveRecord::Migration
2
+ def change
3
+ create_table :asset_attachments do |t|
4
+ t.references :asset
5
+ t.references :assetable, :polymorphic => true
6
+ t.string :name
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :asset_attachments, :asset_id
11
+ add_index :asset_attachments, [:assetable_type, :assetable_id]
12
+ add_index :asset_attachments, [:assetable_type, :assetable_id, :name], unique: true, name: "named_asset"
13
+ add_index :asset_attachments, :assetable_id
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ class CreateGalleries < ActiveRecord::Migration
2
+ def change
3
+ create_table :galleries do |t|
4
+ t.references :galleryable, :polymorphic => true
5
+ t.string :name
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :galleries, [:galleryable_type, :galleryable_id]
10
+ add_index :galleries, [:galleryable_type, :galleryable_id, :name], unique: true, name: "named_gallery"
11
+
12
+ add_index :galleries, :galleryable_id
13
+ end
14
+ end
data/lib/assetable.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "carrierwave"
2
+ require "fog"
3
+ require "plupload-rails"
4
+ require "kaminari"
5
+
6
+ require "haml-rails"
7
+ require "sass-rails"
8
+ require "jquery-rails"
9
+
10
+ require "assetable/core"
11
+ require "assetable/engine"
12
+ require "assetable/config"
13
+
14
+ module Assetable
15
+
16
+ extend Config
17
+
18
+ end
@@ -0,0 +1,23 @@
1
+ module Assetable
2
+ module Config
3
+
4
+ VALID_OPTION_KEYS = [
5
+ :storage,
6
+ :external_document_types
7
+ ]
8
+
9
+ attr_accessor *VALID_OPTION_KEYS
10
+
11
+ def configure
12
+ yield self
13
+ self
14
+ end
15
+
16
+ def options
17
+ options = {}
18
+ VALID_OPTION_KEYS.each{ |pname| options[pname] = send(pname) }
19
+ options
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ module Assetable
2
+ module Core
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ end
7
+
8
+ module ClassMethods
9
+ def assetable *args
10
+ if args.present?
11
+ args.each do |arg|
12
+ has_one :"#{arg}_association", -> { where(name: arg) }, class_name: "AssetAttachment", as: :assetable
13
+ has_one arg, through: :"#{arg}_association", source: :asset
14
+ accepts_nested_attributes_for :"#{arg}_association", allow_destroy: true
15
+ end
16
+ end
17
+ end
18
+
19
+ # Galleries
20
+ def galleryable *args
21
+ # By default, let's include a gallery.
22
+ unless args.include? :gallery
23
+ has_one :gallery, as: :galleryable, dependent: :destroy
24
+ accepts_nested_attributes_for :gallery
25
+ end
26
+
27
+ if args.present?
28
+ args.each do |arg|
29
+ has_one arg, -> { where(name: arg) }, class_name: "Gallery", as: :galleryable
30
+ accepts_nested_attributes_for arg
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ end
38
+ end
39
+ end
40
+
41
+ ActiveRecord::Base.send :include, Assetable::Core
@@ -0,0 +1,15 @@
1
+ module Assetable
2
+ class Engine < ::Rails::Engine
3
+ config.generators.integration_tool :rspec
4
+ config.generators.test_framework :rspec
5
+
6
+ # Run the engine migrations with the main app rake task
7
+ initializer :append_migrations do |app|
8
+ unless app.root.to_s.match root.to_s
9
+ config.paths["db/migrate"].expanded.each do |expanded_path|
10
+ app.config.paths["db/migrate"] << expanded_path
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Assetable
2
+ VERSION = "0.1.2"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :assetable do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,11 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ # This model initially had no columns defined. If you add columns to the
4
+ # model remove the '{}' from the fixture names and add the columns immediately
5
+ # below each fixture, per the syntax in the comments below
6
+ #
7
+ one: {}
8
+ # column: value
9
+ #
10
+ two: {}
11
+ # column: value
@@ -0,0 +1,11 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ # This model initially had no columns defined. If you add columns to the
4
+ # model remove the '{}' from the fixture names and add the columns immediately
5
+ # below each fixture, per the syntax in the comments below
6
+ #
7
+ one: {}
8
+ # column: value
9
+ #
10
+ two: {}
11
+ # column: value