Front-end HTPC hardware: No perfect solutions

I’ve been searching for a while for a perfect front-end for my home automation and entertainment system.  In my setup, the front-end system needs to do the following

  1. display media on the tv over HDMI
  2. send digital audio to the receiver
  3. accept input from a remote control
  4. handle HD content streamed over the network
  5. run quietly and use little power

The front-end doesn’t need to have any storage, TV tuners, or DVD/Blu-ray drives.  That is all handled elsewhere in my setup.  My perfect front-end system would have these features

At least four USB ports
I have two RF remotes and one Bluetooth adapter plugged into each of my front-ends.  My primary RF remote is a media-center type remote – with a numeric keypad and play/pause style controls.  My secondary remote has a QUERTY keyboard and a touch pad mouse – used when surfing the web.  I also have a USB Bluetooth adapter.  I’d like to have at least four USB ports to support these devices and anything else I need to add in the future.

Suspend to RAM with USB wake-up
On average, I probably only watch about an hour of TV a day.  That means twenty-three hours of the day the front-end system is sitting idle.  I’d like to be able to put the computer into a low power mode (S3 – suspend to RAM) when it is not being used.  I’d also like to be able to wake-up the computer with a remote control rather than needing to push the power button.  In my setup, I have an RF remote control with a USB dongle plugged into the front-end.  I need the USB port to stay active when the computer is suspended so that it can wake-up when a button is pressed on the remote.

NVIDIA GPU powerful enough to de-interlace at 1080p
My home automation and entertainment system is running Linux.  Today, the only graphics card vendor to fully support hardware acceleration under Linux is NVIDIA (see VDPAU).  Not all NVIDIA GPUs are created equal and I want one that supports de-interlacing at 1080p resolutions.

HDMI and digital audio out
My TVs have HDMI connections for video, but I don’t necessarily want the audio to go to the television.  Rather, I’d like the audio to go to my receiver.  The front-end system needs to have both an HDMI port and a digital audio out port.  I’d prefer a coax audio out over a fiber-optic audio out because I don’t have to worry about pinching and breaking a coax cable.

Network booting and Wake-on-LAN
I don’t want to have hard drives on my front-end systems.  I’m not doing any recording on these systems and a hard drive contributes to power use – and it needs to be backed up.  The network card in the front-end needs to support PXE booting.  This way I can store the OS on the back-end and easily update it and keep proper backups.  I’d also like the network card to support wake-on-lan (WoL).  If I ever upgrade the software, or lose power, I need my back-end server to start first, then send the wake-on-lan packet to each of the front-end computers.

Gigabit Ethernet
I’m streaming HD content from the front-end and also booting over the network. I don’t want to slow down my wireless network with this traffic or have wireless interference disrupt my media.  I’d like to have a Gigabit Ethernet card in the front-end.

At least 4GB of RAM
I’m not putting a hard disk into my front-end system.  There will be no swap space and everything will need to be stored in RAM.  I’d like to have at least 4GB of RAM in a front-end system.

Bluetooth
I have Bluetooth USB dongles already, but it would be nice to have Bluetooth integrated right on the computer to I don’t have to have yet another USB dongle sticking out of the comptuer.

Serial port(s)
Yes, serial ports are old technology, but my television and receiver can be controlled over a serial interface.  In my experience, this is much more reliable than IR.  I’d like the front-end to have at least one serial port.  Two would be preferred.

IR Output
Several HTPCs come with an IR input and a media center remote.  I’d rather use RF for input so the PC can be out of sight. IR output is what I’d really like to see on an HTPC.  This is needed to control DVD players/gaming consoles and every other device that cannot be controlled via ethernet or serial.

 

I haven’t been able to find any retail HTPC computers that have everything I’d like in a front-end system. The NVIDIA Next Generation ION (aka ION2)based computers from Asus and Zotac come close, but most lack bluetooth, serial ports, and IR Outputs. It is also hard to tell which motherboards support network booting and wake on USB/LAN.  Hopefully the next generation of HTPC systems will have more of what I’d like. For now I’ll stick with the Zotac ZBOX HD-ID11 and add a bluetooth dongle and the GC-100 for serial and IR.

Share
Categories: Uncategorized Tags:

One Server: Researching the hardware

