2008-06-27 00:13:15 -04:00
class Photo < ActiveRecord :: Base
attr_accessor :file
validates_presence_of :author_id , :album_id
belongs_to :album
belongs_to :author
has_many :photo_tags , :dependent = > :destroy
has_many :tags , :through = > :photo_tags
before_validation_on_create :set_author_id
before_create :validate_image_sanity
after_create :create_directories
before_destroy :destroy_directories
attr_protected :author_id
##
# Determines the base directory for all files in this model.
#
def base_directory
" #{ Merb . root } /public/photos/ #{ id } "
end
2008-06-27 21:54:04 -04:00
##
# Checks to see if the file is found on the filesystem.
#
def exist?
File . exist? ( self . pathname )
end
##
# Returns the full path to the file on the filesystem.
#
def pathname
" #{ self . base_directory } / #{ self . filename } "
end
2008-06-27 00:13:15 -04:00
def self . popular_tags ( limit = nil )
2009-03-23 00:29:23 -04:00
query = " SELECT tags.id, tags.name, count(*) AS count FROM photo_tags, tags, photos WHERE tags.id = tag_id AND photo_tags.photo_id = photos.id GROUP BY tags.id, tags.name ORDER BY count DESC "
2008-06-27 00:13:15 -04:00
query << " LIMIT #{ limit } " unless limit . nil?
2009-03-23 00:29:23 -04:00
Tag . find_by_sql ( query ) . sort { | a , b | a . name < = > b . name }
2008-06-27 00:13:15 -04:00
end
protected
##
# Sets the Author marker for ownership on creation.
#
def set_author_id
self . author_id || = Application . current_author_id
end
##
# Checks to make sure that the file exists and is an image.
#
def validate_image_sanity
if self . file [ :tempfile ] . nil?
self . errors . add ( :file , 'File is not a file' )
end
if self . file [ :content_type ] !~ / image \/ \ w+ /
self . errors . add ( :file , 'File is not a supported type' )
end
if self . file [ :size ] > 3 * 1048576
self . errors . add ( :file , 'File is too big (3MB max)' )
end
2009-03-21 22:31:52 -04:00
if self . album . photos . count ( :conditions = > { :filename = > self . file [ :filename ] } ) > 0
self . errors . add ( :file , 'already seems to exist in this album' )
end
2008-06-27 00:13:15 -04:00
return false unless self . errors . empty?
begin
@fstr = self . file [ :tempfile ] . read
iary = Magick :: Image . from_blob ( @fstr )
self . filename = File . basename ( self . file [ :filename ] ) . gsub ( / [^ \ w._-] / , '' )
if iary . first . to_s =~ / ( \ d+)x( \ d+) /
self . width = $1
self . height = $2
end
rescue
$stderr . puts ( " Caught an exception saving an image: " )
$stderr . puts ( " * #{ $! } " )
self . errors . add ( :file , 'File could not be read as an image' )
return false
end
self . content_type = self . file [ :content_type ]
true
end
##
# Makes the directories and writes the file to disk.
#
def create_directories
File . umask ( 0022 )
Dir . mkdir ( base_directory ) unless File . exist? ( base_directory )
File . open ( " #{ base_directory } / #{ self . filename } " , " w " ) do | f |
f . puts ( @fstr )
end
File . chmod ( 0644 , " #{ base_directory } / #{ self . filename } " )
end
##
# Removes the directories and files associated with this model on destroy.
#
def destroy_directories
return unless File . exists? ( base_directory )
Dir . foreach ( base_directory ) do | file |
next if file =~ / ^ \ . \ .?$ /
File . delete ( base_directory + '/' + file )
end
Dir . delete ( base_directory )
end
2009-03-21 22:00:41 -04:00
end