Published Benchmarks

I’ve begun a new resource that I’m calling Benchmarks. When I start learning about a new area or want to teach myself something my first plan of action is to find the resources in that area that define the landscape. Often these are books, but sometimes they can be blogs or other resources. My growing list of resources is I believe one of the most valuable results (apart from my own learning). These resources are like great teachers and dear friends. I hope they’re of at least a fraction of the use they are to me — if so, I’d be pleased.

My Benchmarks is still a work in progress and will remain so as long as I’m learning. Go on, have a look!

How to find a cover image for a book with an ISBN

Searching yielded the following options.

  1. OpenLibrary’s Cover API
  2. ISBNdb.com
  3. Amazon Product Advertising API
  4. Google Book API

Open Library Cover APIIt took me a while to find OpenLibrary’s Cover API, but it’s by far the best for my purposes. The following are my reasons for not choosing the others.

  • ISBNdb.com doesn’t actually provide the cover image. They have a useful API for finding out more information about a given ISBN, but not the cover image.
  • Amazon’s serving of images for this purpose seems against their License Agreement. It even seems that in order to be incompliance with the license, one cannot make any public communication about the license or your use of the service. (“You will not issue any press release or make any other public communication with respect to this License Agreement or your use of the Product Advertising API, Data Feed, or Product Advertising Content.”)
  • Google’s Book API has a number of required branding guidelines.

Hat tip to jrochkind of Bibliographic Wilderness for the following articles which lead me to OpenLibrary’s Cover API.

I’ll provide a link to my usage of it, once that site goes live.

Update November 2011: In January 2011 I launched a new website for the Bemidji State University Library. The New Books section uses the OpenLibrary covers where they exist. Unfortunately OpenLibrary doesn’t have covers for a lot of books, but on the positive side, you can easily contribute a cover for a book that doesn’t have one – getting one for yourself and contributing to the good of everyone.

First Steps with Google App Engine

I’ve been researching about Google App Engine recently. Google App Engine provides free web app hosting in the cloud. You can host either Python or Java apps. Once the app is in the the system you have an allotment of free usage and pay (it seems pretty reasonable) when you go over that. I’ve found the system to be really smooth for development and deployment. As a web programmer, it allows you to focus your efforts on writing great code.

My experience is still very limited with GAE. I went through a basic tutorial and put together a basic password generator. It’s really fun to get back to writing python code. My day job is mostly writing PHP/MySQL and it feels refreshing to be programming in python (I feel a much cleaner language) and using a MVC framework.

Since I use a Mac on a daily basis I used the Goolge App Engine Launcher which makes it a synch to start a project, test it in development mode and then deploy to the Google cloud with a single click. Things couldn’t be easier.

By using python on GAE you have limitless options for frameworks. You can use Google’s webapp which is apparently open soure (and possible to host on your own server if you wish). Also, you can use django (version 0.96 is already included in the framework) or any other python WSGI-enabled web framwork like CherryPy, Pylons, webpy, and so on.

One of the major differences about using GAE is that you have to use the Google Datastore, a non-relational database, for all your storage needs. The python API for the Datastore is really nice and succint, however it is a mindset shift when coming from a relational DB background. Although I haven’t yet built a fully-fledged web application, my sense is that the limitations will require you to think differently, but won’t make things impossible. Clearly, Google has found that this is an efficient way to store data for the web and it seems to be working very well for them.

To get started, I read What is App Engine, and then followed the Python Getting Started guide and tutorial.

Here’s some resources I’ve ran across so far.

Documentation:

Speaking at WordCamp MSP, 2010

I’m going to be speaking at WordCamp Minneapolis 2010 on November 13.

My presentation is titled WordPress Off Road. I’m going to talk about integrating WordPress with a multi-faceted (non-WordPress) website. I will be introducing a PHP class called wp_posts for exporting WordPress posts, scripts I’ve developed for maintaining multi-site WordPresses and experiences setting up LDAP authentication.

Register now – I look forward to seeing you there!

Art Space Tokyo

Art Space Tokyo (front)I received Art Space Tokyo a little while back and have been meaning to write about it. Art Space Tokyo by Ashley Rawlings and Craig Mod was not going to see a second printing so Craig took it into his own hands to reprint it. He started a Kickstarter project which had incredible success with 100′s of folks (myself included) throwing in a few dollars in exchange for a copy of the book if it all panned out.

I don’t have any connections (yet) with Tokyo but was won frankly by the beauty of the book and Craig’s vision for bringing some wonderful back to life. I love that Craig is now self-printing the book. It seems similar to how Edward Tufte found that the best way to publish books was actually to publish them himself.

Here’s a description from the website about the book:

Art Space Tokyo acts as your 272 page personal guide and interpreter, connecting you with the neighborhoods and figures behind some of the most inspiring art spaces in this colossal city.

Each of the featured spaces has been rendered as a striking illustration by Nobumasa Takahashi. The book covers art spaces in neighborhoods such as Ginza, Yanaka, Gaienmae, Omotesando, Harajuku, Roppongi, Asakusa and more. The neighborhood surrounding each art space has been meticulously mapped with recommendations for the best food, coffee and sights to enjoy in an afternoon of art viewing.

Whether you live in Japan or not, if you want insight into the Tokyo art world, this is the book for you.

Craig Mod has written up his experience of bringing Art Space Tokyo (2nd edition) to life again on his blog. Craig has some pretty interesting thoughts about publishing the 21st century.

Art Space Tokyo (front) Art Space Tokyo (illustration) Art Space Tokyo (map) Art Space Tokyo (binding)