Using my list of requirements, I set out to find the hardware for my new server.  I was building this from scratch so at minimum my purchase list needed to include

  1. hard drive storage
  2. server case
  3. motherboard, RAM & CPU

Hard drive storage
I decided to focus first on the requirements for the fileserver side of the project.  Recall that I was planning for 16TB of storage space.  At the time, the largest consumer hard drives were 2 TB.  I also wanted to be able to support multiple drive failures and be able to replace the drives without shutting down the system.  That meant I needed at least 10 hard drives.

When researching the hardware for this server I came across a good blog post from Adaptec about real life RAID reliability.  That article compared the reliability of  RAID-5 and RAID-6 arrays and showed that a RAID-6 array should last 172 times longer than a RAID-5 array.  Reliability was important to me on this project, so I decided to go with RAID-6.  The Adaptec article only considered enterprise grade drives. I planned to build this server with consumer grade drives.  Therefore, as a precaution, I chose to add two extra drives as hot spares.

A RAID-6 array with 10 drives was likely to run slow.  So I did some more searching and came across RAID-60.  RAID-60 combines the redundancy of RAID-6 with the speed of striping found in RAID-0.  However, to get 16 TB with RAID-60, and have two hot spares, I now needed 14 hard drives.  Six drives for each of the two RAID-6 arrays and two hot spares.

RAID-60 with 8 drives. Image from Wikipedia

I wanted to make sure the fileserver would run quickly so that I could stream video from it while MythTV was also recording new programs and all the virtual machines were also running.  I thought running everything off one set of storage drives might be too much, so I decided to split the VM storage from the NAS storage.  That meant adding additional drives.  I had four 1TB drives from my previous NAS, so I decided to use them for storing the VM images.

That put the total number of hard drives needed at 18.  This was shaping up to be quite a storage server!  The next task was determining how to fit that many hard drives into a computer case.

Server Case
I wanted the server to be able to stay running while I replaced a failed drive, so I needed a case that accommodated hot swappable drive bays.  I considered putting the drives into some six-bay external drive enclosures, but decided that would get too expensive and end up using more power then was needed.  Plus, I could just see the cables getting disconnected between the external enclosures and the main CPU.

No tower-style case that I could find would hold that many drives, so I looked for rack mountable cases.   To fit 18 drives, a 4U rack mount case was needed.

Motherboard, RAM & CPU
I wanted to be able to expand this system in the future, so when choosing the motherboard I focused on server boards that supported dual CPUs.  My plan was to put the system together with one CPU, and if needed, add another CPU later.  I also needed to find a motherboard with multiple network interfaces, and plenty of PCI-express slots for adding RAID cards.  Since reliability was important to me, I focused only on motherboards that supported ECC RAM.  Form factor wasn’t a big issue for this system as it was being placed into a rack mount case with plenty of space.

For the CPU, I needed a processor that supported VT-d.  VT-d processors support mapping cards plugged into PCIe slots directly into virtual machines.  My goal was to create a virtual machine for the fileserver and map the RAID card directly into that VM.

Another goal of mine was to make the new server easy to administer.  I didn’t want to have to find a spare keyboard, mouse, and monitor and plug them all in when there was trouble.  The solution, IPMI.  A motherboard with IPMI would allow me to remotely control the keyboard, mouse, video and even attach a remote DVD-ROM to perform an OS install.  It is basically a built-in KVM over IP.  I can even remotely reset the computer using IPMI.

Parts list
I ended up purchasing the following components for this system

  • 14 x 2 TB hard drives (5 x Hitachi HDS72202, 3 x SAMSUNG HD203WI, 6 x WDC WD20EADS)
  • Norco RPC-4220 4U rackmount case with 20 hot swappable drive bays
  • Supermicro X8DTi-F motherboard with 3 PCIe 8x slots and IPMI
  • 24Gb ECC Registered DDR3 1066 RAM
  • Intel Xeon E5506 Nehalem-EP 2.14 GHz processor
Share
Categories: Uncategorized Tags:

A home server using VMware ESX and ZFS

Server CaseIf you are like me, and you like technology, you probably find yourself wanting to try the latest operating systems and software.  You also likely have a router for your network, a NAS device for your storage, and maybe a web server for a blog or wiki.  After a while, you end up with the situation shown in the picture below, a closet full of servers.

