Recently by John Cato
A common CSS problem is the need to crop and scale an image on a page. Scaling an image is easily done using the hight and width attributes of the image. Likewise cropping an image can be accomplished by using the image as a background of an element and setting the hight and width of the element. Both scaling and cropping an image is a bit more involved however, and if it's something that's done often it pays to have a class that handles the creation of cropped and scaled images. For this purpose I've written the Croppenscaler.
The idea here is to create a div element with a set size that has a nested div within that displays a relatively positioned image. I found that it was useful to have a hash of image data that defines the default size and crop position of an image. These values are adjusted when the frame is built so that no matter what scale the resulting frame has, the image is positioned in the same place.
CSS Classes
Let's examine the nessessary CSS classes first:
.croppenscaler {
display: inline-block;
overflow: hidden;
}
.croppenscaler img {
position: relative;
border: none;
}
The important attributes to note above are the use of overflow on the main croppenscaler, this ensures that the top frame has the intended size. The nested image is positioned relatively. All of the other CSS attributes are written in the style attribute because they have to be calculated when the frame is built.
The Croppenscaler Class:
The javascript below uses the Prototype framework, but it could just as easily use JQuery or raw javascript to accomplish the same thing.
var imageData = {
kittah: { width:900, top:-175, left:-165, url: 'http://www.nearinfinity.com/blogs/assets/jcato/images/Kittah.jpg' },
};
var Croppenscaler = Class.create();
Croppenscaler.prototype = {
initialize: function(options) {
var image = imageData[options.image];
this.url = image.url;
this.frameHeight = options.height || 400;
this.frameWidth = options.width || 300;
var scale = this.frameWidth / 300;
this.imageWidth = (image.width) * scale;
this.positionTop = (image.top) * scale;
this.positionLeft = (image.left) * scale;
},
buildFrame: function() {
var img = new Element('img',{src:this.url, 'class':'zoom'});
img.setStyle({
width: this.imageWidth+'px',
top: this.positionTop+'px',
left: this.positionLeft+'px',
});
var frame = new Element('div',{'class':'croppenscaler'});
frame.update(img);
frame.setStyle({
height:this.frameHeight+'px',
width:this.frameWidth+'px',
});
return frame;
},
};
The class has two functions. The constructor takes a hash of options for the resulting frame; the image key and the height and width of the frame. In this version the constructor references an imageData hash to get the details about the image to display, but they could be passed into the function as well. The important thing is that the constructor has access to the height and width of the frame, as well as the default width of the image and the top and left attributes that define where the upper left corner of the image should be when it's displayed at its default width.
The buildFrame() function takes the calculated sizes and uses them to construct the frame div, with a nested image at a scale that fits within the frame, and positioned the same at any scale.
Then to use the class, create a new Croppenscaler with a hash that at least includes the image key, and an optional height and width, call the buildFrame() function and insert the resulting element onto the page.
var loadImages = function() {
$('cats').insert(new Croppenscaler({image:'kittah'}).buildFrame());
$('cats').insert(new Croppenscaler({image:'kittah',height:300}).buildFrame());
$('cats').insert(new Croppenscaler({image:'kittah',width:400,height:250}).buildFrame());
$('cats').insert(new Croppenscaler({image:'kittah',width:200,height:300}).buildFrame());
$('cats').insert(new Croppenscaler({image:'kittah',width:100,height:150}).buildFrame());
}
The above code will then produce the clowder of cats below.
Capistrano is great to work with. It's simple, powerful and flexible. For the last couple of weeks I've been building a series of Capistrano tasks that check the status and configuration of our web servers. I'm pretty happy with the results, so I though I would share the basic structure of what I've come up with. I'm just going to provide a couple of tasks here, along with all of the support methods, to provide a framework, but the idea would be to expand it with whatever commands would be run to verify the health of a server.
There were several requirements that I had to keep in mind when I was designing this
- The cap tasks should use the environment configuration files that we already have.
- Because there are a large number of tasks we should be able to run them individually, or with a single command we should be able to run the entire suite.
- The cap script should produce well formatted, easy to read output, so that it's clear what's broken and where.
Control Support Methods
While building the validation tasks I found that I was having to do the same basic operations fairly often:
- Issue a command on a remote host.
- Parse the output of that command.
- Issue more commands based on the output.
Or sometimes I just wanted to run a series of commands on one host, verifying that it was correct before moving on to the next. It's possible to make Capistrano work this way, but it's not well documented. By default, if you give Capistrano multiple commands to run on multiple hosts, the it will run the commands in host order. However what I really wanted is for Capistrano to run the commands in command order.
For instance: given that we have host-A, host-B, host-C, and I want to run commands doA, doB, and doC by default Capistrano will run:
HostA > doA
HostB > doA
HostC > doA
HostA > doB
HostB > doB
HostC > doB
HostA > doC
HostB > doC
HostC > doC
But what I needed it to do was:
HostA > doA
HostA > doB
HostA > doC
HostB > doA
HostB > doB
HostB > doC
HostC > doA
HostC > doB
HostC > doC
By using the roles that we already have configured for our deploy tasks with Capistrano we were able to create a few support methods that issue commands in the order that we want.
each_host
The each_host method is used to iterate through our configured hosts. The method prints out the hostname (which is important for the look of the script's output) sets the current host, then yields the block that was passed into it.
def each_host
roles[:web].each do |host|
print_hostname host
set(:current_host, host.host)
yield host
end
end
run_serial
The run_serial method runs the given command, but only on the current host, yielding the output of the command and the name of the output stream (:out or :err). The ssh channel we don't have much use for.
def run_serial(command)
run command, :hosts => fetch(:current_host) do |chan, stream, data|
yield stream, data
end
end
run_primary
We also have a primary server set in our configuration. We can create a few more support methods that take advantage of the primary host, for issuing command on one host only.
def run_primary(command)
run command, :hosts => fetch(:primary) do |chan, stream, data|
set_current_host channel
yield stream, data
end
end
currently_primary?
Having a method that tells us if we're currently on the primary host is helpful as well.
def currently_primary?
fetch(:current_host) == fetch(:primary).host
end
set_current_host
The current host can also be set from the ssh channel. This method is called from the run_primary method, but this needs to be called when we call the default run method.
def set_current_host(channel)
host = channel.properties[:host]
print_hostname host
set(:current_host, host)
end
Now we can write tasks that execute in in command order, execute tasks just on the primary host, and as we're preforming checks we print out the current host, so we're able to keep track of where we are.
Printing Support Methods
Because printing the script output out to the command line is an important part of the script I'm going to go over the printing support next. When running the server checks I wanted the output to look like rspec or cucumber. As each check is performed I wanted to see a colorful pass or fail message with the values that I was checking against to be highlighted. Also once the checks were finished I wanted to see a list of everything that failed, grouped by host.
print_hostname
This is the print_hostname method that was mentioned above. Everytime we move to a different host this method prints out the hostname.
def print_hostname(name)
puts " Host: #{grey(name)} >"
end
step
Also at the beginning of every task I wanted to print the task name and the number of the task.
def step(name)
step = fetch(:step)
puts "\n[#{step}] #{name}"
set(:step, step+1)
end
failure
The failure method is called when a check fails. It prints the failure message, and stores it under the current hostname so that it can be printed again after all the checks have been done. If the expected or actual parameters are included it prints those along with the message, otherwise just the message is printed.
def failure(message, expected=nil, actual=nil)
host = fetch(:current_host)
complete = (expected || actual) ?
"#{message} Expected: #{grey(expected)} Actual: #{grey(actual)}" :
message
errors = fetch(:errors)
unless errors[host]
errors[host] = []
end
errors[host] << message
log_item(complete, :fail)
end
pass
The pass method is called when a check passes.
def pass(message)
log_item(message, :pass)
end
log_item
The log_item method is called by the pass and failure methods. The method includes a warn and empty status which can also be used by the tasks when printing their status.
def log_item(message, flag=nil)
status = case flag
when :pass : " [#{green("PASS")}] "
when :fail : " [#{red("FAIL")}] "
when :warn : " [#{orange("WARN")}] "
else " "
end
puts "#{status}#{message}"
end
colorize
The methods below handle the coloring of the text as it's printed to the command line. This was actually pretty fun figuring out. Every script should have fancy colorized output. (and now every script of mine will, muaha ha ha)
def red(text)
colorize(text, 31)
end
def orange(text)
colorize(text, 33)
end
def green(text)
colorize(text, 32)
end
def grey(text)
colorize(text, 37)
end
def colorize(text, color_code)
"\e[#{color_code}m#{text}\e[0m"
end
Start and Finish Tasks
Now that all that's taken care of we can start writing some actual Capistrano tasks to take advantage of our fine grained control and fancy printing.
These server check tasks all share common startup and finish tasks that need to be run before and after any one of the tasks are run, or when the entire suite is run. This is defined using Capistrano's :start and :finish callbacks, but should only be run for the check tasks.
TASK_LIST = [
"check:all",
"check:environment_variables",
"check:middleware_versions",
"check:apache_configuration"]
on :start, 'check:setup', :only => TASK_LIST
on :finish, 'check:print_errors', :only => TASK_LIST
setup
The setup task handles whatever specific setup needs to be done, but at the very least the step and errors variables need to be defined. They're used by the printing methods. Also, all of the tasks below are inside of the check namespace.
namespace :check do
task :setup do
set :step, 1
set :errors, {}
end
print_errors
The print errors method is run after all the checks have been run to print a convenient list of errors grouped by host. This keeps errors from being lost in the output.
task :print_errors do
errors = fetch(:errors)
if (errors.size() > 0)
print "\n ==== #{red 'Errors'} ===="
errors.each do |host,list|
print_hostname host
list.each {|e| puts " #{e}"}
end
end
end
Validation Tasks
The meat of the script are in the validation tasks. Out current script has fifteen different tasks that do everything from checking environment variables, to verifying directory and file permissions, to checking network and database statuses. If it can be automated, we'll find a way to get it in. Rather then include concrete examples though I'm just going to include some skeleton methods to show the method structure to illustrate how the support methods are used together in the Capistrano tasks.
Simple Tasks
This task executes one command on each server and validates the output from a list of expected results. This form is used by our script to check environment variables, commands on the sudo list, and programs in the cron, all of which can be read and verified with one command. I'm just including the validateVariable, and getVariable methods here to show the pass and failure methods.
VARIABLES = [
{ :key => 'KEY', :value => /Expected Value/ },
{ :key => 'KEY', :value => /Expected Value/ },
{ :key => 'KEY', :value => /Expected Value/ }]
task :simple do
step "A Simple Check"
run "env" do |channel, stream, data|
set_current_host channel
VARIABLES.each do |map|
validateVariable(data, map)
end
end
end
def validateVariable(data, map)
value = getVariable(data, map[:key])
(value.match map[:value]) ?
pass("Env #{grey(map[:key])} is set to #{grey(value)}") :
failure("Env #{grey(map[:key])} is incorrect", map[:value].inspect, value)
end
def getVariable(data, key)
result = data.match /^#{key}=(.*)/
unless result
failure "Env #{grey(key)} is not set."
return nil
end
result[1]
end
Tasks that run multiple commands on the same host
Most of the tasks in our validation script run multiple commands on the same host, using the each_host and run_serial methods. This allows us to read files and act on the values in those files. It's alse used because the script output looks better organized when running tasks in host order. The task below itterates through a list of standard directories, then a list of configured directories. For each directory a run_serial command is executed to see if the directory exists, then once the lists have been gone through it's done again on the next host.
task :serial_example do
step "Run multiple commands on a host"
each_host do
DIRECTORIES.each do |dir|
verify_directory dir
end
[:deploy_to, :transfer_path, :cache_path].each do |key|
dir = fetch(key)
if (dir)
verify_directory dir
else
falure "No directory configured for #{grey(key)}"
end
end
end
end
def verify_directory(path)
command = "[ -d #{path}] && echo 'true' || echo 'false'"
run_serial command do |stream, data|
if (data.strip == 'true')
pass "Verified that #{grey(path)} exists."
else
failure "Directory at #{grey(path)} does not exist."
end
end
end
Tasks using different server combinations
Here's a command that runs on the primary host, reads a file, then acts across multiple hosts. We do something like this to verify that the Apache configuration is correct. We know the httpd.conf is the same across hosts, but we want to verify that the files and directories that are in the configuration are actually on the host in question.
task :primary_example do
step "Verifying Certificates"
path = fetch(:path_to_httpd_conf)
certs = {}
run_primary "grep SSLC[eA] #{path}" do |stream,data|
if (stream == :err)
failure "No http configuration file at #{grey(path)}"
break
end
keys = [
'SSLCertificateFile',
'SSLCertificateKeyFile',
'SSLCACertificatePath',
'SSLCARevocationPath']
keys.each do |key|
certs[key] = read_http_conf_value(data,key)
end
pass "Read Certificate Paths from HTTP Configuration"
end
each_host do
verify_file certs['SSLCertificateFile']
verify_file certs['SSLCertificateKeyFile']
verify_directory certs['SSLCACertificatePath']
verify_directory certs['SSLCARevocationPath']
end
end
And finally we need a task that runs the whole suite of validation tasks. The all task does nothing itself, it just runs all of the other tasks.
desc "Run all of the validation tasks"
after "check:all",
"check:environment_variables",
"check:middleware_versions",
"check:apache_configuration"
task :all do
end
Then to execute the cap task you would type is:
cap -q production check:all
And watch as all the beautiful passes and fails scroll by, though hopefully more of the former.
Example the first: Generics at the end of a line:
def list = [1,2,3] as List<Integer>
println list
If you try to compile this in Groovy it will give you the error message: 'unexpected token: println', however this:
Gives the expected output.def list = [1,2,3] as List<Integer>;
println list
Example the second: Ambiguous Closures
{-> assert GroovyClosureTest == owner.getClass() }()
{-> assert GroovyClosureTest == delegate.getClass() }()
I don't think you'd really ever need to do something like this, but a closure can be defined and called on a single line. Because of Groovy's special closure parameter syntax (e.g. list.each() {} being synonomous with list.each({})) the compiler thinks I'm passing the second closure into the first as an argument. Again a semicolon is needed to seperate the two lines:
{-> assert GroovyClosureTest == owner.getClass() }();
{-> assert GroovyClosureTest == delegate.getClass() }()
I've been interested in data visualization for a long time now, probably because I have backgrounds in both programming and art. After a quick look at the kind of output that the language Processing can create, I think that it's got to go on my lengthening to do list.
I hate blogs that are just links to other blogs, but here's an article about character encodings that everyone should take a look at if you don't have a good understanding of how they work.

