Uncategorized

Parsing RSS feeds with ColdFusion MX 7

A recent project called upon us to parse RSS and present the feed in a simple list format.  Using the straight-forward XMLParse method in ColdFusion MX 7, this task was a cinch.  To speed up performance, the script caches the RSS feed once every fifteen minutes.

So that you don’t have to go through the trouble that we did to perfect it, here’s the script.  As always, if you decide to use this in your own project, don’t forget to the leave the GNU GPL license in place.

 
<!---
RSS Feed Parser
@author Aaron Collegeman
@version 1.0
 
Copyright (C) 2008 Collegeman.net, LLC aaron@collegeman.net
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
--->
 
<cfparam name="feed_url" />
<cfparam name="item_limit" default="10" />
<cfparam name="css_class" default="rss_feed" />
 
<!--- create a cache filename from the URL --->
<cfset cache_name = hash(feed_url) &#038; ".html" />
 
<!--- does our cache file exist, and if so, how old is the file? --->
<cfset dateLastModified = 0 />
<cfif FileExists(ExpandPath(cache_name))>
	<cfdirectory action="list" directory="#ExpandPath("./")#" name="dir" filter="#cache_name#" />
	<cfset dateLastModified = dir.dateLastModified />
</cfif>
 
<!--- if the cache file exists and it is not more than 15 minutes old, send it to the user --->
<cfif FileExists(ExpandPath(cache_name)) AND DateCompare(now(), dateLastModified, "n") LT 15>
	<cffile action="read" file="#ExpandPath(cache_name)#" variable="html" />
	<cfoutput>
		#html#
		<!-- cached RSS from #feed_url#; last updated #dateLastModified# -->
	</cfoutput>
<cfelse>
	<!--- download the feed --->
	<cfhttp url="#feed_url#" method="GET" timeout="30" />
 
	<!--- parse the feed --->
	<cfset xml = mid(cfhttp.filecontent, Find("<rss", cfhttp.filecontent), len(cfhttp.filecontent)) />
	<cfset root = XMLParse(trim(xml)) />
 
	<!--- generate HTML snippet --->
	<cfsavecontent variable="html"><cfoutput>
<div class="#css_class#">
<h2>#root.rss.channel.title.xmlText#</h2>
<ul>
				<cfif StructKeyExists(root.rss.channel, "item")>
					<cfif ArrayLen(root.rss.channel.item) GT 0>
						<cfloop from="1" to="#min(ArrayLen(root.rss.channel.item), item_limit)#" index="i">
							<cfset item=root.rss.channel.item[i] />
<li>
<div class="date">#DateFormat(item.pubDate.xmlText, "dddd, mmmm d, yyyy")#</div>
<div class="title"><a href="#item.link.xmlText#" target="_blank">#item.title.xmlText#</a></div>
<div class="description">#item.description.xmlText#</div>
</li>
 
						</cfloop>
					<cfelse>
<li>There are none.</li>
 
					</cfif>
				<cfelse>
<li>There are none.</li>
 
				</cfif>
			</ul>
</div>
 
	</cfoutput></cfsavecontent>
 
	<!--- cache the snippet --->
	<cffile action="write" file="#ExpandPath(cache_name)#" output="#html#" />
	<!--- send to the user --->
	<cfoutput>
		#html#
		<!-- RSS from #feed_url#; just updated at #now()# -->
	</cfoutput>
</cfif>
 
copy code

Code Snippet 2.0 + Disable wptexturize = Code in my blog

The goal: post snippets of code in my blog.

The problems: First, plain-text code is hard to read – it would be nice to post code and have it appear color-coded in a manner similar to the way it looks in my IDE. Second, every time I put a simple quotation mark in my blog, WordPress turns it into a curly quotation mark. WordPress calls this “texturizing,” and it applies this kind of translation to apostrophes, multiple hyphens, back-ticks, and a range of other character combos.

The solutions: Code Snippet 2.0 for syntax highlighting and “Disable wptexturize” to… well… disable that particular “feature.” Code Snippet is built on top of Geshi, an excellent language syntax highlighter: JavaScript, PHP, and HTML, to name a few of the more important ones. The “Disable wptexturize” plugin is three lines from heaven, removing the texturize filter from the primary content of all blog entries.