The picture below is of my server closet from 2004.  I had a custom Linux router, a NAS box, a VoIP server, and several other computers for trying out operating systems and software.

Old Server ClosetMy setup continued that way for several years.  It took up a lot of space.  It was loud.  It was hard to upgrade because I needed to physically sit at the computer to reload the operating system.  And it used a lot of power.

In 2007 I started to use virtualization to cut down the number of computers and make controlling and upgrading them easier.  I was able to get the number of computers down to only two: A NAS for storage, and a Linux computer for running VirtualBox.  Everything else I needed could run in a VirtualBox guest.

This worked well until 2009 when I started to run out of storage on my 3 terabyte NAS server.  As I was planning to replace it, I decided to try combining the two servers into one.  I wanted a server that would have plenty of disk space for my NAS and be able to run any operating system and software that I wanted to try out.

I called this my One Server project.  The next several posts will cover this project.  These posts describe the hardware behind the server, using VMware ESXi to replace my aging Linux VirtualBox server, setting up a FreeBSD ZFS NAS fileserver under VMware ESXi, and all the issues and solutions I discovered along the way.

  1. One Server: What is needed?
  2. One Server: Researching the hardware
Share
Categories: Uncategorized Tags:

One Server: What is needed?

To make sure I got the right hardware and software for this server I needed to know what the server was going to be used for.  I needed to get an idea of how much computing power I was going to use to run all the virtual machines.  And since this project started off as an upgrade to my NAS fileserver I also needed to figure out how much storage space I was going to need.

I knew from my previous VirtualBox server what guest operating systems I was going to run.  They were:

  • Astaro Security Gateway for the firewall/router
  • Windows 7 for a “standalone” computer used only for banking
  • Linux for a web server
  • Linux for a CrashPlan backup server
  • Linux for a OpenVPN server

My previous fileserver had four disks in a RAID-5 setup for a total of three terabytes.  It was very slow and I wanted to find a way to speed it up.  At the same time I needed to add enough disk space so that I wouldn’t have to think about disk space for a long time.  I previously used the file server for:

  • storing backup copies of my iTunes music and video libraries
  • keeping copies of operating system ISO install images for installing VMs
  • backing up my wife’s and my own laptop as well as my web server
  • storing an ever growing 500Gb RAW photos library from my DSLR camera
  • storing video for my MythTV setup

I had also recently gotten a new camera capable of recording HD video.  HD video files take up a lot of space and with a new baby daughter I was recording a lot of video.

Doing the math, I decided I needed at least 8 terabytes of storage to comfortably cover my needs.  To make sure I wouldn’t have to worry about storage space again, and considering Moore’s law, I decided to double that and plan for 16 TB of storage space.

I had the following additional requirements of the server itself

  1. be reliable enough to run 24×7 for several years
  2. continue working without data loss if two hard drives fail
  3. allow for hard drives to be replaced without shutting down the system
  4. be easy to backup
  5. report any errors with the drives or the virtual machines so they can be fixed quickly
  6. be compatible with as many guest operating systems as possible
  7. be easy to install, maintain, and configure.  Well, easy for a technical person at least
  8. allow for remote maintenance of the host operating system
  9. have room for expansion (cpu/ram/disk/etc upgrades)
  10. be quiet
  11. not use too much electricity
  12. support multiple network interfaces. It is going to be my router and needs to plug into my cable/dsl modem as well as my LAN

The reliability of the server was my most important factor.  Since I was consolidating everything on this one server, if it ever went down nothing would work.  It was also going to store all our family photos and videos.  I planned to keep everything backed up, but I wanted to make sure I wasn’t going to lose those memories due to a failed disk or silent bit rot.

Share
Categories: Uncategorized Tags:

IntenseDebate and Google Analytics

I use IntenseDebate for the comment system on my blog. I also use Google Analytics to keep stats on how many people visit my site. To integrate the two, I created a Google Analytics plugin for IntenseDebate.  With this plugin, when someone leaves a comment, an event is added in Google Analytics.  This event can then be used with advanced segments in Google Analytics to see metrics focusing just on visits that lead to comments.

To see the IntenseDebate events in Google Analytics, browse to Content -> Event Tracking -> Categories ->IntenseDebate

