ample_assets 0.0.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.
Files changed (114) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +68 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/images/ample_assets/bg-noise.png +0 -0
  5. data/app/assets/images/ample_assets/btn-next.png +0 -0
  6. data/app/assets/images/ample_assets/btn-prev.png +0 -0
  7. data/app/assets/images/ample_assets/btn-select-files.png +0 -0
  8. data/app/assets/images/ample_assets/cancel.png +0 -0
  9. data/app/assets/images/ample_assets/closelabel.png +0 -0
  10. data/app/assets/images/ample_assets/collapse.png +0 -0
  11. data/app/assets/images/ample_assets/gravity.png +0 -0
  12. data/app/assets/images/ample_assets/icon_other.gif +0 -0
  13. data/app/assets/images/ample_assets/icon_pdf.gif +0 -0
  14. data/app/assets/images/ample_assets/icon_swf.gif +0 -0
  15. data/app/assets/images/ample_assets/loading.gif +0 -0
  16. data/app/assets/images/ample_assets/play.png +0 -0
  17. data/app/assets/images/ample_assets/prev-next.png +0 -0
  18. data/app/assets/images/ample_assets/reload.png +0 -0
  19. data/app/assets/images/ample_assets/remove.png +0 -0
  20. data/app/assets/javascripts/ample_assets.js +1 -0
  21. data/app/assets/javascripts/ample_assets/application.js +18 -0
  22. data/app/assets/javascripts/ample_assets/classes/ample_assets_gravity.js.coffee +86 -0
  23. data/app/assets/javascripts/ample_assets/classes/ample_assets_toolbar.js.coffee +769 -0
  24. data/app/assets/javascripts/ample_assets/classes/ample_assets_uploadify.js.coffee +30 -0
  25. data/app/assets/javascripts/ample_assets/files.js.coffee +5 -0
  26. data/app/assets/stylesheets/ample_assets.css +3 -0
  27. data/app/assets/stylesheets/ample_assets/application.css +8 -0
  28. data/app/assets/stylesheets/ample_assets/bourbon/css3/_border-radius.scss +59 -0
  29. data/app/assets/stylesheets/ample_assets/bourbon/css3/_box-shadow.scss +11 -0
  30. data/app/assets/stylesheets/ample_assets/custom_mixins.scss +47 -0
  31. data/app/assets/stylesheets/ample_assets/facebox.css +79 -0
  32. data/app/assets/stylesheets/ample_assets/files.css.scss +750 -0
  33. data/app/assets/swf/ample_assets/expressInstall.swf +0 -0
  34. data/app/assets/swf/ample_assets/uploadify.swf +0 -0
  35. data/app/controllers/ample_assets/application_controller.rb +4 -0
  36. data/app/controllers/ample_assets/files_controller.rb +109 -0
  37. data/app/helpers/ample_assets/application_helper.rb +4 -0
  38. data/app/models/ample_assets/file.rb +79 -0
  39. data/app/views/ample_assets/files/_drop.html.erb +12 -0
  40. data/app/views/ample_assets/files/_file.html.erb +1 -0
  41. data/app/views/ample_assets/files/_file.js.erb +3 -0
  42. data/app/views/ample_assets/files/index.html.erb +6 -0
  43. data/app/views/ample_assets/files/new.html.erb +21 -0
  44. data/app/views/ample_assets/files/recent.html.erb +1 -0
  45. data/app/views/ample_assets/files/show.html.erb +1 -0
  46. data/app/views/layouts/ample_assets/application.html.erb +14 -0
  47. data/config/routes.rb +27 -0
  48. data/lib/ample_assets.rb +26 -0
  49. data/lib/ample_assets/configuration.rb +73 -0
  50. data/lib/ample_assets/custom_processor.rb +29 -0
  51. data/lib/ample_assets/devise_constraint.rb +9 -0
  52. data/lib/ample_assets/engine.rb +36 -0
  53. data/lib/ample_assets/form_builder.rb +19 -0
  54. data/lib/ample_assets/form_helper.rb +14 -0
  55. data/lib/ample_assets/plugin_methods.rb +11 -0
  56. data/lib/ample_assets/version.rb +3 -0
  57. data/lib/ample_assets/view_helper.rb +80 -0
  58. data/lib/generators/ample_assets/install_generator.rb +25 -0
  59. data/lib/generators/ample_assets/templates/migration.rb +16 -0
  60. data/lib/generators/ample_assets/utils.rb +15 -0
  61. data/test/dummy/Rakefile +7 -0
  62. data/test/dummy/app/assets/images/rails.png +0 -0
  63. data/test/dummy/app/assets/javascripts/application.js +11 -0
  64. data/test/dummy/app/assets/sample.pdf +0 -0
  65. data/test/dummy/app/assets/stylesheets/application.css +8 -0
  66. data/test/dummy/app/controllers/application_controller.rb +7 -0
  67. data/test/dummy/app/controllers/public/pages_controller.rb +32 -0
  68. data/test/dummy/app/controllers/public_controller.rb +6 -0
  69. data/test/dummy/app/helpers/application_helper.rb +11 -0
  70. data/test/dummy/app/models/page.rb +7 -0
  71. data/test/dummy/app/views/layouts/application.html.erb +17 -0
  72. data/test/dummy/app/views/public/index.html.erb +0 -0
  73. data/test/dummy/app/views/public/pages/_form.html.erb +18 -0
  74. data/test/dummy/app/views/public/pages/edit.html.erb +1 -0
  75. data/test/dummy/app/views/public/pages/index.html.erb +8 -0
  76. data/test/dummy/app/views/public/pages/new.html.erb +1 -0
  77. data/test/dummy/app/views/public/pages/show.html.erb +3 -0
  78. data/test/dummy/config.ru +4 -0
  79. data/test/dummy/config/application.rb +45 -0
  80. data/test/dummy/config/boot.rb +10 -0
  81. data/test/dummy/config/database.yml +25 -0
  82. data/test/dummy/config/environment.rb +5 -0
  83. data/test/dummy/config/environments/development.rb +30 -0
  84. data/test/dummy/config/environments/production.rb +60 -0
  85. data/test/dummy/config/environments/test.rb +39 -0
  86. data/test/dummy/config/initializers/ample_assets.rb +4 -0
  87. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/test/dummy/config/initializers/inflections.rb +10 -0
  89. data/test/dummy/config/initializers/mime_types.rb +5 -0
  90. data/test/dummy/config/initializers/secret_token.rb +7 -0
  91. data/test/dummy/config/initializers/session_store.rb +8 -0
  92. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  93. data/test/dummy/config/locales/en.yml +5 -0
  94. data/test/dummy/config/routes.rb +8 -0
  95. data/test/dummy/db/migrate/20120105034123_create_pages.rb +9 -0
  96. data/test/dummy/db/migrate/20120106192233_create_ample_assets_tables.rb +16 -0
  97. data/test/dummy/db/schema.rb +37 -0
  98. data/test/dummy/public/404.html +26 -0
  99. data/test/dummy/public/422.html +26 -0
  100. data/test/dummy/public/500.html +26 -0
  101. data/test/dummy/public/favicon.ico +0 -0
  102. data/test/dummy/script/rails +6 -0
  103. data/test/functional/ample_assets/files_controller_test.rb +49 -0
  104. data/test/integration/ample_assets/admin_test.rb +96 -0
  105. data/test/integration/ample_assets/public_test.rb +7 -0
  106. data/test/integration_test_helper.rb +24 -0
  107. data/test/test_helper.rb +25 -0
  108. data/test/unit/ample_assets/configuration_test.rb +35 -0
  109. data/test/unit/ample_assets/file_test.rb +14 -0
  110. data/test/unit/ample_assets/plugin_methods_test.rb +30 -0
  111. data/test/unit/helpers/ample_assets/form_builder_test.rb +11 -0
  112. data/test/unit/helpers/ample_assets/form_helper_test.rb +23 -0
  113. data/test/unit/helpers/ample_assets/view_helper_test.rb +128 -0
  114. metadata +395 -0
