jbasdf-uploader 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +323 -0
  3. data/Rakefile +67 -0
  4. data/TODO +3 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/uploader/uploads_controller.rb +126 -0
  7. data/app/helpers/uploader_helper.rb +17 -0
  8. data/app/views/uploads/_swf_javascript.html.erb +63 -0
  9. data/app/views/uploads/_swf_upload.html.erb +32 -0
  10. data/config/uploader_routes.rb +3 -0
  11. data/db/migrate/20090517040220_create_uploads.rb +38 -0
  12. data/lib/active_record/acts/uploader_upload.rb +234 -0
  13. data/lib/daemons/amazonaws.rb +36 -0
  14. data/lib/uploader.rb +24 -0
  15. data/lib/uploader/exceptions.rb +5 -0
  16. data/lib/uploader/initialize_routes.rb +8 -0
  17. data/lib/uploader/middleware/flash_session_cookie_middleware.rb +18 -0
  18. data/lib/uploader/mime_type_groups.rb +18 -0
  19. data/lib/uploader/tasks.rb +42 -0
  20. data/locales/ar.yml +17 -0
  21. data/locales/bg.yml +17 -0
  22. data/locales/ca.yml +17 -0
  23. data/locales/cs.yml +17 -0
  24. data/locales/da.yml +17 -0
  25. data/locales/de.yml +17 -0
  26. data/locales/el.yml +17 -0
  27. data/locales/en.yml +16 -0
  28. data/locales/es.yml +17 -0
  29. data/locales/fr.yml +17 -0
  30. data/locales/it.yml +17 -0
  31. data/locales/iw.yml +17 -0
  32. data/locales/ja.yml +17 -0
  33. data/locales/ko.yml +17 -0
  34. data/locales/lt.yml +17 -0
  35. data/locales/lv.yml +17 -0
  36. data/locales/nl.yml +17 -0
  37. data/locales/no.yml +18 -0
  38. data/locales/pl.yml +17 -0
  39. data/locales/pt.yml +17 -0
  40. data/locales/ro.yml +17 -0
  41. data/locales/ru.yml +17 -0
  42. data/locales/sk.yml +17 -0
  43. data/locales/sl.yml +17 -0
  44. data/locales/sr.yml +17 -0
  45. data/locales/sv.yml +17 -0
  46. data/locales/tl.yml +17 -0
  47. data/locales/uk.yml +17 -0
  48. data/locales/vi.yml +17 -0
  49. data/locales/zh-CN.yml +17 -0
  50. data/locales/zh-TW.yml +17 -0
  51. data/locales/zh.yml +17 -0
  52. data/public/images/SWFUploadButton.png +0 -0
  53. data/public/images/file_icons/excel.gif +0 -0
  54. data/public/images/file_icons/file.gif +0 -0
  55. data/public/images/file_icons/file.png +0 -0
  56. data/public/images/file_icons/file_aac.gif +0 -0
  57. data/public/images/file_icons/file_ai.gif +0 -0
  58. data/public/images/file_icons/file_avi.gif +0 -0
  59. data/public/images/file_icons/file_bin.gif +0 -0
  60. data/public/images/file_icons/file_bmp.gif +0 -0
  61. data/public/images/file_icons/file_cue.gif +0 -0
  62. data/public/images/file_icons/file_divx.gif +0 -0
  63. data/public/images/file_icons/file_doc.gif +0 -0
  64. data/public/images/file_icons/file_eps.gif +0 -0
  65. data/public/images/file_icons/file_flac.gif +0 -0
  66. data/public/images/file_icons/file_flv.gif +0 -0
  67. data/public/images/file_icons/file_gif.gif +0 -0
  68. data/public/images/file_icons/file_html.gif +0 -0
  69. data/public/images/file_icons/file_ical.gif +0 -0
  70. data/public/images/file_icons/file_indd.gif +0 -0
  71. data/public/images/file_icons/file_inx.gif +0 -0
  72. data/public/images/file_icons/file_iso.gif +0 -0
  73. data/public/images/file_icons/file_jpg.gif +0 -0
  74. data/public/images/file_icons/file_mov.gif +0 -0
  75. data/public/images/file_icons/file_mp3.gif +0 -0
  76. data/public/images/file_icons/file_mpg.gif +0 -0
  77. data/public/images/file_icons/file_pdf.gif +0 -0
  78. data/public/images/file_icons/file_php.gif +0 -0
  79. data/public/images/file_icons/file_png.gif +0 -0
  80. data/public/images/file_icons/file_pps.gif +0 -0
  81. data/public/images/file_icons/file_ppt.gif +0 -0
  82. data/public/images/file_icons/file_psd.gif +0 -0
  83. data/public/images/file_icons/file_qxd.gif +0 -0
  84. data/public/images/file_icons/file_qxp.gif +0 -0
  85. data/public/images/file_icons/file_raw.gif +0 -0
  86. data/public/images/file_icons/file_rtf.gif +0 -0
  87. data/public/images/file_icons/file_svg.gif +0 -0
  88. data/public/images/file_icons/file_tif.gif +0 -0
  89. data/public/images/file_icons/file_txt.gif +0 -0
  90. data/public/images/file_icons/file_vcf.gif +0 -0
  91. data/public/images/file_icons/file_wav.gif +0 -0
  92. data/public/images/file_icons/file_wma.gif +0 -0
  93. data/public/images/file_icons/file_xls.gif +0 -0
  94. data/public/images/file_icons/file_xml.gif +0 -0
  95. data/public/images/file_icons/mp3.gif +0 -0
  96. data/public/images/file_icons/pdf.gif +0 -0
  97. data/public/images/file_icons/pdf.png +0 -0
  98. data/public/images/file_icons/text.gif +0 -0
  99. data/public/images/file_icons/text.png +0 -0
  100. data/public/images/file_icons/word.gif +0 -0
  101. data/public/javascripts/swfupload/fileprogress.js +151 -0
  102. data/public/javascripts/swfupload/handlers.js +206 -0
  103. data/public/javascripts/swfupload/swfupload.cookies.js +53 -0
  104. data/public/javascripts/swfupload/swfupload.js +945 -0
  105. data/public/javascripts/swfupload/swfupload.queue.js +77 -0
  106. data/public/javascripts/swfupload/swfupload.swfobject.js +110 -0
  107. data/public/stylesheets/swfupload.css +26 -0
  108. data/public/swf/swfupload.swf +0 -0
  109. data/rails/init.rb +10 -0
  110. data/rdoc/classes/ActionController.html +107 -0
  111. data/rdoc/classes/ActionController/Routing.html +107 -0
  112. data/rdoc/classes/ActionController/Routing/RouteSet.html +148 -0
  113. data/rdoc/classes/ActiveRecord.html +105 -0
  114. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/ClassMethods.html +186 -0
  115. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/InstanceMethods.html +750 -0
  116. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/SingletonMethods.html +111 -0
  117. data/rdoc/classes/Uploader.html +126 -0
  118. data/rdoc/classes/Uploader/Exceptions.html +111 -0
  119. data/rdoc/classes/Uploader/Exceptions/MissingTemplateError.html +111 -0
  120. data/rdoc/classes/Uploader/FlashSessionCookieMiddleware.html +177 -0
  121. data/rdoc/classes/Uploader/MimeTypeGroups.html +143 -0
  122. data/rdoc/classes/Uploader/Tasks.html +146 -0
  123. data/rdoc/created.rid +1 -0
  124. data/rdoc/files/README_rdoc.html +501 -0
  125. data/rdoc/files/lib/active_record/acts/uploader_upload_rb.html +101 -0
  126. data/rdoc/files/lib/uploader/exceptions_rb.html +101 -0
  127. data/rdoc/files/lib/uploader/initialize_routes_rb.html +101 -0
  128. data/rdoc/files/lib/uploader/middleware/flash_session_cookie_middleware_rb.html +108 -0
  129. data/rdoc/files/lib/uploader/mime_type_groups_rb.html +101 -0
  130. data/rdoc/files/lib/uploader/tasks_rb.html +110 -0
  131. data/rdoc/files/lib/uploader_rb.html +112 -0
  132. data/rdoc/fr_class_index.html +39 -0
  133. data/rdoc/fr_file_index.html +35 -0
  134. data/rdoc/fr_method_index.html +54 -0
  135. data/rdoc/index.html +24 -0
  136. data/rdoc/rdoc-style.css +208 -0
  137. data/tasks/rails.rake +2 -0
  138. data/test/test_helper.rb +3 -0
  139. data/test/unit/upload_test.rb +5 -0
  140. data/uninstall.rb +0 -0
  141. data/uploader.gemspec +182 -0
  142. metadata +204 -0