The plugin is not currently in the approved list of IntenseDebate plugins.  I’d like to do more testing before submitting it.  If you’d like to help test, you can download my IntenseDebate Google Analytics plugin and add it to your IntenseDebate custom scripts.

The plugin can be customized to create a virtual page view if you’d like to create a goal based on comments.  To enable this, add the following to your IntenseDebate custom scripts.

var id_ganalytics_plugin = id_ganalytics_plugin || {};
id_ganalytics_plugin.use_vpage = true;

With this enabled, a page view for /service/IntenseDebate/CommentPosted will be created each time a comment is posted.

The plugin can further be customized to change the event that is tracked and to change the virtual page.  The following options control the event.  See the event tracking overview page for documentation on category, action, and label.

var id_ganalytics_plugin = id_ganalytics_plugin || {};
// Use id_ganalytics_plugin.use_event to enable/disable event based tracking
id_ganalytics_plugin.use_event = true;
 
// Use id_ganalytics_plugin.event_category to set the event category
id_ganalytics_plugin.event_category = 'IntenseDebate';
 
// Use id_ganalytics_plugin.event_action to set the event action
id_ganalytics_plugin.event_action = 'Comment Posted';
 
// Use id_ganalytics_plugin.event_label to set the event label
id_ganalytics_plugin.event_label = location.href

The following two options control the virtual page views

var id_ganalytics_plugin = id_ganalytics_plugin || {};
 
// Use id_ganalytics_plugin.use_vpage to enable/disable virtual page tracking
 id_ganalytics_plugin.use_vpage = false;
 
// Use id_ganalytics_plugin.vpage to set the virtual page to be tracked
id_ganalytics_plugin.vpage = '/service/IntenseDebate/CommentPosted';

Leave me a comment if you find this useful, or if there is anything you’d like to see chaged.

Share
Categories: Tutorial Tags:

Hiding Google Analytics Campaign Variables

Do you use a service like Google Analytics for viewing your website statistics? Are you keeping track of your inbound links using campaign variables (utm_source, utm_medium, utm_campaign)? I recently ran into a situation where Google search results were linking to URLs with my campaign variables in them. Not a good thing – it really messes up your stats by reporting Google searches as coming from another source! Not to mention causing duplicate copies of your content to appear in the search listings.

Thankfully there is a quick fix for Google. Setting the canonical header link will cause Google to re-evaluate the URL next time your site is indexed. But what about a user copy-and-pasting a link to another site, or bookmarking that link?

It turns out Google Analytics can parse campaign URLs in two different ways.  It can parse them in the query parameters (those variables that come after the ‘?’ in your URLs). Or, it can also parse them when stored in the fragment after the ‘#’ in your URL. Google provides an API function to enable parsing of the fragment parameters.  The function is _setAllowHash(true).  You insert this just before the call to _trackPageview.

pageTracker._setAllowAnchor(true);
pageTracker._trackPageview();

In theory, this should work well. Google is not supposed to index the fragment parameters that come after a URL. But what if a user bookmarks the URL?  Or what if they copy-and-paste the URL to digg or another site? This still isn’t going to solve the problem.

Time to rethink. Ideally, the campaign variables would only be available to Google Analytics and not even show in the client’s URL bar. Then they cannot be indexed by search engines and it would be unlikely they’d be copy-and-pasted to another site by the user. Here is a better solution.

When campaign variables are passed to a web page, the PHP page that is loaded can look at the $_GET parameters and detect those variables. It can then remove them, stick them in a session cookie, and redirect the user on to the correct URL – the one without the campaign variables.

The fragment portion of the URL, the part after the ‘#’, can be modified by Javascript. When the redirected page loads, before the Google Analytics code is called, a bit of Javascript code can be used to pull the campaign variables out of the cookie and place them into the fragment portion of the URL. After the Google Analytics code runs, these campaign variables can be removed, the cookie can be deleted, and the original fragment (if there was one) can be restored.

