trusty-cms 3.1.11 → 3.2.0

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -14
  3. data/Gemfile.lock +84 -70
  4. data/README.md +4 -0
  5. data/app/assets/images/admin/add.png +0 -0
  6. data/app/assets/images/admin/archive_icon.png +0 -0
  7. data/app/assets/images/admin/audio_icon.png +0 -0
  8. data/app/assets/images/admin/audio_thumbnail.png +0 -0
  9. data/app/assets/images/admin/c_icon.png +0 -0
  10. data/app/assets/images/admin/copy.png +0 -0
  11. data/app/assets/images/admin/css_icon.png +0 -0
  12. data/app/assets/images/admin/database_icon.png +0 -0
  13. data/app/assets/images/admin/delete.png +0 -0
  14. data/app/assets/images/admin/document_icon.png +0 -0
  15. data/app/assets/images/admin/document_thumbnail.png +0 -0
  16. data/app/assets/images/admin/flash_icon.png +0 -0
  17. data/app/assets/images/admin/flash_thumbnail.png +0 -0
  18. data/app/assets/images/admin/font_icon.png +0 -0
  19. data/app/assets/images/admin/gzip_icon.png +0 -0
  20. data/app/assets/images/admin/html_icon.png +0 -0
  21. data/app/assets/images/admin/image_icon.png +0 -0
  22. data/app/assets/images/admin/image_thumbnail.png +0 -0
  23. data/app/assets/images/admin/java_icon.png +0 -0
  24. data/app/assets/images/admin/page_edit.png +0 -0
  25. data/app/assets/images/admin/pdf_icon.png +0 -0
  26. data/app/assets/images/admin/pdf_thumbnail.png +0 -0
  27. data/app/assets/images/admin/perl_icon.png +0 -0
  28. data/app/assets/images/admin/php_icon.png +0 -0
  29. data/app/assets/images/admin/presentation_icon.png +0 -0
  30. data/app/assets/images/admin/python_icon.png +0 -0
  31. data/app/assets/images/admin/reorder_assets.png +0 -0
  32. data/app/assets/images/admin/ruby_icon.png +0 -0
  33. data/app/assets/images/admin/script_icon.png +0 -0
  34. data/app/assets/images/admin/spinner.gif +0 -0
  35. data/app/assets/images/admin/spreadsheet_icon.png +0 -0
  36. data/app/assets/images/admin/tar_icon.png +0 -0
  37. data/app/assets/images/admin/unknown_icon.png +0 -0
  38. data/app/assets/images/admin/unknown_thumbnail.png +0 -0
  39. data/app/assets/images/admin/video_icon.png +0 -0
  40. data/app/assets/images/admin/video_thumbnail.png +0 -0
  41. data/app/assets/images/admin/xml_icon.png +0 -0
  42. data/app/assets/images/admin/zip_icon.png +0 -0
  43. data/app/assets/javascripts/admin/assets.js +268 -0
  44. data/app/assets/javascripts/admin/assets_admin.js +16 -0
  45. data/app/assets/javascripts/admin/jquery.fileupload.js +1457 -0
  46. data/app/assets/javascripts/admin/jquery.iframe-transport.js +214 -0
  47. data/app/assets/javascripts/admin/jquery.ui.widget.js +558 -0
  48. data/app/assets/stylesheets/admin/assets.scss +283 -0
  49. data/app/controllers/admin/assets_controller.rb +88 -0
  50. data/app/controllers/admin/page_attachments_controller.rb +23 -0
  51. data/app/helpers/admin/assets_helper.rb +16 -0
  52. data/app/helpers/admin/page_attachments_helper.rb +2 -0
  53. data/app/models/asset.rb +251 -0
  54. data/app/models/asset_type.rb +239 -0
  55. data/app/models/old_page_attachment.rb +26 -0
  56. data/app/models/page_attachment.rb +20 -0
  57. data/app/views/admin/assets/_asset.html.haml +12 -0
  58. data/app/views/admin/assets/_asset_table.html.haml +30 -0
  59. data/app/views/admin/assets/_errors.html.haml +3 -0
  60. data/app/views/admin/assets/_form.html.haml +18 -0
  61. data/app/views/admin/assets/_page_assets.html.haml +12 -0
  62. data/app/views/admin/assets/_search.html.haml +17 -0
  63. data/app/views/admin/assets/_search_results.html.haml +17 -0
  64. data/app/views/admin/assets/edit.html.haml +40 -0
  65. data/app/views/admin/assets/index.html.haml +15 -0
  66. data/app/views/admin/assets/new.html.haml +24 -0
  67. data/app/views/admin/assets/refresh.html.haml +14 -0
  68. data/app/views/admin/assets/remove.html.haml +16 -0
  69. data/app/views/admin/configuration/_clipped_edit.html.haml +8 -0
  70. data/app/views/admin/configuration/_clipped_show.html.haml +12 -0
  71. data/app/views/admin/page_attachments/_attachment.html.haml +25 -0
  72. data/app/views/admin/pages/_asset_popups.html.haml +37 -0
  73. data/app/views/admin/pages/_assets.html.haml +13 -0
  74. data/app/views/admin/removed/_assets_bucket.html.haml +8 -0
  75. data/app/views/admin/removed/_assets_container.html.haml +54 -0
  76. data/app/views/admin/removed/_bucket.html.haml +11 -0
  77. data/app/views/admin/removed/_bucket_asset.html.haml +9 -0
  78. data/app/views/admin/removed/_show_bucket_link.html.haml +4 -0
  79. data/app/views/admin/removed/_upload_to_page.html.haml +12 -0
  80. data/app/views/admin/removed/bucket/_iframe.html.haml +1 -0
  81. data/config/application.rb +0 -37
  82. data/config/initializers/assets.rb +1 -0
  83. data/config/initializers/interpolation.rb +6 -0
  84. data/config/initializers/kraken.rb +7 -0
  85. data/config/initializers/trusty_cms_config.rb +67 -0
  86. data/config/locales/en.yml +101 -0
  87. data/config/routes.rb +14 -3
  88. data/coverage/index.html +26 -26
  89. data/db/migrate/028_create_assets.rb +12 -0
  90. data/db/migrate/029_create_paperclip_attributes.rb +13 -0
  91. data/db/migrate/030_create_user_observer.rb +13 -0
  92. data/db/migrate/031_create_page_attachments.rb +19 -0
  93. data/db/migrate/032_rename_users.rb +13 -0
  94. data/db/migrate/20110513205050_asset_uuid.rb +11 -0
  95. data/db/migrate/20110606111250_update_configuration.rb +34 -0
  96. data/db/migrate/20110609101438_dimensions.rb +13 -0
  97. data/lib/trusty_cms.rb +1 -1
  98. data/spec/dummy/db/schema.rb +22 -0
  99. data/spec/dummy/log/test.log +95620 -0
  100. data/spec/dummy/tmp/cache/747/A70/TrustyCms%3A%3AConfig +0 -0
  101. data/spec/dummy/tmp/cache/85C/FA0/TrustyCms.cache_mtime +0 -0
  102. data/spec/dummy/tmp/capybara/capybara-20180312152412265881245.html +262 -0
  103. data/spec/dummy/tmp/capybara/capybara-201803121526139973682798.html +149 -0
  104. data/spec/factories/layout.rb +1 -1
  105. data/spec/factories/page.rb +3 -3
  106. data/spec/factories/page_part.rb +1 -1
  107. data/spec/factories/user.rb +1 -1
  108. data/spec/models/layout_spec.rb +6 -6
  109. data/spec/spec_helper.rb +4 -4
  110. data/trusty_cms.gemspec +27 -22
  111. data/vendor/extensions/clipped-extension/clipped_extension.rb +40 -0
  112. data/vendor/extensions/clipped-extension/lib/asset_tags.rb +346 -0
  113. data/vendor/extensions/clipped-extension/lib/clipped/engine.rb +11 -0
  114. data/vendor/extensions/clipped-extension/lib/clipped_admin_ui.rb +28 -0
  115. data/vendor/extensions/clipped-extension/lib/generators/templates/clipped_config.rb +53 -0
  116. data/vendor/extensions/clipped-extension/lib/page_asset_associations.rb +13 -0
  117. data/vendor/extensions/clipped-extension/lib/paperclip/frame_grab.rb +73 -0
  118. data/vendor/extensions/clipped-extension/lib/paperclip/geometry_transformation.rb +80 -0
  119. data/vendor/extensions/clipped-extension/lib/tasks/clipped_extension_tasks.rake +124 -0
  120. data/vendor/extensions/clipped-extension/lib/tasks/paperclip_tasks.rake +79 -0
  121. data/vendor/extensions/clipped-extension/lib/trusty-clipped-extension.rb +2 -0
  122. data/vendor/extensions/clipped-extension/lib/trusty_cms_clipped_extension/cloud.rb +41 -0
  123. metadata +219 -67
  124. data/config/initializers/ckeditor.rb +0 -3
  125. data/config/initializers/haml.rb +0 -2
  126. data/config/initializers/rails_patch.rb +0 -2
  127. data/config/initializers/string_extensions.rb +0 -1
  128. data/config/initializers/symbol_extensions.rb +0 -1
@@ -0,0 +1,283 @@
1
+ @import "compass";
2
+
3
+ p.asset {
4
+ img.preview {
5
+ border: 5px solid white;
6
+ @include box-shadow;
7
+ }
8
+ }
9
+
10
+ .asset_filters {
11
+ float: left;
12
+ padding: 2px 0;
13
+ a {
14
+ @include border-radius(100px);
15
+ color: #555555;
16
+ padding: 3px 8px;
17
+ text-decoration: none;
18
+ font-size: 12px;
19
+ &:hover {
20
+ background: #cccccc;
21
+ }
22
+ &.pressed {
23
+ background: #888888;
24
+ @include box-shadow(0, 1px, 1px, #333333, inset);
25
+ color: white;
26
+ text-shadow: 0 1px 0 #333333;
27
+ &:hover {
28
+ background: #888888;
29
+ @include box-shadow(0, 1px, 1px, #333333, inset);
30
+ color: white;
31
+ text-shadow: 0 1px 0 #333333;
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ .popup {
38
+ div.toolbar {
39
+ background: white;
40
+ @include background-image(linear-gradient(white, #dddddd));
41
+ border-bottom: 1px solid #cccccc;
42
+ @include single-box-shadow(white, 0, 1px, 0);
43
+ margin: -20px -20px 0;
44
+ padding: 6px 10px 3px 10px;
45
+ font-size: 95%;
46
+ height: 30px;
47
+ @include clearfix;
48
+ .right {
49
+ float: right;
50
+ }
51
+ form.search {
52
+ padding: 4px 2px 0;
53
+ input[type=search] {
54
+ font-size: 12px;
55
+ @include border-radius(100px);
56
+ border: 1px solid #cccccc;
57
+ border-top-color: #999999;
58
+ border-left-color: #b0b0b0;
59
+ border-right-color: #bbbbbb;
60
+ background: white url("/assets/admin/search.png") 4px center no-repeat;
61
+ @include box-shadow(rgba(black, 0.2), 0, 1px, 0, inset);
62
+ width: 180px;
63
+ padding: 2px 8px 2px 20px;
64
+ }
65
+ }
66
+ }
67
+ #assets_table.assets {
68
+ overflow: auto;
69
+ }
70
+ }
71
+
72
+ #upload_holders {
73
+ display: none;
74
+ }
75
+
76
+ #attach_asset {
77
+ .viewport {
78
+ overflow-x: hidden;
79
+ width: 610px;
80
+ height: 310px;
81
+ }
82
+ }
83
+
84
+ .attachment_actions {
85
+ text-align: right;
86
+ margin-bottom: -1em;
87
+ ul {
88
+ @include inline-list;
89
+ }
90
+ li {
91
+ padding-left: 1em;
92
+ }
93
+ a {
94
+ color: white !important;
95
+ text-shadow: 1px 1px 0 #888888;
96
+ }
97
+ }
98
+
99
+ .assets {
100
+ height: 150px;
101
+ padding-left: 5px;
102
+ padding-right: 5px;
103
+ ul {
104
+ li.asset {
105
+ display: block;
106
+ float: left;
107
+ margin: 1em;
108
+ width: 110px;
109
+ height: 110px;
110
+ position: relative;
111
+ line-height: 1.2em;
112
+ .front, .back {
113
+ display: block;
114
+ background: #e6eaed;
115
+ border: 5px solid white;
116
+ position: absolute;
117
+ width: 100px;
118
+ height: 100px;
119
+ text-align: center;
120
+ }
121
+ .front {
122
+ @include box-shadow;
123
+ text-align: center;
124
+ }
125
+ .back {
126
+ color: #333333;
127
+ overflow: hidden;
128
+ @include opacity(0);
129
+ }
130
+ .title {
131
+ color: #333333;
132
+ font-size: 10px;
133
+ overflow: hidden;
134
+ margin: 10px 4px;
135
+ height: 15px;
136
+ line-height: 15px;
137
+ text-overflow: ellipsis;
138
+ }
139
+ .icon {
140
+ height: 63px;
141
+ line-height: 63px;
142
+ img {
143
+ vertical-align: bottom;
144
+ }
145
+ }
146
+ ul.actions {
147
+ li {
148
+ margin: 5px 0;
149
+ padding: 0 10px;
150
+ font-size: 10px;
151
+ }
152
+ a {
153
+ background: #666666;
154
+ background: rgba(black, 0.8);
155
+ @include border-radius;
156
+ color: #dddddd;
157
+ display: block;
158
+ padding: 2px 10px;
159
+ text-decoration: none;
160
+ &:hover {
161
+ background: #999999;
162
+ background: rgba(black, 0.6);
163
+ color: white;
164
+ }
165
+ }
166
+ }
167
+ &.unsaved {
168
+ .front {
169
+ opacity: 0.4;
170
+ }
171
+ }
172
+ &:hover {
173
+ .back {
174
+ @include opacity(1);
175
+ background: rgba(white, 0.6);
176
+ }
177
+ }
178
+ &.waiting {
179
+ background-color: #e6eaed;
180
+ .back {
181
+ display: none;
182
+ }
183
+ .front {
184
+ background: transparent url(/assets/admin/spinner.gif) no-repeat center center;
185
+ img {
186
+ opacity: 0.2;
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ #attachment_list.assets {
195
+ @include border-bottom-radius;
196
+ margin: -1em 0.5em 1em 0.5em;
197
+ overflow-y: hidden;
198
+ overflow-x: auto;
199
+ ul.empty {
200
+ display: none;
201
+ }
202
+ p.note {
203
+ margin: 0;
204
+ padding: 8px;
205
+ clear: left;
206
+ span.message {
207
+ float: right;
208
+ color: #aaaaaa;
209
+ &.important {
210
+ color: #dd9999;
211
+ }
212
+ }
213
+ }
214
+ ul.sortable {
215
+ li.asset {
216
+ div.back {
217
+ cursor: move;
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ #assets_table.assets {
224
+ position: relative;
225
+ font-size: 75%;
226
+ p {
227
+ padding: 40px {
228
+ top: 45px;
229
+ };
230
+ color: silver;
231
+ text-align: center;
232
+ font-style: oblique;
233
+ }
234
+ ul {
235
+ clear: both;
236
+ li.asset {
237
+ input {
238
+ display: none;
239
+ }
240
+ }
241
+ }
242
+ div.pagination {
243
+ position: relative;
244
+ overflow: hidden;
245
+ clear: left;
246
+ width: 100%;
247
+ height: 3em;
248
+ padding: 0.5em 0;
249
+ span, a, em {
250
+ display: block;
251
+ float: left;
252
+ padding: 0.25em;
253
+ margin: 1em 2px 1em 0;
254
+ @include border-radius(2px);
255
+ text-decoration: none;
256
+ }
257
+ span.current {
258
+ color: black;
259
+ font-weight: bold;
260
+ }
261
+ span.disabled {
262
+ background-color: #eeeeee;
263
+ color: #cccccc;
264
+ }
265
+ a {
266
+ background-color: #eeeeee;
267
+ color: #444444;
268
+ &:hover {
269
+ background-color: #BC045C;
270
+ color: white;
271
+ }
272
+ }
273
+ span {
274
+ color: #888888;
275
+ }
276
+ span, a {
277
+ display: block;
278
+ float: left;
279
+ padding: 2px 6px;
280
+ line-height: 1.5em;
281
+ }
282
+ }
283
+ }
@@ -0,0 +1,88 @@
1
+ class Admin::AssetsController < Admin::ResourceController
2
+ paginate_models(:per_page => 50)
3
+ COMPRESS_FILE_TYPE = ["image/jpeg", "image/png", "image/gif", "image/svg+xml"]
4
+
5
+ def index
6
+ assets = Asset.order("created_at DESC")
7
+ @page = Page.find(params[:page_id]) if params[:page_id]
8
+
9
+ @term = params[:search] || ''
10
+ assets = assets.matching(@term) if @term && !@term.blank?
11
+
12
+ @types = params[:filter] ? params[:filter].split(",") : []
13
+ if @types.include?('all')
14
+ params[:filter] = nil
15
+ elsif @types.any?
16
+ assets = assets.of_types(@types)
17
+ end
18
+
19
+ @assets = paginated? ? assets.paginate(pagination_parameters) : assets.all
20
+ respond_to do |format|
21
+
22
+ format.js {
23
+ @page = Page.find_by_id(params[:page_id])
24
+ render :partial => 'asset_table', :locals => {:with_pagination => true}
25
+ }
26
+ format.html {
27
+ render
28
+ }
29
+ end
30
+ end
31
+
32
+ def create
33
+ @assets, @page_attachments = [], []
34
+ compress = current_site.try(:compress) ? current_site.compress : true
35
+ binding.pry
36
+ asset_params[:asset][:asset].to_a.each do |uploaded_asset|
37
+ if uploaded_asset.content_type == "application/octet-stream"
38
+ flash[:notice] = "Please only upload assets that have a valid extension in the name."
39
+ else
40
+ uploaded_asset = compress(uploaded_asset) if $kraken.api_key.present? && COMPRESS_FILE_TYPE.include?(uploaded_asset.content_type) && compress
41
+ @asset = Asset.create(:asset => uploaded_asset, :caption => asset_params[:asset][:caption])
42
+ if params[:for_attachment]
43
+ @page = Page.find_by_id(params[:page_id]) || Page.new
44
+ @page_attachments << @page_attachment = @asset.page_attachments.build(:page => @page)
45
+ end
46
+ @assets << @asset
47
+ end
48
+ end
49
+ if asset_params[:for_attachment]
50
+ render :partial => 'admin/page_attachments/attachment', :collection => @page_attachments
51
+ else
52
+ response_for :create
53
+ end
54
+ end
55
+
56
+ def refresh
57
+ if asset_params[:id]
58
+ @asset = Asset.find(params[:id])
59
+ @asset.asset.reprocess!
60
+ flash[:notice] = t('clipped_extension.thumbnails_refreshed')
61
+ redirect_to edit_admin_asset_path(@asset)
62
+ else
63
+ render
64
+ end
65
+ end
66
+
67
+ only_allow_access_to :regenerate,
68
+ :when => [:admin],
69
+ :denied_url => { :controller => 'admin/assets', :action => 'index' },
70
+ :denied_message => 'You must have admin privileges to refresh the whole asset set.'
71
+
72
+ def regenerate
73
+ Asset.all.each { |asset| asset.asset.reprocess! }
74
+ flash[:notice] = t('clipped_extension.all_thumbnails_refreshed')
75
+ redirect_to admin_assets_path
76
+ end
77
+
78
+ private
79
+ def compress(uploaded_asset)
80
+ data = $kraken.upload(uploaded_asset.tempfile.path, 'lossy' => true)
81
+ File.write(uploaded_asset.tempfile, open(data.kraked_url).read, { :mode => 'wb' })
82
+ uploaded_asset
83
+ end
84
+
85
+ def asset_params
86
+ params.permit(:id, :for_attachment, :asset => [:caption, :for_attachment, :asset => []])
87
+ end
88
+ end
@@ -0,0 +1,23 @@
1
+ class Admin::PageAttachmentsController < Admin::ResourceController
2
+ helper 'admin/assets'
3
+
4
+ def new
5
+ render :partial => 'attachment', :object => model
6
+ end
7
+
8
+ def load_model
9
+ begin
10
+ @asset = Asset.find(params[:asset_id])
11
+ @page = page_attachment_params[:page_id].blank? ? Page.new : Page.find_by_id(page_attachment_params[:page_id])
12
+ rescue ActiveRecord::RecordNotFound
13
+ render :nothing => true, :layout => false
14
+ end
15
+ self.model = PageAttachment.new(:asset => @asset, :page => @page)
16
+ end
17
+
18
+ private
19
+ def page_attachment_params
20
+ params.permit(:asset_id, :page_id)
21
+ end
22
+
23
+ end
@@ -0,0 +1,16 @@
1
+ module Admin::AssetsHelper
2
+
3
+ def automatic_size_descriptions
4
+ Asset.thumbnail_sizes.collect{|k,v| "#{k} (#{(v.to_s).match(/\d+x\d+/)})"}.join(', ')
5
+ end
6
+
7
+ def asset_insertion_link(asset)
8
+ radius_tag = asset.asset_type.default_radius_tag || 'link';
9
+ link_to t('clipped_extension.insert'), '#', :class => 'insert_asset', :rel => "#{radius_tag}_#{TrustyCms.config['assets.insertion_size']}_#{asset.id}"
10
+ end
11
+
12
+ def asset_attachment_link(asset)
13
+ link_to t("clipped_extension.attach"), new_admin_page_attachment_path(:asset_id => asset.id), :class => 'attach_asset', :rel => "attach_#{asset.id}"
14
+ end
15
+
16
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::PageAttachmentsHelper
2
+ end
@@ -0,0 +1,251 @@
1
+ class Asset < ActiveRecord::Base
2
+ include Paperclip::Glue
3
+
4
+ has_many :page_attachments, :dependent => :destroy
5
+ has_many :pages, :through => :page_attachments
6
+ has_site if respond_to? :has_site
7
+
8
+ belongs_to :created_by, :class_name => 'User'
9
+ belongs_to :updated_by, :class_name => 'User'
10
+
11
+ default_scope {order("created_at DESC")}
12
+
13
+ attr_accessible :title, :asset, :caption
14
+
15
+ scope :latest, lambda { |limit|
16
+ order("created_at DESC").limit(limit)
17
+ }
18
+
19
+ scope :of_types, lambda { |types|
20
+ mimes = AssetType.slice(*types).map(&:mime_types).flatten
21
+ Asset.select { |x| mimes.include?(x.asset_content_type) }
22
+ }
23
+
24
+ scope :matching, lambda { |term|
25
+ where(["LOWER(assets.asset_file_name) LIKE (:term) OR LOWER(title) LIKE (:term) OR LOWER(caption) LIKE (:term)", {:term => "%#{term.downcase}%" }])
26
+ }
27
+
28
+ scope :excepting, lambda { |assets|
29
+ if assets.any?
30
+ assets = assets.split(',') if assets.is_a?(String)
31
+ asset_ids = assets.first.is_a?(Asset) ? assets.map(&:id) : assets
32
+ where(["assets.id NOT IN(#{asset_ids.map{ '?' }.join(',')})", *asset_ids])
33
+ else
34
+ {}
35
+ end
36
+ }
37
+
38
+ has_attached_file :asset,
39
+ :styles => lambda { |attachment|
40
+ AssetType.for(attachment).paperclip_styles
41
+ },
42
+ :processors => lambda { |asset|
43
+ asset.paperclip_processors
44
+ },
45
+ :whiny => false,
46
+ :storage => TrustyCms.config["paperclip.storage"],
47
+ :path => TrustyCms.config["paperclip.path"],
48
+ :url => TrustyCms.config["paperclip.url"],
49
+ :fog_credentials =>
50
+ TrustyCmsClippedExtension::Cloud.credentials,
51
+ :fog_directory => TrustyCms.config["paperclip.fog.directory"],
52
+ :fog_public => TrustyCms.config["paperclip.fog.public?"] || true,
53
+ :fog_host => TrustyCmsClippedExtension::Cloud.host,
54
+ :fog_file => {
55
+ 'Cache-Control' => 'max-age=2419200'
56
+ #'Expires' => 1.month.from_now.httpdate
57
+ }
58
+
59
+ validates_attachment_content_type :asset, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif", "application/pdf", "application/javascript", "text/javascript", "text/css"]
60
+
61
+ before_save :assign_title
62
+ before_save :assign_uuid
63
+
64
+ after_post_process :read_dimensions
65
+
66
+ validates_attachment_presence :asset, :message => "You must choose a file to upload!"
67
+ if TrustyCms.config["paperclip.skip_filetype_validation"] != "true" && TrustyCms.config['paperclip.content_types']
68
+ validates_attachment_content_type :asset, :content_type => TrustyCms.config["paperclip.content_types"].gsub(' ','').split(',')
69
+ else
70
+ validates_attachment_presence :asset, :message => "Your uploaded file must have an extension in its name!"
71
+ end
72
+ validates_attachment_size :asset, :less_than => ( TrustyCms.config["assets.max_asset_size"] || 5 ).to_i.megabytes
73
+
74
+ def asset_type
75
+ AssetType.for(asset)
76
+ end
77
+ delegate :paperclip_processors, :paperclip_styles, :style_dimensions, :style_format, :to => :asset_type
78
+
79
+ def thumbnail(style_name='original')
80
+ return asset.url if style_name.to_sym == :original
81
+ return asset.url(style_name.to_sym) if has_style?(style_name)
82
+ return asset_type.icon(style_name)
83
+ end
84
+
85
+ def has_style?(style_name='original')
86
+ style_name == 'original' || paperclip_styles.keys.include?(style_name.to_sym)
87
+ end
88
+
89
+ def basename
90
+ File.basename(asset_file_name, ".*") if asset_file_name
91
+ end
92
+
93
+ def extension(style_name='original')
94
+ if style_name == 'original'
95
+ return original_extension
96
+ elsif style = paperclip_styles[style_name.to_sym]
97
+ return style.format
98
+ else
99
+ return original_extension
100
+ end
101
+ end
102
+
103
+ def original_extension
104
+ return asset_file_name.split('.').last.downcase if asset_file_name
105
+ end
106
+
107
+ def attached_to?(page)
108
+ pages.include?(page)
109
+ end
110
+
111
+ def original_geometry
112
+ @original_geometry ||= Paperclip::Geometry.new(original_width, original_height)
113
+ end
114
+
115
+ def geometry(style_name='original')
116
+ raise Paperclip::StyleError, "Requested style #{style_name} is not defined for this asset." unless has_style?(style_name)
117
+ @geometry ||= {}
118
+ begin
119
+ @geometry[style_name] ||= if style_name.to_s == 'original'
120
+ original_geometry
121
+ else
122
+ style = self.asset.styles[style_name.to_sym]
123
+ original_geometry.transformed_by(style.geometry) # this can return dimensions for fully specified style sizes but not for relative sizes when there are no original dimensions
124
+ end
125
+ rescue Paperclip::TransformationError => e
126
+ Rails.logger.warn "geometry transformation error: #{e}"
127
+ original_geometry # returns a blank geometry if the real geometry cannot be calculated
128
+ end
129
+ end
130
+
131
+ def aspect(style_name='original')
132
+ geometry(style_name).aspect
133
+ end
134
+
135
+ def orientation(style_name='original')
136
+ a = aspect(style_name)
137
+ case
138
+ when a == nil?
139
+ 'unknown'
140
+ when a < 1.0
141
+ 'vertical'
142
+ when a > 1.0
143
+ 'horizontal'
144
+ else
145
+ 'square'
146
+ end
147
+ end
148
+
149
+ def width(style_name='original')
150
+ geometry(style_name).width.to_i
151
+ end
152
+
153
+ def height(style_name='original')
154
+ geometry(style_name).height.to_i
155
+ end
156
+
157
+ def square?(style_name='original')
158
+ geometry(style_name).square?
159
+ end
160
+
161
+ def vertical?(style_name='original')
162
+ geometry(style_name).vertical?
163
+ end
164
+
165
+ def horizontal?(style_name='original')
166
+ geometry(style_name).horizontal?
167
+ end
168
+
169
+ def dimensions_known?
170
+ original_width? && original_height?
171
+ end
172
+
173
+ private
174
+
175
+ # at this point the file queue will not have been written
176
+ # but the upload should be in place. We read dimensions from the
177
+ # original file and calculate thumbnail dimensions later, on demand.
178
+
179
+ def read_dimensions
180
+ if image?
181
+ if file = asset.queued_for_write[:original]
182
+ geometry = Paperclip::Geometry.from_file(file)
183
+ self.original_width = geometry.width
184
+ self.original_height = geometry.height
185
+ self.original_extension = File.extname(file.path)
186
+ end
187
+ end
188
+ true
189
+ end
190
+
191
+ def assign_title
192
+ self.title = self.asset_file_name.sub(self.original_extension, "").sub(".", "")
193
+ end
194
+
195
+ def assign_uuid
196
+ self.uuid = UUIDTools::UUID.timestamp_create.to_s unless uuid?
197
+ end
198
+
199
+ class << self
200
+ def known_types
201
+ AssetType.known_types
202
+ end
203
+
204
+ # searching and pagination moved to the controller
205
+
206
+ def find_all_by_asset_types(asset_types, *args)
207
+ with_asset_types(asset_types) { where *args }
208
+ end
209
+
210
+ def count_with_asset_types(asset_types, *args)
211
+ with_asset_types(asset_types) { where(*args).count }
212
+ end
213
+
214
+ def with_asset_types(asset_types, &block)
215
+ w_asset_types = AssetType.conditions_for(asset_types)
216
+ with_scope(where(:conditions => ["#{w_asset_types} = ?", block]))
217
+ end
218
+ end
219
+
220
+ # called from AssetType to set type_condition? methods on Asset
221
+ def self.define_class_method(name, &block)
222
+ eigenclass.send :define_method, name, &block
223
+ end
224
+
225
+ # returns the return value of class << self block, which is self (as defined within that block)
226
+ def self.eigenclass
227
+ class << self; self; end
228
+ end
229
+
230
+ # for backwards compatibility
231
+ def self.thumbnail_sizes
232
+ AssetType.find(:image).paperclip_styles
233
+ end
234
+
235
+ def self.thumbnail_names
236
+ thumbnail_sizes.keys
237
+ end
238
+
239
+ # this is a convenience for image-pickers
240
+ def self.thumbnail_options
241
+ asset_sizes = thumbnail_sizes.collect{|k,v|
242
+ size_id = k
243
+ size_description = "#{k}: "
244
+ size_description << (v.is_a?(Array) ? v.join(' as ') : v)
245
+ [size_description, size_id]
246
+ }.sort_by{|pair| pair.last.to_s}
247
+ asset_sizes.unshift ['Original (as uploaded)', 'original']
248
+ asset_sizes
249
+ end
250
+
251
+ end