@@ -0,0 +1,17 @@
1
+ module UploaderHelper
2
+
3
+ # parent is the object to which the uploads will be attached
4
+ def upload_form(parent, display_upload_indicators = true)
5
+ render :partial => 'uploads/swf_upload', :locals => {:parent => parent, :display_upload_indicators => display_upload_indicators}
6
+ end
7
+
8
+ def new_upload_path_with_session_information(upload_parent)
9
+ session_key = ActionController::Base.session_options[:key]
10
+ swfupload_uploads_path({session_key => cookies[session_key], request_forgery_protection_token => form_authenticity_token}.merge(make_parent_params(upload_parent)))
11
+ end
12
+
13
+ def make_parent_params(parent)
14
+ { :parent_id => parent.id, :parent_type => parent.class.to_s }
15
+ end
16
+
17
+ end
@@ -0,0 +1,63 @@
1
+ <% content_for :head do -%>
2
+ <%= javascript_include_tag %w{
3
+ swfupload/swfupload.js
4
+ swfupload/swfupload.swfobject
5
+ swfupload/swfupload.cookies
6
+ swfupload/swfupload.queue
7
+ swfupload/fileprogress.js
8
+ swfupload/handlers.js }, :cache => 'swf_js_cached' %>
9
+ <%= stylesheet_link_tag 'swfupload' %>
10
+
11
+ <script type='text/javascript'>
12
+
13
+ var swfu;
14
+
15
+ SWFUpload.onload = function () {
16
+ var settings = {
17
+
18
+ flash_url : '/swf/swfupload.swf',
19
+ upload_url: '<%= new_upload_path_with_session_information(parent) %>',
20
+
21
+ file_size_limit : "100 MB",
22
+ file_types : "*.*",
23
+ file_types_description : "All Files",
24
+ file_upload_limit : 100,
25
+ file_queue_limit : 0,
26
+ post_params : {
27
+ authenticity_token : '<%= u form_authenticity_token.inspect -%>',
28
+ },
29
+ custom_settings : {
30
+ <%= 'progressTarget : "swf_fs_upload_progress",' if display_upload_indicators -%>
31
+ cancelButtonId : "swf_cancel_button"
32
+ },
33
+ debug: false,
34
+
35
+ // Button Settings
36
+ button_image_url : "/images/SWFUploadButton.png", // Relative to the SWF file
37
+ button_placeholder_id : "swf_button_holder",
38
+ button_width: 61,
39
+ button_height: 22,
40
+
41
+ // The event handler functions are defined in handlers.js
42
+ swfupload_loaded_handler : swfUploadLoaded,
43
+ file_queued_handler : fileQueued,
44
+ file_queue_error_handler : fileQueueError,
45
+ file_dialog_complete_handler : fileDialogComplete,
46
+ upload_start_handler : uploadStart,
47
+ upload_progress_handler : uploadProgress,
48
+ upload_error_handler : uploadError,
49
+ upload_success_handler : uploadSuccess,
50
+ upload_complete_handler : uploadComplete,
51
+ queue_complete_handler : queueComplete, // Queue plugin event
52
+
53
+ // SWFObject settings
54
+ minimum_flash_version : "9.0.28",
55
+ swfupload_pre_load_handler : swfUploadPreLoad,
56
+ swfupload_load_failed_handler : swfUploadLoadFailed
57
+ };
58
+
59
+ swfu = new SWFUpload(settings);
60
+ }
61
+
62
+ </script>
63
+ <% end -%>
@@ -0,0 +1,32 @@
1
+ <div id="degraded_container" style="display:none;">
2
+ <% form_for :upload, :url => uploads_path(make_parent_params(parent)), :html => { :multipart => true } do |f| -%>
3
+ <p><%= f.file_field :uploaded_data, :size => 25 %></p>
4
+ <%= submit_tag t('uploader.upload_file') %>
5
+ <% end %>
6
+ </div>
7
+ <div id="swfupload_container">
8
+ <form>
9
+ <div id="swf_upload_UI">
10
+ <p><span id="swf_button_holder"></span></p>
11
+ <div id="swf_fs_upload_progress">
12
+ <span class="legend"></span>
13
+ <input id="swf_cancel_button" type="button" value="<%=t('uploader.cancel_all')%>" style="display:none;" />
14
+ <p id="divStatus"></p>
15
+ </div>
16
+ </div>
17
+ <noscript class="swf-error-msg">
18
+ <%= t('uploader.javascript_not_enabled') %>
19
+ </noscript>
20
+ <div id="swf_loading_content" class="swf-error-msg" style="display:none;">
21
+ <%= t('uploader.swf_loading') %>
22
+ </div>
23
+ <div id="swf_long_loading" class="swf-error-msg" style="display:none;">
24
+ <%= t('uploader.swf_taking_to_long') %>
25
+ </div>
26
+ <div id="swf_alternate_content" class="swf-error-msg" style="display: none;">
27
+ <%= t('uploader.swf_not_loading', :url => '<a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Adobe Website</a>') %>
28
+ </div>
29
+ </form>
30
+ </div>
31
+
32
+ <%= render :partial => 'uploads/swf_javascript', :locals => { :parent => parent, :display_upload_indicators => display_upload_indicators } %>
@@ -0,0 +1,3 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resources :uploads, :controller => 'uploader/uploads', :collection => { :swfupload => :post }
3
+ end
@@ -0,0 +1,38 @@
1
+ class CreateUploads < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :uploads, :force => true do |t|
4
+ t.integer :creator_id
5
+ t.string :name
6
+ t.string :caption, :limit => 1000
7
+ t.text :description
8
+ t.boolean :is_public, :default => true
9
+ t.integer :uploadable_id
10
+ t.string :uploadable_type
11
+ t.string :width
12
+ t.string :height
13
+
14
+ t.string :local_file_name
15
+ t.string :local_content_type
16
+ t.integer :local_file_size
17
+ t.datetime :local_updated_at
18
+
19
+ t.string :remote_file_name
20
+ t.string :remote_content_type
21
+ t.integer :remote_file_size
22
+ t.datetime :remote_updated_at
23
+
24
+ t.timestamps
25
+ end
26
+
27
+ add_index :uploads, ["creator_id"]
28
+ add_index :uploads, ["uploadable_id"]
29
+ add_index :uploads, ["uploadable_type"]
30
+ add_index :uploads, ["local_content_type"]
31
+
32
+ end
33
+
34
+ def self.down
35
+ drop_table :uploads
36
+ end
37
+
38
+ end
@@ -0,0 +1,234 @@
1
+ module ActiveRecord
2
+ module Acts #:nodoc:
3
+
4
+ module UploaderUpload #:nodoc:
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ # acts_as_uploader requires an option for :has_attached_file. These values will be passed to paperclip.
12
+ # i.e.
13
+ # acts_as_uploader :has_attached_file => {
14
+ # :url => "/uploads/:class/:id/:style_:basename.:extension",
15
+ # :path => ":rails_root/public/uploads/:class/:id/:style_:basename.:extension",
16
+ # :styles => { :icon => "30x30!", :thumb => "100>", :small => "150>", :medium => "300>", :large => "660>"},
17
+ # :default_url => "/images/profile_default.jpg" }
18
+ def acts_as_uploader(options)
19
+
20
+ #Named scopes
21
+ named_scope :newest_first, :order => "created_at DESC"
22
+ named_scope :alphabetic, :order => "filename DESC"
23
+ named_scope :recent, :order => "created_at DESC"
24
+ named_scope :public, :conditions => 'is_public = true'
25
+ named_scope :images, :conditions => "local_content_type IN (#{Uploader::MimeTypeGroups::IMAGE_TYPES.collect{|type| "'#{type}'"}.join(',')})"
26
+ named_scope :documents, :conditions => "local_content_type IN (#{(Uploader::MimeTypeGroups::WORD_TYPES + Uploader::MimeTypeGroups::EXCEL_TYPES + Uploader::MimeTypeGroups::PDF_TYPES).collect{|type| "'#{type}'"}.join(',')})"
27
+ named_scope :files, :conditions => "local_content_type NOT IN (#{Uploader::MimeTypeGroups::IMAGE_TYPES.collect{|type| "'#{type}'"}.join(',')})"
28
+ named_scope :since, lambda { |*args| { :conditions => ["created_at > ?", (args.first || 7.days.ago.to_s(:db)) ]} }
29
+ named_scope :pending_s3_migration, lambda { { :conditions => ["remote_file_name IS NULL AND created_at <= ?", 20.minutes.ago.to_s(:db)], :order => 'created_at DESC' } }
30
+
31
+ # Paperclip
32
+ has_attached_file :local, options[:has_attached_file].merge(:storage => :filesystem) # Override any storage settings. This one has to be local.
33
+ if options[:enable_s3] == true
34
+ has_attached_file :remote, options[:has_attached_file].merge(:url => ':s3_alias_url',
35
+ :path => options[:s3_path],
36
+ :storage => :s3)
37
+ end
38
+
39
+
40
+ belongs_to :uploadable, :polymorphic => true
41
+ belongs_to :creator, :class_name => 'User', :foreign_key => 'creator_id'
42
+
43
+ class_eval <<-EOV
44
+ validates_attachment_size :local, :less_than => 10.megabytes
45
+
46
+ before_post_process :transliterate_file_name
47
+ before_create :add_width_and_height
48
+
49
+ # prevents a user from submitting a crafted form that bypasses activation
50
+ attr_protected :creator_id, :uploadable_id, :uploadable_type
51
+ EOV
52
+
53
+ include ActiveRecord::Acts::UploaderUpload::InstanceMethods
54
+ extend ActiveRecord::Acts::UploaderUpload::SingletonMethods
55
+ end
56
+ end
57
+
58
+ # class methods
59
+ module SingletonMethods
60
+
61
+ end
62
+
63
+ # All the methods available to a record that has had <tt>acts_as_uploader</tt> specified.
64
+ module InstanceMethods
65
+
66
+ def file
67
+ local_file_name ? local : remote
68
+ end
69
+
70
+ def file_name
71
+ remote_file_name || local_file_name
72
+ end
73
+
74
+ def send_to_remote
75
+ if local_file_name
76
+ self.remote = local.to_file
77
+ if self.save and remote.original_filename and remote.exists?
78
+ self.local = nil
79
+ self.save
80
+ else
81
+ false
82
+ end
83
+ end
84
+ end
85
+
86
+ def swfupload_local=(filedata)
87
+ filedata.content_type = MIME::Types.type_for(filedata.original_filename)[0].to_s
88
+ self.local = filedata
89
+ end
90
+
91
+ def is_image?
92
+ Uploader::MimeTypeGroups::IMAGE_TYPES.include?(self.local_content_type)
93
+ end
94
+
95
+ def is_mp3?
96
+ Uploader::MimeTypeGroups::MP3_TYPES.include?(self.local_content_type)
97
+ end
98
+
99
+ def is_excel?
100
+ Uploader::MimeTypeGroups::EXCEL_TYPES.include?(self.local_content_type)
101
+ end
102
+
103
+ def is_pdf?
104
+ Uploader::MimeTypeGroups::PDF_TYPES.include?(self.local_content_type)
105
+ end
106
+
107
+ def is_word?
108
+ Uploader::MimeTypeGroups::WORD_TYPES.include?(self.local_content_type)
109
+ end
110
+
111
+ def is_text?
112
+ Uploader::MimeTypeGroups::TEXT_TYPES.include?(self.local_content_type)
113
+ end
114
+
115
+ def upload_type
116
+ if self.is_pdf?
117
+ 'Adobe pdf file'
118
+ elsif self.is_word?
119
+ 'Word document'
120
+ elsif self.is_image?
121
+ 'photo'
122
+ elsif self.is_mp3?
123
+ 'mp3'
124
+ elsif self.is_excel?
125
+ 'Excel document'
126
+ elsif self.is_text?
127
+ 'text file'
128
+ else
129
+ 'file'
130
+ end
131
+ end
132
+
133
+ def icon
134
+ if self.is_pdf?
135
+ '/images/file_icons/file_pdf.gif'
136
+ elsif self.is_word?
137
+ '/images/file_icons/file_doc.gif'
138
+ elsif self.is_image?
139
+ self.file.url(:icon)
140
+ elsif self.is_mp3?
141
+ '/images/file_icons/file_mp3.gif'
142
+ elsif self.is_excel?
143
+ '/images/file_icons/file_xls.gif'
144
+ elsif self.is_text?
145
+ '/images/file_icons/file_txt.gif'
146
+ else
147
+ '/images/file_icons/file_raw.gif'
148
+ end
149
+ end
150
+
151
+ def display_name
152
+ CGI::escapeHTML(self.local_file_name)
153
+ end
154
+
155
+ def can_edit?(check_user)
156
+ return false if check_user.blank?
157
+ check_user == self.creator
158
+ end
159
+
160
+ # Image dimension calculations
161
+
162
+ def width(style = :default)
163
+ return nil unless self[:width]
164
+ return self[:width] if style == :default
165
+ calculate_sizes(style.to_sym)
166
+ return @image_width.to_i
167
+ end
168
+
169
+ def height(style = :default)
170
+ return nil unless self[:height]
171
+ return self[:height] if style == :default
172
+ calculate_sizes(style.to_sym)
173
+ return @image_height.to_i
174
+ end
175
+
176
+ def size(style = :default)
177
+ return nil unless width || height
178
+ return "#{width}x#{height}" if style == :default
179
+ calculate_sizes(style.to_sym)
180
+ return @image_size
181
+ end
182
+
183
+ def max_dimension(style)
184
+ @max_dimension ||= Paperclip::Geometry.parse(self.local.styles[style][:geometry]).width.to_f
185
+ end
186
+
187
+ def image_ratio
188
+ @image_ratio ||= width.to_f / height.to_f
189
+ end
190
+
191
+ def calculate_sizes(style)
192
+ if image_ratio > 1
193
+ @image_width ||= width > max_dimension(style) ? max_dimension(style) : width
194
+ @image_height ||= (@image_width / image_ratio).round
195
+ else
196
+ @image_height ||= height > max_dimension(style) ? max_dimension(style) : height
197
+ @image_width ||= (@image_height * image_ratio).round
198
+ end
199
+ @image_size ||= "#{@image_width.to_i}x#{@image_height.to_i}"
200
+ end
201
+
202
+ protected
203
+ def transliterate_file_name
204
+ extension = File.extname(local_file_name).gsub(/^\.+/, '')
205
+ filename = local_file_name.gsub(/\.#{extension}$/, '')
206
+ self.local.instance_write(:file_name, "#{transliterate(filename)}.#{transliterate(extension)}")
207
+ end
208
+
209
+ def transliterate(str)
210
+ # Lifted from permalink_fu by Rick Olsen
211
+ # Escape str by transliterating to UTF-8 with Iconv,
212
+ # downcasing, then removing illegal characters and replacing them with ’-’
213
+ s = Iconv.iconv('ascii//ignore//translit', 'utf-8', str).to_s
214
+ s.downcase!
215
+ s.gsub!(/\'/, '')
216
+ s.gsub!(/[^A-Za-z0-9]+/, ' ')
217
+ s.strip!
218
+ s.gsub!(/\ +/, '-') # set single or multiple spaces to a single dash
219
+ return s
220
+ end
221
+
222
+ def add_width_and_height
223
+ return unless self.is_image?
224
+ if self.local.to_file
225
+ geometry = Paperclip::Geometry.from_file self.local.to_file
226
+ self[:width] = geometry.width.to_i
227
+ self[:height] = geometry.height.to_i
228
+ end
229
+ end
230
+
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # You might want to change this
4
+ ENV["RAILS_ENV"] ||= "production"
5
+
6
+ require File.dirname(__FILE__) + "/../../config/environment"
7
+
8
+ $running = true
9
+ Signal.trap("TERM") do
10
+ $running = false
11
+ end
12
+
13
+ # Waiting is a timer variable to allow the daemon to restart
14
+ # within two seconds of the Signal rather than using a long
15
+ # sleep command and forcing the daemon to wait.
16
+ $waiting = 0
17
+
18
+ ActiveRecord::Base.logger.info "[AmazonS3] Migration daemon started at #{Time.now}.\n"
19
+
20
+ while($running) do
21
+
22
+ if $waiting < 120
23
+ $waiting += 2
24
+ sleep 2
25
+ else
26
+ $waiting = 0
27
+ upload = Upload.pending_s3_migration.first
28
+
29
+ if upload
30
+ $waiting = 120 - 2
31
+ ActiveRecord::Base.logger.info "[AmazonS3] Migrating upload ##{upload.id}\n"
32
+ upload.remote = upload.local
33
+ upload.save!
34
+ end
35
+ end
36
+ end
data/lib/uploader.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'uploader/exceptions'
2
+ require 'uploader/mime_type_groups'
3
+ require 'uploader/middleware/flash_session_cookie_middleware'
4
+
5
+ begin
6
+ require 'thoughtbot-paperclip'
7
+ rescue LoadError
8
+ begin
9
+ gem 'thoughtbot-paperclip'
10
+ rescue Gem::LoadError
11
+ puts "Please install the thoughtbot-paperclip gem"
12
+ end
13
+ end
14
+
15
+
16
+ begin
17
+ require 'mime/types'
18
+ rescue LoadError
19
+ begin
20
+ gem 'mime-types'
21
+ rescue Gem::LoadError
22
+ puts "Please install the mime-types gem"
23
+ end
24
+ end