##// END OF EJS Templates
Don't add the inclusion error when tracker is not set, the blank error is enough....
Don't add the inclusion error when tracker is not set, the blank error is enough. git-svn-id: http://svn.redmine.org/redmine/trunk@15492 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r15027:3e776af8066e
r15110:90d14b71b365
Show More
attachment.rb
410 lines | 12.5 KiB | text/x-ruby | RubyLexer
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673 # Redmine - project management software
Jean-Philippe Lang
Updates copyright for 2016....
r14856 # Copyright (C) 2006-2016 Jean-Philippe Lang
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 #
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673 #
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673 #
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "digest/md5"
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 require "fileutils"
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
Jean-Philippe Lang
Removed unneeded :foreign_key option on belongs_to associations....
r13102 belongs_to :author, :class_name => "User"
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 validates_presence_of :filename, :author
Jean-Philippe Lang
Added several validates_length_of...
r590 validates_length_of :filename, :maximum => 255
validates_length_of :disk_filename, :maximum => 255
Jean-Philippe Lang
Validate attachment description length (#11365)....
r9801 validates_length_of :description, :maximum => 255
Jean-Philippe Lang
Files upload restriction by files extensions (#20008)....
r14410 validate :validate_max_file_size, :validate_file_extension
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 attr_protected :id
Jean-Philippe Lang
Merged 0.6 branch into trunk....
r663
acts_as_event :title => :filename,
Jean-Philippe Lang
Appends the filename to the attachment url so that clients that ignore content-disposition http header get the real filename (#1649)....
r1669 :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
Jean-Philippe Lang
Merged 0.6 branch into trunk....
r663
Jean-Philippe Lang
Activity refactoring....
r1692 acts_as_activity_provider :type => 'files',
:permission => :view_files,
Jean-Philippe Lang
Display latest user's activity on account/show view....
r2064 :author_key => :author_id,
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 :scope => select("#{Attachment.table_name}.*").
joins("LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )")
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Activity refactoring....
r1692 acts_as_activity_provider :type => 'documents',
:permission => :view_documents,
Jean-Philippe Lang
Display latest user's activity on account/show view....
r2064 :author_key => :author_id,
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 :scope => select("#{Attachment.table_name}.*").
joins("LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id")
Jean-Philippe Lang
Activity refactoring....
r1692
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 cattr_accessor :storage_path
Jean-Philippe Lang
Code cleanup....
r9381 @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files")
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Displays thumbnails of attached images of the issue view (#1006)....
r9750 cattr_accessor :thumbnails_storage_path
@@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
Jean-Philippe Lang
Attachment content type not set when uploading attachment (#18667)....
r13405 before_create :files_to_final_location
Jean-Philippe Lang
Removes attachment from disk after rollback on create (#21125)....
r14703 after_rollback :delete_from_disk, :on => :create
Jean-Philippe Lang
Remove attachment after transaction commit (#20388)....
r14248 after_commit :delete_from_disk, :on => :destroy
Toshi MARUYAMA
Rails3: replace deprecated 'before_save' method at Attachment model....
r6636
Jean-Philippe Lang
Copy attachments on issue and project copy (#3055)....
r8556 # Returns an unsaved copy of the attachment
def copy(attributes=nil)
copy = self.class.new
copy.attributes = self.attributes.dup.except("id", "downloads")
copy.attributes = attributes if attributes
copy
end
Toshi MARUYAMA
Rails3: replace deprecate 'validate' instance method to declared validation method at Attachment model....
r6594 def validate_max_file_size
Jean-Philippe Lang
Copy attachments on issue and project copy (#3055)....
r8556 if @temp_file && self.filesize > Setting.attachment_max_size.to_i.kilobytes
Jean-Philippe Lang
Better message for file size validation error....
r8817 errors.add(:base, l(:error_attachment_too_big, :max_size => Setting.attachment_max_size.to_i.kilobytes))
Jean-Philippe Lang
Fixes that custom values length and attachment size validation error raises an error....
r2575 end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Jean-Philippe Lang
Files upload restriction by files extensions (#20008)....
r14410 def validate_file_extension
if @temp_file
extension = File.extname(filename)
unless self.class.valid_extension?(extension)
errors.add(:base, l(:error_attachment_extension_not_allowed, :extension => extension))
end
end
end
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 def file=(incoming_file)
unless incoming_file.nil?
@temp_file = incoming_file
if @temp_file.size > 0
Jean-Philippe Lang
Adds support for adding attachments to issues through the REST API (#8171)....
r8808 if @temp_file.respond_to?(:original_filename)
self.filename = @temp_file.original_filename
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 self.filename.force_encoding("UTF-8")
Jean-Philippe Lang
Adds support for adding attachments to issues through the REST API (#8171)....
r8808 end
if @temp_file.respond_to?(:content_type)
self.content_type = @temp_file.content_type.to_s.chomp
end
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 self.filesize = @temp_file.size
end
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/attachment.rb...
r8892
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 def file
nil
end
Jean-Philippe Lang
Adds support for adding attachments to issues through the REST API (#8171)....
r8808 def filename=(arg)
write_attribute :filename, sanitize_filename(arg.to_s)
filename
end
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 # Copies the temporary file to its final location
# and computes its MD5 hash
Toshi MARUYAMA
Rails3: replace deprecated 'before_save' method at Attachment model....
r6636 def files_to_final_location
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 if @temp_file && (@temp_file.size > 0)
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 self.disk_directory = target_directory
self.disk_filename = Attachment.disk_filename(filename, disk_directory)
Jean-Philippe Lang
NoMethodError when uploading a file without logger (#14977)....
r11972 logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)") if logger
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 path = File.dirname(diskfile)
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 md5 = Digest::MD5.new
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673 File.open(diskfile, "wb") do |f|
Jean-Philippe Lang
Use Mail instead of TMail in MailHandler....
r9447 if @temp_file.respond_to?(:read)
buffer = ""
while (buffer = @temp_file.read(8192))
f.write(buffer)
md5.update(buffer)
end
else
f.write(@temp_file)
md5.update(@temp_file)
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 end
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 end
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 self.digest = md5.hexdigest
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 end
Jean-Philippe Lang
Fixed: file uploads broken by r6312 (#8912)....
r6200 @temp_file = nil
Jean-Philippe Lang
Attachment content type not set when uploading attachment (#18667)....
r13405
if content_type.blank? && filename.present?
self.content_type = Redmine::MimeType.of(filename)
end
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 # Don't save the content type if it's longer than the authorized length
if self.content_type && self.content_type.length > 255
self.content_type = nil
end
end
Jean-Philippe Lang
Copy attachments on issue and project copy (#3055)....
r8556 # Deletes the file from the file system if it's not referenced by other attachments
Toshi MARUYAMA
Rails3: replace deprecated 'after_destroy' method at Attachment model....
r6643 def delete_from_disk
Jean-Philippe Lang
Code cleanup....
r9534 if Attachment.where("disk_filename = ? AND id <> ?", disk_filename, id).empty?
Jean-Philippe Lang
Copy attachments on issue and project copy (#3055)....
r8556 delete_from_disk!
end
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 end
# Returns file's location on disk
def diskfile
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s)
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Adds Attachment#title....
r9829 def title
title = filename.to_s
if description.present?
title << " (#{description})"
end
title
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 def increment_download
increment!(:downloads)
end
Jean-Philippe Lang
Attachments can now be added to wiki pages (original patch by Pavol Murin). Only authorized users can add/delete attachments....
r538
def project
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 container.try(:project)
Jean-Philippe Lang
Attachments can now be added to wiki pages (original patch by Pavol Murin). Only authorized users can add/delete attachments....
r538 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 def visible?(user=User.current)
Jean-Philippe Lang
Merged ajax_upload branch (#3957)....
r10748 if container_id
container && container.attachments_visible?(user)
else
author == user
end
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Edit attachments after upload (#1326)....
r13283 def editable?(user=User.current)
if container_id
container && container.attachments_editable?(user)
else
author == user
end
end
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 def deletable?(user=User.current)
Jean-Philippe Lang
Merged ajax_upload branch (#3957)....
r10748 if container_id
container && container.attachments_deletable?(user)
else
author == user
end
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Image attachments are now sent inline to be viewed directly in the browser....
r636 def image?
Jean-Philippe Lang
Displays thumbnails of attached images of the issue view (#1006)....
r9750 !!(self.filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i)
end
def thumbnailable?
image?
end
# Returns the full path the attachment thumbnail, or nil
# if the thumbnail cannot be generated.
Jean-Philippe Lang
Adds a macro for inserting thumbnails in formatted text (#3510)....
r9830 def thumbnail(options={})
Jean-Philippe Lang
Displays thumbnails of attached images of the issue view (#1006)....
r9750 if thumbnailable? && readable?
Jean-Philippe Lang
Adds a macro for inserting thumbnails in formatted text (#3510)....
r9830 size = options[:size].to_i
if size > 0
# Limit the number of thumbnails per image
size = (size / 50) * 50
# Maximum thumbnail size
size = 800 if size > 800
else
size = Setting.thumbnails_size.to_i
end
Jean-Philippe Lang
Displays thumbnails of attached images of the issue view (#1006)....
r9750 size = 100 unless size > 0
target = File.join(self.class.thumbnails_storage_path, "#{id}_#{digest}_#{size}.thumb")
begin
Redmine::Thumbnail.generate(self.diskfile, target, size)
rescue => e
logger.error "An error occured while generating thumbnail for #{disk_filename} to #{target}\nException was: #{e.message}" if logger
return nil
end
end
end
# Deletes all thumbnails
def self.clear_thumbnails
Dir.glob(File.join(thumbnails_storage_path, "*.thumb")).each do |file|
File.delete file
end
Jean-Philippe Lang
Image attachments are now sent inline to be viewed directly in the browser....
r636 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
File viewer for attached text files....
r1506 def is_text?
Redmine::MimeType.is_type?('text', filename)
end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Add inline image preview/display for attachments and repository entries (#22058)....
r14942 def is_image?
Redmine::MimeType.is_type?('image', filename)
end
Jean-Philippe Lang
Unified diff viewer for attached files with .patch or .diff extension (#1403)....
r1502 def is_diff?
self.filename =~ /\.(patch|diff)$/i
end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Don't force download of PDF (#22483)....
r15027 def is_pdf?
Redmine::MimeType.of(filename) == "application/pdf"
end
Jean-Philippe Lang
Returns a 404 error when trying to view/download an attachment that can't be read from disk....
r2600 # Returns true if the file is readable
def readable?
File.readable?(diskfile)
end
Eric Davis
Refactor: Moved ApplicationController#attach_files to the Attachment model...
r3409
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 # Returns the attachment token
def token
"#{id}.#{digest}"
end
# Finds an attachment that matches the given token and that has no container
def self.find_by_token(token)
if token.to_s =~ /^(\d+)\.([0-9a-f]+)$/
attachment_id, attachment_digest = $1, $2
Jean-Philippe Lang
Code cleanup....
r9533 attachment = Attachment.where(:id => attachment_id, :digest => attachment_digest).first
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 if attachment && attachment.container.nil?
attachment
end
end
end
Eric Davis
Refactor: Moved ApplicationController#attach_files to the Attachment model...
r3409 # Bulk attaches a set of files to an object
#
# Returns a Hash of the results:
# :files => array of the attached files
# :unsaved => array of the files that could not be attached
def self.attach_files(obj, attachments)
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 result = obj.save_attachments(attachments, User.current)
obj.attach_saved_attachments
result
Eric Davis
Refactor: Moved ApplicationController#attach_files to the Attachment model...
r3409 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Edit attachments after upload (#1326)....
r13283 # Updates the filename and description of a set of attachments
# with the given hash of attributes. Returns true if all
# attachments were updated.
#
# Example:
# Attachment.update_attachments(attachments, {
# 4 => {:filename => 'foo'},
# 7 => {:filename => 'bar', :description => 'file description'}
# })
#
def self.update_attachments(attachments, params)
params = params.transform_keys {|key| key.to_i}
saved = true
transaction do
attachments.each do |attachment|
if p = params[attachment.id]
attachment.filename = p[:filename] if p.key?(:filename)
attachment.description = p[:description] if p.key?(:description)
saved &&= attachment.save
end
end
unless saved
raise ActiveRecord::Rollback
end
end
saved
end
Toshi MARUYAMA
move logic to use latest image file attachment to class method for common use (#3261)...
r7788 def self.latest_attach(attachments, filename)
Jean-Philippe Lang
Code cleanup....
r13141 attachments.sort_by(&:created_on).reverse.detect do |att|
Jean-Philippe Lang
Wrong syntax for resizing inline images may throw a 500 error (#20278)....
r14091 filename.casecmp(att.filename) == 0
Jean-Philippe Lang
Code cleanup....
r13141 end
Toshi MARUYAMA
move logic to use latest image file attachment to class method for common use (#3261)...
r7788 end
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 def self.prune(age=1.day)
Jean-Philippe Lang
Code cleanup....
r9533 Attachment.where("created_on < ? AND (container_type IS NULL OR container_type = '')", Time.now - age).destroy_all
Jean-Philippe Lang
Better handling of attachments when issue validation fails (#10253)....
r8771 end
Toshi MARUYAMA
remove trailing white-space from app/models/attachment.rb...
r11037 # Moves an existing attachment to its target directory
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 def move_to_target_directory!
Jean-Philippe Lang
Log errors when moving attachments (#15295)....
r12019 return unless !new_record? & readable?
src = diskfile
self.disk_directory = target_directory
dest = diskfile
return if src == dest
if !FileUtils.mkdir_p(File.dirname(dest))
logger.error "Could not create directory #{File.dirname(dest)}" if logger
return
end
if !FileUtils.mv(src, dest)
logger.error "Could not move attachment from #{src} to #{dest}" if logger
return
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 end
Jean-Philippe Lang
Log errors when moving attachments (#15295)....
r12019
update_column :disk_directory, disk_directory
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 end
# Moves existing attachments that are stored at the root of the files
# directory (ie. created before Redmine 2.3) to their target subdirectories
def self.move_from_root_to_target_directory
Attachment.where("disk_directory IS NULL OR disk_directory = ''").find_each do |attachment|
attachment.move_to_target_directory!
end
end
Jean-Philippe Lang
Files upload restriction by files extensions (#20008)....
r14410 # Returns true if the extension is allowed, otherwise false
def self.valid_extension?(extension)
extension = extension.downcase.sub(/\A\.+/, '')
denied, allowed = [:attachment_extensions_denied, :attachment_extensions_allowed].map do |setting|
Setting.send(setting).to_s.split(",").map {|s| s.strip.downcase.sub(/\A\.+/, '')}.reject(&:blank?)
end
if denied.present? && denied.include?(extension)
return false
end
unless allowed.blank? || allowed.include?(extension)
return false
end
true
end
Jean-Philippe Lang
Copy attachments on issue and project copy (#3055)....
r8556 private
# Physically deletes the file from the file system
def delete_from_disk!
if disk_filename.present? && File.exist?(diskfile)
File.delete(diskfile)
end
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 def sanitize_filename(value)
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 # get only the filename, not the whole path
Jean-Philippe Lang
Strip eols from file names (#14819)....
r11898 just_filename = value.gsub(/\A.*(\\|\/)/m, '')
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Jean-Philippe Lang
Limit the characters stripped by Attachment#sanitize_filename (#4324)....
r7797 # Finally, replace invalid characters with underscore
Jean-Philippe Lang
Removed unused instance variable....
r13142 just_filename.gsub(/[\/\?\%\*\:\|\"\'<>\n\r]+/, '_')
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Toshi MARUYAMA
remove trailing white-spaces from Attachment model source....
r5673
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 # Returns the subdirectory in which the attachment will be saved
def target_directory
time = created_on || DateTime.now
time.strftime("%Y/%m")
end
# Returns an ASCII or hashed filename that do not
# exists yet in the given subdirectory
def self.disk_filename(filename, directory=nil)
Jean-Philippe Lang
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 timestamp = DateTime.now.strftime("%y%m%d%H%M%S")
ascii = ''
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
Jean-Philippe Lang
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 ascii = filename
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 else
Jean-Philippe Lang
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 ascii = Digest::MD5.hexdigest(filename)
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 # keep the extension if any
Jean-Philippe Lang
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 end
Jean-Philippe Lang
Store attachments in subdirectories (#5298)....
r10761 while File.exist?(File.join(storage_path, directory.to_s, "#{timestamp}_#{ascii}"))
Jean-Philippe Lang
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 timestamp.succ!
end
"#{timestamp}_#{ascii}"
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 end
Jean-Philippe Lang
Initial commit...
r2 end