So, putting it all together, here is what happens.

  1. User clicks on a link with campaign variables and visits your website with a URL that looks something like: http://example.com/page/?utm_source=youtube&…
  2. The PHP code running your website detects that the user has clicked on a link with campaign variables, stores those variables in a cookie, and redirects the user to that same URL but without the campaign variables.
  3. The user’s browser visits the new page, without the campaign variables, and passes the cookie along to that page. The new URL looks something like this: http://example.com/page/
  4. The page loads in the user’s browser. As it loads a bit of Javascript runs.  The Javascript adds the campaign variables to the fragment portion of the URL.  At this snapshot in time, the URL looks like this: http://example.com/page/#utm_source=youtube&…
  5. Immediately after the URL is rewritten, the Google Analytics page tracker code runs and credits the source to the intended campaign. Immediately afterward, the custom Javascript erases the variables from the fragment so that the user never sees them, putting the URL back to: http://example.com/page/#

That’s it. Google Analytics gets the proper information to keep track of your campaigns, the user doesn’t see a cluttered URL, and Google doesn’t get a chance to index the page with the campaign variables in the query string.

There is one bug annoyance.  That is, after the Google Analytics page tracker runs and the fragment is erased, it still leaves the single ‘#’ character in the URL.  But at least this won’t cause any harm if the user bookmarks it or copy-and-pastes it somewhere.  If anyone has ideas on how to get rid of this, please leave me feedback in the comments.

Now, if only this could be incorporated into Joost de Valk’s wonderful Google Analytics for WordPress plugin! I’ve modified my copy to do this already. See the attached Google Analytics for WordPress Modifications. This isn’t a complete plugin, only a modification to the source file for version 2.9.5 of the official plugin.
[Update: See the comments below. Adding this to Google Analytics for WordPress might not be that useful]

Lastly, the code :)  Here is the bit of PHP code the detects the Google Analytics variables, sets the cookie, and redirects the user to a “clean” URL. If you have run into a similar situation and solved it a different/better way, please leave a comment and let me know what you did. I’m very interested in knowing if this could be done a better way!

// Add any Google Analytics Campaign variables to the found_tags array.
// Remove them from the _GET array so they don't get forwarded on
$found_tags = array();
foreach(array('utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content') as $tag) {
    if(isset($_GET[$tag]) && !empty($_GET[$tag])) {
        $found_tags[$tag] = $_GET[$tag];
        unset($_GET[$tag]);
    }
}
 
// If any campaign variables were found, redirect the user to the "clean" URL
// after setting the 'gatmp' session cookie with the campaign variables.
if(count($found_tags) > 0) {
    setcookie('gatmp', http_build_query($found_tags));
    $dest = $_SERVER['SCRIPT_URI'];
    if( count($_GET) > 0 ) {
        $dest .= '?'.http_build_query($_GET);
    }
    header ('HTTP/1.1 301 Moved Permanently');
    header ('Location: '.$dest);
    exit(0);
}

Next, here is the javascript that detects the cookie and passes the campaign variables on to Google Analytics. This code takes the place of the normal pageTracker._trackPageview() function call.

function gaTrackerClass() {
  this.cookieVal = false;
 
  // Grab the cookie, if it exists, store in this.cookieVal
  if (typeof(document.cookie) != "undefined" && document.cookie.length > 0) {
    c_name = 'gatmp'; // Cookie name
    var c_start=document.cookie.indexOf(c_name + "=");
    if (c_start!=-1) {
      var v_start=c_start + c_name.length+1;
      var v_end=document.cookie.indexOf(";",v_start);
      if (v_end==-1) v_end=document.cookie.length;
      this.cookieVal = unescape(document.cookie.substring(v_start,v_end));
      // Unset the cookie so it doesn't get used multiple times
      document.cookie = c_name + "=; expires=Thu, 01-Jan-1970 00:00:10 GMT";
    }
  }
 
  // Our _trackPageview function. It emulates the behavior of the Google
  // function, using the cookie rather than query parameters in the URL.
  // If no cookie is found, just call the normal _trackPageview function
  this._trackPageview = function(str) {
    if( typeof(pageTracker) != "undefined" ) {
      if(this.cookieVal != false && typeof(window.location) != "undefined") {
        // Save the current fragment
        var hashtmp = window.location.hash;
 
        // Call Google Analytics and record the campaign variables
        window.location.hash = '#' + this.cookieVal;
        pageTracker._setAllowHash(true);
        pageTracker._trackPageview(str);
 
        // Restore the fragment to its original value
        window.location.hash = hashtmp;
      } else {
        pageTracker._trackPageView(str);
      }
    }
  }
}
var gaTracker = new gaTrackerClass();
gaTracker._trackPageview();
Share
Categories: Tutorial Tags: campaign, Google Analytics

