admin_assistant 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/admin_assistant.gemspec +1 -285
- metadata +3 -287
- data/test_rails_app/README +0 -256
- data/test_rails_app/Rakefile +0 -13
- data/test_rails_app/app/controllers/admin/appointments2_controller.rb +0 -15
- data/test_rails_app/app/controllers/admin/appointments_controller.rb +0 -11
- data/test_rails_app/app/controllers/admin/blog_posts2_controller.rb +0 -138
- data/test_rails_app/app/controllers/admin/blog_posts3_controller.rb +0 -76
- data/test_rails_app/app/controllers/admin/blog_posts4_controller.rb +0 -21
- data/test_rails_app/app/controllers/admin/blog_posts5_controller.rb +0 -27
- data/test_rails_app/app/controllers/admin/blog_posts6_controller.rb +0 -10
- data/test_rails_app/app/controllers/admin/blog_posts_controller.rb +0 -8
- data/test_rails_app/app/controllers/admin/blog_posts_custom_new_and_edit_controller.rb +0 -15
- data/test_rails_app/app/controllers/admin/blog_posts_read_only_controller.rb +0 -19
- data/test_rails_app/app/controllers/admin/bookmarks_controller.rb +0 -11
- data/test_rails_app/app/controllers/admin/comments2_controller.rb +0 -14
- data/test_rails_app/app/controllers/admin/comments_controller.rb +0 -12
- data/test_rails_app/app/controllers/admin/file_column_images2_controller.rb +0 -10
- data/test_rails_app/app/controllers/admin/file_column_images_controller.rb +0 -6
- data/test_rails_app/app/controllers/admin/images2_controller.rb +0 -11
- data/test_rails_app/app/controllers/admin/images_controller.rb +0 -6
- data/test_rails_app/app/controllers/admin/misconfigured1_controller.rb +0 -7
- data/test_rails_app/app/controllers/admin/not_migrated_yets_controller.rb +0 -9
- data/test_rails_app/app/controllers/admin/product_categories2_controller.rb +0 -7
- data/test_rails_app/app/controllers/admin/product_categories_controller.rb +0 -5
- data/test_rails_app/app/controllers/admin/products2_controller.rb +0 -15
- data/test_rails_app/app/controllers/admin/products_controller.rb +0 -31
- data/test_rails_app/app/controllers/admin/television_airings_controller.rb +0 -5
- data/test_rails_app/app/controllers/admin/television_time_slots_controller.rb +0 -5
- data/test_rails_app/app/controllers/admin/users2_controller.rb +0 -10
- data/test_rails_app/app/controllers/admin/users_controller.rb +0 -63
- data/test_rails_app/app/controllers/application.rb +0 -16
- data/test_rails_app/app/controllers/application_controller.rb +0 -16
- data/test_rails_app/app/controllers/blog_posts_controller.rb +0 -5
- data/test_rails_app/app/helpers/admin/appointments2_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/appointments_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/blog_posts2_helper.rb +0 -27
- data/test_rails_app/app/helpers/admin/blog_posts3_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/blog_posts4_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/blog_posts6_helper.rb +0 -16
- data/test_rails_app/app/helpers/admin/blog_posts_custom_new_and_edit_helper.rb +0 -29
- data/test_rails_app/app/helpers/admin/blog_posts_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/blog_posts_read_only_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/bookmarks_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/comments2_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/comments_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/file_column_images2_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/file_column_images_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/images2_helper.rb +0 -8
- data/test_rails_app/app/helpers/admin/images_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/misconfigured1_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/not_migrated_yets_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/product_categories2_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/product_categories_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/products2_helper.rb +0 -3
- data/test_rails_app/app/helpers/admin/products_helper.rb +0 -6
- data/test_rails_app/app/helpers/admin/television_airings_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/television_time_slots_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/users2_helper.rb +0 -2
- data/test_rails_app/app/helpers/admin/users_helper.rb +0 -25
- data/test_rails_app/app/helpers/application_helper.rb +0 -3
- data/test_rails_app/app/helpers/blog_posts_helper.rb +0 -2
- data/test_rails_app/app/models/appointment.rb +0 -5
- data/test_rails_app/app/models/blog_post.rb +0 -14
- data/test_rails_app/app/models/blog_post_tag.rb +0 -6
- data/test_rails_app/app/models/bookmark.rb +0 -6
- data/test_rails_app/app/models/comment.rb +0 -4
- data/test_rails_app/app/models/file_column_image.rb +0 -3
- data/test_rails_app/app/models/image.rb +0 -3
- data/test_rails_app/app/models/not_migrated_yet.rb +0 -2
- data/test_rails_app/app/models/product.rb +0 -7
- data/test_rails_app/app/models/product_category.rb +0 -9
- data/test_rails_app/app/models/tag.rb +0 -4
- data/test_rails_app/app/models/television_airing.rb +0 -3
- data/test_rails_app/app/models/television_time_slot.rb +0 -11
- data/test_rails_app/app/models/user.rb +0 -14
- data/test_rails_app/app/views/admin/appointments/_subject_input.html.erb +0 -2
- data/test_rails_app/app/views/admin/appointments2/_time_input.html.erb +0 -31
- data/test_rails_app/app/views/admin/blog_posts2/_after_form.html.erb +0 -5
- data/test_rails_app/app/views/admin/blog_posts2/_after_index.html.erb +0 -1
- data/test_rails_app/app/views/admin/blog_posts2/_after_tags_input.html.erb +0 -16
- data/test_rails_app/app/views/admin/blog_posts2/_before_index.html.erb +0 -2
- data/test_rails_app/app/views/admin/blog_posts5/_after_index_header.html.erb +0 -8
- data/test_rails_app/app/views/admin/blog_posts_read_only/_body_for_show.html.erb +0 -1
- data/test_rails_app/app/views/admin/products/_name_input.html.erb +0 -2
- data/test_rails_app/app/views/admin/products/_percent_off_input.html.erb +0 -2
- data/test_rails_app/app/views/admin/products/_price_input.html.erb +0 -10
- data/test_rails_app/app/views/blog_posts/show.html.erb +0 -13
- data/test_rails_app/app/views/layouts/admin.html.erb +0 -31
- data/test_rails_app/config/boot.rb +0 -109
- data/test_rails_app/config/database.yml +0 -28
- data/test_rails_app/config/environment.rb +0 -78
- data/test_rails_app/config/environments/development.rb +0 -17
- data/test_rails_app/config/environments/production.rb +0 -24
- data/test_rails_app/config/environments/test.rb +0 -24
- data/test_rails_app/config/initializers/inflections.rb +0 -10
- data/test_rails_app/config/initializers/mime_types.rb +0 -5
- data/test_rails_app/config/initializers/new_rails_defaults.rb +0 -17
- data/test_rails_app/config/locales/en.yml +0 -5
- data/test_rails_app/config/routes.rb +0 -43
- data/test_rails_app/db/migrate/20090213215514_create_blog_posts.rb +0 -12
- data/test_rails_app/db/migrate/20090217225542_add_body_to_blog_posts.rb +0 -9
- data/test_rails_app/db/migrate/20090221220917_create_tags.rb +0 -13
- data/test_rails_app/db/migrate/20090221220947_create_blog_post_tags.rb +0 -14
- data/test_rails_app/db/migrate/20090222162204_add_textile_to_blog_posts.rb +0 -9
- data/test_rails_app/db/migrate/20090222163231_add_published_at_to_blog_posts.rb +0 -9
- data/test_rails_app/db/migrate/20090301191722_create_images.rb +0 -16
- data/test_rails_app/db/migrate/20090305165345_create_accounts.rb +0 -14
- data/test_rails_app/db/migrate/20090307225027_rename_accounts_to_users.rb +0 -9
- data/test_rails_app/db/migrate/20090307225750_add_user_id_to_blog_posts.rb +0 -9
- data/test_rails_app/db/migrate/20090309185114_change_blog_posts_textile.rb +0 -9
- data/test_rails_app/db/migrate/20090309193635_create_products.rb +0 -14
- data/test_rails_app/db/migrate/20090309203056_create_comments.rb +0 -15
- data/test_rails_app/db/migrate/20090323005947_create_file_column_images.rb +0 -12
- data/test_rails_app/db/migrate/20090326160049_add_birthday_to_users.rb +0 -9
- data/test_rails_app/db/migrate/20090326223606_add_state_to_users.rb +0 -9
- data/test_rails_app/db/migrate/20090503134004_add_file_column_image_to_products.rb +0 -9
- data/test_rails_app/db/migrate/20090617173651_create_bookmarks.rb +0 -15
- data/test_rails_app/db/migrate/20090624165355_add_tags_string_to_blog_post.rb +0 -9
- data/test_rails_app/db/migrate/20090625144313_add_avatar_fields_to_user.rb +0 -11
- data/test_rails_app/db/migrate/20090629202956_add_merged_into_to_blog_posts.rb +0 -9
- data/test_rails_app/db/migrate/20090701171857_add_force_textile_to_users.rb +0 -9
- data/test_rails_app/db/migrate/20090704163647_add_deleted_at_to_products.rb +0 -9
- data/test_rails_app/db/migrate/20090704173800_add_sale_fields_to_products.rb +0 -13
- data/test_rails_app/db/migrate/20090714024501_create_product_categories.rb +0 -15
- data/test_rails_app/db/migrate/20090819162835_add_admin_level_to_users.rb +0 -9
- data/test_rails_app/db/migrate/20091115134559_add_first_and_last_names_to_users.rb +0 -11
- data/test_rails_app/db/migrate/20091221011256_add_position_to_product_categories.rb +0 -9
- data/test_rails_app/db/migrate/20091222160814_create_appointments.rb +0 -14
- data/test_rails_app/db/migrate/20091227224547_add_user_id_to_appointments.rb +0 -9
- data/test_rails_app/db/migrate/20100214213359_create_television_time_slots.rb +0 -13
- data/test_rails_app/db/migrate/20100214213451_create_television_airings.rb +0 -15
- data/test_rails_app/doc/README_FOR_APP +0 -5
- data/test_rails_app/lib/tasks/rspec.rake +0 -163
- data/test_rails_app/public/404.html +0 -30
- data/test_rails_app/public/422.html +0 -30
- data/test_rails_app/public/500.html +0 -33
- data/test_rails_app/public/dispatch.cgi +0 -10
- data/test_rails_app/public/dispatch.fcgi +0 -24
- data/test_rails_app/public/dispatch.rb +0 -10
- data/test_rails_app/public/favicon.ico +0 -0
- data/test_rails_app/public/images/rails.png +0 -0
- data/test_rails_app/public/index.html +0 -274
- data/test_rails_app/public/javascripts/application.js +0 -2
- data/test_rails_app/public/javascripts/controls.js +0 -963
- data/test_rails_app/public/javascripts/dragdrop.js +0 -973
- data/test_rails_app/public/javascripts/effects.js +0 -1128
- data/test_rails_app/public/javascripts/prototype.js +0 -4320
- data/test_rails_app/public/robots.txt +0 -5
- data/test_rails_app/public/stylesheets/admin.css +0 -3
- data/test_rails_app/public/stylesheets/scaffold.css +0 -54
- data/test_rails_app/script/about +0 -4
- data/test_rails_app/script/autospec +0 -5
- data/test_rails_app/script/console +0 -3
- data/test_rails_app/script/dbconsole +0 -3
- data/test_rails_app/script/destroy +0 -3
- data/test_rails_app/script/generate +0 -3
- data/test_rails_app/script/performance/benchmarker +0 -3
- data/test_rails_app/script/performance/profiler +0 -3
- data/test_rails_app/script/performance/request +0 -3
- data/test_rails_app/script/plugin +0 -3
- data/test_rails_app/script/populate_tables.rb +0 -49
- data/test_rails_app/script/process/inspector +0 -3
- data/test_rails_app/script/process/reaper +0 -3
- data/test_rails_app/script/process/spawner +0 -3
- data/test_rails_app/script/runner +0 -3
- data/test_rails_app/script/server +0 -3
- data/test_rails_app/script/spec +0 -5
- data/test_rails_app/script/spec_server +0 -125
- data/test_rails_app/spec/controllers/admin/appointments2_controller_spec.rb +0 -88
- data/test_rails_app/spec/controllers/admin/appointments_controller_spec.rb +0 -419
- data/test_rails_app/spec/controllers/admin/blog_posts2_controller_spec.rb +0 -1021
- data/test_rails_app/spec/controllers/admin/blog_posts3_controller_spec.rb +0 -532
- data/test_rails_app/spec/controllers/admin/blog_posts4_controller_spec.rb +0 -231
- data/test_rails_app/spec/controllers/admin/blog_posts5_controller_spec.rb +0 -77
- data/test_rails_app/spec/controllers/admin/blog_posts6_controller_spec.rb +0 -49
- data/test_rails_app/spec/controllers/admin/blog_posts_controller_spec.rb +0 -987
- data/test_rails_app/spec/controllers/admin/blog_posts_custom_new_and_edit_controller_spec.rb +0 -99
- data/test_rails_app/spec/controllers/admin/blog_posts_read_only_controller_spec.rb +0 -94
- data/test_rails_app/spec/controllers/admin/bookmarks_controller_spec.rb +0 -505
- data/test_rails_app/spec/controllers/admin/comments2_controller_spec.rb +0 -70
- data/test_rails_app/spec/controllers/admin/comments_controller_spec.rb +0 -82
- data/test_rails_app/spec/controllers/admin/file_column_images2_controller_spec.rb +0 -25
- data/test_rails_app/spec/controllers/admin/file_column_images_controller_spec.rb +0 -82
- data/test_rails_app/spec/controllers/admin/images2_controller_spec.rb +0 -44
- data/test_rails_app/spec/controllers/admin/images_controller_spec.rb +0 -97
- data/test_rails_app/spec/controllers/admin/misconfigured1_controller_spec.rb +0 -21
- data/test_rails_app/spec/controllers/admin/not_migrated_yets_controller_spec.rb +0 -10
- data/test_rails_app/spec/controllers/admin/product_categories2_controller_spec.rb +0 -215
- data/test_rails_app/spec/controllers/admin/product_categories_controller_spec.rb +0 -19
- data/test_rails_app/spec/controllers/admin/products2_controller_spec.rb +0 -203
- data/test_rails_app/spec/controllers/admin/products_controller_spec.rb +0 -255
- data/test_rails_app/spec/controllers/admin/television_airings_controller_spec.rb +0 -32
- data/test_rails_app/spec/controllers/admin/television_time_slots_controller_spec.rb +0 -10
- data/test_rails_app/spec/controllers/admin/users2_controller_spec.rb +0 -65
- data/test_rails_app/spec/controllers/admin/users_controller_spec.rb +0 -344
- data/test_rails_app/spec/controllers/blog_posts_controller_spec.rb +0 -13
- data/test_rails_app/spec/data/ruby_throated.jpg +0 -0
- data/test_rails_app/spec/data/tweenbot.jpg +0 -0
- data/test_rails_app/spec/fixtures/appointments.yml +0 -9
- data/test_rails_app/spec/fixtures/blog_post_tags.yml +0 -9
- data/test_rails_app/spec/fixtures/blog_posts.yml +0 -7
- data/test_rails_app/spec/fixtures/bookmarks.yml +0 -11
- data/test_rails_app/spec/fixtures/comments.yml +0 -11
- data/test_rails_app/spec/fixtures/file_column_images.yml +0 -7
- data/test_rails_app/spec/fixtures/images.yml +0 -7
- data/test_rails_app/spec/fixtures/not_migrated_yets.yml +0 -7
- data/test_rails_app/spec/fixtures/product_categories.yml +0 -7
- data/test_rails_app/spec/fixtures/products.yml +0 -9
- data/test_rails_app/spec/fixtures/tags.yml +0 -7
- data/test_rails_app/spec/fixtures/television_airings.yml +0 -11
- data/test_rails_app/spec/fixtures/television_time_slots.yml +0 -7
- data/test_rails_app/spec/fixtures/users.yml +0 -9
- data/test_rails_app/spec/helpers/admin/appointments2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/appointments_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts3_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts4_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts_custom_new_and_edit_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/blog_posts_read_only_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/bookmarks_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/comments2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/comments_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/file_column_images2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/file_column_images_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/images2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/images_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/misconfigured1_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/not_migrated_yets_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/product_categories2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/product_categories_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/products2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/products_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/television_airings_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/television_time_slots_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/users2_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/admin/users_helper_spec.rb +0 -11
- data/test_rails_app/spec/helpers/blog_posts_helper_spec.rb +0 -11
- data/test_rails_app/spec/models/appointment_spec.rb +0 -16
- data/test_rails_app/spec/models/blog_post_spec.rb +0 -13
- data/test_rails_app/spec/models/blog_post_tag_spec.rb +0 -14
- data/test_rails_app/spec/models/bookmark_spec.rb +0 -15
- data/test_rails_app/spec/models/comment_spec.rb +0 -15
- data/test_rails_app/spec/models/file_column_image_spec.rb +0 -12
- data/test_rails_app/spec/models/image_spec.rb +0 -12
- data/test_rails_app/spec/models/not_migrated_yet_spec.rb +0 -15
- data/test_rails_app/spec/models/product_category_spec.rb +0 -15
- data/test_rails_app/spec/models/product_spec.rb +0 -14
- data/test_rails_app/spec/models/tag_spec.rb +0 -13
- data/test_rails_app/spec/models/television_airing_spec.rb +0 -15
- data/test_rails_app/spec/models/television_time_slot_spec.rb +0 -13
- data/test_rails_app/spec/models/user_spec.rb +0 -14
- data/test_rails_app/spec/rcov.opts +0 -2
- data/test_rails_app/spec/spec.opts +0 -4
- data/test_rails_app/spec/spec_helper.rb +0 -88
- data/test_rails_app/spec/spec_or_test_helper.rb +0 -49
- data/test_rails_app/test/fixtures/file_column_images.yml +0 -7
- data/test_rails_app/test/integration/admin_blog_posts2_integration_test.rb +0 -16
- data/test_rails_app/test/integration/admin_blog_posts5_integration_test.rb +0 -19
- data/test_rails_app/test/integration/admin_blog_posts_integration_test.rb +0 -25
- data/test_rails_app/test/test_helper.rb +0 -28
- data/test_rails_app/vendor/plugins/file_column/CHANGELOG +0 -69
- data/test_rails_app/vendor/plugins/file_column/README +0 -54
- data/test_rails_app/vendor/plugins/file_column/Rakefile +0 -36
- data/test_rails_app/vendor/plugins/file_column/TODO +0 -6
- data/test_rails_app/vendor/plugins/file_column/init.rb +0 -13
- data/test_rails_app/vendor/plugins/file_column/lib/file_column.rb +0 -723
- data/test_rails_app/vendor/plugins/file_column/lib/file_column_helper.rb +0 -150
- data/test_rails_app/vendor/plugins/file_column/lib/file_compat.rb +0 -28
- data/test_rails_app/vendor/plugins/file_column/lib/magick_file_column.rb +0 -260
- data/test_rails_app/vendor/plugins/file_column/lib/rails_file_column.rb +0 -19
- data/test_rails_app/vendor/plugins/file_column/lib/test_case.rb +0 -124
- data/test_rails_app/vendor/plugins/file_column/lib/validations.rb +0 -112
- data/test_rails_app/vendor/plugins/file_column/test/abstract_unit.rb +0 -63
- data/test_rails_app/vendor/plugins/file_column/test/connection.rb +0 -17
- data/test_rails_app/vendor/plugins/file_column/test/file_column_helper_test.rb +0 -97
- data/test_rails_app/vendor/plugins/file_column/test/file_column_test.rb +0 -650
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/entry.rb +0 -32
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/invalid-image.jpg +0 -1
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/kerb.jpg +0 -0
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/mysql.sql +0 -25
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/schema.rb +0 -10
- data/test_rails_app/vendor/plugins/file_column/test/fixtures/skanthak.png +0 -0
- data/test_rails_app/vendor/plugins/file_column/test/magick_test.rb +0 -380
- data/test_rails_app/vendor/plugins/file_column/test/magick_view_only_test.rb +0 -21
@@ -1,150 +0,0 @@
|
|
1
|
-
# This module contains helper methods for displaying and uploading files
|
2
|
-
# for attributes created by +FileColumn+'s +file_column+ method. It will be
|
3
|
-
# automatically included into ActionView::Base, thereby making this module's
|
4
|
-
# methods available in all your views.
|
5
|
-
module FileColumnHelper
|
6
|
-
|
7
|
-
# Use this helper to create an upload field for a file_column attribute. This will generate
|
8
|
-
# an additional hidden field to keep uploaded files during form-redisplays. For example,
|
9
|
-
# when called with
|
10
|
-
#
|
11
|
-
# <%= file_column_field("entry", "image") %>
|
12
|
-
#
|
13
|
-
# the following HTML will be generated (assuming the form is redisplayed and something has
|
14
|
-
# already been uploaded):
|
15
|
-
#
|
16
|
-
# <input type="hidden" name="entry[image_temp]" value="..." />
|
17
|
-
# <input type="file" name="entry[image]" />
|
18
|
-
#
|
19
|
-
# You can use the +option+ argument to pass additional options to the file-field tag.
|
20
|
-
#
|
21
|
-
# Be sure to set the enclosing form's encoding to 'multipart/form-data', by
|
22
|
-
# using something like this:
|
23
|
-
#
|
24
|
-
# <%= form_tag {:action => "create", ...}, :multipart => true %>
|
25
|
-
def file_column_field(object, method, options={})
|
26
|
-
result = ActionView::Helpers::InstanceTag.new(object.dup, method.to_s+"_temp", self).to_input_field_tag("hidden", {})
|
27
|
-
result << ActionView::Helpers::InstanceTag.new(object.dup, method, self).to_input_field_tag("file", options)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Creates an URL where an uploaded file can be accessed. When called for an Entry object with
|
31
|
-
# id 42 (stored in <tt>@entry</tt>) like this
|
32
|
-
#
|
33
|
-
# <%= url_for_file_column(@entry, "image")
|
34
|
-
#
|
35
|
-
# the following URL will be produced, assuming the file "test.png" has been stored in
|
36
|
-
# the "image"-column of an Entry object stored in <tt>@entry</tt>:
|
37
|
-
#
|
38
|
-
# /entry/image/42/test.png
|
39
|
-
#
|
40
|
-
# This will produce a valid URL even for temporary uploaded files, e.g. files where the object
|
41
|
-
# they are belonging to has not been saved in the database yet.
|
42
|
-
#
|
43
|
-
# The URL produces, although starting with a slash, will be relative
|
44
|
-
# to your app's root. If you pass it to one rails' +image_tag+
|
45
|
-
# helper, rails will properly convert it to an absolute
|
46
|
-
# URL. However, this will not be the case, if you create a link with
|
47
|
-
# the +link_to+ helper. In this case, you can pass <tt>:absolute =>
|
48
|
-
# true</tt> to +options+, which will make sure, the generated URL is
|
49
|
-
# absolute on your server. Examples:
|
50
|
-
#
|
51
|
-
# <%= image_tag url_for_file_column(@entry, "image") %>
|
52
|
-
# <%= link_to "Download", url_for_file_column(@entry, "image", :absolute => true) %>
|
53
|
-
#
|
54
|
-
# If there is currently no uploaded file stored in the object's column this method will
|
55
|
-
# return +nil+.
|
56
|
-
def url_for_file_column(object, method, options=nil)
|
57
|
-
case object
|
58
|
-
when String, Symbol
|
59
|
-
object = instance_variable_get("@#{object.to_s}")
|
60
|
-
end
|
61
|
-
|
62
|
-
# parse options
|
63
|
-
subdir = nil
|
64
|
-
absolute = false
|
65
|
-
if options
|
66
|
-
case options
|
67
|
-
when Hash
|
68
|
-
subdir = options[:subdir]
|
69
|
-
absolute = options[:absolute]
|
70
|
-
when String, Symbol
|
71
|
-
subdir = options
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
relative_path = object.send("#{method}_relative_path", subdir)
|
76
|
-
return nil unless relative_path
|
77
|
-
|
78
|
-
url = ""
|
79
|
-
url << request.relative_url_root.to_s if absolute
|
80
|
-
url << "/"
|
81
|
-
url << object.send("#{method}_options")[:base_url] << "/"
|
82
|
-
url << relative_path
|
83
|
-
end
|
84
|
-
|
85
|
-
# Same as +url_for_file_colum+ but allows you to access different versions
|
86
|
-
# of the image that have been processed by RMagick.
|
87
|
-
#
|
88
|
-
# If your +options+ parameter is non-nil this will
|
89
|
-
# access a different version of an image that will be produced by
|
90
|
-
# RMagick. You can use the following types for +options+:
|
91
|
-
#
|
92
|
-
# * a <tt>:symbol</tt> will select a version defined in the model
|
93
|
-
# via FileColumn::Magick's <tt>:versions</tt> feature.
|
94
|
-
# * a <tt>geometry_string</tt> will dynamically create an
|
95
|
-
# image resized as specified by <tt>geometry_string</tt>. The image will
|
96
|
-
# be stored so that it does not have to be recomputed the next time the
|
97
|
-
# same version string is used.
|
98
|
-
# * <tt>some_hash</tt> will dynamically create an image
|
99
|
-
# that is created according to the options in <tt>some_hash</tt>. This
|
100
|
-
# accepts exactly the same options as Magick's version feature.
|
101
|
-
#
|
102
|
-
# The version produced by RMagick will be stored in a special sub-directory.
|
103
|
-
# The directory's name will be derived from the options you specified
|
104
|
-
# (via a hash function) but if you want
|
105
|
-
# to set it yourself, you can use the <tt>:name => name</tt> option.
|
106
|
-
#
|
107
|
-
# Examples:
|
108
|
-
#
|
109
|
-
# <%= url_for_image_column @entry, "image", "640x480" %>
|
110
|
-
#
|
111
|
-
# will produce an URL like this
|
112
|
-
#
|
113
|
-
# /entry/image/42/bdn19n/filename.jpg
|
114
|
-
# # "640x480".hash.abs.to_s(36) == "bdn19n"
|
115
|
-
#
|
116
|
-
# and
|
117
|
-
#
|
118
|
-
# <%= url_for_image_column @entry, "image",
|
119
|
-
# :size => "50x50", :crop => "1:1", :name => "thumb" %>
|
120
|
-
#
|
121
|
-
# will produce something like this:
|
122
|
-
#
|
123
|
-
# /entry/image/42/thumb/filename.jpg
|
124
|
-
#
|
125
|
-
# Hint: If you are using the same geometry string / options hash multiple times, you should
|
126
|
-
# define it in a helper to stay with DRY. Another option is to define it in the model via
|
127
|
-
# FileColumn::Magick's <tt>:versions</tt> feature and then refer to it via a symbol.
|
128
|
-
#
|
129
|
-
# The URL produced by this method is relative to your application's root URL,
|
130
|
-
# although it will start with a slash.
|
131
|
-
# If you pass this URL to rails' +image_tag+ helper, it will be converted to an
|
132
|
-
# absolute URL automatically.
|
133
|
-
# If there is currently no image uploaded, or there is a problem while loading
|
134
|
-
# the image this method will return +nil+.
|
135
|
-
def url_for_image_column(object, method, options=nil)
|
136
|
-
case object
|
137
|
-
when String, Symbol
|
138
|
-
object = instance_variable_get("@#{object.to_s}")
|
139
|
-
end
|
140
|
-
subdir = nil
|
141
|
-
if options
|
142
|
-
subdir = object.send("#{method}_state").create_magick_version_if_needed(options)
|
143
|
-
end
|
144
|
-
if subdir.nil?
|
145
|
-
nil
|
146
|
-
else
|
147
|
-
url_for_file_column(object, method, subdir)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module FileColumn
|
2
|
-
|
3
|
-
# This bit of code allows you to pass regular old files to
|
4
|
-
# file_column. file_column depends on a few extra methods that the
|
5
|
-
# CGI uploaded file class adds. We will add the equivalent methods
|
6
|
-
# to file objects if necessary by extending them with this module. This
|
7
|
-
# avoids opening up the standard File class which might result in
|
8
|
-
# naming conflicts.
|
9
|
-
|
10
|
-
module FileCompat # :nodoc:
|
11
|
-
def original_filename
|
12
|
-
File.basename(path)
|
13
|
-
end
|
14
|
-
|
15
|
-
def size
|
16
|
-
File.size(path)
|
17
|
-
end
|
18
|
-
|
19
|
-
def local_path
|
20
|
-
path
|
21
|
-
end
|
22
|
-
|
23
|
-
def content_type
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
@@ -1,260 +0,0 @@
|
|
1
|
-
module FileColumn # :nodoc:
|
2
|
-
|
3
|
-
class BaseUploadedFile # :nodoc:
|
4
|
-
def transform_with_magick
|
5
|
-
if needs_transform?
|
6
|
-
begin
|
7
|
-
img = ::Magick::Image::read(absolute_path).first
|
8
|
-
rescue ::Magick::ImageMagickError
|
9
|
-
if options[:magick][:image_required]
|
10
|
-
@magick_errors ||= []
|
11
|
-
@magick_errors << "invalid image"
|
12
|
-
end
|
13
|
-
return
|
14
|
-
end
|
15
|
-
|
16
|
-
if options[:magick][:versions]
|
17
|
-
options[:magick][:versions].each_pair do |version, version_options|
|
18
|
-
next if version_options[:lazy]
|
19
|
-
dirname = version_options[:name]
|
20
|
-
FileUtils.mkdir File.join(@dir, dirname)
|
21
|
-
transform_image(img, version_options, absolute_path(dirname))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
if options[:magick][:size] or options[:magick][:crop] or options[:magick][:transformation] or options[:magick][:attributes]
|
25
|
-
transform_image(img, options[:magick], absolute_path)
|
26
|
-
end
|
27
|
-
|
28
|
-
GC.start
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_magick_version_if_needed(version)
|
33
|
-
# RMagick might not have been loaded so far.
|
34
|
-
# We do not want to require it on every call of this method
|
35
|
-
# as this might be fairly expensive, so we just try if ::Magick
|
36
|
-
# exists and require it if not.
|
37
|
-
begin
|
38
|
-
::Magick
|
39
|
-
rescue NameError
|
40
|
-
require 'RMagick'
|
41
|
-
end
|
42
|
-
|
43
|
-
if version.is_a?(Symbol)
|
44
|
-
version_options = options[:magick][:versions][version]
|
45
|
-
else
|
46
|
-
version_options = MagickExtension::process_options(version)
|
47
|
-
end
|
48
|
-
|
49
|
-
unless File.exists?(absolute_path(version_options[:name]))
|
50
|
-
begin
|
51
|
-
img = ::Magick::Image::read(absolute_path).first
|
52
|
-
rescue ::Magick::ImageMagickError
|
53
|
-
# we might be called directly from the view here
|
54
|
-
# so we just return nil if we cannot load the image
|
55
|
-
return nil
|
56
|
-
end
|
57
|
-
dirname = version_options[:name]
|
58
|
-
FileUtils.mkdir File.join(@dir, dirname)
|
59
|
-
transform_image(img, version_options, absolute_path(dirname))
|
60
|
-
end
|
61
|
-
|
62
|
-
version_options[:name]
|
63
|
-
end
|
64
|
-
|
65
|
-
attr_reader :magick_errors
|
66
|
-
|
67
|
-
def has_magick_errors?
|
68
|
-
@magick_errors and !@magick_errors.empty?
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def needs_transform?
|
74
|
-
options[:magick] and just_uploaded? and
|
75
|
-
(options[:magick][:size] or options[:magick][:versions] or options[:magick][:transformation] or options[:magick][:attributes])
|
76
|
-
end
|
77
|
-
|
78
|
-
def transform_image(img, img_options, dest_path)
|
79
|
-
begin
|
80
|
-
if img_options[:transformation]
|
81
|
-
if img_options[:transformation].is_a?(Symbol)
|
82
|
-
img = @instance.send(img_options[:transformation], img)
|
83
|
-
else
|
84
|
-
img = img_options[:transformation].call(img)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
if img_options[:crop]
|
88
|
-
dx, dy = img_options[:crop].split(':').map { |x| x.to_f }
|
89
|
-
w, h = (img.rows * dx / dy), (img.columns * dy / dx)
|
90
|
-
img = img.crop(::Magick::CenterGravity, [img.columns, w].min,
|
91
|
-
[img.rows, h].min, true)
|
92
|
-
end
|
93
|
-
|
94
|
-
if img_options[:size]
|
95
|
-
img = img.change_geometry(img_options[:size]) do |c, r, i|
|
96
|
-
i.resize(c, r)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
ensure
|
100
|
-
img.write(dest_path) do
|
101
|
-
if img_options[:attributes]
|
102
|
-
img_options[:attributes].each_pair do |property, value|
|
103
|
-
self.send "#{property}=", value
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
File.chmod options[:permissions], dest_path
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# If you are using file_column to upload images, you can
|
113
|
-
# directly process the images with RMagick,
|
114
|
-
# a ruby extension
|
115
|
-
# for accessing the popular imagemagick libraries. You can find
|
116
|
-
# more information about RMagick at http://rmagick.rubyforge.org.
|
117
|
-
#
|
118
|
-
# You can control what to do by adding a <tt>:magick</tt> option
|
119
|
-
# to your options hash. All operations are performed immediately
|
120
|
-
# after a new file is assigned to the file_column attribute (i.e.,
|
121
|
-
# when a new file has been uploaded).
|
122
|
-
#
|
123
|
-
# == Resizing images
|
124
|
-
#
|
125
|
-
# To resize the uploaded image according to an imagemagick geometry
|
126
|
-
# string, just use the <tt>:size</tt> option:
|
127
|
-
#
|
128
|
-
# file_column :image, :magick => {:size => "800x600>"}
|
129
|
-
#
|
130
|
-
# If the uploaded file cannot be loaded by RMagick, file_column will
|
131
|
-
# signal a validation error for the corresponding attribute. If you
|
132
|
-
# want to allow non-image files to be uploaded in a column that uses
|
133
|
-
# the <tt>:magick</tt> option, you can set the <tt>:image_required</tt>
|
134
|
-
# attribute to +false+:
|
135
|
-
#
|
136
|
-
# file_column :image, :magick => {:size => "800x600>",
|
137
|
-
# :image_required => false }
|
138
|
-
#
|
139
|
-
# == Multiple versions
|
140
|
-
#
|
141
|
-
# You can also create additional versions of your image, for example
|
142
|
-
# thumb-nails, like this:
|
143
|
-
# file_column :image, :magick => {:versions => {
|
144
|
-
# :thumb => {:size => "50x50"},
|
145
|
-
# :medium => {:size => "640x480>"}
|
146
|
-
# }
|
147
|
-
#
|
148
|
-
# These versions will be stored in separate sub-directories, named like the
|
149
|
-
# symbol you used to identify the version. So in the previous example, the
|
150
|
-
# image versions will be stored in "thumb", "screen" and "widescreen"
|
151
|
-
# directories, resp.
|
152
|
-
# A name different from the symbol can be set via the <tt>:name</tt> option.
|
153
|
-
#
|
154
|
-
# These versions can be accessed via FileColumnHelper's +url_for_image_column+
|
155
|
-
# method like this:
|
156
|
-
#
|
157
|
-
# <%= url_for_image_column "entry", "image", :thumb %>
|
158
|
-
#
|
159
|
-
# == Cropping images
|
160
|
-
#
|
161
|
-
# If you wish to crop your images with a size ratio before scaling
|
162
|
-
# them according to your version geometry, you can use the :crop directive.
|
163
|
-
# file_column :image, :magick => {:versions => {
|
164
|
-
# :square => {:crop => "1:1", :size => "50x50", :name => "thumb"},
|
165
|
-
# :screen => {:crop => "4:3", :size => "640x480>"},
|
166
|
-
# :widescreen => {:crop => "16:9", :size => "640x360!"},
|
167
|
-
# }
|
168
|
-
# }
|
169
|
-
#
|
170
|
-
# == Custom attributes
|
171
|
-
#
|
172
|
-
# To change some of the image properties like compression level before they
|
173
|
-
# are saved you can set the <tt>:attributes</tt> option.
|
174
|
-
# For a list of available attributes go to http://www.simplesystems.org/RMagick/doc/info.html
|
175
|
-
#
|
176
|
-
# file_column :image, :magick => { :attributes => { :quality => 30 } }
|
177
|
-
#
|
178
|
-
# == Custom transformations
|
179
|
-
#
|
180
|
-
# To perform custom transformations on uploaded images, you can pass a
|
181
|
-
# callback to file_column:
|
182
|
-
# file_column :image, :magick =>
|
183
|
-
# Proc.new { |image| image.quantize(256, Magick::GRAYColorspace) }
|
184
|
-
#
|
185
|
-
# The callback you give, receives one argument, which is an instance
|
186
|
-
# of Magick::Image, the RMagick image class. It should return a transformed
|
187
|
-
# image. Instead of passing a <tt>Proc</tt> object, you can also give a
|
188
|
-
# <tt>Symbol</tt>, the name of an instance method of your model.
|
189
|
-
#
|
190
|
-
# Custom transformations can be combined via the standard :size and :crop
|
191
|
-
# features, by using the :transformation option:
|
192
|
-
# file_column :image, :magick => {
|
193
|
-
# :transformation => Proc.new { |image| ... },
|
194
|
-
# :size => "640x480"
|
195
|
-
# }
|
196
|
-
#
|
197
|
-
# In this case, the standard resizing operations will be performed after the
|
198
|
-
# custom transformation.
|
199
|
-
#
|
200
|
-
# Of course, custom transformations can be used in versions, as well.
|
201
|
-
#
|
202
|
-
# <b>Note:</b> You'll need the
|
203
|
-
# RMagick extension being installed in order to use file_column's
|
204
|
-
# imagemagick integration.
|
205
|
-
module MagickExtension
|
206
|
-
|
207
|
-
def self.file_column(klass, attr, options) # :nodoc:
|
208
|
-
require 'RMagick'
|
209
|
-
options[:magick] = process_options(options[:magick],false) if options[:magick]
|
210
|
-
if options[:magick][:versions]
|
211
|
-
options[:magick][:versions].each_pair do |name, value|
|
212
|
-
options[:magick][:versions][name] = process_options(value, name.to_s)
|
213
|
-
end
|
214
|
-
end
|
215
|
-
state_method = "#{attr}_state".to_sym
|
216
|
-
after_assign_method = "#{attr}_magick_after_assign".to_sym
|
217
|
-
|
218
|
-
klass.send(:define_method, after_assign_method) do
|
219
|
-
self.send(state_method).transform_with_magick
|
220
|
-
end
|
221
|
-
|
222
|
-
options[:after_upload] ||= []
|
223
|
-
options[:after_upload] << after_assign_method
|
224
|
-
|
225
|
-
klass.validate do |record|
|
226
|
-
state = record.send(state_method)
|
227
|
-
if state.has_magick_errors?
|
228
|
-
state.magick_errors.each do |error|
|
229
|
-
record.errors.add attr, error
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
|
236
|
-
def self.process_options(options,create_name=true)
|
237
|
-
case options
|
238
|
-
when String then options = {:size => options}
|
239
|
-
when Proc, Symbol then options = {:transformation => options }
|
240
|
-
end
|
241
|
-
if options[:geometry]
|
242
|
-
options[:size] = options.delete(:geometry)
|
243
|
-
end
|
244
|
-
options[:image_required] = true unless options.key?(:image_required)
|
245
|
-
if options[:name].nil? and create_name
|
246
|
-
if create_name == true
|
247
|
-
hash = 0
|
248
|
-
for key in [:size, :crop]
|
249
|
-
hash = hash ^ options[key].hash if options[key]
|
250
|
-
end
|
251
|
-
options[:name] = hash.abs.to_s(36)
|
252
|
-
else
|
253
|
-
options[:name] = create_name
|
254
|
-
end
|
255
|
-
end
|
256
|
-
options
|
257
|
-
end
|
258
|
-
|
259
|
-
end
|
260
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# require this file from your "config/environment.rb" (after rails has been loaded)
|
2
|
-
# to integrate the file_column extension into rails.
|
3
|
-
|
4
|
-
require 'file_column'
|
5
|
-
require 'file_column_helper'
|
6
|
-
|
7
|
-
|
8
|
-
module ActiveRecord # :nodoc:
|
9
|
-
class Base # :nodoc:
|
10
|
-
# make file_column method available in all active record decendants
|
11
|
-
include FileColumn
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module ActionView # :nodoc:
|
16
|
-
class Base # :nodoc:
|
17
|
-
include FileColumnHelper
|
18
|
-
end
|
19
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
# Add the methods +upload+, the <tt>setup_file_fixtures</tt> and
|
4
|
-
# <tt>teardown_file_fixtures</tt> to the class Test::Unit::TestCase.
|
5
|
-
class Test::Unit::TestCase
|
6
|
-
# Returns a +Tempfile+ object as it would have been generated on file upload.
|
7
|
-
# Use this method to create the parameters when emulating form posts with
|
8
|
-
# file fields.
|
9
|
-
#
|
10
|
-
# === Example:
|
11
|
-
#
|
12
|
-
# def test_file_column_post
|
13
|
-
# entry = { :title => 'foo', :file => upload('/tmp/foo.txt')}
|
14
|
-
# post :upload, :entry => entry
|
15
|
-
#
|
16
|
-
# # ...
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# === Parameters
|
20
|
-
#
|
21
|
-
# * <tt>path</tt> The path to the file to upload.
|
22
|
-
# * <tt>content_type</tt> The MIME type of the file. If it is <tt>:guess</tt>,
|
23
|
-
# the method will try to guess it.
|
24
|
-
def upload(path, content_type=:guess, type=:tempfile)
|
25
|
-
if content_type == :guess
|
26
|
-
case path
|
27
|
-
when /\.jpg$/ then content_type = "image/jpeg"
|
28
|
-
when /\.png$/ then content_type = "image/png"
|
29
|
-
else content_type = nil
|
30
|
-
end
|
31
|
-
end
|
32
|
-
uploaded_file(path, content_type, File.basename(path), type)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Copies the fixture files from "RAILS_ROOT/test/fixtures/file_column" into
|
36
|
-
# the temporary storage directory used for testing
|
37
|
-
# ("RAILS_ROOT/test/tmp/file_column"). Call this method in your
|
38
|
-
# <tt>setup</tt> methods to get the file fixtures (images, for example) into
|
39
|
-
# the directory used by file_column in testing.
|
40
|
-
#
|
41
|
-
# Note that the files and directories in the "fixtures/file_column" directory
|
42
|
-
# must have the same structure as you would expect in your "/public" directory
|
43
|
-
# after uploading with FileColumn.
|
44
|
-
#
|
45
|
-
# For example, the directory structure could look like this:
|
46
|
-
#
|
47
|
-
# test/fixtures/file_column/
|
48
|
-
# `-- container
|
49
|
-
# |-- first_image
|
50
|
-
# | |-- 1
|
51
|
-
# | | `-- image1.jpg
|
52
|
-
# | `-- tmp
|
53
|
-
# `-- second_image
|
54
|
-
# |-- 1
|
55
|
-
# | `-- image2.jpg
|
56
|
-
# `-- tmp
|
57
|
-
#
|
58
|
-
# Your fixture file for this one "container" class fixture could look like this:
|
59
|
-
#
|
60
|
-
# first:
|
61
|
-
# id: 1
|
62
|
-
# first_image: image1.jpg
|
63
|
-
# second_image: image1.jpg
|
64
|
-
#
|
65
|
-
# A usage example:
|
66
|
-
#
|
67
|
-
# def setup
|
68
|
-
# setup_fixture_files
|
69
|
-
#
|
70
|
-
# # ...
|
71
|
-
# end
|
72
|
-
def setup_fixture_files
|
73
|
-
tmp_path = File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
74
|
-
file_fixtures = Dir.glob File.join(RAILS_ROOT, "test", "fixtures", "file_column", "*")
|
75
|
-
|
76
|
-
FileUtils.mkdir_p tmp_path unless File.exists?(tmp_path)
|
77
|
-
FileUtils.cp_r file_fixtures, tmp_path
|
78
|
-
end
|
79
|
-
|
80
|
-
# Removes the directory "RAILS_ROOT/test/tmp/file_column/" so the files
|
81
|
-
# copied on test startup are removed. Call this in your unit test's +teardown+
|
82
|
-
# method.
|
83
|
-
#
|
84
|
-
# A usage example:
|
85
|
-
#
|
86
|
-
# def teardown
|
87
|
-
# teardown_fixture_files
|
88
|
-
#
|
89
|
-
# # ...
|
90
|
-
# end
|
91
|
-
def teardown_fixture_files
|
92
|
-
FileUtils.rm_rf File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def uploaded_file(path, content_type, filename, type=:tempfile) # :nodoc:
|
98
|
-
if type == :tempfile
|
99
|
-
t = Tempfile.new(File.basename(filename))
|
100
|
-
FileUtils.copy_file(path, t.path)
|
101
|
-
else
|
102
|
-
if path
|
103
|
-
t = StringIO.new(IO.read(path))
|
104
|
-
else
|
105
|
-
t = StringIO.new
|
106
|
-
end
|
107
|
-
end
|
108
|
-
(class << t; self; end).class_eval do
|
109
|
-
alias local_path path if type == :tempfile
|
110
|
-
define_method(:local_path) { "" } if type == :stringio
|
111
|
-
define_method(:original_filename) {filename}
|
112
|
-
define_method(:content_type) {content_type}
|
113
|
-
end
|
114
|
-
return t
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
# If we are running in the "test" environment, we overwrite the default
|
119
|
-
# settings for FileColumn so that files are not uploaded into "/public/"
|
120
|
-
# in tests but rather into the directory "/test/tmp/file_column".
|
121
|
-
if RAILS_ENV == "test"
|
122
|
-
FileColumn::ClassMethods::DEFAULT_OPTIONS[:root_path] =
|
123
|
-
File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
124
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
module FileColumn
|
2
|
-
module Validations #:nodoc:
|
3
|
-
|
4
|
-
def self.append_features(base)
|
5
|
-
super
|
6
|
-
base.extend(ClassMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
# This module contains methods to create validations of uploaded files. All methods
|
10
|
-
# in this module will be included as class methods into <tt>ActiveRecord::Base</tt>
|
11
|
-
# so that you can use them in your models like this:
|
12
|
-
#
|
13
|
-
# class Entry < ActiveRecord::Base
|
14
|
-
# file_column :image
|
15
|
-
# validates_filesize_of :image, :in => 0..1.megabyte
|
16
|
-
# end
|
17
|
-
module ClassMethods
|
18
|
-
EXT_REGEXP = /\.([A-z0-9]+)$/
|
19
|
-
|
20
|
-
# This validates the file type of one or more file_columns. A list of file columns
|
21
|
-
# should be given followed by an options hash.
|
22
|
-
#
|
23
|
-
# Required options:
|
24
|
-
# * <tt>:in</tt> => list of extensions or mime types. If mime types are used they
|
25
|
-
# will be mapped into an extension via FileColumn::ClassMethods::MIME_EXTENSIONS.
|
26
|
-
#
|
27
|
-
# Examples:
|
28
|
-
# validates_file_format_of :field, :in => ["gif", "png", "jpg"]
|
29
|
-
# validates_file_format_of :field, :in => ["image/jpeg"]
|
30
|
-
def validates_file_format_of(*attrs)
|
31
|
-
|
32
|
-
options = attrs.pop if attrs.last.is_a?Hash
|
33
|
-
raise ArgumentError, "Please include the :in option." if !options || !options[:in]
|
34
|
-
options[:in] = [options[:in]] if options[:in].is_a?String
|
35
|
-
raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Array
|
36
|
-
|
37
|
-
validates_each(attrs, options) do |record, attr, value|
|
38
|
-
unless value.blank?
|
39
|
-
mime_extensions = record.send("#{attr}_options")[:mime_extensions]
|
40
|
-
extensions = options[:in].map{|o| mime_extensions[o] || o }
|
41
|
-
record.errors.add attr, "is not a valid format." unless extensions.include?(value.scan(EXT_REGEXP).flatten.first)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
# This validates the file size of one or more file_columns. A list of file columns
|
48
|
-
# should be given followed by an options hash.
|
49
|
-
#
|
50
|
-
# Required options:
|
51
|
-
# * <tt>:in</tt> => A size range. Note that you can use ActiveSupport's
|
52
|
-
# numeric extensions for kilobytes, etc.
|
53
|
-
#
|
54
|
-
# Examples:
|
55
|
-
# validates_filesize_of :field, :in => 0..100.megabytes
|
56
|
-
# validates_filesize_of :field, :in => 15.kilobytes..1.megabyte
|
57
|
-
def validates_filesize_of(*attrs)
|
58
|
-
|
59
|
-
options = attrs.pop if attrs.last.is_a?Hash
|
60
|
-
raise ArgumentError, "Please include the :in option." if !options || !options[:in]
|
61
|
-
raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Range
|
62
|
-
|
63
|
-
validates_each(attrs, options) do |record, attr, value|
|
64
|
-
unless value.blank?
|
65
|
-
size = File.size(value)
|
66
|
-
record.errors.add attr, "is smaller than the allowed size range." if size < options[:in].first
|
67
|
-
record.errors.add attr, "is larger than the allowed size range." if size > options[:in].last
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
IMAGE_SIZE_REGEXP = /^(\d+)x(\d+)$/
|
74
|
-
|
75
|
-
# Validates the image size of one or more file_columns. A list of file columns
|
76
|
-
# should be given followed by an options hash. The validation will pass
|
77
|
-
# if both image dimensions (rows and columns) are at least as big as
|
78
|
-
# given in the <tt>:min</tt> option.
|
79
|
-
#
|
80
|
-
# Required options:
|
81
|
-
# * <tt>:min</tt> => minimum image dimension string, in the format NNxNN
|
82
|
-
# (columns x rows).
|
83
|
-
#
|
84
|
-
# Example:
|
85
|
-
# validates_image_size :field, :min => "1200x1800"
|
86
|
-
#
|
87
|
-
# This validation requires RMagick to be installed on your system
|
88
|
-
# to check the image's size.
|
89
|
-
def validates_image_size(*attrs)
|
90
|
-
options = attrs.pop if attrs.last.is_a?Hash
|
91
|
-
raise ArgumentError, "Please include a :min option." if !options || !options[:min]
|
92
|
-
minimums = options[:min].scan(IMAGE_SIZE_REGEXP).first.collect{|n| n.to_i} rescue []
|
93
|
-
raise ArgumentError, "Invalid value for option :min (should be 'XXxYY')" unless minimums.size == 2
|
94
|
-
|
95
|
-
require 'RMagick'
|
96
|
-
|
97
|
-
validates_each(attrs, options) do |record, attr, value|
|
98
|
-
unless value.blank?
|
99
|
-
begin
|
100
|
-
img = ::Magick::Image::read(value).first
|
101
|
-
record.errors.add('image', "is too small, must be at least #{minimums[0]}x#{minimums[1]}") if ( img.rows < minimums[1] || img.columns < minimums[0] )
|
102
|
-
rescue ::Magick::ImageMagickError
|
103
|
-
record.errors.add('image', "invalid image")
|
104
|
-
end
|
105
|
-
img = nil
|
106
|
-
GC.start
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|