@@ -0,0 +1,4 @@
1
+ module AmpleAssets
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,109 @@
1
+ module AmpleAssets
2
+ class FilesController < ApplicationController
3
+
4
+ ([:index, :recent] | AmpleAssets.allowed_mime_types.keys).compact.each do |key|
5
+ define_method key do
6
+ respond_to do |format|
7
+ format.js { render current_files, :content_type => :html }
8
+ format.json { render :json => current_files.to_json }
9
+ format.html
10
+ end
11
+ end
12
+ end
13
+
14
+ def new
15
+ render 'ample_assets/files/new', :layout => false, :content_type => :html if request.xhr?
16
+ end
17
+
18
+ def create
19
+ if uploadify?
20
+ filename, filedata = params['Filename'], params['Filedata']
21
+ file = File.new(:attachment => filedata)
22
+ else
23
+ file = File.new(params[:file])
24
+ end
25
+ if file.save
26
+ if uploadify?
27
+ render :nothing => true
28
+ else
29
+ redirect_to file_path(file)
30
+ end
31
+ else
32
+ flash[:error] = "Whoops! There was a problem creating new asset."
33
+ redirect_to :action => :index
34
+ end
35
+ end
36
+
37
+ def show
38
+ raise ActiveRecord::RecordNotFound if current_file.nil?
39
+ respond_to do |format|
40
+ format.json { render :json => current_file.to_json }
41
+ format.html
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ current_file.destroy
47
+ if request.xhr?
48
+ render :nothing => true
49
+ else
50
+ flash[:notice] = 'Asset deleted successfully.'
51
+ redirect_to request.referrer
52
+ end
53
+ end
54
+
55
+ def touch
56
+ raise ActiveRecord::RecordNotFound if current_file.nil?
57
+ current_file.touch
58
+ render :nothing => true
59
+ end
60
+
61
+ def gravity
62
+ raise ActiveRecord::RecordNotFound if current_file.nil?
63
+ current_file.update_attribute :attachment_gravity, params[:gravity]
64
+ render :nothing => true
65
+ end
66
+
67
+ def search
68
+ @current_files = File.with_query("^#{params[:q]}")
69
+ respond_to do |format|
70
+ format.js { render current_files, :content_type => :html }
71
+ format.json { render :json => current_files.to_json }
72
+ format.html { render :nothing => true }
73
+ end
74
+ end
75
+
76
+ protected
77
+
78
+ helper_method :current_files, :recent_files, :current_file
79
+
80
+ def current_files
81
+ conditions = AmpleAssets.allowed_mime_types.keys.include?(params[:action].intern) ? current_file_conditions : nil
82
+ pagination = { :page => params[:page], :per_page => per_page }
83
+ @current_files ||= File.find(:all, :conditions => conditions, :order => 'created_at DESC').paginate(pagination)
84
+ end
85
+
86
+ def current_file_conditions
87
+ are = params[:type] == 'documents' ? 'NOT in' : 'in'
88
+ type = params[:action].intern
89
+ [ "attachment_mime_type #{are} (?)", AmpleAssets.allowed_mime_types[type] ]
90
+ end
91
+
92
+ def recent_files
93
+ @recent_files ||= File.recent.paginate(:page => params[:page], :per_page => per_page)
94
+ end
95
+
96
+ def per_page
97
+ params[:per_page] || 20
98
+ end
99
+
100
+ def current_file
101
+ @current_file ||= File.find params[:id]
102
+ end
103
+
104
+ def uploadify?
105
+ params['Filename'] && params['Filedata']
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,4 @@
1
+ module AmpleAssets
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,79 @@
1
+ require 'dragonfly'
2
+
3
+ module AmpleAssets
4
+ class File < ActiveRecord::Base
5
+
6
+ ###---------------------------------------------------- Plugins
7
+
8
+ image_accessor :attachment do
9
+ after_assign { |a| self.keywords = a.name.gsub(/[^a-zA-Z0-9]/,' ').humanize unless a.name.nil? }
10
+ end
11
+
12
+ self.per_page = 20
13
+ acts_as_indexed :fields => [:keywords]
14
+
15
+ ###---------------------------------------------------- Scopes
16
+
17
+ scope :recent, order('updated_at DESC')
18
+
19
+ ###---------------------------------------------------- Validations
20
+
21
+ validates_presence_of :attachment
22
+ validates_property :mime_type, :of => :attachment, :in => AmpleAssets.allowed_mime_types.collect{ |a| a[1] }.flatten
23
+
24
+ ###---------------------------------------------------- Instance Methods
25
+
26
+ def is_swf?
27
+ attachment_mime_type == 'application/x-shockwave-flash'
28
+ end
29
+
30
+ def is_pdf?
31
+ attachment_mime_type == 'application/pdf'
32
+ end
33
+
34
+ def is_image?
35
+ AmpleAssets.allowed_mime_types[:images].include?(attachment_mime_type)
36
+ end
37
+
38
+ def is_doc?
39
+ AmpleAssets.allowed_mime_types[:documents].include?(attachment_mime_type)
40
+ end
41
+
42
+ def thumbnail
43
+ if is_image?
44
+ attachment.process(:matte, :dimensions => '75x75', :background => 'white').url
45
+ elsif is_swf?
46
+ AmpleAssets.icons[self.attachment_mime_type]
47
+ elsif AmpleAssets.icons.has_key?(self.attachment_mime_type)
48
+ AmpleAssets.icons[self.attachment_mime_type]
49
+ else
50
+ AmpleAssets.icons[:other]
51
+ end
52
+ end
53
+
54
+ def medium
55
+ attachment.thumb('500x>').url if is_image?
56
+ end
57
+
58
+ def orientation
59
+ attachment.portrait? ? 'portrait' : 'landscape'
60
+ end
61
+
62
+ def as_json(options={})
63
+ search_terms = keywords.split(" ") rescue nil
64
+ { :id => id,
65
+ :uid => attachment_uid,
66
+ :filename => attachment_name,
67
+ :document => is_doc? ? 'true' : 'false',
68
+ :orientation => orientation,
69
+ :mime_type => attachment_mime_type,
70
+ :keywords => search_terms,
71
+ :url => attachment.url,
72
+ :gravity => attachment_gravity,
73
+ :size => "#{attachment.width}x#{attachment.height}",
74
+ :sizes => { :tn => thumbnail, :md => medium }
75
+ }
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,12 @@
1
+ <div class="asset-drop">
2
+ <%= hidden_field object_name, method, :value => drop.try(:id) %>
3
+ <%= link_to 'Remove', '#', :class => 'asset-action asset-remove' + (drop ? '' : ' hide') %>
4
+ <%= link_to 'Select', '#', :class => 'asset-action asset-select' %>
5
+ <div class="droppable">
6
+ <% if drop %>
7
+ <%= link_to image_tag(drop.thumbnail, :size => '75x75'), ample_assets.file_path(drop), 'data-uid' => drop.attachment_uid, 'data-orientation' => drop.orientation, 'data-gravity' => drop.attachment_gravity %>
8
+ <% else %>
9
+ <span>Drag Asset Here</span>
10
+ <% end %>
11
+ </div>
12
+ </div>
@@ -0,0 +1 @@
1
+ <%= link_to image_tag(file.thumbnail, :size => '75x75'), ample_assets.file_path(file.id) %>
@@ -0,0 +1,3 @@
1
+ <%= content_tag :li, :class => :file do %>
2
+ <%= link_to '', file_path(file.id) %>
3
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= content_tag :ul do %>
2
+ <% current_files.each do |file| %>
3
+ <%= content_tag :li, render(file) %>
4
+ <% end %>
5
+ <% end %>
6
+ <%= will_paginate current_files %>
@@ -0,0 +1,21 @@
1
+ <% if request.xhr? %>
2
+
3
+ <p><input type="file" name="uploadify" id="uploadify" /></p>
4
+
5
+ <div id="fileQueue"></div>
6
+
7
+ <script type="text/javascript">
8
+ $(document).ready(function() {
9
+ new AmpleAssetsUploadify()
10
+ });
11
+ </script>
12
+
13
+ <% else %>
14
+
15
+ <%= form_for AmpleAssets::File.new, :multipart => true do |f| %>
16
+ <%= f.label :attachment %>
17
+ <%= f.file_field :attachment %>
18
+ <%= f.submit %>
19
+ <% end %>
20
+
21
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= content_tag :ul, render(recent_files) %>
@@ -0,0 +1 @@
1
+ <%= render :partial => 'file', :object => current_file %>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>AmpleAssets</title>
5
+ <%= stylesheet_link_tag "ample_assets/application" %>
6
+ <%= javascript_include_tag "ample_assets/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'ample_assets/devise_constraint'
2
+
3
+ AmpleAssets::Engine.routes.draw do
4
+
5
+ # Require authentication when Devise is detected
6
+ constraints(AmpleAssets::DeviseConstraint) do
7
+ resources :files do
8
+ member do
9
+ post :touch
10
+ post :gravity
11
+ end
12
+ collection do
13
+ post :search
14
+ get :recent
15
+ AmpleAssets.allowed_mime_types.keys.each do |key|
16
+ get key
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # This shouldn't be behind authentication
23
+ match '/files/thumbs/:geometry' => AmpleAssets.dfly.endpoint { |params, app|
24
+ AmpleAssets.dfly.fetch(params[:uid]).thumb(params[:geometry])
25
+ }
26
+
27
+ end
@@ -0,0 +1,26 @@
1
+ require 'ample_assets/configuration'
2
+ require 'ample_assets/plugin_methods'
3
+
4
+ module AmpleAssets
5
+ require 'ample_assets/engine' if defined?(Rails)
6
+ extend Configuration
7
+ class << self
8
+
9
+ # hooks AmpleAssets::ViewHelpers into ActionView::Base
10
+ def enable_actionpack
11
+ return if ActionView::Base.instance_methods.include? :asset_drop
12
+ require 'ample_assets/view_helper'
13
+ require 'ample_assets/form_helper'
14
+ require 'ample_assets/form_builder'
15
+ ActionView::Base.send :include, ViewHelper
16
+ ActionView::Base.send :include, AmpleAssets::FormHelper
17
+ ActionView::Helpers::FormBuilder.send :include, AmpleAssets::FormBuilder
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ if defined? Rails
24
+ AmpleAssets.enable_actionpack if defined? ActionController
25
+ ActiveRecord::Base.extend AmpleAssets::PluginMethods
26
+ end
@@ -0,0 +1,73 @@
1
+ require 'dragonfly'
2
+
3
+ module AmpleAssets
4
+ # Defines constants and methods related to configuration
5
+ module Configuration
6
+
7
+ # An array of valid keys in the options hash when configuring
8
+ VALID_OPTIONS_KEYS = [
9
+ :mount_at,
10
+ :dfly,
11
+ :tabs,
12
+ :icons,
13
+ :allowed_mime_types].freeze
14
+
15
+ # Route path prefix
16
+ DEFAULT_MOUNT_AT = '/ample_assets/'
17
+
18
+ # Access to Dragonfly
19
+ DEFAULT_DFLY = ::Dragonfly[:images]
20
+
21
+ # Tabs available in the Assets Toolbar
22
+ DEFAULT_TABS = [
23
+ { :id => 'recent-assets', :title => 'Recently Viewed', :url => '/ample_assets/files/recent', :panels => true, :data_type => 'json' },
24
+ { :id => 'image-assets', :title => 'Images', :url => '/ample_assets/files/images', :panels => true, :data_type => 'json' },
25
+ { :id => 'document-assets', :title => 'Documents', :url => '/ample_assets/files/documents', :panels => true, :data_type => 'json' },
26
+ { :id => 'upload', :title => 'Upload', :url => '/ample_assets/files/new' }
27
+ ]
28
+
29
+ # File types available for upload
30
+ DEFAULT_ALLOWED_MIME_TYPES = {
31
+ :images => %w(image/jpeg image/png image/gif),
32
+ :documents => %w(application/pdf),
33
+ :other => %w(application/x-shockwave-flash)
34
+ }
35
+
36
+ DEFAULT_ICONS = {
37
+ 'application/x-shockwave-flash' => '/assets/ample_assets/icon_swf.gif',
38
+ 'application/pdf' => '/assets/ample_assets/icon_pdf.gif',
39
+ :other => '/assets/ample_assets/icon_other.gif'
40
+ }
41
+
42
+ # @private
43
+ attr_accessor *VALID_OPTIONS_KEYS
44
+
45
+ # When this module is extended, set all configuration options to their default values
46
+ def self.extended(base)
47
+ base.reset
48
+ end
49
+
50
+ # Convenience method to allow configuration options to be set in a block
51
+ def configure
52
+ yield self
53
+ end
54
+
55
+ # Create a hash of options and their values
56
+ def options
57
+ options = {}
58
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
59
+ options
60
+ end
61
+
62
+ # Reset all configuration options to defaults
63
+ def reset
64
+ self.mount_at = DEFAULT_MOUNT_AT
65
+ self.dfly = DEFAULT_DFLY
66
+ self.tabs = DEFAULT_TABS
67
+ self.allowed_mime_types = DEFAULT_ALLOWED_MIME_TYPES
68
+ self.icons = DEFAULT_ICONS
69
+ self
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,29 @@
1
+ module AmpleAssets
2
+ class CustomProcessor
3
+
4
+ include Dragonfly::ImageMagick::Utils
5
+ include Dragonfly::Configurable
6
+
7
+ def matte(temp_object, args={})
8
+ opts = {
9
+ :background => 'transparent',
10
+ :gravity => 'Center',
11
+ :dimensions => '100x100'
12
+ }.merge(args)
13
+ raise "Geometry of #{opts[:dimensions]} not supported for matte images" unless opts[:dimensions][/^(\d+)x(\d+)$/]
14
+ convert(temp_object, "-gravity #{opts[:gravity]} -resize #{opts[:dimensions]}^> -crop #{opts[:dimensions]}+0+0>\! -background #{opts[:background]} -flatten")
15
+ end
16
+
17
+ def play_button(temp_object)
18
+ attrs = identify(temp_object)
19
+ # hardcoded for convenience
20
+ icon_size = 500.to_f
21
+ shortest_edge = [attrs[:width], attrs[:height]].max.to_f
22
+ scale = (shortest_edge / 3) / icon_size
23
+ final_icon_size = (scale * icon_size).to_i
24
+ geometry = "#{final_icon_size}x#{final_icon_size}+#{(attrs[:width]/2)-(final_icon_size/2)}+#{(attrs[:height]/2)-(final_icon_size/2)}"
25
+ convert(temp_object, "#{AmpleAssets::Engine.root}/app/assets/images/ample_assets/play.png -geometry #{geometry} -composite")
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ module AmpleAssets
2
+ class DeviseConstraint
3
+
4
+ def self.matches?(request)
5
+ request.env['warden'].present? ? request.env['warden'].authenticate! : true
6
+ end
7
+
8
+ end
9
+ end