Host Your Own URL Shortener: 10 PHP Apps Reviewed

Shorter URLs

I have been planning to host a personal tinyurl or bit.ly like URL Shortening service on my website.  I was going to write my own software for this, but thought I’d start by reviewing some existing PHP Apps just in case one already met my needs. I wanted to add a URL shortener to my website for a couple of reasons:

  1. People don’t always trust blind redirect links from tinyurl or bit.ly.  If the links came from my website, people would know the links were somehow related to my site and that I considered them safe.
  2. To shorten links sent over email, but still append a small path to them so people have some idea what they’re clicking on.  For example, assume http://esev.com/Fga34A was a shortened URL that pointed to a Google Map of my house.  I’d like to be able to append /MyHouse to the end of the link (i.e. http://esev.com/Fga34A/MyHouse) without that breaking the redirect.  This is not easily possible with most URL shortening services.
  3. To also use the shortener to create custom landing pages for my website.  I’d like to keep my domain name in these landing pages and also be able to customize the name of the short URL.  Hosting the URL shortener on my site enables me to pick any name I’d like for the short link, without worrying whether someone else already reserved it.  These landing pages are handy for adding Google Analytics custom campaign tracking tags so I can tell which sites are linking to my blog posts.
  4. To have the ability to use regular expressions to create dynamic URLs to the destination page would be nice too especially for Amazon affiliate links.  These require you to add an /affiiliateID to the end of the URL.  A regular expression could take the path passed to the short URL and generate the long URL.  For example, I’d like something like this which you get with mod_rewrite:
    Link: /amazon/([^/]+)
    Destination: http://amazon.com/exec/obidos/ASIN/$1/ref=nosim/affiliateId

The table below lists the URL shorteners I reviewed and compares them to the features I was looking for.

Name Random link Custom link Append URI Regex Has API Redir Type Private Custom title Edit Stand alone
Pretty Link Yes Yes Pass / Prevent Query String Yes 301 / 307 Yes Yes Yes No
YOURLS Yes Yes Prevent No Yes 301 Yes / No No Yes Yes
Link Shortcut Yes Yes Fail No No 301 / 302 Yes Yes Yes No
Simple Link Cloaker No Yes Pass No No 302 Yes No Yes No
GoCodes No Yes Prevent No No 301 Yes No No No
phurl Yes No Fail No Yes 301 No No No Yes
urlShort Yes Yes Prevent No Yes 301 No No No Yes
Shorty Yes Yes Fail No No 302 Yes No Yes Yes
TightURL Yes No Prevent No Yes 301 No No No Yes
Short URL Script Yes No Fail No No 301 Yes No No Yes
Last updated June 30, 2009

