importable_attachments 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +24 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +38 -0
- data/MIT-LICENSE +20 -0
- data/README.md +8 -0
- data/README.rdoc +3 -0
- data/Rakefile +29 -0
- data/app/assets/images/importable_attachments/.gitkeep +0 -0
- data/app/assets/images/importable_attachments/buttons/.htaccess +5 -0
- data/app/assets/images/importable_attachments/buttons/download_32.png +0 -0
- data/app/assets/images/importable_attachments/buttons/upload_32.png +0 -0
- data/app/assets/javascripts/importable_attachments/application.js +14 -0
- data/app/assets/javascripts/importable_attachments/attachments.coffee +41 -0
- data/app/assets/stylesheets/importable_attachments/application.css +14 -0
- data/app/assets/stylesheets/importable_attachments/attachments.css +4 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/importable_attachments/application_controller.rb +4 -0
- data/app/controllers/importable_attachments/attachments_controller.rb +190 -0
- data/app/controllers/importable_attachments/versions_controller.rb +87 -0
- data/app/helpers/importable_attachments/application_helper.rb +4 -0
- data/app/models/attachment.rb +24 -0
- data/app/models/importable_attachments/attachment.rb +143 -0
- data/app/models/importable_attachments/version.rb +50 -0
- data/app/validators/existing_class_validator.rb +17 -0
- data/app/validators/importable_attachments/csv_validator.rb +36 -0
- data/app/validators/importable_attachments/excel.rb +18 -0
- data/app/validators/importable_attachments/excel_validator.rb +18 -0
- data/app/views/importable_attachments/attachments/_attachment.html.haml +9 -0
- data/app/views/importable_attachments/attachments/_form.html.haml +22 -0
- data/app/views/importable_attachments/attachments/_nested_form.html.haml +20 -0
- data/app/views/importable_attachments/attachments/edit.html.haml +39 -0
- data/app/views/importable_attachments/attachments/index.html.haml +23 -0
- data/app/views/importable_attachments/attachments/index.xml.builder +23 -0
- data/app/views/importable_attachments/attachments/new.html.haml +10 -0
- data/app/views/importable_attachments/attachments/show.html.haml +43 -0
- data/app/views/importable_attachments/versions/_form.html.haml +25 -0
- data/app/views/importable_attachments/versions/edit.html.haml +7 -0
- data/app/views/importable_attachments/versions/index.html.haml +27 -0
- data/app/views/importable_attachments/versions/new.html.haml +5 -0
- data/app/views/importable_attachments/versions/show.html.haml +21 -0
- data/app/views/layouts/_version.html.haml +33 -0
- data/app/views/layouts/importable_attachments/application.html.haml +48 -0
- data/bin/set_lc.sh +47 -0
- data/config/database.yml +25 -0
- data/config/features/attachments.rb +8 -0
- data/config/features/mark_requirements.rb +3 -0
- data/config/features/smarter_dates.rb +3 -0
- data/config/features/versioning.rb +7 -0
- data/config/initializers/0_configuration.rb +7 -0
- data/config/initializers/formtastic.rb +76 -0
- data/config/initializers/generators.rb +10 -0
- data/config/initializers/paperclip.rb +27 -0
- data/config/locales/responders.en.yml +10 -0
- data/config/routes.rb +11 -0
- data/db/migrate/001_create_importable_attachments_versions.rb +14 -0
- data/db/migrate/100_create_attachments.rb +19 -0
- data/importable_attachments.gemspec +81 -0
- data/lib/generators/importable_attachments/install_generator.rb +66 -0
- data/lib/generators/importable_attachments/templates/features/attachments.rb.erb +7 -0
- data/lib/generators/importable_attachments/templates/features/versioning.rb +7 -0
- data/lib/generators/importable_attachments/templates/initializers/paperclip.rb +27 -0
- data/lib/importable_attachments/base.rb +108 -0
- data/lib/importable_attachments/blueprints.rb +9 -0
- data/lib/importable_attachments/engine.rb +8 -0
- data/lib/importable_attachments/importers/csv.rb +208 -0
- data/lib/importable_attachments/importers/excel.rb +37 -0
- data/lib/importable_attachments/importers.rb +7 -0
- data/lib/importable_attachments/version.rb +3 -0
- data/lib/importable_attachments.rb +9 -0
- data/lib/paperclip_processors/save_upload.rb +33 -0
- data/lib/tasks/importable_attachments_tasks.rake +4 -0
- data/script/rails +8 -0
- data/spec/attachments/books.csv +6 -0
- data/spec/attachments/books.txt +6 -0
- data/spec/attachments/books2.csv +4 -0
- data/spec/attachments/empty.csv +0 -0
- data/spec/attachments/failed_instances.csv +3 -0
- data/spec/attachments/invalid_headers.csv +3 -0
- data/spec/attachments/just_headers.csv +1 -0
- data/spec/attachments/mostly_empty.csv +2 -0
- data/spec/attachments/mostly_empty_copy.xls +0 -0
- data/spec/controllers/importable_attachments/attachments_controller_spec.rb +236 -0
- data/spec/controllers/importable_attachments/versions_controller_spec.rb +158 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/book.rb +13 -0
- data/spec/dummy/app/models/library.rb +54 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/0_configuration.rb +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/101_create_libraries.rb +10 -0
- data/spec/dummy/db/migrate/102_create_books.rb +12 -0
- data/spec/dummy/db/schema.rb +57 -0
- data/spec/dummy/features/person_uploads_generic_file.feature +11 -0
- data/spec/dummy/features/step_definitions/person_uploads_generic_file_steps.rb +11 -0
- data/spec/dummy/features/step_definitions/web_steps.rb +211 -0
- data/spec/dummy/features/support/capybara.rb +6 -0
- data/spec/dummy/features/support/database_cleaner.rb +26 -0
- data/spec/dummy/features/support/developer_helpers.rb +47 -0
- data/spec/dummy/features/support/env.rb +53 -0
- data/spec/dummy/features/support/paths.rb +33 -0
- data/spec/dummy/features/support/poltergeist.rb +1 -0
- data/spec/dummy/features/support/selectors.rb +39 -0
- data/spec/dummy/features/support/transactional_fixtures.rb +14 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +38 -0
- data/spec/dummy/public/422.html +38 -0
- data/spec/dummy/public/500.html +36 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/support/.gitkeep +0 -0
- data/spec/dummy/spec/support/paperclip.rb +1 -0
- data/spec/models/importable_attachments/attachment_spec.rb +177 -0
- data/spec/models/importable_attachments/library_spec.rb +155 -0
- data/spec/models/importable_attachments/version_spec.rb +25 -0
- data/spec/routing/importable_attachments/versions_routing_spec.rb +43 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +30 -0
- metadata +737 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'filemagic'
|
|
2
|
+
require 'mime/types'
|
|
3
|
+
require 'paper_trail'
|
|
4
|
+
require 'paperclip'
|
|
5
|
+
require 'smarter_dates'
|
|
6
|
+
#require File.join(File.dirname(__FILE__), '../..', 'config/initializers/0_configuration')
|
|
7
|
+
|
|
8
|
+
# An attachment represents a file within the system.
|
|
9
|
+
module ImportableAttachments
|
|
10
|
+
class Attachment < ActiveRecord::Base
|
|
11
|
+
self.abstract_class = true
|
|
12
|
+
self.table_name = :importable_attachments_attachments
|
|
13
|
+
|
|
14
|
+
include SmarterDates if ::Configuration.for('smarter_dates').enabled
|
|
15
|
+
include Rails::MarkRequirements if ::Configuration.for('mark_requirements').enabled
|
|
16
|
+
|
|
17
|
+
if ::Configuration.for('versioning').enabled
|
|
18
|
+
has_paper_trail ignore: [:updated_at], class_name: 'ImportableAttachments::Version'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# url for client downloadable content
|
|
22
|
+
if ::Configuration.for('attachments').enabled
|
|
23
|
+
include Paperclip::Glue
|
|
24
|
+
if ::Configuration.for('attachments').include_revision_in_filename
|
|
25
|
+
CONTENT_URL = ::Configuration.for('versioned').url
|
|
26
|
+
CONTENT_PATH = ::Configuration.for('versioned').path
|
|
27
|
+
else
|
|
28
|
+
CONTENT_URL = ::Configuration.for('attachments').url
|
|
29
|
+
CONTENT_PATH = ::Configuration.for('attachments').path
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
has_attached_file :io_stream, :url => CONTENT_URL, :path => CONTENT_PATH,
|
|
33
|
+
:styles => {original: {io_stream_attr: :attach}},
|
|
34
|
+
:processors => [:save_upload]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# --------------------------------------------------------------------------
|
|
38
|
+
# define: attributes and relationships
|
|
39
|
+
belongs_to :attachable, :polymorphic => true
|
|
40
|
+
|
|
41
|
+
# --------------------------------------------------------------------------
|
|
42
|
+
# define: aliases and delegations
|
|
43
|
+
delegate :url, :to => :io_stream, :prefix => true
|
|
44
|
+
|
|
45
|
+
# --------------------------------------------------------------------------
|
|
46
|
+
# define: DTD i.e. validations
|
|
47
|
+
|
|
48
|
+
# NOTE: to save nested-model forms, new instances must be valid. Therefore,
|
|
49
|
+
# attachable_id = nil must be valid when attachable is != nil
|
|
50
|
+
validates :attachable_id, :if => :attachable_id?,
|
|
51
|
+
:numericality => {only_integer: true, greater_than: 0}
|
|
52
|
+
|
|
53
|
+
validates :attachable_type, alpha_numeric: {punctuation: true}, existing_class: true, :if => :attachable_type?
|
|
54
|
+
|
|
55
|
+
validates_attachment :io_stream, :presence => true,
|
|
56
|
+
:size => {greater_than: 0}
|
|
57
|
+
|
|
58
|
+
validates :io_stream_file_name, :presence => true,
|
|
59
|
+
:alpha_numeric => {punctuation: true}
|
|
60
|
+
|
|
61
|
+
validates :io_stream_file_size, :presence => true,
|
|
62
|
+
:numericality => {only_integer: true, greater_than_or_equal_to: 0}
|
|
63
|
+
|
|
64
|
+
validates :io_stream_content_type, :presence => true,
|
|
65
|
+
:alpha_numeric => {punctuation: true}
|
|
66
|
+
|
|
67
|
+
validates :io_stream_updated_at, :chronic_parsable => true,
|
|
68
|
+
:if => :io_stream_updated_at?
|
|
69
|
+
|
|
70
|
+
# --------------------------------------------------------------------------
|
|
71
|
+
# define: scopes
|
|
72
|
+
|
|
73
|
+
attr_accessible :attachable_id, :attachable_type
|
|
74
|
+
attr_accessible :io_stream
|
|
75
|
+
attr_accessible :io_stream_file_name, :io_stream_content_type, :io_stream_file_size,
|
|
76
|
+
:io_stream_updated_at
|
|
77
|
+
|
|
78
|
+
# --------------------------------------------------------------------------
|
|
79
|
+
# define: behaviors
|
|
80
|
+
|
|
81
|
+
# :call-seq:
|
|
82
|
+
# revision_number
|
|
83
|
+
#
|
|
84
|
+
# yields an integer representing the version-index
|
|
85
|
+
#
|
|
86
|
+
# NOTE: paper_trail manages version-tracking automatically
|
|
87
|
+
|
|
88
|
+
def revision_number
|
|
89
|
+
ver = version
|
|
90
|
+
case
|
|
91
|
+
when live? then
|
|
92
|
+
versions.count
|
|
93
|
+
when ver then
|
|
94
|
+
ver.index
|
|
95
|
+
else
|
|
96
|
+
0
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# :call-seq:
|
|
101
|
+
# io_stream_mime_type
|
|
102
|
+
#
|
|
103
|
+
# yields the files MIME::Type
|
|
104
|
+
|
|
105
|
+
def io_stream_mime_type
|
|
106
|
+
mime = new_record? ? io_stream.content_type : magic_mime_type
|
|
107
|
+
MIME::Types[mime].first
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# :call-seq:
|
|
111
|
+
# magic_mime_type
|
|
112
|
+
#
|
|
113
|
+
# yields a saved attachments mime_type according to libmagic
|
|
114
|
+
|
|
115
|
+
def magic_mime_type
|
|
116
|
+
return if new_record?
|
|
117
|
+
return unless File.exists? io_stream.path
|
|
118
|
+
FileMagic.mime.file(io_stream.path).split(/;\s*/).first
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# == Schema Information
|
|
125
|
+
#
|
|
126
|
+
# Table name: attachments
|
|
127
|
+
#
|
|
128
|
+
# id :integer not null, primary key
|
|
129
|
+
# attachable_type :string(255)
|
|
130
|
+
# attachable_id :string(255)
|
|
131
|
+
# io_stream_file_name :string(255)
|
|
132
|
+
# io_stream_content_type :string(255)
|
|
133
|
+
# io_stream_file_size :integer
|
|
134
|
+
# io_stream_updated_at :datetime
|
|
135
|
+
# created_at :datetime not null
|
|
136
|
+
# updated_at :datetime not null
|
|
137
|
+
#
|
|
138
|
+
# Indexes
|
|
139
|
+
#
|
|
140
|
+
# idx_importable_attachments_on_attachable_type_and_id (attachable_type,attachable_id)
|
|
141
|
+
# index_attachments_on_io_stream_file_name (io_stream_file_name)
|
|
142
|
+
#
|
|
143
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# versions are managed by the paper_trail gem... providing a history of
|
|
2
|
+
# instance-deltas
|
|
3
|
+
module ImportableAttachments
|
|
4
|
+
class Version < ActiveRecord::Base
|
|
5
|
+
self.abstract_class = true
|
|
6
|
+
self.table_name = :importable_attachments_versions
|
|
7
|
+
attr_accessible :event, :item_id, :item_type, :object, :object_changes, :whodunnit
|
|
8
|
+
|
|
9
|
+
include SmarterDates if ::Configuration.for('smarter_dates').enabled
|
|
10
|
+
include Rails::MarkRequirements if ::Configuration.for('mark_requirements').enabled
|
|
11
|
+
|
|
12
|
+
belongs_to :item, polymorphic: true
|
|
13
|
+
|
|
14
|
+
# NOTE: to save nested-model forms, new instances must be valid. Therefore,
|
|
15
|
+
# attachable_id = nil must be valid when attachable is != nil
|
|
16
|
+
#validates :item_id, if: :item_id?, numericality: {only_integer: true, greater_than: 0}
|
|
17
|
+
validates :item_id, alpha_numeric: {punctuation: true}, if: :item_id?
|
|
18
|
+
|
|
19
|
+
validates :item_type, alpha_numeric: {punctuation: true}, if: :item_type?
|
|
20
|
+
|
|
21
|
+
if ::Configuration.for('versioning').validate_item_type_constants
|
|
22
|
+
validates :item_type, existing_class: true, if: :item_type?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# :call-seq:
|
|
26
|
+
# object_has? :pattern
|
|
27
|
+
#
|
|
28
|
+
# yields versions in which the object contains a pattern
|
|
29
|
+
|
|
30
|
+
scope :object_has?, lambda { |pattern| where('object LIKE ?', "%#{pattern}%") }
|
|
31
|
+
|
|
32
|
+
# :call-seq:
|
|
33
|
+
# Klass.in_the_last N
|
|
34
|
+
#
|
|
35
|
+
# yields objects created in the last N (where N is a timestamp)
|
|
36
|
+
|
|
37
|
+
scope :in_the_last, lambda { |dt| where('created_at > ?', dt.ago) }
|
|
38
|
+
|
|
39
|
+
# :call-seq:
|
|
40
|
+
# yml_to_ruby
|
|
41
|
+
#
|
|
42
|
+
# loads the yaml object into a ruby-hash
|
|
43
|
+
# if this is the 'destroyed' version, then RTFM reify
|
|
44
|
+
|
|
45
|
+
def yml_to_ruby
|
|
46
|
+
Psych.load object
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# validate field contains the name of an existing class
|
|
2
|
+
class ExistingClassValidator < ActiveModel::EachValidator
|
|
3
|
+
|
|
4
|
+
# :call-seq:
|
|
5
|
+
# validate_each :record, :attr, :value
|
|
6
|
+
#
|
|
7
|
+
# validates that value is the name of an existing class
|
|
8
|
+
|
|
9
|
+
def validate_each(record, attr, value)
|
|
10
|
+
types = value.split(/::/).map(&:to_sym)
|
|
11
|
+
item_type_result = types.inject(Module) do |constant, name|
|
|
12
|
+
constant.const_get(name) if constant && constant.constants.include?(name)
|
|
13
|
+
end
|
|
14
|
+
record.errors[attr] << 'unknown module or class' unless item_type_result.present?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
# validate attachment is a CSV file
|
|
4
|
+
module ImportableAttachments # :nodoc:
|
|
5
|
+
class CsvValidator < ActiveModel::Validator
|
|
6
|
+
|
|
7
|
+
# :call-seq:
|
|
8
|
+
# validate :record
|
|
9
|
+
#
|
|
10
|
+
# ensures that the record's attachment file name has a .xls extension
|
|
11
|
+
|
|
12
|
+
def validate(record)
|
|
13
|
+
extension = record.attachment.io_stream_file_name.split('.').last
|
|
14
|
+
if extension.downcase != 'csv'
|
|
15
|
+
record.errors.add :attachment, 'invalid attachment'
|
|
16
|
+
record.attachment.errors.add :base, 'File must be a CSV (.csv) file'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if defined? FasterCSV
|
|
20
|
+
begin
|
|
21
|
+
FasterCSV.read record.attachment.io_stream
|
|
22
|
+
rescue FasterCSV::MalformedCSVError => err
|
|
23
|
+
record.errors.add :attachment, 'invalid attachment'
|
|
24
|
+
record.attachment.errors.add :base, err.messages.join(', ')
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
begin
|
|
28
|
+
CSV.read record.attachment.io_stream.path
|
|
29
|
+
rescue CSV::MalformedCSVError => err
|
|
30
|
+
record.errors.add :attachment, 'invalid attachment'
|
|
31
|
+
record.attachment.errors.add :base, err.messages.join(', ')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module ImportableAttachments # :nodoc:
|
|
2
|
+
# validate attachment is an excel file
|
|
3
|
+
class ExcelValidator < ActiveModel::Validator
|
|
4
|
+
|
|
5
|
+
# :call-seq:
|
|
6
|
+
# validate :record
|
|
7
|
+
#
|
|
8
|
+
# ensures that the record's attachment file name has a .xls extension
|
|
9
|
+
|
|
10
|
+
def validate(record)
|
|
11
|
+
extension = record.attachment.io_stream_file_name.split('.').last
|
|
12
|
+
if extension != 'xls'
|
|
13
|
+
record.errors[:attachment] << 'File must be an Excel (.xls) file'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module ImportableAttachments # :nodoc:
|
|
2
|
+
# validate attachment is an excel file
|
|
3
|
+
class ExcelValidator < ActiveModel::Validator
|
|
4
|
+
|
|
5
|
+
# :call-seq:
|
|
6
|
+
# validate :record
|
|
7
|
+
#
|
|
8
|
+
# ensures that the record's attachment file name has a .xls extension
|
|
9
|
+
|
|
10
|
+
def validate(record)
|
|
11
|
+
extension = record.attachment.io_stream_file_name.split('.').last
|
|
12
|
+
if extension != 'xls'
|
|
13
|
+
record.errors[:attachment] << 'File must be an Excel (.xls) file'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
%tr.group_data
|
|
2
|
+
- img_tag = image_tag '/assets/importable_attachments/buttons/download_32.png', alt: "Download #{attachment.io_stream_file_name}", title: "Download #{attachment.io_stream_file_name.inspect}", id: "icon_file_download_#{attachment.id}", :class => 'faux_link'
|
|
3
|
+
%td.text_col{style: 'text-align: center;'}= link_to img_tag, attachment.io_stream.url
|
|
4
|
+
%td.text_col= link_to attachment.io_stream_file_name, attachment, title: "View metadata for #{attachment.io_stream_file_name.inspect}", alt: "View metadata for #{attachment.io_stream_file_name.inspect}"
|
|
5
|
+
%td.text_col{style: 'text-align: center;'}= attachment.revision_number
|
|
6
|
+
%td.text_col= attachment.updated_at.strftime('%Y-%m-%d %I:%M %p')
|
|
7
|
+
%td.action_col= link_to 'Edit', edit_attachment_path(attachment)
|
|
8
|
+
%td.action_col= link_to 'Destroy', attachment, confirm: 'Are you sure?', method: :delete
|
|
9
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
= javascript_include_tag 'importable_attachments/attachments'
|
|
2
|
+
|
|
3
|
+
#spreadsheet_action_panel.actions_menu
|
|
4
|
+
= image_tag '/assets/importable_attachments/buttons/upload_32.png', alt: 'Upload File', title: 'Upload File', id: 'icon_file_upload', :class => 'faux_link'
|
|
5
|
+
|
|
6
|
+
- if attachment.new_record?
|
|
7
|
+
= image_tag '/assets/importable_attachments/buttons/download_32.png', alt: 'No File to Download', title: 'No File to Download', id: 'icon_file_download', :class => 'faux_link'
|
|
8
|
+
- else
|
|
9
|
+
- img_tag = image_tag '/assets/importable_attachments/buttons/download_32.png', alt: 'Download Original File', title: 'Download Original File', id: 'icon_file_download', :class => 'faux_link'
|
|
10
|
+
=link_to img_tag, attachment.io_stream_url
|
|
11
|
+
|
|
12
|
+
%li
|
|
13
|
+
%label.label File name:
|
|
14
|
+
#file_name{disabled: 'disabled', value: attachment.io_stream_file_name || ""}
|
|
15
|
+
= f.inputs id: 'attachment_attributes_io_stream_fields' do
|
|
16
|
+
- opts = { as: :file, id: 'attachment_io_stream_input' }
|
|
17
|
+
- opts.merge! required: f.object.mark_required?(:io_stream) if ::Configuration.for('mark_requirements').enabled
|
|
18
|
+
= f.input :io_stream, opts
|
|
19
|
+
|
|
20
|
+
- if attachment.attachable_type || attachment.attachable_id
|
|
21
|
+
= f.input :attachable_type, as: :hidden, input_html: { value: attachment.attachable_type }
|
|
22
|
+
= f.input :attachable_id, as: :hidden, input_html: { value: attachment.attachable_id }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
= javascript_include_tag 'importable_attachments/attachments'
|
|
2
|
+
|
|
3
|
+
#spreadsheet_action_panel.actions_menu
|
|
4
|
+
= image_tag '/assets/importable_attachments/buttons/upload_32.png', alt: 'Upload File', title: 'Upload File', id: 'icon_file_upload', :class => 'faux_link'
|
|
5
|
+
|
|
6
|
+
- if attachment.new_record?
|
|
7
|
+
= image_tag '/assets/importable_attachments/buttons/download_32.png', alt: 'No File to Download', title: 'No File to Download', id: 'icon_file_download', :class => 'faux_link'
|
|
8
|
+
- else
|
|
9
|
+
- img_tag = image_tag '/assets/importable_attachments/buttons/download_32.png', alt: 'Download Original File', title: 'Download Original File', id: 'icon_file_download', :class => 'faux_link'
|
|
10
|
+
=link_to img_tag, attachment.io_stream_url
|
|
11
|
+
|
|
12
|
+
%li
|
|
13
|
+
%label.label File name
|
|
14
|
+
%input#file_name{disabled: 'disabled', value: attachment.io_stream_file_name}
|
|
15
|
+
= f.inputs id: 'attachment_attributes_io_stream_fields' do
|
|
16
|
+
- opts = { as: :file, id: 'attachment_io_stream_input' }
|
|
17
|
+
= f.semantic_fields_for :attachment do |attachment_form|
|
|
18
|
+
- opts.merge! required: attachment_form.object.mark_required?(:io_stream) if ::Configuration.for('mark_requirements').enabled
|
|
19
|
+
= attachment_form.inputs do
|
|
20
|
+
= attachment_form.input :io_stream, opts
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
%h2 Editing Attachment #{@attachment.io_stream_file_name}
|
|
2
|
+
|
|
3
|
+
= semantic_form_for @attachment, url: attachment_path(@attachment), html: {multipart: true} do |f|
|
|
4
|
+
= f.inputs do
|
|
5
|
+
= render 'form', f: f, attachment: @attachment
|
|
6
|
+
|
|
7
|
+
= f.action :submit, input_html: { value: 'Upload File', onclick: "this.disabled=true;this.value='Please wait...';this.form.submit();" }
|
|
8
|
+
|
|
9
|
+
- if @attachment.attachable_type
|
|
10
|
+
%p
|
|
11
|
+
%b Represents:
|
|
12
|
+
= "#{@attachment.attachable_type} id: #{@attachment.attachable_id}"
|
|
13
|
+
|
|
14
|
+
%p
|
|
15
|
+
%b File Name:
|
|
16
|
+
=link_to @attachment.io_stream_file_name, @attachment.io_stream.url, title: @attachment.io_stream_file_name, alt: @attachment.io_stream_file_name
|
|
17
|
+
|
|
18
|
+
- if %w(development test).include?(Rails.env)
|
|
19
|
+
%p
|
|
20
|
+
%b File Path:
|
|
21
|
+
=link_to @attachment.io_stream.path.sub(Rails.root.to_s + '/', ""), File.dirname(@attachment.io_stream.path)
|
|
22
|
+
|
|
23
|
+
%p
|
|
24
|
+
%b File Size:
|
|
25
|
+
= "#{@attachment.io_stream_file_size} bytes"
|
|
26
|
+
|
|
27
|
+
%p
|
|
28
|
+
%b Content Type:
|
|
29
|
+
= @attachment.io_stream.content_type
|
|
30
|
+
|
|
31
|
+
%p
|
|
32
|
+
%b Version:
|
|
33
|
+
= @attachment.revision_number
|
|
34
|
+
|
|
35
|
+
%br/
|
|
36
|
+
= link_to 'Show', @attachment
|
|
37
|
+
|
|
|
38
|
+
= link_to 'View All Attachments', attachments_path
|
|
39
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
%h2 Attachments
|
|
2
|
+
|
|
3
|
+
= semantic_form_for Attachment.new, url: attachments_path, html: {multipart: true} do |f|
|
|
4
|
+
= f.inputs do
|
|
5
|
+
= render 'form', f: f, attachment: f.object
|
|
6
|
+
|
|
7
|
+
= f.action :submit, input_html: { value: 'Upload File', onclick: "this.disabled=true;this.value='Please wait...';this.form.submit();" }
|
|
8
|
+
|
|
9
|
+
%table#resource_table{alt: 'Attachments'}
|
|
10
|
+
%thead
|
|
11
|
+
%tr
|
|
12
|
+
%th Download
|
|
13
|
+
%th File Name
|
|
14
|
+
%th Version
|
|
15
|
+
%th Last Modified
|
|
16
|
+
%th.action_col_header{colspan: 2} Actions
|
|
17
|
+
|
|
18
|
+
%tbody
|
|
19
|
+
= render @attachments
|
|
20
|
+
|
|
21
|
+
%br/
|
|
22
|
+
= link_to 'New Attachment', new_attachment_path, title: 'New Attachment'
|
|
23
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
xml.instruct! :xml, version: '1.0', encoding: 'UTF-8'
|
|
2
|
+
xml.attachments do
|
|
3
|
+
xml.page params[:page]
|
|
4
|
+
xml.total_pages(@filtered_collection ? (@filtered_collection.count / params[:rows].to_f).ceil : 1)
|
|
5
|
+
xml.num_records(@filtered_collection ? @filtered_collection.count : 0)
|
|
6
|
+
xml.rows do
|
|
7
|
+
@attachments && @attachments.each do |u|
|
|
8
|
+
xml.attachment id: u.id do
|
|
9
|
+
xml.id u.id
|
|
10
|
+
xml.parent_type u.parent_type
|
|
11
|
+
xml.parent_id u.parent_id
|
|
12
|
+
xml.revision_number u.revision_number
|
|
13
|
+
xml.io_stream_file_name u.io_stream_file_name
|
|
14
|
+
xml.io_stream_content_type u.io_stream_content_type
|
|
15
|
+
xml.io_stream_file_size u.io_stream_file_size
|
|
16
|
+
xml.io_stream_updated_at u.io_stream_updated_at
|
|
17
|
+
xml.created_at u.created_at
|
|
18
|
+
xml.updated_at u.updated_at
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
%h2 New Attachment
|
|
2
|
+
|
|
3
|
+
= semantic_form_for @attachment, url: attachments_path, html: {multipart: true} do |f|
|
|
4
|
+
= f.inputs do
|
|
5
|
+
= render 'form', f: f, attachment: @attachment
|
|
6
|
+
|
|
7
|
+
= f.action :submit, input_html: { value: 'Upload File', onclick: "this.disabled=true;this.value='Please wait...';this.form.submit();" }
|
|
8
|
+
|
|
9
|
+
= link_to 'View All Attachments', attachments_path
|
|
10
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
%h2 Attachment #{@attachment.io_stream_file_name}
|
|
2
|
+
|
|
3
|
+
#spreadsheet_action_panel.actions_menu
|
|
4
|
+
- img_tag = image_tag '/assets/importable_attachments/buttons/download_32.png', alt: 'Download Original File', title: 'Download Original File', id: 'icon_file_download', :class => 'faux_link'
|
|
5
|
+
=link_to img_tag, @attachment.io_stream.url, title: @attachment.io_stream_file_name, alt: @attachment.io_stream_file_name
|
|
6
|
+
|
|
7
|
+
- if @attachment.attachable_type
|
|
8
|
+
%p
|
|
9
|
+
%b Represents:
|
|
10
|
+
= "#{@attachment.attachable_type} id: #{@attachment.attachable_id}"
|
|
11
|
+
|
|
12
|
+
%p
|
|
13
|
+
%b File Name:
|
|
14
|
+
=link_to @attachment.io_stream_file_name, @attachment.io_stream.url, title: @attachment.io_stream_file_name, alt: @attachment.io_stream_file_name
|
|
15
|
+
|
|
16
|
+
- if %w(development test).include?(Rails.env)
|
|
17
|
+
%p
|
|
18
|
+
%b File Path:
|
|
19
|
+
=link_to @attachment.io_stream.path.sub(Rails.root.to_s + '/', ""), File.dirname(@attachment.io_stream.path)
|
|
20
|
+
|
|
21
|
+
%p
|
|
22
|
+
%b File Size:
|
|
23
|
+
= "#{@attachment.io_stream_file_size} bytes"
|
|
24
|
+
|
|
25
|
+
%p
|
|
26
|
+
%b Content Type:
|
|
27
|
+
= @attachment.io_stream_mime_type.try(:simplified) || 'Unknown'
|
|
28
|
+
|
|
29
|
+
%p
|
|
30
|
+
%b Version:
|
|
31
|
+
= @attachment.revision_number
|
|
32
|
+
|
|
33
|
+
%p
|
|
34
|
+
%b Last Modified:
|
|
35
|
+
= @attachment.updated_at.strftime('%Y-%m-%d %I:%M %p')
|
|
36
|
+
|
|
37
|
+
%br/
|
|
38
|
+
= link_to 'Edit', edit_attachment_path(@attachment)
|
|
39
|
+
|
|
|
40
|
+
= link_to 'Destroy', @attachment, confirm: 'Are you sure?', method: :delete
|
|
41
|
+
|
|
|
42
|
+
= link_to 'View All Attachments', attachments_path
|
|
43
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
= form_for @version do |f|
|
|
2
|
+
- if @version.errors.any?
|
|
3
|
+
#error_explanation
|
|
4
|
+
%h2= "#{pluralize(@version.errors.count, "error")} prohibited this version from being saved:"
|
|
5
|
+
%ul
|
|
6
|
+
- @version.errors.full_messages.each do |msg|
|
|
7
|
+
%li= msg
|
|
8
|
+
|
|
9
|
+
.field
|
|
10
|
+
= f.label :item_type
|
|
11
|
+
= f.text_field :item_type
|
|
12
|
+
.field
|
|
13
|
+
= f.label :item_id
|
|
14
|
+
= f.text_field :item_id
|
|
15
|
+
.field
|
|
16
|
+
= f.label :event
|
|
17
|
+
= f.text_field :event
|
|
18
|
+
.field
|
|
19
|
+
= f.label :whodunit
|
|
20
|
+
= f.text_field :whodunit
|
|
21
|
+
.field
|
|
22
|
+
= f.label :object
|
|
23
|
+
= f.text_area :object
|
|
24
|
+
.actions
|
|
25
|
+
= f.submit 'Save'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
%h1 Listing versions
|
|
2
|
+
|
|
3
|
+
%table
|
|
4
|
+
%tr
|
|
5
|
+
%th Item type
|
|
6
|
+
%th Item
|
|
7
|
+
%th Event
|
|
8
|
+
%th Whodunit
|
|
9
|
+
%th Object
|
|
10
|
+
%th
|
|
11
|
+
%th
|
|
12
|
+
%th
|
|
13
|
+
|
|
14
|
+
- @versions.each do |version|
|
|
15
|
+
%tr
|
|
16
|
+
%td= version.item_type
|
|
17
|
+
%td= version.item_id
|
|
18
|
+
%td= version.event
|
|
19
|
+
%td= version.whodunit
|
|
20
|
+
%td= version.object
|
|
21
|
+
%td= link_to 'Show', version
|
|
22
|
+
%td= link_to 'Edit', edit_version_path(version)
|
|
23
|
+
%td= link_to 'Destroy', version, :method => :delete, :data => { :confirm => 'Are you sure?' }
|
|
24
|
+
|
|
25
|
+
%br
|
|
26
|
+
|
|
27
|
+
= link_to 'New Version', new_version_path
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
%p#notice= notice
|
|
2
|
+
|
|
3
|
+
%p
|
|
4
|
+
%b Item type:
|
|
5
|
+
= @version.item_type
|
|
6
|
+
%p
|
|
7
|
+
%b Item:
|
|
8
|
+
= @version.item_id
|
|
9
|
+
%p
|
|
10
|
+
%b Event:
|
|
11
|
+
= @version.event
|
|
12
|
+
%p
|
|
13
|
+
%b Whodunit:
|
|
14
|
+
= @version.whodunit
|
|
15
|
+
%p
|
|
16
|
+
%b Object:
|
|
17
|
+
= @version.object
|
|
18
|
+
|
|
19
|
+
= link_to 'Edit', edit_version_path(@version)
|
|
20
|
+
\|
|
|
21
|
+
= link_to 'Back', versions_path
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
- current_version = collection.last || Version.new
|
|
2
|
+
%h3
|
|
3
|
+
Current Version: #{collection.length}
|
|
4
|
+
|
|
5
|
+
%b Created At:
|
|
6
|
+
= current_version.created_at
|
|
7
|
+
|
|
8
|
+
%br/
|
|
9
|
+
= succeed ':' do
|
|
10
|
+
%b Admin
|
|
11
|
+
|
|
12
|
+
%br/
|
|
13
|
+
- if collection.length.to_i > 1
|
|
14
|
+
- if params[:version].to_i > 1 || !params[:version]
|
|
15
|
+
= link_to 'Previous version', {version: (params[:version] || collection.length).to_i - 1}
|
|
16
|
+
|
|
17
|
+
%br/
|
|
18
|
+
|
|
19
|
+
- if params[:version]
|
|
20
|
+
%h3
|
|
21
|
+
This is #{params[:version]} version
|
|
22
|
+
|
|
23
|
+
%b Modify at:
|
|
24
|
+
= collection[(params[:version].to_i - 1)].created_at
|
|
25
|
+
|
|
26
|
+
%br/
|
|
27
|
+
|
|
28
|
+
= succeed ':' do
|
|
29
|
+
%b Admin
|
|
30
|
+
|
|
31
|
+
%br/
|
|
32
|
+
= link_to 'Go to current version'
|
|
33
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
!!! 1.1
|
|
2
|
+
%html{lang: 'en', 'xml:lang' => 'en', xmlns: 'http://www.w3.org/1999/xhtml'}
|
|
3
|
+
%head
|
|
4
|
+
%meta{content: 'text/html; charset=utf-8', :'http-equiv' => 'Content-type'}/
|
|
5
|
+
%meta{name: 'document-rights', content: 'Copyrighted Work'}
|
|
6
|
+
%meta{name: 'Copyright', content: 'Copyright (c) Paul Belt'}
|
|
7
|
+
%meta{name: 'Rating', content: 'General'}
|
|
8
|
+
%meta{name: 'Keywords', content: 'attachments upload download'}
|
|
9
|
+
%meta{name: 'Description', content: 'Attachments Engine'}
|
|
10
|
+
%meta{name: 'csrf-token_name', content: request_forgery_protection_token}
|
|
11
|
+
%meta{name: 'csrf-token', content: form_authenticity_token}
|
|
12
|
+
%meta{name: 'csrf-param', content: 'authenticity_token'}
|
|
13
|
+
|
|
14
|
+
%title Attachments
|
|
15
|
+
|
|
16
|
+
= stylesheet_link_tag 'importable_attachments/application', media: 'all', charset: 'utf-8'
|
|
17
|
+
= javascript_include_tag 'importable_attachments/application', charset: 'utf-8'
|
|
18
|
+
|
|
19
|
+
/[if IE 6]
|
|
20
|
+
= stylesheet_link_tag 'formtastic_ie6'
|
|
21
|
+
/[if IE 7]
|
|
22
|
+
= stylesheet_link_tag 'formtastic_ie7'
|
|
23
|
+
|
|
24
|
+
- if protect_against_forgery?
|
|
25
|
+
= csrf_meta_tags # this must be last
|
|
26
|
+
|
|
27
|
+
%body
|
|
28
|
+
#flash
|
|
29
|
+
- flash.each do |key, value|
|
|
30
|
+
%div{:id => "flash_#{key}"}
|
|
31
|
+
%p{:style => 'float:right;'}
|
|
32
|
+
= link_to_function 'X', "Effect.Fade('flash_#{key}')"
|
|
33
|
+
%ul
|
|
34
|
+
- if value.is_a?(Hash)
|
|
35
|
+
%li.message
|
|
36
|
+
= h value[:message]
|
|
37
|
+
%li.flash_followup_action
|
|
38
|
+
= h value[:followup]
|
|
39
|
+
- else
|
|
40
|
+
%li.message
|
|
41
|
+
= h value
|
|
42
|
+
.clear
|
|
43
|
+
|
|
44
|
+
#contents
|
|
45
|
+
%noscript.noscript
|
|
46
|
+
%p Please enable JavaScript for a better experience.
|
|
47
|
+
|
|
48
|
+
= yield
|