##// END OF EJS Templates
Do not try to copy relations for issues that could not be copied....
Do not try to copy relations for issues that could not be copied. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4484 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r3660:f08b2a394d73
r4370:cd71c1cc0ad7
Show More
attachment.rb
191 lines | 6.5 KiB | text/x-ruby | RubyLexer
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # redMine - project management software
# Copyright (C) 2006-2007 Jean-Philippe Lang
#
# 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.
#
# 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.
#
# 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"
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
Jean-Philippe Lang
Anonymous users can now be allowed to create, edit, comment issues, comment news and post messages in the forums....
r906 validates_presence_of :container, :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
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
Activity refactoring....
r1692 :find_options => {: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 " +
Jean-Philippe Lang
Fixed: Files without Version aren't visible in the Activity page (#2930)....
r2501 "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 )"}
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
Activity refactoring....
r1692 :find_options => {: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
added svn:eol-style native property on /app files...
r330 cattr_accessor :storage_path
@@storage_path = "#{RAILS_ROOT}/files"
def validate
Jean-Philippe Lang
Fixes that custom values length and attachment size validation error raises an error....
r2575 if self.filesize > Setting.attachment_max_size.to_i.kilobytes
errors.add(:base, :too_long, :count => Setting.attachment_max_size.to_i.kilobytes)
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 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
self.filename = sanitize_filename(@temp_file.original_filename)
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418 self.disk_filename = Attachment.disk_filename(filename)
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 self.content_type = @temp_file.content_type.to_s.chomp
Jean-Philippe Lang
Auto-detect attachment content type when blank (#3782)....
r3144 if content_type.blank?
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 self.filesize = @temp_file.size
end
end
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
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
Fixes memory consumption on file upload (#3116)....
r2578 # Copies the temporary file to its final location
# and computes its MD5 hash
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 def before_save
if @temp_file && (@temp_file.size > 0)
logger.debug("saving '#{self.diskfile}'")
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 md5 = Digest::MD5.new
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 File.open(diskfile, "wb") do |f|
Jean-Philippe Lang
Fixes memory consumption on file upload (#3116)....
r2578 buffer = ""
while (buffer = @temp_file.read(8192))
f.write(buffer)
md5.update(buffer)
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
# 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
# Deletes file on the disk
def after_destroy
Jean-Philippe Lang
Fixed: TypeError in WikiController#destroy_attachment (#1281)....
r1430 File.delete(diskfile) if !filename.blank? && File.exist?(diskfile)
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
"#{@@storage_path}/#{self.disk_filename}"
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
* Updated German translation (Thomas Löber)...
r921 container.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
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 def visible?(user=User.current)
container.attachments_visible?(user)
end
def deletable?(user=User.current)
container.attachments_deletable?(user)
end
Jean-Philippe Lang
Image attachments are now sent inline to be viewed directly in the browser....
r636 def image?
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 self.filename =~ /\.(jpe?g|gif|png)$/i
Jean-Philippe Lang
Image attachments are now sent inline to be viewed directly in the browser....
r636 end
Jean-Philippe Lang
File viewer for attached text files....
r1506 def is_text?
Redmine::MimeType.is_type?('text', 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
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
# 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)
attached = []
if attachments && attachments.is_a?(Hash)
attachments.each_value do |attachment|
file = attachment['file']
next unless file && file.size > 0
a = Attachment.create(:container => obj,
:file => file,
:description => attachment['description'].to_s.strip,
:author => User.current)
Eric Davis
Fix a nil error when a Project cannot save attachments....
r3658
if a.new_record?
obj.unsaved_attachments ||= []
obj.unsaved_attachments << a
else
attached << a
end
Eric Davis
Refactor: Moved ApplicationController#attach_files to the Attachment model...
r3409 end
end
Eric Davis
Refactor: Decouple failed attachments and the flash messages...
r3414 {:files => attached, :unsaved => obj.unsaved_attachments}
Eric Davis
Refactor: Moved ApplicationController#attach_files to the Attachment model...
r3409 end
Jean-Philippe Lang
Returns a 404 error when trying to view/download an attachment that can't be read from disk....
r2600
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 private
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
just_filename = value.gsub(/^.*(\\|\/)/, '')
# NOTE: File.basename doesn't work right with Windows paths on Unix
# INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Jean-Philippe Lang
Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione)....
r1306 # Finally, replace all non alphanumeric, hyphens or periods with underscore
@filename = just_filename.gsub(/[^\w\.\-]/,'_')
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Jean-Philippe Lang
Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089)....
r1418
# Returns an ASCII or hashed filename
def self.disk_filename(filename)
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
Fixed: attachments with the same name at the same time overwrite (#3691)....
r3397 while File.exist?(File.join(@@storage_path, "#{timestamp}_#{ascii}"))
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