Using fonts with CFImage

One of the more useful bits of ColdFusion (version 8 and above) is the ability to dynamically write text as an image. As you can imagine, there are nearly endless uses for this. However, one of the more curious things is that it is not that easy to determine which fonts are available for you to use on the system on the fly. You can do it in the Administrative Console, but not programatically. . Worse, if you specify either a non-existent font or one that is not usable, ColdFusion throws a really ugly error. In the Pencilneck CMS, we have a number of bits of code that allow both ourselves & our users to generate images from text on the fly, and so it has become important to know what fonts are available. To that end, I wrote a pair of scripts today that now handle this for me, which I’m going to share below. One important note: In order for this script to work, you must have administrative access to ColdFusion, as it uses one of the Admin API components. The first script simply loads a list of all the valid, usable fontnames in a list (my apologies in advance for this not being properly indented. I’ve not yet found a good way of writing code with WordPress):

<cffunction name=”getServerFonts” access=”public” output=”false” returntype=”string”>
<cfargument name=”loginPW” type=”string” required=”true” />
<cfset var x = structNew() />
<cfscript>
adminObj = createObject(“component”,”cfide.adminapi.administrator”);
// this shoud be the CF admin log in
adminObj.login(arguments.loginPW);
myAdmin = createObject(“component”,”cfide.adminapi.runtime”);
x.fontList = myAdmin.getfonts();
</cfscript>
<cfset x.basicFontList = “” />
<cfloop collection=”#x.fontlist.systemfonts#” item=”x.i”>
<cfloop collection=”#x.fontlist.systemfonts[x.i]#” item=”x.j”>
<!— we disallow the “Adobe Built-in” fonts because CF can’t use them. This list is inclusive, not exclusive simply by my own preference —>
<cfif ListFindNoCase(“TRUETYPE,TRUETYPE-COLLECTION,OPENTYPE”,x.fontlist.systemFonts[x.i][x.j].fonttype)>
<cfset x.basicfontList =ListAppend(x.basicfontList,x.j) />
</cfif>
</cfloop>
</cfloop>

<cfloop collection=”#x.fontlist.userfonts#” item=”x.i”>
<cfloop collection=”#x.fontlist.userfonts[x.i]#” item=”x.j”>
<cfif ListFindNoCase(“TRUETYPE,TRUETYPE-COLLECTION,OPENTYPE”,x.fontlist.userFonts[x.i][x.j].fonttype)>
<cfset x.basicfontList =ListAppend(x.basicfontList,x.j) />
</cfif>
</cfloop>
</cfloop>

<cfreturn listSort(x.basicfontlist,”TextNoCase”) />
</cffunction>

So I like to run this script once on init, and load this list of fonts up into server scope so it’s available to all my applications. Once that exists, it becomes trivial to check for the existence of a font, which I do with the following script:

<cffunction name=”isSystemFont” output=”false” access=”public” returntype=”boolean”>
<cfargument name=”fontName” type=”string” required=”true” />
<cfset var x = structNew() />

<cfif NOT isDefined(‘server.fontList’)>
<!— do this in case the server.fontList hasn’t been initialized yet. If you load your fonts into a different scope, edit this —>
<cfset server.fontlist = getServerFonts() />
</cfif>
<cfif ListFindNoCase(server.fontList,arguments.fontName)>
<cfreturn true />
<cfelse>
<cfreturn false />
</cfif>
</cffunction>

And that’s it. I can now safely test to see if a font is available on a server or not, and then have conditionals by preference, etc. or whatnot. Hopefully, this’ll be useful for you too in your adventures in coding.

SQL Data conundrum – please help!

So, I need to chart this “change over time” graph. And I feel like it should be really easy, but it’s totally breaking my brain how to write the query to do this right now, so I’m hoping someone out there might be able to help. So here’s the issue. I have a table, “cats”. Cats have a birthday and & adoption date. If they’re not adopted, there’s no date. And I want a chart of “current cats” over time. Which seems like it should be easy, but I can’t figure it out right now. Here’s the sample data:

Cat TS_Birth TS_Adoption
Henry 2009-4-4
Fluffy 2009-6-4 2009-7-29
Spots 2009-7-29 2009-10-1
Boots 2009-8-1

So now how could I write a query that’ll give me something like (we’ll assume we counting the number of cats available at 11:59:59pm on the last day of the month):

Num Cats Month
1 May
2 June
2 July
3 August
3 September
2 October

Oh brain, why hast thou abandoned me? If anyone could help me with the SQL, I would be very very grateful.

15 years of web development! (Bloor & Bedford)

I was reading Mark Pilgrim’s Post on the history of the <img> tag & realized that yesterday (November 1st) marks the 15th anniversary of the very first web page I ever wrote! In Fall 1994, I was in grade 13, and the only student in my school to be taking OAC Computer Science. Earlier, my teacher had introduced me to this thing called the “World Wide Web”, and were playing around with this software called “Mosaic” that allowed us to look at sites on the web. We bought a book called “The Whole Internet User’s Guide” and were using to look at what people were doing online.

As usual, I got sick near the end of October (traditionally, I’m always sick either on my birthday or halloween). I’m fairly certain Halloween was on the weekend, and so, being stuck in the house, I took a poem I had to hand in the next day to my creative writing class, and marked it up in HTML to create my very first web page, hosted on a computer at the school. I’m fairly certain that for at least a year if you went to my high school’s website, this is what would have shown up for you. Please don’t judge me on the poetry, but as the page itself is long since gone, I’m reposting it here in a wave of nostalgia:

Bloor & Bedford

It’s Bloor & Bedford
at 3 a.m.
We drive your old Fords
to bring you them

15 stacks on the curb.
Snow’s still falling.
Outside the Reverb
taxis are stalling

Back in our warm homes
we’ve left our wives.
We hand out these tomes
that rule our lives.

At home asleep
you dream of cake.
We deliver, without a peep,
try to make sure you’re not
awake

There’s a small envelope
tucked in the door.
$55.50 you hope
will help feed the poor.

It’s Bloor & Bedford
for 15 years.
You’ve grown old & bored
yet we’re all still here.

I can see from the yellowed paper I got an A for the poem – not sure how I feel about it now, but there you go. If you couldn’t tell, it’s about newspaper delivery-people, and really, all those working while we sleep or stumble home from clubs & whatnot. I don’t recall if I got an A for building a website out of this, but this was the start of the site that would eventually become this very website, although it has changed domains, names, designs & servers numerous times since then. Sadly, when I left Smartt Net as an ISP in the late 90’s I somehow lost my site & all documents on it at the time, so I can’t simply re-print the original HTML itself, which I’m sure would be interesting.

Within 6 months of this inauspicious start I completed my first paid website, a further year after that my first commercial Web App, and well, the rest is history, as they say.

