Google App Engine Attempt #2

When Google App Engine was released I attended Google’s sprint in New York City excited at the possibility of being able to host python applications without having to deal with the hassles of maintaining a server.  I spent the week after the sprint rewriting a Plyons project so that I could host it on App Engine.

The rewrite left me extremely frustrated:

  1. I had designed the application with a relational database in mind, and couldn’t stop myself from thinking about the data in a relational way.  After the rewrite, the database layer of my project was both ugly and inefficient.
  2. Beaker (the session and cache middleware that ships with Pylons) was extremely buggy when interacting with GAE.  (I would log into my application from Firefox, open up same application with Safari, and it would show me as logged in even though Safari didn’t have any cookies set)
  3. Since the pylons project rolled its own user management / authentication system, I wasn’t taking advantage of Google App Engine’s ability to interact with Google Accounts.

This was almost a year ago.  I didn’t look at Google App Engine again until a train ride a few weeks ago.  I was in the process of tutoring a friend for the LSAT exam and I wanted him to memorize a few terms for the exam.  I urged him to make a set of flash cards so that he could regularly quiz himself.  I searched online for a website that would allow me to easily create and share flashcards.  I found a few, but none that saved a revision history of the edits made to a card.

My goal was to create an application that allows users to log in and create and edit flash cards.  I had another requirement: I did not want to spend more than two hours on the project.  Unfortunately, from past experience I know that writing code for a user management system with passwords and email confirmation can take a week in itself.
I figured that this would be a good time to try and use Google App Engine to see how easy it would be to integrate an application with Google Accounts.  It turned out to be much simpler than I had originally expected.  There are only three function calls that you have to know about when integrating Google Apps within your app:

  1. When your app wants to log a user in: users.create_login_url(“/”) where the string passed in is the URL that you want Google to redirect the user to after they login.
  2. To check to see which user (if any) us logged in, your app can use the users.get_current_user() command.
  3. When your app want log a user out: users.create_logout_link(“/”) where the string passed in is the URL that you want Google to redirect the user to after they logout.

And that is it!  In five minutes I had a user management / authentication system for my application (with CAPTCHA, confirmation email, and forgot password functionality that is available with every Google account).  With the user management part of the application taken care of, the rest of the application was extremely simple and straight forward to create.

For me, the biggest win in using Google App Engine is not the ability to send my application into the cloud (and thus not have to worry about scaling and system adminitration).   Rather, I love not having to build a user management system every time I create a new application.

The code for the flash card application lives at Github.

The application itself runs here.

Planet WordPress Plugin Released

I love the Planet feed aggregator, but I hate managing it via a text configuration file. I created a WordPress plugin that automatically creates a Planet configuration file from the links that are stored in a WordPress database. Every time a link is updated, deleted, or created, a new planet configuration is generated.

For more information on how to install and configure the plugin, visit the plugin’s homepage. The source code for the plugin is hosted at wordpress.org.

DataIO

A few weeks ago my employer helped the NY State Senate parse the MTA budget information into a machine searchable format. (The MTA originally published the budget as a PDF.) To parse the PDF I used a utility called pdftohtml to first convert the PDL into an XML document. I then used the python library lxml to convert the document into a set of csv files. The results of this labor can be seen on TOPP’s data site.

Soon after I published this data, however, I was told by a number of people that the data would be more useful if presented in another format. At first I just started creating a bunch of command line python scripts that would suck in these csv files, and spit them out in different formats. I quickly realized that I could accumulate these scripts and create a quick and dirty web application.

Over a few train rides I created an application called DataIO, and today, I finally got a chance to upload it to Google App Engine. The application is pretty simple to interact with; instructions are located on its front page.

Continue reading “DataIO”

New Years Resolutions