Extending HTML5 input types with regular expressions

I was reading Jeremy Keith’s, HTML5 for Web Designers which I’ve written about before. This quote is from the section on new <input> tag types, end of chapter 4:

The good news is that you can use the pattern attribute to specify exactly what kind of value is expected. The bad news is that you have to use a regular expression:


<label for="zip">US Zip code</label>
<input id="zip" name="zip" pattern="[d]{5}(-[d]{5})">US Zip code</label>

Most of the time, you’ll never need to use the pattern attribute. On the occasions that you do, you have my sympathy.

Although I’m appreciative of Keith’s lucid explanation, I find that I disagree with him on this point. It’s a great step that we can define input types at will; but it’s even better that the patterns are defined using regular expressions. I can’t think of a more succinct and powerful way to allow infinite extensibility.

As a side note, the example in the book will match 9-digit zip codes, but unfortunately allows other strings also (such as “asdf12345-2345″ or “12345-2345qwer”). I think the following example might be more useful for validating zip codes.


<input id="zip" name="zip" pattern="^[d]{5}(-[d]{4})?$">

The regular expression here matches either 5- or 9-digit strings and nothing else. Unfortunately, you can’t test this in a browser, since no browsers seem to support this attribute yet (I tested Chrome, Safari, Firefox). When browsers do support it, if they end up using regex parsing similar to javascript, you’d be set.

Update November 2011: I’ve come back and tested this and found that the original example does in fact limit to only 9-digit zip codes. Some regex parsers (perl, php and javascript, for example) would have matched “asdf12345-1234″ as matching the book’s regex. It seems that the browser parsers (I checked Firefox and Chrome) are a little more strict by default and don’t require you to indicate the start and end of the string with ^ and $, respectively. However, the regex I included does have the feature of accepting either 5-digit or 9-digit zip codes. So if that’s what you’re looking for, have at it!

PS. Sorry Jeremy for saying your pattern was not strict enough the first time round.

Accessing IPInfoDB with a PHP class

I am working on an analytics tool and needed to pull info from the public IPInfoDb. You can get data for 1 – 25 IP’s at a time, and the data is returned as XML or JSON. I wrote a quick Library for PHP that accesses their data using the JSON format. It selects the correct query URL based on how many IP’s you give it.

Installation and Usage

First install the script at some PHP-accessible place, for example, /path/to/class/IPInfo.php. I would also set up autoloading classes to make things simpler. Here’s an example of pulling some information on either an individual IP or several. The class returns an associative array with IP’s for the keys and information arrays (containing city, region, country, latitude, longitude) as the value.

PHP
1
2
3
4
5
6
7
8
9
10
11
// include the class or use autoload instead.
require('/path/to/class/IPInfo.php');
// instantiate the class
$ipinfo = new IPInfo();
// option1
$oneIP = $ipinfo-&gt;getInfo('123.234.345.123');
// option2
$multipleIPs = $ipinfo-&gt;getInfo( array('123.234.345.123', '1.4.3.123') );

Download

Download the IPInfo class or copy / paste from below.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
&lt;?
/* class that grabs IP info based on a couple of IP's
using the IPInfo DB http://ipinfodb.com/
*/
class IPInfo {
function getInfo($ips) {
// expects either 1 IP or an array of ips.
if (!$ips) {
return false;
}
if (!is_array($ips)) {
$ips = array($ips);
}
//IP Info db allows multiple IP request in series of up to 25. so if there are more than one, hit the
if (count($ips)&gt;1) {
$ips = array_map(array(&amp;$this, "cleanIP"), $ips);
$ips = array_unique($ips);
$ip_chunks = array_chunk($ips,25);
$ipinfo = array();
foreach($ip_chunks as $ipch) {
$url = "http://ipinfodb.com/ip_query2.php?timezone=false&amp;output=json&amp;ip=".implode(',',$ipch);
$val = $this-&gt;makeRequest($url);
foreach($val['page']['Locations'] as $i) {
$ipinfo[$i['Ip']] = $i;
}
}
return $ipinfo;
}
else {
$url = "http://ipinfodb.com/ip_query.php?timezone=false&amp;output=json&amp;ip=".$this-&gt;cleanIP($ips[0]);
$val = $this-&gt;makeRequest($url);
$ipinfo = array("{$ips[0]}" =&gt; $val['page']);
return array("{$ips[0]}" =&gt; $val['page']);
}
}
function cleanIP($ip) {
return preg_replace('/[^0-9.]/','',$ip);
}
private function makeRequest($url) {
$referer = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_REFERER, $referer);
$tries=0;
$page=false;
while( $page===false &amp;&amp; $tries&lt;= 5) {
$page = curl_exec($ch);
$tries++;
}
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return array('page'=&gt;json_decode($page,true), 'tries'=&gt;$tries, 'httpcode' =&gt; $httpcode);
}
}
?&gt;

WP Plugin: Widget Context

Last night I ran across a WordPress plugin called Widget Context by Kaspars Dambis. The plugin gives you the ability to control on what context any widget will show up in, allowing you to narrow down widget content to certain types of posts / pages, to certain categories and URL’s. It’s really useful and allowed me to do some things within WordPress rather than making an ugly hack to a template — making things easier to maintain for non-developers in the future.

Currently, I’m using the plugin to show a custom menu on a certain set of sub-pages over on Mt Zion Church‘s website. Any WP developers out there, let me know if there’s a better way, but thanks Kaspars for the plugin — it’s certainly useful.