Behind the scenes at Brazen Careerist -- Feeds module

Since I started as a drupal developer at Brazen Careerist last fall, one of the projects I couldn't wait to get my hands on was an overhaul of the RSS infrastructure. We were using the (wonderful) FeedAPI module, but running into scaling issues; trying to pull and parse the number of feeds we're importing on drupal's cron wasn't going to cut it. One of our early ideas was to offload the feed fetching and parsing to a custom daemon. While this is still a viable idea, it comes with the overhead of added infrastructure to manage. In the short term we've decided to upgrade to the successor to FeedAPI, the Feeds module.

One of the especially exciting parts of this conversion is the Feeds module built in support for PubSubHubbub (PuSH). PuSH allows near real time notification when the feed URL of interest is updated. Roughly half of the feeds we were interested in aggregating already had support for PuSH, including those from Wordpress, Feedburner, Blogger and Typepad. In addition, by using Superfeedr as a designated hub, we can mimic real time notifications for feeds that aren't already PuSH enabled. This allows us to get notifications within (worst case scenario) 15 minutes of the original post, helping us make the conversations on Brazen Careerist closer to real time. Thankfully, superfeedr's service doesn't require us to distinguish between PuSH and non-PuSH enabled feeds, so it can be used for all feeds.

Anyone who has experience with a data conversion like this knows that it can be a bit tricky and requires quite a bit of testing. Luckily, the wonderful folks at Development Seed have released a module called FeedAPI2Feeds to help get the process started. FeedAPI2Feeds comes with a pair of drush commands that will help migrate FeedAPI content types to Feeds importer configurations. In our case this worked perfectly for creating the importer configurations. The feed configurations are exportable relying on Ctools to provide the exportables API. Ctools defines hook_ctools_plugin_api() which allows a module to define it's own plugin hook. The exported feed importer configuration can then be placed in hook_feeds_imported_default() like this:

<?php
/**
 * Implementation of hook_feeds_imported_default.
 * Exports of existing feed importers, exported from dev site.
 */
function custom_feeds_importer_default() {
  
$export = array();
  
// Copied export from test site.
  
$feeds_importer = new stdClass;
  
$feeds_importer->disabled FALSE;
  
$feeds_importer->api_version 1;
  
$feeds_importer->id 'feedapi_node';
  
$feeds_importer->config = array(
    
//...
  
);
  
  
$export['feedapi_node'] = $feeds_importer;
  return 
$export;
}

/**
 * Implementation of hook_ctools_plugin_api().
 * This needs to be present for the exports in the hook above to work.
 * See http://drupal.org/node/622698 for more details.
 */
function custom_ctools_plugin_api($module ''$api '') {
  if (
$module == 'feeds' && $api == 'feeds_importer_default') {
    
// The current API version is 1.
    
return array('version' => 1);
  }
}
?>

This whole process is also documented on drupal.org. I, along with the rest of the Brazen Careerist team, am a big fan of exportables and keeping configuration in code (and version control) as much as possible. Ctools provides a handy framework for module developers to support exportables. Thanks for making life easier Earl and Alex!

After our configuration settings had been moved over, accomplishing the full data migration required a bit more additional work. I decided to write a few drush commands to process the migration in stages. Creating your own custom drush commands is quite simple. Drush will find any file named *.drush.inc within your custom module directory. All your drush.inc file needs to do is implement hook_drush_help() and hook_drush_command(). Here's an example:

<?php
/**
 * Implementation of hook_drush_help().
 */
function custom_drush_help($section) {
  switch (
$section) {
   case 
'drush:custom migrateFeedURLs':
    return 
dt('Runs custom drush command code');
   break;
  }
}
/**
 * Implementation of hook_drush_command().
 */
function custom_drush_command() {
  
$items['custom mydrushcommand'] = array(
    
'callback' => 'custom_my_drush_command',
    
'description' => dt('runs my custom drush command code'),
  );
  return 
$items;
}

function 
custom_my_drush_command() {
  
// Run my awesome drush code here...
}
?>

The most complicated custom drush command I wrote handled the actual subscription of feeds to superfeedr. If you haven't had a look at drush in a while I'd highly recommend it (especially 'drush mmas').

So what's next? I can't speak with any great certainty, but I'd love to clean up our Activity Streams and start offering them via PuSH. I'd also love to add to the conversation by integrating with other sites using the Salmon protocol (thanks for the inspiration at DrupalCon Brett).

DrupalCon DC WrapUp

