/enbake_attach

A woop-de-do version of AttachmentFu

Primary LanguageRubyMIT LicenseMIT

attach
=====================

attach is a plugin by Chris Hapgood.  It evolved from Rick Olson's attachment_fu, but is substantially changed to

	a. Support local and remote attachments.
	b. Abstract the concept of storage into a URI
	c. Support higher order abstractions for content_type (::Mime::Type).
	d. Encapsulate the attachment source into the state pattern (encompassing the null, remote/loaded, processed and stored phases of an attachment.)
	e. Remove support for s3 and filesystem backends.  These are likely to be easily reinstated, but for now...
	f. Remove support for image_science and mini_magick processors.  Again, these are likely to be easily reinstated, but for now...
	g. Add support for the EXIFR gem to extract extensive metadata from JPEG and TIFF files.
	
Attributes required of any model that includes the Attach plugin are:
	:uri			*an absolute URI identifying the location of the attachment (formerly url in some early versions)
	:content_type	*valid MIME type string
	:digest			the MD5 hash of the attachment data, not encoded
	:size			the size of the attachment data
	:aspect			identifier of alternate views of the original attachment (formerly thumbnail, in earlier versions and AttachmentFu)
	:filename		a reasonable filename to suggest to anyone downloading the attachment.  Useful for the alt property of img tags.
	:metadata		a YAML serialized hash of additional metadata (width, camera model, date picture taken, etc.)
	:description	a description of the attachment.
	:parent_id		foreign key referencing the attachment to which an aspect refers.
	:attachee_id	foreign key id referencing the owner of the attachment
	:attachee_type	foreign key type referencing the owner of the attachment

The :aspect attribute deserves special attention.  It is intended to hold a short string that identifies an alternate view of an attachment.  In the case of image
attachments, :aspect would typically be one of "thumbnail", "vignette", "icon", "proof", etc.  For other types of attachments, :aspect might be "thumbshot", 
"summary", "still", "trailer", etc.  For a given application, there would typically be an agreed convention on the list of valid aspects.

Features of Attach-enabled models:
=======================
Sources can be automatically processed for both uploaded files (HTML multipart forms) and URI-referenced remote attachments.  

Uploaded files (passed using the :file virtual attribute) are stored locally and processed to extract the size and digest attributes (in
the case of images, additional metadata is also extracted, including EXIF headers).

URI-referenced attachments (using the :url virtual attribute) are handled differently based on the :store virtual attribute.  If :store is not specified or 
true, the referenced document is automatically downloaded, processed to extract metadata and stored.  If :store is false, the document is probed (with a HEAD
request) to determine the :size, :content_type and possibly :digest attributes.  If :store is false but aspects are required to be built (as is the case for 
images), the remote document will be downloaded for processing of aspects but not stored.  More complete attributes/metadata are opportunistically extracted in
this case.

Image attachments are automatically resized to a :max size they exceed the given size limits.  (More documentation needed).

Automatic aspect creation is controlled by the :_aspects virtual attribute.  Typically it is set to an array of standardized aspect names.  The :_aspects 
attribute can also be set to a hash where the keys are aspect names and the values are a hash of attributes to be assigned manually to the aspect.  Finally, 
setting the :_aspects virtual attribute to false will ensure no aspects are built.  By default, :_aspects is set to [:thumbnail], which results in a 
single 128x128 :thumbnail aspect being built for image attachments.

TODO:
	1. Generate thumbshot aspects for web page content types (HTML, XHTML)
 	2. Generate icon aspects for application content types (xls, word, etc.)
 	3. Restore Amazon S3 and file system storage capability
	4. Restore alternate processor capability.
 	4. Support DRB-based background processing for expensive transforms

Limitations
=====================
a. Declaration of "image" content types is weak and not documented.
b. URI-based sources are probed using a HEAD request, and then depending on need, entirely fetched with a GET request.  It is not generally 
possible to know in advance if the document body will be required without reading the headers (notably, to get the size and content type).  
Technically, cleanly reading the header on a GET and subsequently not downloading the body is possible, but its execution is beyond the
scope of this initial implementation.  The expedient solution (a HEAD followed by a GET) is used.  
c. Declaration of standard processing-by-aspect is weak and not well documented.

Tests
=====================
This plugin include a test suite embedded in an application.  You can run the suite as follows:

	$ cd vendor/plugins/attach/test
	$ rake
	
You can specify the database adapter and a specific Gem version of Rails to use as follows:

	$ RAILS_GEM_VERSION=2.1 DB=mysql rake