trusty-cms 3.1.11 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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