(Final useless/interesting tidbit: This post is apparently #1900 on this site, which feels a significant number too.)

Better redirection

For sites powered by the Pencilneck CMS, we’ve for ages and ages had what we called “Friendly URLs”. These are common across CMS’s, blogs, etc (some ironically, I don’t use them on Tannock.net because I’m too lazy to reconfigure my config & htaccess files). Back in the day, we did this by physically writing a folder to the server. Which was not ideal. So we then switched to redirected using ColdFusions onMissingTemplate() handler. In this instance, we have the IIS server trigger a 404 error, which calls a custom CFM file, which does not, in fact, exist. This triggers the sites onMissingTemplate() handler to actually read the URL and load up the appropriate page from the DB. This works well, but there’s a fair amount of overhead. Vs. the physical stub option, it added between 400-600 ms – not a huge amount, but enough to cause a noticeable overhead on busy sites.

But a while back for a larger project, we installed the Helicon ISAPI rewrite module for IIS. I’ve been using this for a variety of things on sites, such as locking down directories for documents, redirecting particular scripts elsewhere, etc. But I hadn’t set it up to handle our friendly URL system.

This past weekend, I finally spent the time to test out the difference – and it’s impressive. Despite running exactly the same script as the current OnMissingTemplate() handler calls, it runs much faster – on average, 80-100 ms (vs. 400-600 previously) – a significant decrease – I’m guessing because there’s overhead from IIS to generate the 404, hand that off to the custom 404 page, which doesn’t exist, so hands it off to the onMissingTemplate() handler which then calls this script. Now, the the ISAPI rewrite condition kicks in and it calls the script directly.

And now all of our sites are slightly more responsive, which is better for everyone!

Installing root Certificates for ColdFusion

This another one of those post-this-here-so-I-don’t-have-to-google-forever items.

In May of this year, Verisign introduced a new intermediate root certificate. This september, Paypal renewed their own, forcing API users to be using this new root certificate on their end for all API calls. So that’s all fine and dandy, the solution is pretty easy:

  1. Go to Verisign & download the new root certificates
  2. For me, the critical one is the ‘Class 3 Public Primary Certification Authority – G2’ – to be used with the Paypal Payflow API
  3. Install it. For installation to IIS, this is straightforward – simply click on the .cer file and follow the instructions. However, for Coldfusion, this process is a little more involved:

All of the following instructions can be found on Talkingtree.com – I’m rewriting them here for clarity and how I had to do it:

  1. Grab the newly downloaded .cer file and copy it to your {CFROOT}/runtime/jre/lib/security folder (or the equivalent location if you’re using a different JRE).
  2. Run the Keytool function to install it. Keytool exists in {CFROOT}/runtime/jre/bin, using the following path:
    keytool -import -keystore cacerts -alias {UniqueName} -file {filename.cer}
    the  Uniquename can be anything – I recommend something that references what the cert is for. The filename from above is “Class 3 Public Primary Certification Authority – G2.cer”
  3. The keytool will ask for a password. By default, in CFMX7, the password is “changeit”
  4. restart CF server

Happy connecting!

UPDATE 2009-10-23: Sarah Kelly has a great post about why doing this is important, beyond just the how, so read that too.

BCHydro Power Outage Alerts: A suggestion

Today, when the power went out at work, the first thing I did (after getting my laptop tethered to my phone) was to go to the BC Hydro Power Outages page, then check the list of outages and finally, double-checked the map to see if that was the correct area. As I clicked on the map, I noticed that each outage has a unique ID (quite sensibly).  I then noticed that there was a mobile site. Unfortunately, it doesn’t work on the iPhone, because it’s a super-old-school WAP deck.

But! Here’s my suggestion. Given that there’s a unique ID per outage, why not let me “sign up” to receive updates? everytime an engineer updates the status of the outage, there could be a system in place to deliver that update to me automatically. Ideally, I’d be able to choose any number of ways of getting updated: Email, SMS, Facebook, Twitter, whatever,  but the most simple to implement would probably be email updates.

That way, I wouldn’t have to constantly check the site, or worse yet for BC Hydro, call them, and everyone would be happier because they can passively receive information rather than having to actively hunt it out.

Beyond this manual per-outage-sign up idea, the next step would be for me to be able to create an account at BC Hydro and input one or more addresses that I would like to “watch” for power-service updates. For instance, I’d like to know about power issues at my house & at my office.

I don’t know if this power outage/service data is “public”. If so, this seems to be another great open data hack for some determined person to build out. If anyone from BC Hydro IT sees this, I’d certainly love to talk with you about trying to build this out – I can’t (at a quick glance) find a way to get this information easily off-site for use by a “power-watcher” app.

Greasemonkey VPL Catalogue Listings Script for Amazon

So David Eaves posted “5 Municipal apps I’d love to see“. One of them was an extension of an existing Greasemonkey script to search local library catalogue listings when browsing Amazon. So I downloaded Bryan Larsen’s Ottawa library script, modified it to look up in the Vancouver library, and have now posted in on Userscripts.org, for all of your pleasure.

Even if the initial lookup fails, you can still do a direct title & ISBN lookup from links that the Greasemonkey script pushes into the page, directly below the title of the book:

The VPL Greasemonkey script at work on Amazon
The VPL Greasemonkey script at work on Amazon

So, install the script, and test it out on Amazon! Let me know if you have any issues

UPDATE: I’ve updated the script a couple of times since this was initially posted, with the following revisions:

1.0: basic modification of the script
1.1: updated to include a new ISBN look-up URL variable
1.2: updated the ISBN lookup to use the correct OCLC web service
1.3: Fixed getIsbn() regex to look for /,? or end-of-string to extract the ISBN.
1.4: edited the Code-matching to use a central array of codes, and loop over those to provide a simplified messaging around status, and in particular, multiple statuses.

This means that it should be *alot* easier for anyone to further modify this in the future for any other libraries they may want to hook into, as well as providing better answers for books with multiple statuses and copies.

Ideally, I’d like to have this crawl the resulting code to pull out both the branch & due-date information, but this’ll do for now I think.

UPDATE 2009-10-20: There’s now also a script for use on the Vancouver Island Regional Library too: http://userscripts.org/scripts/show/60170

The power of Twitter & the “Ellen Effect”

So, on Thursday, one of my clients, the Vancouver Orphan Kitten Rescue Association (VOKRA) was linked to from the Ellen DeGeneres Show’s Blog, after being mentioned on the show. At the same time, a tweet was sent from the @TheEllenShow twitter account (As an aside, the reason for all of this is that Anna Torv, who is the star of the Vancouver-filmed show Fringe, fosters kittens for VOKRA, so she’s now much cooler in my books than she was before I knew this). Because of this one-time spike, I thought it would be interesting to have a look at VOKRA stats to see what sort of effect this had on their site, particularly as I had been worried a huge flood of traffic might down our servers (for the record, they passed with nary even a flinch. The charts below will show why).

The Ellen Bump
The Ellen Bump

As you can see, traffic generated from Ellen gave VOKRA a huge, but very brief, jump in traffic, from an average of 300 visitors a day to 3900 visitors. Which is nice to see. But, given Ellen’s reach (she’s the 4th-most influential woman in media & has over 3 million followers on twitter), I had been expecting a larger bump from it.

What’s particularly interesting, however, is how that traffic arrived at VOKRA:

How Ellen Viewers reached VOKRA
How Ellen Viewers reached VOKRA

Twitter blew the link on Ellen’s blog out of the water, driving 3 times more traffic to it than the links on the blog. Of the twitter traffic, all but 100 of those clicks came either from the individual tweet or the main page of Ellen’s account – the split is about 50/50 (of those 100 remaining visitors, all but 3 came from my own tweet – thanks, followers!). Being mentioned on the show was nearly as powerful as the tweet. Breaking down those Google searches, the most common was “kitten rescue vancouver ellen“, which suggests to me that comes from people watching the show and searching. A mere 839 visitors clicked through from the blog post itself. Although, perhaps not that surprising: It takes far more investment in the topic to do that, as likely, you’ll

  1. Watch the show & become interested in the topic
  2. THEN go to the Ellen show’s website and read more
  3. AND FINALLY, click through to the end point.

Which is yes, only one extra step, but in terms of buy-in, seems much, much more to me.

A final analysis. What VOKRA wants more than anything when you go to their site is one of 2 things:

  1. Apply to adopt a kitten
  2. Donate to them

What’s disappointing is that all this traffic had almost no effect on either of those 2 goals. There were a few more applications than usual over the past couple of days – a total of 14, vs, I believe, 8 for same period the previous week. And there was no effect on donations – no increase in either number of donations or amount over the previous week (given the increase in visitors, their donations-per-visitor ratio in fact just took a huge hit).

My conclusions to the above? VOKRA’s homepage is not as effective as it should be in communicating those 2 goals, and should be looked at (hopefully this analysis will mean that I get the chance to do). Analyzing what visitors did at the site, nearly every visitor clicked on the big cat banner picture – and then nothing else. The 2nd most popular click was to the blog post about being on Ellen – and then nothing else. In fact, the links to adopt & donate did not see a similar-sized jump in clicks, whereas the blog, gallery  & about us pages all did.

French (and other) accents in Mac OS X

So I only just learned this, and so thought I’d pass it along for others, and also, as a handily searchable record for myself, so here’s the list:

  • Accent Grave (à): option + ` – followed by the letter
  • Accent Aigu (é): option + e – followed by the letter
  • Accent Circonflex (ô): option + o – followed by the letter
  • Cédille: (ç): option + c
  • Tréma (ü): option + u – followed by the letter

Some other useful codes:

  • ellipses (…): option + :
  • n-dash (–): option + –
  • m-dash (—): option + shift + –

generally, if you’re looking for a special code, hold the option key and start pressing around. I’ve tried to find a comprehensive list on the apple support site without luck. So happy typing!

Women in tech I admire: Lauren & Emira

So today is “Ada Lovelace day“, a brand-new thing, to celebrate women in Tech, something that is definitely an issue, as many have pointed out when looking at conference speaker lists and whatnot. And there’s plenty of awesome women in tech & design, and I’ve been fortunate to work with several. However, I’m going to tell a story about two in particular, and the two are probably pretty obvious if you know me: Lauren Bacon & Emira Mears

I met Lauren way back when, when the internet was still young enough that we often had to explain to people why they might want a website. I met Lauren in one of those circuitous routes that made it inevitable we would be friends: I had a class with her younger sister, who introduced me to Day, who at the time was working part time at Duthie Books on 10th, and also starting up a small company called “Envolve Communications” with Jason Mogus (Envolve later became Communicopia). Day then introduced me to Lauren, who had moved down from Prince George and was working for Day & Jason when I started working there too. Lauren and I worked together at Communicopia, where we also met Emira. Way, way back in 2000, Lauren & Emira left to start their company Raised Eyebrow. I left Communicopia shortly thereafter to burn-out in a dot-com startup, while they slowly but surely, built what seemed to me an entirely different business model – one that I longed for, but was definitely not convinced it would work. Given that they’re thriving and not only the company I worked for at the time, but all but one of our clients, vendors and partners no longer exist, their business model clealy works ;).

When I started a sideline development company, Pencilneck Creations, I got to work with Lauren & Emira. And let me tell you – I’ve never had better bosses than they. They were patient, but knew how to push me to get things done. They both inspired and were inspired by their clients, and passed that on to myself and other contractors they worked with. They had a zine (Soapbox Girls, now sadly defunct), that inspired me to start blogging regularly some 8 years ago. They fought hard for women in tech to be recognized. They fought hard for themselves to be recognized, and slowly, surely, they were. I don’t think it’d be a stretch to say that they are now one of the most well-known local design firms, particularly in the sector of social-tech and progressive tech.

Lauren & Emira were also an inspiration to me when I left Digitopolis and formed Pencilneck Software with Jeff – I knew how they had worked, and that gave me the confidence to think I could do it too. They were also incredibly kind to Jeff and I, and we did a number of projects together our first years in business.

Lauren & Emira have also written a book, The Boss of You, celebrate International Women’s Day as a stat at their company, write passionately about women in business in technology on their blogs, continue to build beautiful, functional, useful websites, and also reach out to not only help, but promote other women in business across North America. I’ve worked, and continue to work now with a remarkable number of women in tech & design, but really, none are quite as rockin’.

So today, for Ada Lovelace day, I’m celebrating Lauren & Emira.

%d bloggers like this: