beef-has_assets 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.
Files changed (41) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +7 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/admin/assets_controller.rb +159 -0
  8. data/app/helpers/admin/assets_helper.rb +34 -0
  9. data/app/models/asset.rb +72 -0
  10. data/app/models/asseting.rb +5 -0
  11. data/app/views/admin/assets/_browser.html.erb +25 -0
  12. data/app/views/admin/assets/_document.html.erb +12 -0
  13. data/app/views/admin/assets/_file_info.html.erb +51 -0
  14. data/app/views/admin/assets/_form.html.erb +26 -0
  15. data/app/views/admin/assets/_image.html.erb +19 -0
  16. data/app/views/admin/assets/_list.html.erb +12 -0
  17. data/app/views/admin/assets/_toggle.html.erb +4 -0
  18. data/app/views/admin/assets/index.html.erb +10 -0
  19. data/app/views/admin/assets/index.js.rjs +1 -0
  20. data/app/views/admin/assets/rename_category.js.rjs +1 -0
  21. data/app/views/admin/assets/show.html.erb +36 -0
  22. data/app/views/admin/assets/show.js.rjs +3 -0
  23. data/config/routes.rb +5 -0
  24. data/generators/asset_migration/asset_migration_generator.rb +11 -0
  25. data/generators/asset_migration/templates/migration.rb +30 -0
  26. data/generators/assets_admin_files/asset_admin_files_generator.rb +19 -0
  27. data/generators/assets_admin_files/templates/public/flash/swfupload.swf +0 -0
  28. data/generators/assets_admin_files/templates/public/javascripts/admin/assets.js +383 -0
  29. data/generators/assets_admin_files/templates/public/javascripts/swfupload.js +980 -0
  30. data/generators/assets_admin_files/templates/public/javascripts/upload_progress.js +179 -0
  31. data/has_assets.gemspec +76 -0
  32. data/lib/custom_redcloth_tags.rb +18 -0
  33. data/lib/flash_sesion_cookie_middleware.rb +16 -0
  34. data/lib/geometry_crop.rb +51 -0
  35. data/lib/has_assets.rb +28 -0
  36. data/lib/imagescience_crop.rb +40 -0
  37. data/lib/swfupload.rb +32 -0
  38. data/rails/init.rb +19 -0
  39. data/test/has_assets_test.rb +7 -0
  40. data/test/test_helper.rb +10 -0
  41. metadata +94 -0
@@ -0,0 +1,179 @@
1
+ var UploadHandler = {
2
+ fileQueueError: function(fileObj, error_code, message) {
3
+ try {
4
+ var error_name = "";
5
+ switch(error_code) {
6
+ case SWFUpload.ERROR_CODE_QUEUE_LIMIT_EXCEEDED:
7
+ error_name = "You have attempted to queue too many files.";
8
+ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
9
+ error_name = "This file is zero bytes, it may be corrupt";
10
+ break;
11
+ case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
12
+ error_name = "The file size is to large";
13
+ break;
14
+ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
15
+ case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
16
+ default:
17
+ image_name = "The file type is not allowed, these are jpg, gif, png";
18
+ break;
19
+ };
20
+
21
+ if (error_name !== "") {
22
+ alert(error_name);
23
+ return;
24
+ }
25
+
26
+ } catch (ex) { this.debug(ex); }
27
+
28
+ },
29
+
30
+ fileDialogComplete: function(num_files_queued) {
31
+ if (num_files_queued > 0) {
32
+ UploadProgress.create(this.customSettings.upload_form);
33
+ this.setPostParams($(this.customSettings.upload_form).serialize(true));
34
+ this.startUpload();
35
+ }
36
+ },
37
+
38
+ uploadStart: function(fileObj) {
39
+ UploadProgress.start(fileObj);
40
+ },
41
+
42
+ uploadProgress: function(fileObj, bytesLoaded) {
43
+ UploadProgress.update(fileObj, bytesLoaded);
44
+ },
45
+
46
+ uploadSuccess: function(fileObj, server_data) {
47
+ // Override to do something with the file
48
+ },
49
+
50
+ uploadComplete: function(fileObj) {
51
+ /* I want the next upload to continue automatically so I'll call startUpload here */
52
+ if (this.getStats().files_queued > 0) {
53
+ this.startUpload();
54
+ } else {
55
+ UploadProgress.finish();
56
+ }
57
+ },
58
+
59
+ uploadError: function(fileObj, error_code, message) {
60
+ switch(error_code) {
61
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
62
+ UploadProgress.errors('Upload Stoped');
63
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
64
+ UploadProgress.errors('Upload limit Exceeded');
65
+ break;
66
+ default:
67
+ UploadProgress.errors(message);
68
+ break;
69
+ }
70
+ }
71
+ };
72
+
73
+ var UploadProgress = {
74
+ create: function(form) {
75
+ if (!this.uploading) {
76
+ $$('div.progress-bar').invoke('remove');
77
+ this.uploadForm = $(form);
78
+ this.uploadForm.insert({ bottom: '<div class="progress-bar"></div>' });
79
+ this.container = this.uploadForm.down('div.progress-bar');
80
+ this.StatusBar.create(this.container);
81
+ this.uploading = true;
82
+ }
83
+ },
84
+
85
+ start: function(fileObj) {
86
+ this.StatusBar.update(0, "Begining upload of " + fileObj.name);
87
+ },
88
+
89
+
90
+ update: function(fileObj, current) {
91
+ var status = (current / fileObj.size);
92
+ var statusHTML = "<div id='total-loaded'><strong>" + fileObj.name + "</strong> " + status.toPercentage() + "<br>" + current.toHumanSize() + ' of ' + fileObj.size.toHumanSize() + " uploaded.</div>";
93
+ this.StatusBar.update(status, statusHTML);
94
+ },
95
+
96
+ finish: function() {
97
+ this.uploading = false;
98
+ this.StatusBar.finish();
99
+ },
100
+
101
+ errors: function(html) {
102
+ this.uploadForm.insert({top: '<div class="upload-errors">' + html + '</div>'});
103
+ },
104
+
105
+ cancel: function(msg) {
106
+ if(!this.uploading) return;
107
+ this.uploading = false;
108
+ if(this.StatusBar.statusText) this.StatusBar.statusText.innerHTML = msg || 'canceled';
109
+ },
110
+
111
+ StatusBar: {
112
+ statusBar: null,
113
+ statusText: null,
114
+ statusBarWidth: 500,
115
+
116
+ create: function(element) {
117
+ this.progress = element;
118
+ this.statusBar = this._createStatus('status-bar');
119
+ this.statusText = this._createStatus('status-text');
120
+ this.statusText.innerHTML = '0%';
121
+ this.statusBar.style.width = '0';
122
+ },
123
+
124
+ update: function(status, statusHTML) {
125
+ this.statusText.innerHTML = statusHTML;
126
+ this.statusBar.style.width = status.toPercentage();
127
+ },
128
+
129
+ finish: function() {
130
+ this.statusText.innerHTML = 'All files uploaded';
131
+ this.statusBar.style.width = '100%';
132
+ },
133
+
134
+ _createStatus: function(id) {
135
+ el = this.progress.getElementsByClassName(id)[0];
136
+ if(!el) {
137
+ el = new Element('span', { 'class': id });
138
+ this.progress.appendChild(el);
139
+ }
140
+ return el;
141
+ }
142
+ }
143
+
144
+ };
145
+
146
+ Number.prototype.bytes = function() { return this; };
147
+ Number.prototype.kilobytes = function() { return this * 1024; };
148
+ Number.prototype.megabytes = function() { return this * (1024).kilobytes(); };
149
+ Number.prototype.gigabytes = function() { return this * (1024).megabytes(); };
150
+ Number.prototype.terabytes = function() { return this * (1024).gigabytes(); };
151
+ Number.prototype.petabytes = function() { return this * (1024).terabytes(); };
152
+ Number.prototype.exabytes = function() { return this * (1024).petabytes(); };
153
+ ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte', 'exabyte'].each(function(meth) {
154
+ Number.prototype[meth] = Number.prototype[meth+'s'];
155
+ });
156
+
157
+ Number.prototype.toPrecision = function() {
158
+ var precision = arguments[0] || 2;
159
+ var s = Math.round(this * Math.pow(10, precision)).toString();
160
+ var pos = s.length - precision;
161
+ var last = s.substr(pos, precision);
162
+ return s.substr(0, pos) + (last.match("^0{" + precision + "}$") ? '' : '.' + last);
163
+ };
164
+
165
+ // (1/10).toPercentage()
166
+ // # => '10%'
167
+ Number.prototype.toPercentage = function() {
168
+ return Math.ceil(this * 100) + '%';
169
+ };
170
+
171
+ Number.prototype.toHumanSize = function() {
172
+ if(this < (1).kilobyte()) return this + " Bytes";
173
+ if(this < (1).megabyte()) return (this / (1).kilobyte()).toPrecision() + ' KB';
174
+ if(this < (1).gigabytes()) return (this / (1).megabyte()).toPrecision() + ' MB';
175
+ if(this < (1).terabytes()) return (this / (1).gigabytes()).toPrecision() + ' GB';
176
+ if(this < (1).petabytes()) return (this / (1).terabytes()).toPrecision() + ' TB';
177
+ if(this < (1).exabytes()) return (this / (1).petabytes()).toPrecision() + ' PB';
178
+ return (this / (1).exabytes()).toPrecision() + ' EB';
179
+ };
@@ -0,0 +1,76 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{has_assets}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Steve England"]
9
+ s.date = %q{2009-06-24}
10
+ s.email = %q{steve@wearebeef.co.uk}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "app/controllers/admin/assets_controller.rb",
23
+ "app/helpers/admin/assets_helper.rb",
24
+ "app/models/asset.rb",
25
+ "app/models/asseting.rb",
26
+ "app/views/admin/assets/_browser.html.erb",
27
+ "app/views/admin/assets/_document.html.erb",
28
+ "app/views/admin/assets/_file_info.html.erb",
29
+ "app/views/admin/assets/_form.html.erb",
30
+ "app/views/admin/assets/_image.html.erb",
31
+ "app/views/admin/assets/_list.html.erb",
32
+ "app/views/admin/assets/_toggle.html.erb",
33
+ "app/views/admin/assets/index.html.erb",
34
+ "app/views/admin/assets/index.js.rjs",
35
+ "app/views/admin/assets/rename_category.js.rjs",
36
+ "app/views/admin/assets/show.html.erb",
37
+ "app/views/admin/assets/show.js.rjs",
38
+ "config/routes.rb",
39
+ "generators/asset_migration/asset_migration_generator.rb",
40
+ "generators/asset_migration/templates/migration.rb",
41
+ "generators/assets_admin_files/asset_admin_files_generator.rb",
42
+ "generators/assets_admin_files/templates/public/flash/swfupload.swf",
43
+ "generators/assets_admin_files/templates/public/javascripts/admin/assets.js",
44
+ "generators/assets_admin_files/templates/public/javascripts/swfupload.js",
45
+ "generators/assets_admin_files/templates/public/javascripts/upload_progress.js",
46
+ "has_assets.gemspec",
47
+ "lib/custom_redcloth_tags.rb",
48
+ "lib/flash_sesion_cookie_middleware.rb",
49
+ "lib/geometry_crop.rb",
50
+ "lib/has_assets.rb",
51
+ "lib/imagescience_crop.rb",
52
+ "lib/swfupload.rb",
53
+ "rails/init.rb",
54
+ "test/has_assets_test.rb",
55
+ "test/test_helper.rb"
56
+ ]
57
+ s.homepage = %q{http://github.com/beef/assets}
58
+ s.rdoc_options = ["--charset=UTF-8"]
59
+ s.require_paths = ["lib"]
60
+ s.rubygems_version = %q{1.3.3}
61
+ s.summary = %q{Rails Engine. Adds uploadable assets to a model and admin area for files}
62
+ s.test_files = [
63
+ "test/has_assets_test.rb",
64
+ "test/test_helper.rb"
65
+ ]
66
+
67
+ if s.respond_to? :specification_version then
68
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
69
+ s.specification_version = 3
70
+
71
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
72
+ else
73
+ end
74
+ else
75
+ end
76
+ end
@@ -0,0 +1,18 @@
1
+ module RedCloth::Formatters::HTML
2
+ def after_transform(text)
3
+ # Asset Links
4
+ text.gsub! /\[asset\(([^\)]+)\)\]/ do |s|
5
+ asset_id, size = $1.split('|')
6
+ asset = Asset.find_by_id(asset_id)
7
+ return if asset.nil?
8
+ html = "<a href=\"#{asset.public_filename}\" class=\"fancybox\" rel=\"group\">"
9
+ if asset.is_image?
10
+ html << "<img src=\"#{asset.public_filename(size)}\" alt=\"#{asset.description}\" />"
11
+ else
12
+ html << asset.description.titleize
13
+ end
14
+ html << '</a>'
15
+ end
16
+ text.chomp!
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require 'rack/utils'
2
+
3
+ class FlashSessionCookieMiddleware
4
+ def initialize(app, session_key = '_session_id')
5
+ @app = app
6
+ @session_key = session_key
7
+ end
8
+
9
+ def call(env)
10
+ if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
11
+ params = ::Rack::Utils.parse_query(env['QUERY_STRING'])
12
+ env['HTTP_COOKIE'] = [ @session_key, params[@session_key] ].join('=').freeze unless params[@session_key].nil?
13
+ end
14
+ @app.call(env)
15
+ end
16
+ end
@@ -0,0 +1,51 @@
1
+ Geometry.module_eval do
2
+ # ! and @ are removed until support for them is added
3
+ FLAGS = ['', '%', '<', '>', '!']#, '@']
4
+
5
+ # Convert object to a geometry string
6
+ def to_s
7
+ str = ''
8
+ str << "%g" % @width if @width > 0
9
+ str << 'x' if (@width > 0 || @height > 0)
10
+ str << "%g" % @height if @height > 0
11
+ str << "%+d%+d" % [@x, @y] if (@x != 0 || @y != 0)
12
+ str << RFLAGS.index(@flag)
13
+ end
14
+
15
+ # attempts to get new dimensions for the current geometry string given these old dimensions.
16
+ # This doesn't implement the aspect flag (!) or the area flag (@). PDI
17
+ def new_dimensions_for(orig_width, orig_height)
18
+ new_width = orig_width
19
+ new_height = orig_height
20
+
21
+ RAILS_DEFAULT_LOGGER.debug "Flag is #{@flag}"
22
+
23
+ case @flag
24
+ when :aspect
25
+ new_width = @width unless @width.nil?
26
+ new_height = @height unless @height.nil?
27
+ when :percent
28
+ scale_x = @width.zero? ? 100 : @width
29
+ scale_y = @height.zero? ? @width : @height
30
+ new_width = scale_x.to_f * (orig_width.to_f / 100.0)
31
+ new_height = scale_y.to_f * (orig_height.to_f / 100.0)
32
+ when :<, :>, nil
33
+ scale_factor =
34
+ if new_width.zero? || new_height.zero?
35
+ 1.0
36
+ else
37
+ if @width.nonzero? && @height.nonzero?
38
+ [@width.to_f / new_width.to_f, @height.to_f / new_height.to_f].min
39
+ else
40
+ @width.nonzero? ? (@width.to_f / new_width.to_f) : (@height.to_f / new_height.to_f)
41
+ end
42
+ end
43
+ new_width = scale_factor * new_width.to_f
44
+ new_height = scale_factor * new_height.to_f
45
+ new_width = orig_width if @flag && orig_width.send(@flag, new_width)
46
+ new_height = orig_height if @flag && orig_height.send(@flag, new_height)
47
+ end
48
+
49
+ [new_width, new_height].collect! { |v| v.round }
50
+ end
51
+ end
data/lib/has_assets.rb ADDED
@@ -0,0 +1,28 @@
1
+ module Beef
2
+ module Has
3
+ module Assets
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def has_assets
10
+ has_many :assetings, :as => :assetable, :order => 'assetable.id', :dependent => :delete_all
11
+ has_many :assets, :through => :assetings
12
+
13
+ # Override the default asset_ids method
14
+ define_method("asset_ids=") do |new_value|
15
+ ids = (new_value || []).reject { |nid| nid.blank? }
16
+ ids.collect!{ |id| id.to_i}
17
+ logger.debug "ASSETS the same #{ids == self.asset_ids} | IDS #{ids} | #{self.asset_ids}"
18
+ return if ids == self.asset_ids
19
+ self.assets.clear
20
+ ids.each_index do |idx|
21
+ self.assets << Asset.find(ids[idx])
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ Technoweenie::AttachmentFu::Processors::ImageScienceProcessor.module_eval do
2
+ def resize_image(img, size)
3
+ # img.strip!
4
+ # create a dummy temp file to write to
5
+ filename.sub! /gif$/, 'png'
6
+ content_type.sub!(/gif$/, 'png')
7
+ temp_paths.unshift write_to_temp_file(filename)
8
+ grab_dimensions = lambda do |img|
9
+ self.width = img.width if respond_to?(:width)
10
+ self.height = img.height if respond_to?(:height)
11
+ img.save self.temp_path
12
+ self.size = File.size(self.temp_path)
13
+ callback_with_args :after_resize, img
14
+ end
15
+
16
+ size = size.first if size.is_a?(Array) && size.length == 1
17
+
18
+ if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
19
+ if size.is_a?(Fixnum)
20
+ img.thumbnail(size, &grab_dimensions)
21
+ else
22
+ img.resize(size[0], size[1], &grab_dimensions)
23
+ end
24
+ else
25
+ n_size = [img.width, img.height] / size.to_s
26
+ if size.ends_with? "!"
27
+ aspect = n_size[0].to_f / n_size[1].to_f
28
+ ih, iw = img.height, img.width
29
+ w, h = (ih * aspect), (iw / aspect)
30
+ w = [iw, w].min.to_i
31
+ h = [ih, h].min.to_i
32
+ img.with_crop( (iw-w)/2, (ih-h)/2, (iw+w)/2, (ih+h)/2) {
33
+ |crop| crop.resize(n_size[0], n_size[1], &grab_dimensions )
34
+ }
35
+ else
36
+ img.resize(n_size[0], n_size[1], &grab_dimensions)
37
+ end
38
+ end
39
+ end
40
+ end
data/lib/swfupload.rb ADDED
@@ -0,0 +1,32 @@
1
+ Technoweenie::AttachmentFu::InstanceMethods.module_eval do
2
+
3
+ # Overriding this method to allow content_type to be detected when
4
+ # swfupload submits images with content_type set to 'application/octet-stream'
5
+ def uploaded_data=(file_data)
6
+ if file_data.respond_to?(:content_type)
7
+ return nil if file_data.size == 0
8
+ self.content_type = detect_mimetype(file_data)
9
+ self.filename = file_data.original_filename if respond_to?(:filename)
10
+ else
11
+ return nil if file_data.blank? || file_data['size'] == 0
12
+ self.content_type = file_data['content_type']
13
+ self.filename = file_data['filename']
14
+ file_data = file_data['tempfile']
15
+ end
16
+ if file_data.is_a?(StringIO)
17
+ file_data.rewind
18
+ set_temp_data file_data.read
19
+ else
20
+ self.temp_paths.unshift file_data
21
+ end
22
+ end
23
+
24
+ def detect_mimetype(file_data)
25
+ if file_data.content_type.strip == "application/octet-stream"
26
+ return File.mime_type?(file_data.original_filename)
27
+ else
28
+ return file_data.content_type
29
+ end
30
+ end
31
+
32
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'flash_sesion_cookie_middleware'
2
+ require 'admin_area'
3
+ require 'swfupload'
4
+ require 'geometry_crop'
5
+ require 'imagescience_crop'
6
+
7
+ config.to_prepare do
8
+ # Rack middleware for fixing flash's issues with sessions
9
+ # http://thewebfellas.com/blog/2008/12/22/flash-uploaders-rails-cookie-based-sessions-and-csrf-rack-middleware-to-the-rescue
10
+ ActionController::Dispatcher.middleware.use FlashSessionCookieMiddleware, ActionController::Base.session_options[:key]
11
+ # Add the asset management helpers to admin
12
+ Admin::BaseController.helper(Admin::AssetsHelper)
13
+ end
14
+ ActiveRecord::Base.send :include, Beef::Has::Assets
15
+
16
+ if defined?(Redcloth)
17
+ require 'custom_redcloth_tags'
18
+ end
19
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class HasAssetsTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'has_assets'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beef-has_assets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Steve England
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-24 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: steve@wearebeef.co.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - app/controllers/admin/assets_controller.rb
33
+ - app/helpers/admin/assets_helper.rb
34
+ - app/models/asset.rb
35
+ - app/models/asseting.rb
36
+ - app/views/admin/assets/_browser.html.erb
37
+ - app/views/admin/assets/_document.html.erb
38
+ - app/views/admin/assets/_file_info.html.erb
39
+ - app/views/admin/assets/_form.html.erb
40
+ - app/views/admin/assets/_image.html.erb
41
+ - app/views/admin/assets/_list.html.erb
42
+ - app/views/admin/assets/_toggle.html.erb
43
+ - app/views/admin/assets/index.html.erb
44
+ - app/views/admin/assets/index.js.rjs
45
+ - app/views/admin/assets/rename_category.js.rjs
46
+ - app/views/admin/assets/show.html.erb
47
+ - app/views/admin/assets/show.js.rjs
48
+ - config/routes.rb
49
+ - generators/asset_migration/asset_migration_generator.rb
50
+ - generators/asset_migration/templates/migration.rb
51
+ - generators/assets_admin_files/asset_admin_files_generator.rb
52
+ - generators/assets_admin_files/templates/public/flash/swfupload.swf
53
+ - generators/assets_admin_files/templates/public/javascripts/admin/assets.js
54
+ - generators/assets_admin_files/templates/public/javascripts/swfupload.js
55
+ - generators/assets_admin_files/templates/public/javascripts/upload_progress.js
56
+ - has_assets.gemspec
57
+ - lib/custom_redcloth_tags.rb
58
+ - lib/flash_sesion_cookie_middleware.rb
59
+ - lib/geometry_crop.rb
60
+ - lib/has_assets.rb
61
+ - lib/imagescience_crop.rb
62
+ - lib/swfupload.rb
63
+ - rails/init.rb
64
+ - test/has_assets_test.rb
65
+ - test/test_helper.rb
66
+ has_rdoc: false
67
+ homepage: http://github.com/beef/assets
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --charset=UTF-8
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.2.0
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Rails Engine. Adds uploadable assets to a model and admin area for files
92
+ test_files:
93
+ - test/has_assets_test.rb
94
+ - test/test_helper.rb