The columns indicate the features I was interested in and show if the URL Shortener supported that feature.

  • Random link - Does the software have the ability to generate a random link?  This is useful for automating tasks.  For example, if I wanted to post a short link to each blog post on Twitter, I would want the software to automatically generate a random link name.
  • Custom link - Does the software allow me to choose the name of my link?  Sometimes I do want to specify the name of the short link.
  • Append URI - Does the software allow data to be appended to the end of a short URL? For example, if the short link is http://esev.com/Fga3A and it points to http://www.google.com/, what happens when I type http://esev.com/Fga3A/analytics/?  Fail means the software could not handle that type of request and did no redirection at all.  Pass means it passes the extra URL data along when doing redirection – something that I did not want to happen.  Prevent means the shortener ignored the extra path and still forwarded to the original URL – which is what I wanted.
  • Regex – Does the software support regular expressions for mapping the path passed to a Short URL to the destination URL?  See #4 above for the reason behind this.  Only Pretty Link comes close to this, enabling the query parameters (stuff after the ? in a link) to be generated based on the URL.
  • Has API – Does the software have an API to support using it inside other software?  For example, if there is a really great plugin sending blog posts to Twitter, is it going to be easy to integrate the URL shortener software with this plugin?
  • Redir Type – What type of redirection does the software generate?  301 redirects are optimized out by search engines – which is what I wanted.  This post on URL Shorteners has a good description of the differences between 301 and 302 redirects. (It is also where I got the idea to make this table.)
  • Private – Does the software require an username/password for adding links?  Some of the software for URL Shortening is meant for public sites like tinyurl and bit.ly.  I’d rather be in control of all the links on my site.
  • Custom title – Does the software allow the user to enter a description of the link?  This can be useful later to determine the difference between two similar links (i.e. http://esev.com/a?q=1 and http://esev.com/a?q=2).
  • Edit – Can the destination link be changed after the short URL is created?  If the destination site changes, it would be useful to be able to modify the link.
  • Stand alone – Can the software be run on its own, without WordPress?  I’d like my blog to live in /blog on my website.  If the shortener is tied to WordPress then all my short links would need to include /blog in them – making them a little longer than I’d like.

Conclusion
In the end, I decided Pretty Link fit most of my needs.  The developer, Blair Williams, is also very responsive to questions and requests for new features.  I expect Pretty Link will continue to improve.  There were only two things Pretty Link didn’t satisfy; supporting regular expressions and being standalone.  Both of which I worked around with a few mod_rewrite Apache rules and a small modification to the Pretty Link source code.

In addition to the features I was looking for, Pretty Link includes a few extra features:

  • Optionally track the Number of Hits per link
  • Provides a reporting interface where you can see a configurable chart of clicks per day. This report can be filtered by the specific link clicked, date range, and/or unique clicks.
  • Can use the short URLs as Tracking Pixels and track impressions

Do you know of other URL Shorteners that might fit the solutions I need?  Or did I make any mistakes in the comparisons?  Leave me a comment and let me know.

Share

Google Reader in Facebook

This has been around for a while, but I only recently started using it. Facebook’s built-in importer application can automatically add your Google Reader shared items to your mini feed.

To configure this, open your Profile to display all items you have posted.

Select your Profile at the top of the Facebook website

Select your Profile at the top of the Facebook website

On the profile page:

  1. Click “Settings” on the bottom right side of the Write Something box
  2. Choose “Google Reader” as the site to import from
  3. Enter the URL to your public “Shared items” page from Google Reader and press import

That’s all it takes. Now, when you share an article in Google Reader a post will be made in your mini feed on Facebook with a link to the article.

Steps to add Google Reader

Steps to add Google Reader

Share

TekSavvy and SpeakOut: My Alternatives to Rogers and Bell

I’m always looking for a better deal when it comes to my utility bills.  In Ontario, it seems like there aren’t many choices when it comes to telephone, television, wireless, and internet service.  Either you sign up with Bell or you sign up with Rogers.  At least that’s what their advertising campaigns would like you to think.

There are, however, good alternatives that will save you a few dollars per month.  Here are the companies I’m using instead of the “Big Two”.

Internet Service Provider (ISP)

I’m using an ISP based in Chatham, Ontario called TekSavvy Solutions.  TekSavvy rents DSL lines from Bell to provide internet service to its customers.  I have a Dry Loop DSL line with TekSavvy, which means the phone line coming into my house is only used for DSL service.  There is no phone number associated with the line.

TekSavvy takes care of all the billing.  I only pay a bill to TekSavvy and they pay Bell for the DSL line.  The connection to the internet is completely independent from Bell’s connection.  TechSavvy maintains their own backbone connection via Cogent and Peer1. The total cost for TekSavvy internet is $38/month.

Wireless Cell Phone Service

Just this month I switched my wireless phone service from Fido to SpeakOut.  SpeakOut is a prepaid GSM provider that is offered by 7-Eleven.  I like SpeakOut because there aren’t any hidden daily charges or System Access Fees – just a flat 20¢/minute.  The minutes don’t expire for an entire year – and you don’t lose them as long as you purchase more minutes before they expire.

Virgin Mobile is another good alternative for wireless phone service, but they’re not GSM based – meaning you can’t just switch SIM cards and have your phone work on a network in another country.

Television Service

I’m not a fan of being forced to watch advertisements when I’m paying for a service.  I feel that I shouldn’t be subjected to advertising interruptions if I’m spending money to watch something.  That said, paying for cable television service is a non-starter for me.

I still feel it is important to pay for professional entertainment – the actors/producers/writers/etc deserve to be paid for a job well done – especially if that means they’ll keep producing the shows that I like. So, instead of paying for television service, I choose to pay for my shows À la carte by using services like Apple’s iTunes and Amazon’s Video on Demand.  I feel this is a good alternative because I’m still contributing to the shows I like, but I’m not forced to watch advertisements and all the other junk on cable.

Telephone Service

I always enjoy when the big “land-line” phone companies call me up and try to sell me their phone service.  They usually spend about five minutes rambling on about how good their prices are, without even taking a breath so I can stop them and save their time.  After the five minute spiel they always ask the same question, “May I ask how much you are currently paying for telephone service?”  To which I answer “$15/month, including 500 minutes of long distance, voice mail and call display.”  Which usually gets the response “Uhhhh. Oh. Thanks, have a nice day (click)” from the sales person.  They just can’t compete with Vonage.  I’ve been a very happy Vonage customer since 2002.  I have the occasional dropouts due to my sometimes flaky internet access (I can use my cell phone in those cases), but when my ISP is reliable the service has been exceptional.

Do you have any other alternatives to Rogers and Bell?  Please tell me about them in the comments.

Share

Using Google Reader to stay on top of RSS feeds

I just started using Google Reader this month to keep on top of websites that I visit frequently. Google Reader is a RSS feed aggregator – meaning, it keeps track of the latest news from many of the websites I visit in just one location. This is really handy, it means instead of checking lots of websites to see if they have any new articles, I can check Google Reader and it shows the new articles from all the websites that I’m interested in following.

It has a couple of useful features:

  1. Folders – Just like in GMail, you can assign feeds, and individual posts, to multiple folders. These folders help sort and sift through all your feeds. I’m using a folder sorting system originally described by Alan Rimm-Kaufman to help organize things and make sure I see the news I’m most interested in first.
  2. Sharing – At the bottom of each article in Google Reader is a button labeled Share. Pressing this button places the article on a personal RSS feed that can be shared with others. Here are my Google Reader shared items. I’m also subscribed to a few of my friends shared items. It’s interesting to see the things they share. I’ve discovered a few interesting RSS feeds this way.
  3. Discover – Google Reader keeps track of how many people subscribe to a particular news feed. With this data, Google Reader is able to offer recommendations of other feeds that may be of interest to you. The Discover feature uses my list of subscribed feeds to recommend feeds that other people, with my similar feeds, are subscribed to.
  4. Trends – Each time I read an article Google Reader keeps a record of it. Information about the articles I have read is summarized by the Trends feature. This feature allows me to see what percentage of articles I read from a particular feed, how many articles I read per day, how many new articles appear in a feed per day, and how many people are subscribed to a particular feed. This information helps me to prioritize the feeds according to how often new posts come out and how many of those posts I actually read.
  5. Starred Items – Find an article interesting and want to come back to it again? Star it. The Starred items feature works just like GMail. All starred items show up in a folder where you can view them later.

In addition to following news and technology websites, I’ve also been using Google Reader to follow interesting people on YouTube, Facebook, and for reading new articles on Google News.

Using the YouTube API, you can enter a URL that will retrieve an RSS feed of a user’s uploaded videos. You can use this to have Google Reader include YouTube videos as articles. The URL format is:

http://www.youtube.com/rss/user/[insert_username_here]/videos.rss

If you’re already subscribed to people on the YouTube site, you can also use Yahoo Pipes to follow all your subscriptions from one feed.

Facebook posts can also be added to Google Reader, as can status updates. Facebook status updates can be added to Google Reader by clicking the See All option for status updates, then subscribing to the Friends’ Status Feeds. Facebook has a help page for more information about getting updates via RSS.

Google News also provides RSS feeds for its content. In addition to the usual topics like Top Stories, Sci/Tech, and World; Google News searches can also be viewed via RSS feeds. I use this for keeping track of any news items related to topics of interest, like my work, or the small community that I live in for example. Try it, search for something in Google news. At the bottom of your search results will be a “Subscribe to a news feed for X in Google Reader” link. Any new news articles that Google finds related to your search will automatically show up in Google Reader.

All in all I’ve been happy with Google Reader. Having all my news in one location saves a bunch of time. And it even displays well on the iPhone.

Do you have a Google Reader shared items feed or, have any interesting news feeds to share? Post a comment below.

Share
Categories: Review Tags: feed, Google Reader, rss