With this combo of plugins, I can now do this in my blog…

 
// javascript:
var helloWorld = {
    talk: function() {
        alert('Hello, world!');
    }
};
 
copy code

… and this …

 
/* php: */
class HelloWorld {
    public function talk() {
        echo 'Hello, world!';
    }
}
 
copy code

Nice.  Remember that if you want WordPress to respect tab stops, you’ll have to edit your post in HTML mode. Perhaps in the future I’ll hack WordPress to make it stop removing the tab stops from my visually-styled content.

InfoWorld Open Source Software Awards 2008

InfoWorld has published its Best of Open Source Software Awards for 2008.

Prominently featured are a few of my favorites:

  • Best Wiki: MediaWiki – Wiki collaboration software of Wikipedia fame
  • Best Blog Publishing: WordPress – Highly extensible blogging platform, and in no small conincidence, the software used to drive our own blog
  • Best JavaScript Framework: Prototype – Makes JavaScript more object oriented.  (But if you need to get the job done fast, consider jQuery.)
  • Best Web Services Test Tool: soapUI – Specifically, the plugin for Open Source IDE Eclipse
  • Best Server OS: CentOS Paraphrasing: “RedHat Linux, without the overhead of a RedHat support contract.”
  • Best Database: MySQL
  • Best MySQL Administration: phpMyAdmin – This software is better than MySQL’s own desktop clients for query and administration
  • Best Web Browser: Firefox – Duh.
  • Best Image Editing: GIMP – Funny name; nonetheless high quality photo editing
  • Best Productivity Suite: OpenOffice.org – I’m struggling with this one, because the X11 port of this for the Mac SUCKS.  I understand they’re working on a native version for OSX… I’m trying to be patient.

And for our own future reference:

Google Talk Badge + Firefox Ubiquity = Chat with me anytime

This evening I did a little PHP and JavaScript work to embed the Google Talk Badge into my blog’s home page and make the visibility of the badge configurable from within Firefox. The Google Talk Badge is an embeddable chunk of HTML that allows anonymous website visitors to chat with you through your website, while you use Google Talk or any compatible chat client (I like Adium on Mac and Digsby on the PC).  The configuration through Firefox is facilitated by the new (early alpha) Ubquity user interface component – more about that in a moment.

Getting Google’s script is easy – just sign up for a Google Account, then go to the help page (linked above) and follow their links to the badge creation form.  The badge’s appearance is configurable, but I liked the chat bubble look and feel.  The final component script looks something like this:

 
<iframe
src="http://www.google.com/talk/service/badge/Show?tk=...&w=200&h=60"
allowtransparency="true"
frameborder="0"
height="60"
width="200"></iframe>
 
copy code

I used a little CSS and some jQuery magic to make the chat bubble hover over the standard “Contact” link and fade in at page load time.

Now in and of itself, the Google Talk Badge is pretty cool.  It features three statuses: Available, Away and Offline.  And it responds quickly (though not without a page refresh) to my desktop client’s status changes.  So throughout my day I need only change my client’s status to indicate my availability.  But having an eye for aesthetics, it quickly occurred to me that I wanted my extended unavailability to be represented by a total absence of the widget – something that isn’t built into the widget’s behavior.

An associate of mine recently introduced me to Ubiquity for Firefox.  Ubiquity is to Firefox what Spotlight is to Mac users and what Launchy is to PC users: a programmable natural language interface that features fast access to a range of functionality.  So, for example, with any Web page visible in Firefox, if I type ALT + SPACE (my chosen keyboard shortcut), a box opens prompting me to type a command.  If I type “define ubiquity”, this is what I see.

The Firefox Ubiquity user interface in action.

The Firefox Ubiquity user interface in action.

Once installed, you can access custom commands by typing the address chrome://ubiquity/content/editor.html into the Firefox address bar.  The editor is basically a big textarea, and anything you type therein is saved automatically and in realtime.  The scripting language – like most everything else in Firefox – is built on top of JavaScript. Even better still: all Ubiquity scripts have complete access to the jQuery APIs.

