Project

General

Profile

Please check if i am doing this correctly

Added by saurabh agarwal over 14 years ago

Hi All,

I need your help , In one of my previous questions also I also told that i want to store files and documents in database instead of file system but never got any response, I had moved someway ahead and need your kind help.

http://www.redmine.org/boards/2/topics/7737

I tried some things out I am not getting any error but I guess file is not getting stored in database , Please have a look and suggest:

1. Changed the model of attachments table.

2. Changed the attachment controller ,things seems running but the file is not getting stored in the blob column (bdata) ,can anybody give any hint what is wrong with the code

I am italicizing and bolding the code I had changed or added

  1. redMine - project management software
  2. Copyright (C) 2006-2007 Jean-Philippe Lang #
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. 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"
  1. self.bdata = @temp_file.read
    end
    end
    end
validates_presence_of :container, :filename, :author
validates_length_of :filename, :maximum => 255
validates_length_of :disk_filename, :maximum => 255
acts_as_event :title => :filename,
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
acts_as_activity_provider :type => 'files',
:permission => :view_files,
:author_key => :author_id,
: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 " +
"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 )"}
acts_as_activity_provider :type => 'documents',
:permission => :view_documents,
:author_key => :author_id,
: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"}
cattr_accessor :storage_path
@@storage_path = "#{RAILS_ROOT}/files"
def validate
errors.add_to_base :too_long if self.filesize > Setting.attachment_max_size.to_i.kilobytes
end
def file=(incoming_file)
puts " In the file= function............."
unless incoming_file.nil?
@temp_file = incoming_file
if @temp_file.size > 0
self.filename = sanitize_filename(@temp_file.original_filename)
self.disk_filename = Attachment.disk_filename(filename)
self.content_type = @temp_file.content_type.to_s.chomp
self.filesize = @temp_file.size
_ * def bdata=(incoming_file)
unless incoming_file.nil?
@temp_file = incoming_file
if @temp_file.size > 0
self.bdata = @incoming_file
end
end
end*__
_
  1. def file
  2. nil
  3. end
  1. Copies the temporary file to its final location
  2. and computes its MD5 hash
    _ *def before_save
    if @temp_file && (@temp_file.size > 0)
    logger.debug("saving '#{self.diskfile}'")
    md5 = Digest::MD5.new
    self.bdata = @temp_file.read
    #File.open(diskfile, "wb") do |f| # buffer = "" # while (buffer = @temp_file.read(8192)) # f.write(buffer) # md5.update(buffer) # end
    #end
    self.digest = md5.hexdigest
    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
    *_
  3. Deletes file on the disk
    def after_destroy
    File.delete(diskfile) if !filename.blank? && File.exist?(diskfile)
    end
  1. Returns file's location on disk
    def diskfile
    "#{@@storage_path}/#{self.disk_filename}"
    end
def increment_download
increment!(:downloads)
end
def project
container.project
end
def visible?(user=User.current)
container.attachments_visible?(user)
end
def deletable?(user=User.current)
container.attachments_deletable?(user)
end
def image?
self.filename =~ /\.(jpe?g|gif|png)$/i
end
def is_text?
Redmine::MimeType.is_type?('text', filename)
end
def is_diff?
self.filename =~ /\.(patch|diff)$/i
end

private
def sanitize_filename(value) # 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('\\\\', '/'))

  1. Finally, replace all non alphanumeric, hyphens or periods with underscore
    @filename = just_filename.gsub(/[^\w\.\-]/,'_')
    end
  1. Returns an ASCII or hashed filename
    def self.disk_filename(filename)
    df = DateTime.now.strftime("%y%m%d%H%M%S") + "_"
    if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
    df << filename
    else
    df << Digest::MD5.hexdigest(filename) # keep the extension if any
    df << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
    end
    df
    end
    end