After being back at work for three days, I finally feel recovered from DrupalCon DC. Needless to say, it was an absolutely amazing event. The DC organizers (especially the folks at Development Seed) did a great job handling 1500 excited Drupalistas. There are tons of photos on flickr, including two of my favorites. The panel on DrupalCamps went extremely well; I'm excited to start working on the next DrupalCampWI. Video for most of the sessions has already been posted on archive.org (tagged "Drupalcon DC 2009"). You can also find links to the videos for a particular session from the schedule grid. Here are a few of my favorite sessions from the conference:

I'm as re-energized as ever. Here's hoping we can make the next DrupalCampWI as successful!

Bravo Keith!!!

Couldn't have been said any better. I'm honestly sorry for anyone that can watch this and be proud of voting yes on Prop 8.

Naomi Klein in Madison

Naomi Klein will be in Madison giving a talk tonight (7:30 3650 Humanities Bldg if you're interested). I've been a fan of her work since I first read No Logo. On a trip to London in August I picked up a copy of her latest book The Shock Doctrine: The Rise of Disaster Capitalism. Maybe it's just because I'm excited for the talk, but I couldn't help noticing a quote from Rahm Emanuel in today's New York Times article Obama, Assembling Team, Turns to the Economy:

“You don’t ever want a crisis to go to waste; it’s an opportunity to do important things that you would otherwise avoid,” Mr. Emanuel said in an interview.

Looks like both parties are at least subconsciously agree with Klein's thesis.

[I'll attempt to update this entry with photos, and a summary of the event for those of you who can't make it.]

Yes we did

Since I can't post the victory speech Obama hasn't given yet, this will have to do:

Now let's just hope the Dems can get to 60 too

Acer Aspire One -- 3 month review

I've been meaning to write up a review of the Acer Aspire One since I purchased one in August. All in all, it's a good thing I waited...

Ultraportable Laptop Computing @BarCampMilwaukee3

Since upgrading to Ubuntu 8.10 several of my would-be complaints have vanished. Gone is the wifi (wpa) instability, boot times appear a bit quicker as well. The guide on the Ubuntu Community Wiki proved invaluable during the initial setup process. (As Pete said at BCMKE3 "who wants to use an OS called Linpus... just say it out loud once").

 

[Photo: Tapps on flickr]

So far there are two things I've found disappointing. First, the battery life under Ubuntu sucks. If I'm lucky, it will hang in there for a shade under two hours before I need to find an outlet. I've seen the new 6-cell battery, but $119 battery for a $350 computer just doesn't make any sense. (If anyone has any ideas for maximizing battery performance I'm all ears) Also the system drags to a crawl when I have too many programs / tabs open. Swapping is obviously never a good thing, especially with only a half gig of ram. I'm obviously spoiled spending most of my time working on an iMac with 4GB of ram (compared to the measly 512MB in the spire). To remedy the situation I've got another 1GB on the way from Crucial.com.

Since Firefox has proven to be a memory hog, I've used it as an excuse to brush up on some command line tools. I've been spending a lot of time in vim, irssi, and mutt. It will be interesting to see if this trend continues when the system has more memory at it's disposal. I'm still not convinced the netbook will stand up to a week long trip to DrupalCon; I might have to swipe the MacBookPro from Jeni in March. For most of my daily needs though, as long as I have shell access to a development server and/or wifi this Acer seems to do alright. All things considered, I'm happy with the purchase, and glad to have an ultraportable laptop at my disposal.

Wow

F1 Overn1ght Webs1te Challenge

On Friday I'm making the trek up 94 to the Twin Cities with some of my pals from Web414 for the F1 Overn1ght Webs1te Challenge to defend cheesehead honor. We've been challenged to a bowling duel by Kyle Drake the night before the challenge. The event actually gets underway on Saturday March 1st, at 8:30 a.m. Here's a link to the flickr stream, the media page , and a youtube video all for your enjoyment. Hopefully we'll be able to hold similar events in Madison, Milwaukee, and Chicago in the future. I know lots of nonprofits with small budgets that could use some help. I'm actually leaving the event a little early to catch my flight to DrupalCon 2008 -- Boston. I'll try and post some photos, and a writeup if I don't pass out on the plane.

Drupal 6 -- My contribution

While drupal-related work occupies a large chunk of my time, I don't always feel like I'm a "contributor" to the project.

I try to balance my drupalkarma with things like DrupalCampWI, and the Madison Drupal Users Group.

Reading the various Drupal 6 release announcements, I came across one from webchick that credits all the contributions to the latest version of drupal. Curious, I checked out greggles contributor calculation, and the results.

With 3 patches I'm # 79 :P

Hopefully I'll see some fellow Wisconsinites on the list for Drupal 7, and maybe I can break the top 50.

Syndicate content