The Ubiquity project is well documented, so I won’t go into the syntax for scripting commands.  The purpose of my first Ubiquity scripts are to hide and reveal my Google Talk Badge.  Ubiquity provides the client, and a PHP script living in and utilizing WordPress provides the server.  The end result is a simple REST interface that allows me to toggle the visibility of the badge without changing Web pages and without logging in.  My final Ubiquity scripts look like this:

 
CmdUtils.CreateCommand({
  name: "connect-aaron",
  preview: "Enables the 'Connect with Aaron' balloon on blog.collegeman.net.",
  execute: function() {
    jQuery.get(
      'http://blog.collegeman.net/...',
      { action: 'enable', key: '' },
      function() {
        displayMessage( 'Chat enabled.' );
      }
    );
  }
});
 
CmdUtils.CreateCommand({
  name: "disconnect-aaron",
  preview: "Disables the 'Connect with Aaron' balloon on blog.collegeman.net.",
  execute: function() {
    jQuery.get(
      'http://blog.collegeman.net/...',
      { action: 'disable', key: '' },
      function() {
        displayMessage( 'Chat disabled.' );
      }
    );
  }
});
 
copy code

With these scripts in place, I need only type ALT + SPACE followed by connect-aaron and press enter, and my Google Talk Badge magically appears on my blog.  The Ubiquity command disconnect-aaron has the opposite effect.

Check back soon for more ways to use these technologies – Google Talk, JavaScript and jQuery, and Ubiquity – to build cutting-edge user interfaces that solve real-world problems.

Look, immitation is the sincerest form of flatery, OK?

I just want to go on the record as having said, “Yes, we totally ripped-off WordPress’ corporate website design.”  This is low rent, I know.  I never claimed to be a good designer – I just work with a couple of really good ones; however, they’re on vacation, so for now, I’m on my own.

To give credit where credit is due: the folks at WordPress are good at what they do.  Their stuff is aesthetically appealing.  So if you find our site to be aesthetically appealing, you know who to thank.  But I want you all to know that I didn’t just download their stylesheet and craft it into my own: I code everything from scratch – even my work that seems to be a blatant impostor.

Why not just steal their code?  Well, I guess you could say that’s where I draw the line.  It’s one thing to imitate someone else’s work; but it’s entirely another thing to steal it wholesale.  Besides, one learns nothing from cut and paste.  A lot of work – type fingers, type! – goes into all that style; and just because I can’t imagine such perfection on my own doesn’t mean I can run around the Internet, borrowing liberally from other folks’ code.

Incidentally, if you have no idea who WordPress is, you should know that it is WordPress that makes this website possible.  WordPress is an Open Source blog platform.  And if you don’t have a blog, they’re more than happy to host yours for free.  Check it out.  OK – now I’ve even gone as far as to plug their products.  I’m done being motivated by guilt.

Show me the dots already!

So, I’m a developer.  Most of the time, developers need to be able to see all of the files on their systems, not simply those that the OS considers necessary and good.  Specifically, Eclipse – my IDE of choice – names its system files and folders with a dot (period) prefix.  This convention is the same convention that Mac uses to hide system files from being visible in Finder.  Files and folders with dot prefixes being visible makes Mac look all Unixy – and we wouldn’t want Mac to have his roots showing, now would we?

Long story short, I found some command line statements that reveal and then re-hide these important files.

To show the files:

defaults write com.apple.finder AppleShowAllFiles -bool true

To hide system files:

defaults write com.apple.finder AppleShowAllFiles -bool false

I found these commands here: Gorkee | Files, Finder, Mac, Type, Just.

Not so fast, Mercury

My wife and I don’t have television.  That is to say, we don’t have network television in our home.  We do have a TV, and we do have a Wii, and we do love watching our Netflix (when she waits for me). Now, primarily, this decision is based upon our finances: there are simply better things one (or two) can do with $80/mo.  In fact, if money was not a constraint, we probably would have cable or, in the very least, some distribution of Discovery Health.

So when the opportunity to bask in the glow of the boob tube does arise, we jump on it; and today, babysitting our friends’ cats afforded such an opportunity.  Our friends do have TiVo, but sometimes commercial television can be just as interesting as the entertainment its affording.  Unfortunately, Discovery turned out some real stinkers, mostly targeted at Grandma and Grandpa: pharmaceuticals, life insurance, reverse mortgages, and Robert Wagner.

