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.
Files changed (142) hide show
  1. data/.gitignore +24 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +38 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +8 -0
  7. data/README.rdoc +3 -0
  8. data/Rakefile +29 -0
  9. data/app/assets/images/importable_attachments/.gitkeep +0 -0
  10. data/app/assets/images/importable_attachments/buttons/.htaccess +5 -0
  11. data/app/assets/images/importable_attachments/buttons/download_32.png +0 -0
  12. data/app/assets/images/importable_attachments/buttons/upload_32.png +0 -0
  13. data/app/assets/javascripts/importable_attachments/application.js +14 -0
  14. data/app/assets/javascripts/importable_attachments/attachments.coffee +41 -0
  15. data/app/assets/stylesheets/importable_attachments/application.css +14 -0
  16. data/app/assets/stylesheets/importable_attachments/attachments.css +4 -0
  17. data/app/assets/stylesheets/scaffold.css +56 -0
  18. data/app/controllers/importable_attachments/application_controller.rb +4 -0
  19. data/app/controllers/importable_attachments/attachments_controller.rb +190 -0
  20. data/app/controllers/importable_attachments/versions_controller.rb +87 -0
  21. data/app/helpers/importable_attachments/application_helper.rb +4 -0
  22. data/app/models/attachment.rb +24 -0
  23. data/app/models/importable_attachments/attachment.rb +143 -0
  24. data/app/models/importable_attachments/version.rb +50 -0
  25. data/app/validators/existing_class_validator.rb +17 -0
  26. data/app/validators/importable_attachments/csv_validator.rb +36 -0
  27. data/app/validators/importable_attachments/excel.rb +18 -0
  28. data/app/validators/importable_attachments/excel_validator.rb +18 -0
  29. data/app/views/importable_attachments/attachments/_attachment.html.haml +9 -0
  30. data/app/views/importable_attachments/attachments/_form.html.haml +22 -0
  31. data/app/views/importable_attachments/attachments/_nested_form.html.haml +20 -0
  32. data/app/views/importable_attachments/attachments/edit.html.haml +39 -0
  33. data/app/views/importable_attachments/attachments/index.html.haml +23 -0
  34. data/app/views/importable_attachments/attachments/index.xml.builder +23 -0
  35. data/app/views/importable_attachments/attachments/new.html.haml +10 -0
  36. data/app/views/importable_attachments/attachments/show.html.haml +43 -0
  37. data/app/views/importable_attachments/versions/_form.html.haml +25 -0
  38. data/app/views/importable_attachments/versions/edit.html.haml +7 -0
  39. data/app/views/importable_attachments/versions/index.html.haml +27 -0
  40. data/app/views/importable_attachments/versions/new.html.haml +5 -0
  41. data/app/views/importable_attachments/versions/show.html.haml +21 -0
  42. data/app/views/layouts/_version.html.haml +33 -0
  43. data/app/views/layouts/importable_attachments/application.html.haml +48 -0
  44. data/bin/set_lc.sh +47 -0
  45. data/config/database.yml +25 -0
  46. data/config/features/attachments.rb +8 -0
  47. data/config/features/mark_requirements.rb +3 -0
  48. data/config/features/smarter_dates.rb +3 -0
  49. data/config/features/versioning.rb +7 -0
  50. data/config/initializers/0_configuration.rb +7 -0
  51. data/config/initializers/formtastic.rb +76 -0
  52. data/config/initializers/generators.rb +10 -0
  53. data/config/initializers/paperclip.rb +27 -0
  54. data/config/locales/responders.en.yml +10 -0
  55. data/config/routes.rb +11 -0
  56. data/db/migrate/001_create_importable_attachments_versions.rb +14 -0
  57. data/db/migrate/100_create_attachments.rb +19 -0
  58. data/importable_attachments.gemspec +81 -0
  59. data/lib/generators/importable_attachments/install_generator.rb +66 -0
  60. data/lib/generators/importable_attachments/templates/features/attachments.rb.erb +7 -0
  61. data/lib/generators/importable_attachments/templates/features/versioning.rb +7 -0
  62. data/lib/generators/importable_attachments/templates/initializers/paperclip.rb +27 -0
  63. data/lib/importable_attachments/base.rb +108 -0
  64. data/lib/importable_attachments/blueprints.rb +9 -0
  65. data/lib/importable_attachments/engine.rb +8 -0
  66. data/lib/importable_attachments/importers/csv.rb +208 -0
  67. data/lib/importable_attachments/importers/excel.rb +37 -0
  68. data/lib/importable_attachments/importers.rb +7 -0
  69. data/lib/importable_attachments/version.rb +3 -0
  70. data/lib/importable_attachments.rb +9 -0
  71. data/lib/paperclip_processors/save_upload.rb +33 -0
  72. data/lib/tasks/importable_attachments_tasks.rake +4 -0
  73. data/script/rails +8 -0
  74. data/spec/attachments/books.csv +6 -0
  75. data/spec/attachments/books.txt +6 -0
  76. data/spec/attachments/books2.csv +4 -0
  77. data/spec/attachments/empty.csv +0 -0
  78. data/spec/attachments/failed_instances.csv +3 -0
  79. data/spec/attachments/invalid_headers.csv +3 -0
  80. data/spec/attachments/just_headers.csv +1 -0
  81. data/spec/attachments/mostly_empty.csv +2 -0
  82. data/spec/attachments/mostly_empty_copy.xls +0 -0
  83. data/spec/controllers/importable_attachments/attachments_controller_spec.rb +236 -0
  84. data/spec/controllers/importable_attachments/versions_controller_spec.rb +158 -0
  85. data/spec/dummy/README.rdoc +261 -0
  86. data/spec/dummy/Rakefile +7 -0
  87. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  88. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  89. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  90. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  91. data/spec/dummy/app/mailers/.gitkeep +0 -0
  92. data/spec/dummy/app/models/.gitkeep +0 -0
  93. data/spec/dummy/app/models/book.rb +13 -0
  94. data/spec/dummy/app/models/library.rb +54 -0
  95. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  96. data/spec/dummy/config/application.rb +65 -0
  97. data/spec/dummy/config/boot.rb +10 -0
  98. data/spec/dummy/config/database.yml +25 -0
  99. data/spec/dummy/config/environment.rb +5 -0
  100. data/spec/dummy/config/environments/development.rb +37 -0
  101. data/spec/dummy/config/environments/production.rb +67 -0
  102. data/spec/dummy/config/environments/test.rb +37 -0
  103. data/spec/dummy/config/initializers/0_configuration.rb +7 -0
  104. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  105. data/spec/dummy/config/initializers/inflections.rb +15 -0
  106. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  107. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  108. data/spec/dummy/config/initializers/session_store.rb +8 -0
  109. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  110. data/spec/dummy/config/locales/en.yml +5 -0
  111. data/spec/dummy/config/routes.rb +4 -0
  112. data/spec/dummy/config.ru +4 -0
  113. data/spec/dummy/db/migrate/101_create_libraries.rb +10 -0
  114. data/spec/dummy/db/migrate/102_create_books.rb +12 -0
  115. data/spec/dummy/db/schema.rb +57 -0
  116. data/spec/dummy/features/person_uploads_generic_file.feature +11 -0
  117. data/spec/dummy/features/step_definitions/person_uploads_generic_file_steps.rb +11 -0
  118. data/spec/dummy/features/step_definitions/web_steps.rb +211 -0
  119. data/spec/dummy/features/support/capybara.rb +6 -0
  120. data/spec/dummy/features/support/database_cleaner.rb +26 -0
  121. data/spec/dummy/features/support/developer_helpers.rb +47 -0
  122. data/spec/dummy/features/support/env.rb +53 -0
  123. data/spec/dummy/features/support/paths.rb +33 -0
  124. data/spec/dummy/features/support/poltergeist.rb +1 -0
  125. data/spec/dummy/features/support/selectors.rb +39 -0
  126. data/spec/dummy/features/support/transactional_fixtures.rb +14 -0
  127. data/spec/dummy/lib/assets/.gitkeep +0 -0
  128. data/spec/dummy/log/.gitkeep +0 -0
  129. data/spec/dummy/public/404.html +38 -0
  130. data/spec/dummy/public/422.html +38 -0
  131. data/spec/dummy/public/500.html +36 -0
  132. data/spec/dummy/public/favicon.ico +0 -0
  133. data/spec/dummy/script/rails +6 -0
  134. data/spec/dummy/spec/support/.gitkeep +0 -0
  135. data/spec/dummy/spec/support/paperclip.rb +1 -0
  136. data/spec/models/importable_attachments/attachment_spec.rb +177 -0
  137. data/spec/models/importable_attachments/library_spec.rb +155 -0
  138. data/spec/models/importable_attachments/version_spec.rb +25 -0
  139. data/spec/routing/importable_attachments/versions_routing_spec.rb +43 -0
  140. data/spec/spec.opts +5 -0
  141. data/spec/spec_helper.rb +30 -0
  142. 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,7 @@
1
+ %h1 Editing version
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Show', @version
6
+ \|
7
+ = link_to 'Back', versions_path
@@ -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,5 @@
1
+ %h1 New version
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Back', versions_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