Dragonfly

Image/asset management for winners

GitHub Repository

How does it work?

Dragonfly apps

At the core of Dragonfly is the Dragonfly app

require 'dragonfly'
app = Dragonfly.app

This is configured using

app.configure do
  # configuration goes here
end

See Configuration for more details.

Normally you will just need the default Dragonfly app, but if you wish you can have multiple apps, each with its own configuration, by giving each a name, e.g.

app1 = Dragonfly.app(:audio)
app2 = Dragonfly.app(:images)

An app comprises of the following:

  • a datastore for storing content and metadata
  • any number of processors for modifying content
  • any number of generators for creating content
  • any number of analysers for analysing content
  • a Rack server object for serving content

Storing content

We can store content with

uid = Dragonfly.app.store(my_content, 'name' => 'dog.png', 'more' => 'metadata')
uid   # ===> "2008/dog.png"  - a unique id given by the data store

my_content can be a String, Pathname, File or Tempfile (or something that responds to path or tempfile)

Jobs

A Job object represents a chained sequence of commands, e.g.

image = Dragonfly.app.fetch('2008/dog.png').thumb('300x300')

represents the steps

  1. fetch the content with uid “2008/dog.png” from the datastore
  2. process this content with the registered “thumb” processor

URLs

We can get a url for this job with

image.url   # ===> "/W1siZiIsIjIwMDgvZG9nLnBuZyJdLFsicCIsInRodW1iIiwiMzAweDMwMCJdXQ"

The commands “fetch the content then process with the thumb processor” are encoded into this url.

The Dragonfly app is itself a Rack app. When we visit it with this url, we get the fetched and processed content!!

Using the content

Doing

image = Dragonfly.app.fetch('2008/dog.png').thumb('300x300')

is lazy, i.e. it hasn’t actually done any fetching or processing yet.

We can force it to do it using apply

image.apply

but we normally won’t need to, because any methods that need the resultant content call apply behind the scenes. Examples are:

image.data                   # ===> a String containing the data
image.to_file('out.png')     # writes to file 'out.png' and returns a readable file object
image.to_file('out.png',
  :mode => 0600,
  :mkdirs => false
)
image.tempfile               # ===> a closed Tempfile object
image.file                   # ===> a readable (open) File object
image.file do |f|            # Yields an open file object, returns the return value of
  data = f.read(256)         #  the block, and closes the file object
end
image.path                   # ===> e.g. "/var/st..." i.e. the path of the tempfile
image.b64_data               # ===> data url like "data:image/png;base64,iVBORw..."

image.meta                   # ===> the stored metadata, e.g. {"name" => "dog.png", ...}
image.name                   # ===> taken from meta["name"], e.g. "dog.png"
image.basename               # ===> taken from name, e.g. "dog"
image.ext                    # ===> taken from name, e.g. "png"
image.mime_type              # ===> "image/png", taken from ext

image.size                   # ===> 134507 (size in bytes)

image.width                  # ===> 288 - one of the registered analysers

Types of Job Step

fetch

Dragonfly.app.fetch('2008/dog.png')

fetches the content (and metadata) stored against uid “2008/dog.png” from the app’s datastore.

fetch_file

Dragonfly.app.fetch_file('public/sausage.gif')

reads the file “public/sausage.gif” from the local filesystem.

fetch_url

Dragonfly.app.fetch_url('http://example.org/balloons.jpg')

gets the content with a GET request from the given url.

generate

Dragonfly.app.generate(:plain, 10, 5)

generates content using one of the registered generators.

See Generators.

Processing steps

Each registered processor adds its own method to Job objects

Dragonfly.app.fetch('2008/dog.png').encode('tiff').rotate(90)

In this example both encode and rotate are registered processors.

See Processors.

Models for maintaining uids

Typically, models are used to keep tabs on data store uids.

For a model with image_uid equal to "2008/dog.png"

model.image.url

is equivalent to

Dragonfly.app.fetch('2008/dog.png').url

See Models for more details.