Inspired by a friend I am going to create list of new years resolutions:

  • Learn a functional programming language. Any suggestions on which one to try out first?
  • Make fewer mockups and write more code. Web frameworks these days allow for such quick development that I think I would be more productive if I just skipped the Omnigraffle/Photoshop step.
  • Learn how to engage in effective Test Driven Development. I have heard of the benefits, but I have never seen a good tutorial on how to do this effectively. Maybe I just need to look a bit harder.
  • Don’t think about work while I am playing and don’t think about playing when I am working. Focus is always good. I am sure at least one person will be happy with this resolution.
  • Make a daily to do list with no more than three items. This was suggested by some lifehacker post and it seems like a great idea.
  • Recycle more at home. I recycle consistently at work because we have containers for different type of containers, but since I do not at home, I get lazy more often.
  • Contribute more back to the open source community. I have written a bunch of code recently that I haven’t yet checked in to a public repository. I have to make contributing back a higher priority.

Exporting Posts from WordPress 2.5

Recently I tried exporting some posts from one WordPress 2.5 blog to another WordPress 2.5 blog. The import worked perfectly, but then I realized that I had forgotten to import one of the posts. Rather than doing to the whole import again, I decided to just import the post that I had forgotten. Unfortunately, WordPress brought over all of my categories again, leaving me with duplicates of all of my categories. Ugg.

I wrote a small python script that takes a wordpress export file and strips out information about categories and tags. It’s a pretty simple script, but I will share it anyway: script

Quick Introduction to Flow Player

At TOPP we have been considering switching Streetfilms over to using FlowPlayer. There are number of advantages to using FlowPlayer:

  1. It is released under a GPL3 license.
  2. It has a neat new jQuery interface.

As I learn more about the advanced features of FlowPlayer I will blog about them, but here is a quick introduction.

Continue reading “Quick Introduction to Flow Player”

Adding Meta Information to a Blogroll

I found a useful blog post on how to add text fields to the “link management” admin menu in WordPress:  http://planetozh.com/blog/2008/02/wordpress-snippet-add_meta_box/

But how do you save this information into your database?  This is a three step approach.

1.  Add the fields to you database:

add_action('activate_geo_blogroll.php','geo_blogroll_update_db');

function geo_blogroll_update_db(){
   global $wpdb;
   $wpdb->query("ALTER TABLE $wpdb->links ADD COLUMN link_city varchar(255);");
   $wpdb->query("ALTER TABLE $wpdb->links ADD COLUMN link_state varchar(255);");
}

2. Add text fields to the link admin screen:

add_action('admin_menu', 'add_geo_meta_to_links');

function add_geo_meta_to_links() {
   add_meta_box ('geo_link', 'Link Geography', 'geo_blogroll_form', 'link');
}

function geo_blogroll_form () {
  global $link;
?>

<table class="form-table" style="width: 100%;" cellspacing="2" cellpadding="5">
  <tr class="form-field">
       <th value="top" scope="row"><label for="blog_city"><?php _e('City'); ?></label></th>
       <td>
           <input name="blog_city" type="text" id="blog_city"
                  value="<?php echo $link->link_city; ?>" style="width: 95%" />
       </td>
  </tr>
  <tr class="form-field">
    <th value="top" scope="row"><label for="blog_state"><?php _e('State'); ?></label></th>
    <td>
      <input name="blog_state" type="text" id="blog_state"
             value="<?php echo $link->link_state; ?>"  style="width: 95%" />
    </td>
  </tr>
</table>

<?php } ?>

3. And finally save this information to the database every time someone saves a new link or updates an old link:

add_action('edit_link', 'geo_blogroll_save_meta');
add_action('add_link', 'geo_blogroll_save_meta');

function geo_blogroll_save_meta ($link_id){
  global $wpdb;
  $sql_statement =  "UPDATE wp_links SET link_city='".$_POST['blog_city'].
                              "', link_state='".$_POST['blog_state'].
                              "' WHERE link_id =".$link_id.";";
  $wpdb->query($sql_statement);
}