Tuesday, August 11, 2009

Cruise Control and PHPUnderControl on Ubuntu 9.04

Most of this was stolen from http://no-names.biz/2008/06/09/cruisecontrol-and-phpundercontrol-in-debian-etch/ and http://confluence.public.thoughtworks.org/display/CC/Getting+Started+With+CruiseControl.

1.) Install the sun's java 6 runtime via `sudo apt-get install sun-java6-bin`. I had to enable the multiverse repositories by editing my /etc/apt/sources.list and adding multiverse to the end of every line.
2.) Add 'JAVA_HOME="/usr/lib/jvm/java-6-openjdk/jre/"' into /etc/environment and run `source /etc/environment`.
3.) Download the Cruise Control binary into opt by running `wget http://switch.dl.sourceforge.net/sourceforge/cruisecontrol/cruisecontrol-bin-2.7.2.zip`
4.) Unzip and make a link to /opt/cruisecontrol.
5.) Install php-pear via `sudo apt-get install php-pear`.
6.) Install php under control and phpunit via pear by running:

pear config-set preferred_state beta
pear channel-discover components.ez.no
pear install -a ezc/Graph
pear channel-discover pear.phpunit.de
pear install --alldeps phpunit/phpUnderControl

Note: When running the last command php's cli let me know it ran out of memory. I edited /etc/php5/cli/php.ini and changed memory_limit from 32M to 512M. I changed this back after the installation was complete.
7.) Run `phpuc install /opt/cruisecontrol` to get phpUnderControl setup in cruise control.
8.) Go into /opt/cruisecontrol/projects and copy the connectfour directory to the name of your project.
9.) go into the directory you just created and delete everything under the src directory. Checkout your subversion repository here.
10.) Edit your build.xml file to look like:









11.) Now run `../../apache-ant-1.7.0/bin/ant checkout` and you should see:

Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-6-sun-1.6.0.14/lib/tools.jar
Buildfile: build.xml

checkout:
[exec] At revision 4347.

BUILD SUCCESSFUL
Total time: 1 second

Friday, August 7, 2009

Examining MySQL Slow Query Logs With AWK and PERL

To pull out the information for the slow queries use:
awk '$2 ~ /Query_time/' slow-log

To print out just the times of each query:
awk '{if ($2 ~ /Query_time/) { print $3; }}' slow-log

To print out each query as "time - query":
#!/usr/bin/perl

# takes in a mysql slow query log and spits out a ranked list of query time
# and queries.
open FILE, "
my @times;
my %times_to_sql;

while ($line = ) {
if ($line =~ m/Query_time: (\d+\.\d+)/) { # looking for query time
my $time = $1;
# building offending query
$sql = "";
while ($line_sql = and ($line_sql !~ m/^#/) and 1) {
chomp($line_sql);
$sql .= $line_sql . " ";
}
$times_to_sql{$time} = $sql;
push @times, $time;
}
}

close $FILE;

open FILE, ">slow-log-ranked" or die $!;

@sorted_times = sort { $b <=> $a } @times;
foreach my $time (@sorted_times) {
print FILE "$time - ".$times_to_sql{$time}."\n";
}
close FILE;

Monday, August 3, 2009

Loading Django models.ImageField via a URL

The Django models.ImageField class is an easy way to store images in Django. However, for me it was unclear what to do if the user just has a URL. In my experience this is a common case. If you are building a website that aggregates content from other places and you are allowed to host the image content you are aggregating then it is cumbersome for a user to save a file to their local system and then upload it. It would be much easier if it was possible to use a URL to import this information.

Here is how to do that via the Django shell:

url = "http://media.buffalonews.com/smedia/2009/07/20/07/646-0720homelife.standalone.prod_affiliate.50.JPG";

import os
original_filename = os.path.basename(url)
fp = urllib.urlopen(url)
imgstr = cStringIO.StringIO(fp.read())
storage = S3Storage()
img = My_Image()
path = S3Storage.save(storage, original_filename, ContentFile(imgstr.getvalue()))
import Image
pilimg = Image.open(imgstr)
img.image = path
img.width = pilimg.size[0]
img.height = pilimg.size[1]
img.save()


I am using the S3Storage library to store my images.