And then, to my great disgust, was a commercial for the latest Mercury Mariner.  Actually, it was a commercial for hot summer deals from Mercury.  But the disgusting part was a not-so-clever or hot repackaging of the standard EPA fuel rating estimates: “429 miles per tank” (paraphrasing).  Miles per tank?  From which marketing guru’s brain did that spew forth?  When did we start advertising how far a car can go on a tank of gas?

I’m disgusted because Mercury has tried and failed to inject into my consciousness an additional step between the actual mileage and the cost of gasoline (actual mileage: 26 MPG, highway, specifications).  I was left feeling very curious about the American public and whether or not there are many of us who would fall for such a ploy.

Relatively speaking, 26 MPG in an SUV is nothing to get upset about (can anyone say, “Hummer”). But “four hundred twenty-nine” certainly sounds like more than “twenty six,” even though the end result (for me) would be the same: $62.70 as the pump.  I’ll have to ask a real marketing guru to refresh my memory on the Blink experiments with regard to numbers and psychology.  The only thing worse than an intentional effort to obscure the truth is an ineffective one.

Keep trying Mercury: maybe one day you’ll have something that people my age want to buy.

Forbidden

Today is the second day of my Apache on Mac nightmare.

This must be a configuration issue.  After all, it was a configuration issue the last time (yesterday).  The premise is simple: I want to run more than one VirtualHost on my MacBook.  I have been using this approach – for better or worse – on my PC for the last two years.  It ain’t workin’ so good in Mac land, and I haven’t yet figured out why.

Yesterday, it turned out to be the reversal of a security paradigm.  On my PC setup – based upon the default configuration for a fresh installation of Apache 2.0.x – all I had to do was define a new VirtualHost, and voila!, instant local testing environment.  The Mac seems to be following the principal of least privilege: no one has access to anything unless specifically configured on a per-VirtualHost basis.  It was the discovery of this, yesterday, that lead me to adding a few choice options to a nested Directory element, namely, AllowOverride all, Order allow,deny, and Allow from all.

Yesterday, with those options in place my first VirtualHost – the one that I used to test configuration for this blog – worked perfectly.  Today I’m trying to configure an additional VirtualHost – this time, for a client’s site.  Same problem as before: Apache says, “Forbidden.”  You don’t have permission to access this.  What?  Where is this?  Am I pointing at the wrong directory path?  Nope.  Did I forget to throw in those choice options from yesterday? Nope.

There’s gotta be a better way.

Update, July 27th The temporary fix for this problem is to relax the whole least privileges thing, and give all VirtualHosts free reign over my system.  This would probably be a huge security hole on a real server; but considering I’m running a Mac now, it should be OK to have my local system setup this way… right?

Perseverance Trumps Talent

I love that phrase.  Perhaps it’s because I embody it: I just spent the last three hours of my life learning how to install and configure Apache, PHP, and MySQL onto my new MacBook.  For those of you who don’t know me, this otherwise routine learning experience was very special: after nearly 13 years of being PC, I’ve gone Mac.

And I hear that once you go Mac… well… you spend an entire evening cursing because you secretly desire for that Fn key to be the Control key that used to power all of your keyboard shortcuts.  But after thirteen years and three hours, I discovered this truth about my life: perseverance trumps talent.

Don’t get me wrong: I’m a pretty talented guy.  (My wife thinks I’m modest, too.)  For years people have been telling me that I’m talented.  They’ve said things like, “I hope you like making money” and, “the sky is the limit.”  But truthfully, I think any success I’ve ever enjoyed has been based upon my absolute aversion to giving up, throwing in the towel, and calling it a day.

Now, you’ll never be able to pass that one over on my high school football coach (I quit after the first day of the second season of practice) or my cub scount leader (she was a smoker and I was a child); but when it comes to my work – that daily practice of sitting in front of my computer for 8+ hours – the only force more powerful than my will to succeed is my body’s need for rest.

Speaking of which, we’re crusing up on bed time pretty quickly.  I have ten minutes left before I have to start this week’s after-hours update of system code…

« Newer Posts

Subscribe to Perseverance Trumps Talent