Tuesday, October 6, 2009

Using Magpie to parse Blogger feeds

I recently redesigned my website and one thing I changed was putting my blog on the front page instead of just linking to it. But what's cool (at least, according to my own geeky tastes) is that my blog is hosted on Blogger--not on my website! In this post, I'm going to walk through how I did this.

1. Blogger setup
First, you need to make sure your Blogger feeds are configured to include the full content of each blog post (as opposed to just the first paragraph or whatever). I think this is the default setting, but to make sure, to go the Settings page and click on the "Site Feed" tab. The "Allow Blog Feeds" option should be set to "Full".



2. Atom feed URL
Now, you must get the URL of your blog's Atom feed. Go to your blog's homepage and view the source (in Firefox, this is under "View > Page Source"). Look for a "link" tag that looks like the one below, and grab the value of its "href" attribute.
<link rel="alternate" type="application/atom+xml" title="mangstacular - Atom" href="http://mangstacular.blogspot.com/feeds/posts/default" />

Note: In this tutorial, I use the Atom feed. The RSS feed also has all the same information--it's just arranged differently.


3. Magpie setup
Download Magpie. This is a wonderfully easy-to-use RSS/Atom parser written in PHP which we'll use to parse the Atom feed.

You'll want to configure Magpie to cache the Atom feed so that it only downloads it when your blog changes in some way (i.e. when there's a new post or a new comment). This way, your website won't have to download the feed from Blogger every time someone visits your page. Open the "rss_fetch.inc" file and add these two lines somewhere at the top:
define('MAGPIE_CACHE_ON', true);
define('MAGPIE_CACHE_DIR', 'cache');

This will turn on caching and instruct Magpie to save the cached Atom file in the directory you specify.

Note: Be sure that the permissions of the cache directory allow your web server to write to it. The way you do this varies from server to server, based on the user that your PHP process runs under, but here are the commands that I had to run:
chmod 775 cache
chgrp web cache

What you do NOT want to do is set the folder to be globally writable. While this would work, it would also allow anyone on the Internet to write to that directory--not a good thing.


4. Parse the Feed
Now you're ready to write the code that fetches and parses the feed. Simply calling Magpie's "fetch_rss" function will parse the feed and return all the data in an associative array (despite "rss" being in the function name, it will also parse Atom feeds). No need to deal with any XML. Below is some sample code.

Note: There are a couple quirks, which may be Blogger-specific--be sure to read the code comments.

require_once('magpierss/rss_fetch.inc');

$atom = fetch_rss('http://mangstacular.blogspot.com/feeds/posts/default');
foreach ($atom->items as $item){
//var_dump($item); //see all the stuff that's in each item

$date = date('F j, Y', strtotime($item['published']));
$title = $item['title'];
$content = $item['atom_content']; //no need to run html_entity_decode() or anything
$url = $item['link'];

//because there are two <link> tags whose "rel" attributes are the same...
//...it stuffs the "href" attributes from both tags into this one string...
//...so you must extract the URL you want...
//...which in my case is the URL to the comments page
$commentsUrl = substr($item['link_replies'], strpos($item['link_replies'], 'https'));

$numberOfComments = $item['thr']['total'];

//generate HTML for the entry
//...
}


And now it looks like you're running fancy Wordpress software! ;)

Tuesday, September 29, 2009

Google Maps and its Traffic overlay

Ever since I started my new job, I've gotten into the habit of turning on the morning news while getting ready for work in the morning. They do reports on rush-hour traffic and this morning, there was one whopper of an accident. A tractor-trailer had slide-lined three cars, completely blocking the flow of traffic in that direction. It was on a road I take everyday to work, but I wasn't sure exactly where on the road it was, so didn't know if it would impact my commute.



Then, I remembered that Google Maps has a live traffic feature that overlays the amount of traffic congestion on the map. I could see where the congestion was and figure out if I needed to find an alternate route. Oddly enough, it reported all roads as being more or less clear, which I knew was not the case. The roadside webcams (another Google Maps overlay) also didn't show any signs of an accident.

It turns out that the data just isn't very "live" after all. Not only was the traffic overlay not reporting the current traffic situation, but the webcam images weren't current either--they were anywhere from 30-60 minutes old. Clicking on the image takes you to the website that operates the webcams, and only going there can you get an up-to-the-minute view of traffic.

So it turned out that my drive wasn't affected. And I learned that, while the traffic overlay on Google Maps is great for seeing general traffic trends, it's not so good for live traffic updates.

Sunday, August 16, 2009

Using phpDocumentor with Eclipse



I just finished making improvements to a PHP/MySQL-powered photo gallery website I had written during college (it kind of felt good to see how much my coding skills have improved since then). Besides moving all the SQL into a DAO, cleaning up the UI, and learning how to do file uploads in PHP, I went through all the code and formally documented all the functions and classes. I decided to use phpDocumentor because the format it requires the comments to be in is nearly identical to Java's Javadoc, which I was already familiar with.

I wanted to set up an Ant target that I could run that would generate the HTML documentation. It was pretty straight-forward--just create a target using the Exec task to run a console command. However, even though I could call the "phpdoc" command straight from the command line, Ant had problems with that. I think this is because "phpdoc" is not an executable, but a PHP script. At any rate, it worked fine once I found the script that the command was linked to and used the "php" command to run the script.

<target name="phpdocs" description="Generates phpDocumentor docs">
<delete dir="${doc.dir}" />
<exec executable="php">
<arg value="/usr/local/PEAR/PhpDocumentor/phpDocumentor/phpdoc.inc" />
<arg value="-f" />
<arg value="*.php" />
<arg value="-t" />
<arg value="${doc.dir}" />
<arg value="-ti" />
<arg value="Photo Gallery Documentation" />
</exec>
</target>

Wednesday, July 15, 2009

SCJP Book Errata

I recently read the book A Programmer's Guide to Java SCJP
Certification: A Comprehensive Primer (Third Edition)
by Khalid Mughal and Rolf Rasmussen in order to prepare for the SCJP exam (which I took and passed last week). I sent the authors of list of mistakes that I found and some have made it into the book's online errata!



How cool is that! :-P

Tuesday, July 14, 2009

OpenOffice and DOC

Sorry, I need to rant a little. >:(

OpenOffice isn't as great as everyone says it is. Or at least as great as I though it was. I'm looking for a job and have been using the open source office suite to update my resume. Most recruiters want resumes in Microsoft Word's ".doc" format, but have no fear! OpenOffice supports that format...

...mostly...sorta kinda.

My resume is pretty basic in terms of features used. It uses two tables, a few bulleted lists, and three drawn lines, along with text of various sizes and fonts. But apparently that's too complex. It can never quite seem to get the bullets in the bulleted lists right:



One time, it used an icon of those things used in movies at the start of a take. Just completely random.

For throw-away documents, this is bearable. But for something important like a resume, you want your .doc to come out exactly right. And OpenOffice fails to do this.

Monday, March 2, 2009

NetBeans and Workspaces


If you're familiar with both Netbeans and Eclipse, you'll probably know of one obvious difference which sets the two apart: Eclipse supports "workspaces", while Netbeans does not (or at least, doesn't appear to--read on). A workspace is sort of like the "state" of the IDE--it's a collection of open project folders and IDE settings. Workspaces are useful when you are working on two unrelated projects which use different code and require the IDE to be configured differently.

By default, Netbeans only allows you to have one workspace. That is, when you exit Netbeans, all your open projects and settings will be restored when it is launched again. This is different from Eclipse, which asks you to specify a workspace every time it is launched. There is a way to specify your workspace with Netbeans as well, though it's not through an easy-to-use UI. An extra parameter must be included when invoking the Netbeans executable:

--userdir C:\path\to\workspace

Here is how to do use this parameter in Windows:
  1. Create a shortcut on your desktop to the Netbeans executable: C:\Program Files\NetBeans x.x\bin\netbeans.exe.

  2. Right-click on the shortcut and click "Properties".

  3. In the "Target" textbox, add the extra parameter to the very end:

    --userdir C:\path\to\new_workspace

  4. Click "OK" to exit the Properties window and double click the shortcut. Netbeans will launch and create/load the workspace at that location.

Tip: I like to use my default workspace as a "jumping-off point" for all my new workspaces. This saves me time I would otherwise have to spend resetting all my IDE settings, like SVN and code formatting preferences. Just make a copy of the default workspace folder and create a shortcut pointing to that folder, as shown above. The default workspace is located here:

~/.netbeans/<version>

Friday, February 27, 2009

Clever Clock UI

There was a power outage in my apartment building the other day, so I went to reset the clock on my stove.

Instead of making you select the hour and minute in two separate steps like most appliances do, you do it in just one. Press the up/down buttons once, and the clock will increment/decrement by one minute. Hold the buttons down, and it moves in ten minute steps for as long as it's pressed.

I thought that was kind of clever. It keeps the task of "Setting the Time" consolidated into a single step, as opposed to breaking it up into as many as three (setting the hour, minute, and am/pm).