David Bock's complete blog can be found at: http://blog.codesherpas.com

Items:   1 to 5 of 20   Next »

Thursday, February 9, 2012

I'm doing a lot of work lately using ActiveResource.  I wanted to get 'down to the wire' and see the traffic flowing over http... so a quick google search, and I found an entry I had written in 2008.  I love it when that happens!  So I'm reblogging it with a slight change to make it work in Ruby 1.9.

If you're using rails, create an initializer name active_resource_spy.rb and drop in this content:

class ActiveResource::Connection
  # Creates new Net::HTTP instance for communication with
  # remote service and resources.
  def http
    http = Net::HTTP.new(@site.host, @site.port)
    http.use_ssl = @site.is_a?(URI::HTTPS)
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
    http.read_timeout = @timeout if @timeout


    #Here's the addition that allows you to see the output
    http.set_debug_output $stderr
    return http
  end
end

All the data that flows over the http connection will be dumped to $stderr (the terminal you started the app in, unless you redirected it).



Thursday, June 30, 2011

I have been a customer of Tivo for a long time; I first saw one at a friend's house in the fall of 1999, and bought one for myself that Christmas.  Over the years I have owned somewhere around 6 tivos... Upgrading when the series2, series3, and most recently the Tivo Premiere came out.

Of course at its heart, the Tivo is a computer with a hard drive, and in the past 12 years I've had a few technical issues.  This story starts last month when my Tivo Premiere died a horrible hard drive death and needed to be replaced, and ends with a lesson on the importance of having a relationship with your customers.

I wasn't looking forward to replacing the Tivo - besides the call to Comcast (which is an entirely separate blog post), I know from experience that every Tivo is a blank slate...  I have to 'teach' it everything about me again... the shows I record, the stuff it should suggest for me, and so on.

Once I got the box set up, I was greeted with a "Welcome to Tivo" message in the Tivo's "messages and settings" that politely told me what I needed to know to use my Tivo, as if I was a first-time user.  I was slightly annoyed at this...  I thought to myself "Tivo *knows* who I am - this Tivo is linked to a lifetime account.  Why not have a welcome message that says 'Here's your replacement Tivo - we hope Rudy at the service center was able to resolve your issue.'?

Of course, Tivo could easily do a lot better than that suggestion.  My Tivo is linked to an account where I can schedule shows on the Tivo website; Why not back up my preferences there, and automatically download them to the new tivo?  Why do I have to set up, yet again, things like "Record episodes of Phineas and Ferb off of DisneyHD"?  I'm not asking Tivo to back up tons of data - not the actual shows, just the 'metadata' about my shows, my thumbs up and down ratings, the premium channels I subscribe to, etc.  This can't be more than a few hundred kilobytes. (I would think they would be interested in that data too - wouldn't TV executives PAY to know how many people gave a TV show a thumbs up vs. a thumbs down rating?).

A week after I set up my replacement Tivo, I received a new message that says "You may have noticed extra recordings that you didn't request - these are Tivo Suggestions".  This reminded me how annoyed I was...  "Yes, I know you suggest shows to me - you've been doing it for ELEVEN YEARS...  DON'T YOU KNOW WHO I AM?!?"  I began to get the feeling that Tivo, as a company, doesn't care that I'm a loyal customer.  They should be sending me a message that says "Its been a week and we see you're recording your preferred shows again.  We're happy everything was set up properly with your cable company".

Another week went by and I got another message "Have you ever missed an episode of your favorite program?  Learn how to set up a Season Pass".  Sigh.  Perhaps you didn't notice, but I've already set up, like, 70 of them?  Remember me?  I was mildly annoyed at having to set everything up - but weeks later, Tivo's naive attempts at customer contact are simply reinforcing the negativity of the whole experience.

Now, I'm not expecting Tivo to greet me by name when I call their service department, or send me cookies at Christmas time, but they can do a lot better than this. As a software engineer, I know the things I'm suggesting are next to trivial to implement.  I'm also quite sure the Tivo engineers have a list of user stories like these sitting in an idea tracker somewhere...  The only reason Tivo, as a company, would not do these things is because they haven't been made a priority.

Thats right, Tivo, as a company, has not made it a priority to have a relationship with their customers.

As much as I love my Tivo, I think they survive because their biggest competition is from cable-proprietary DVRs... and we all know the track record of customer relationship management cable companies typically have.  Tivo should be thankful Apple didn't make the AppleTV a DVR... I don't think they could survive the competition.  If Apple made a DVR, I'm sure it would be sending me tweets: "Hey Dave - Neal DeGrasse Tyson is going to be on Letterman tonight - don't worry, I'll record it for you."

You know what would have been the ultimate experience?  A message on my tivo 2 months ago that said "We've noticed your Tivo is beginning to have issues with its hard drive.  We've backed your schedule data up and scheduled a hardware replacement under warranty.  call 1-800-get-tivo to schedule your return and replacement".  Upon plugging my new Tivo in, a message like "We've downloaded and rescheduled your shows and noticed you've inserted your cable card.  You now need to call 1-800-comcast, and give them this MAC ID and Card Pairing Code to have them reactivate your cable service".  Every piece of hardware and data is available to make that possible; all thats missing is software.


Is there a lesson here?  Yes!  We can trivially use the data we have on our customers to improve their experience, and make it seem like they have a more personal relationship with a big faceless company.  How can you improve your relationship with your customers?


Monday, June 20, 2011

This is a small complaint about Rails 3.1, but its one I'm surprised I'm able to make at all.

If you have been following the evolution of Rails, you know that years ago the framework adopted REST as one of its core principals (well, restful concepts - I'll leave it up to others to debate/defend the true purity of the implementation). One of the core ideas behind REST is the idea that a url represents a unique resource, and that the mimetype/filename extension is used to negotiate the format that gets delivered. for instance:

http://www.davebock.com/resume.html

and

http://www.davebock.com/resume.pdf

should be the same underlying *thing*; what gets transferred is a representation of the thing in the format requested... in this case, my resume, as either html or pdf.

Enter the new Rails Asset Pipeline, which is a fantastic piece of work in general. In diving in and playing with it for the first time, I was trying to wrap my head around some of the conventions. I generated a new rails project with v3.1rc4, and I hadn't added any of my own content yet. I was looking at how everything under assets directory seems to be served up under the /assets/ url without much respect for the directory structure underneath it. Out of the box, rails gives us several files that have default contents. For instance:

http://localhost:3000/assets/application.css

and

http://localhost:3000/assets/application.js

Compare that to my first example above. These are the same url, but with different extensions - different "content negotiators"... but they aren't serving up the same thing at all. One could argue that they are two things designed to work together, but I don't think thats enough - the principal is violated - these are not the same thing, just in different formats, these are really much different things - one being code in the Javascript language meant to be used by your web application, and the other being a css file that contains all of the view/layout of your app. the browser isn't saying, "Give me that same information, but in the .js format", the browser really is requesting a different asset.

I like the asset pipeline, and I like the convention of treating all of these things as "first-class citizens" in their own assets directory under /app instead of as "a bunch of stuff" that happens to live under the /public directory - but I don't think this first-class citizenry has gone far enough - why aren't these things further scoped by the /images, /javascripts, and /stylesheets directory when referenced via url?


Monday, May 30, 2011

I was just doing some routine maintenance on our servers when I had to use some command-line judo so solve a small issue and thought I'd share it.  Not for the particular solution, but for the path of thought that led to the solution; that is, demonstrating the power of the unix/linux command shell.

On a server running CentOS 5.6 (a linux distribution), I ran the command to perform routine maintenance and got an error upgrading a package named "shadow-utils-4.0.17-18.el5_6.1.x86_64".  To make a long story short, I realized it was failing because a file it wanted to update was set to be 'immutable'...  that is, a security tool I ran modified a bunch of files that are routinely hijacked by viruses and made them unmodifiable.  This makes the machine a little more secure, but this also means the updater can't modify them either.

I found the unmodifiable file and using the 'chattr' command, made the file modifiable (with the intent to set it back to be unmodifiable later).  I ran the updater again, and it failed on yet another file.  I did the same to that file, tried to update, and ran into a third.

I stopped and thought to myself "there could be dozens of files I'll have to manually set and restore for this process... and it'll be prone to error... there has to be a better way".

I realized all three files I had to modify so far were in the /usr/sbin directory.  This makes sense - all the shadow utilities I was updating were tools for the system administrator to run.  So I made the assumption that all the files that were going to need to be set and reset were in this directory.

So I reset the files I had manually modified so far, and dumped the contents of the extended permissions to a file:

lsattr /usr/sbin > sbin-results.txt

That uses a feature of the shell called 'redirection'...  the '>' symbol says "take whatever this would normally dump to the screen, and dump it into a text file with this name instead".  So now I had a record of the settings I was going to have to restore after my update.

Next, I ran this command to reset all the permissions to a modifiable state:

sudo chattr -i /usr/sbin/*

'chattr' is the tool to 'change attributes', and '-i' means 'remove the immutable setting'

I was then able to run 'yum update' and have my update succeed.

At this point I had some work to do.  I could have manually gone through that text file, found every immutable file, and manually applied the immutable setting back...  but that might take a long time *and* be error-prone.  Is there a way I can have the computer do that for me?

First, lets use 'grep' to get a list of all the files that were originally set to be immutable:

grep '\-i\-' sbin-results.txt

and we get the output:

----i-------- /usr/sbin/irdadump
----i-------- /usr/sbin/pwunconv
----i-------- /usr/sbin/grpconv
----i-------- /usr/sbin/clockdiff
----i-------- /usr/sbin/useradd
----i-------- /usr/sbin/sys-unconfig
----i-------- /usr/sbin/tracepath6
----i-------- /usr/sbin/irdaping
----i-------- /usr/sbin/adduser
----i-------- /usr/sbin/grpck
----i-------- /usr/sbin/pwck
----i-------- /usr/sbin/usermod
----i-------- /usr/sbin/findchip
----i-------- /usr/sbin/irnetd
----i-------- /usr/sbin/groupdel
----i-------- /usr/sbin/irattach
----i-------- /usr/sbin/ping6
----i-------- /usr/sbin/chpasswd
----i-------- /usr/sbin/arping
----i-------- /usr/sbin/usernetctl
----i-------- /usr/sbin/pwconv
----i-------- /usr/sbin/dongle_attach
----i-------- /usr/sbin/tracepath
----i-------- /usr/sbin/groupmod
----i-------- /usr/sbin/grpunconv
----i-------- /usr/sbin/newusers
----i-------- /usr/sbin/userdel
----i-------- /usr/sbin/groupadd

looks good... thats not a huge list as I feared, but that is still going to be a lot of copy and pasting, and error prone to do by hand.  In order to get closer to automating this, I need to extract just the filenames from that list.  Here a tool called 'awk' is invaluable:

grep '\-i\-' sbin-results.txt | awk '{ print $2 }'

gives me the output:

/usr/sbin/irdadump
/usr/sbin/pwunconv
/usr/sbin/grpconv
/usr/sbin/clockdiff
/usr/sbin/useradd
/usr/sbin/sys-unconfig
/usr/sbin/tracepath6
/usr/sbin/irdaping
/usr/sbin/adduser
/usr/sbin/grpck
/usr/sbin/pwck
/usr/sbin/usermod
/usr/sbin/findchip
/usr/sbin/irnetd
/usr/sbin/groupdel
/usr/sbin/irattach
/usr/sbin/ping6
/usr/sbin/chpasswd
/usr/sbin/arping
/usr/sbin/usernetctl
/usr/sbin/pwconv
/usr/sbin/dongle_attach
/usr/sbin/tracepath
/usr/sbin/groupmod
/usr/sbin/grpunconv
/usr/sbin/newusers
/usr/sbin/userdel
/usr/sbin/groupadd


looking good...  notice the "|" symbol in the command - this is called the 'pipe' symbol, and with it, I can take the output of one command and feed it to the input of another.  the command above now means "take the file with the previous directory permissions in it, find me every line that contains a file set to be immutable, and print out just the filename".

We are getting very close now...  for every one of those files, we now need to run the command:

sudo chattr +i <filename>

so we can restore the immutable setting.  We can use the command "xargs" to do that, again, with the pipe command:

grep '\-i\-' sbin-results.txt | awk '{ print $2 }' | xargs -l sudo chattr +i


and voila!  All directory settings are restored.  One line, no manual mistakes, and it took less than a second to run.  that saved me enough time to write this blog entry.


This is such a useful mechanism I'm now going to turn it into some command line utilities.  Imagine running into this situation again and being able to say:

sudo unlock-immutable /usr/sbin
yum update
sudo relock-immutable /usr/sbin

and having that just work.  By passing in the directory, I could choose to reuse this on directories like 'usr/bin' should that be the cause of my pain next time.  Maybe thats my next blog entry, or maybe I'll just leave that as an exercise for the reader.

I'm hardly the first person to use grep, awk, and xargs in a command line - I do things like this a lot, and so do many sysadmins...  but I see far too many developers who don't think this way - they look for a button in their IDE, and when there isn't one, they spend far too much time and effort on manual, error-prone attempts.  Spend the time to learn a half dozen command line tools that can be chained this way... make the command line your IDE!


Saturday, April 16, 2011

Dear Restaurant owner,

I want to eat at your restaurant, but I need to find you first. You need a website. And not just any website. It has to work on a mobile device. If not, you might as well not exist anymore.

In the past few months, I have been out with my friends several times, spontaneously decided to get a lunch, dinner, etc. and had a bad experience with a restaurant's website.

Today's typical dining experience starts with a bit of research on a phone, looking for a menu. I start with the maps app on my iPhone, search for something like "Indian" or "Italian" around my current location, find a restaurant, go to the website, and I'd greeted with a message like "you must install Flash version 9 or higher" if I'm lucky enough to find your website at all.

You know what the cool kids call that? EPIC FAIL.

Even if I can see the website, I'm more likely to find a picture of the owner's family as if they are slaving over a hot stove, the history of the restaurant starting with the owner's mother immigrating in 1977, or a stock photo of a slice of pizza. If there is a menu at all, its an out of date pdf file I'm struggling to view on my tiny screen.

If you care about your restaurant, you should want your customers to find you.

What information should be at their fingertips?

When visiting a restaurants website from my phone, I want:

  1. location (including phone number)
  2. hours
  3. menu

Anything else is just noise on a mobile phone... If I'm planning a catered event, I'll do that from my computer.

But I bought a package deal...

Yes, I'm aware that ground-up website design can be expensive, and restaurants often fall for the "Website for $29.95 a month" marketing ploy, where you get a "billboard-at-a-url" and a scanned menu. You are losing out. You need a real website.

Here's why:

Customers can find what they are looking for

You wouldn't imagine not having a sign outside your restaurant - a website is the same thing to the person actively looking for you. Restaurants think nothing of printing thousands of folded menus and sticking them on every car in a parking lot or every door in a heighborhood. Your website can have a far greater reach than that, and with immediate impact.

you can have a CMS to keep the menu up to date

For most restaurants, the menu on the website is like a time capsule. Dishes come and go... prices change... why shouldn't your website reflect that? With a content management system behind your menu, you can log in to update prices, add specials, etc. Why shouldn't your website be able to tell people what the soup of the day is?

You can tailor your SEO strategy

Try this: Put the name of your city and the type of food your restaurant serves into Google. (If you are in a big city, try your zip code). Is your restaurant's website on the first page? It should be. If you put in the name of your restaurant, are you the first result? If you're not, the first result is probably something like a restaurant review - and you have no control over that! Your worst customer could be the first thing people learn about your restaurant.

With your own website, you can easily influence how search engines view you. That is a topic larger than this blog entry though - its called 'Search Engine Optimization' or 'Search Engine Marketing'.

Further, by having your website as a real website (as opposed to flash or pdf), all your dishes become keywords Google can index. Maybe I'll find you because I searched on "Vindaloo" or "Pad Thai". All those words are pure SEO gold.

You can target your market more effectively

Visitors to your website can be tracked more closely than cattle with tags in their ears. Are most of your visitors coming from a particular neighborhood? Maybe thats the place to target with your door hangers. Is there a neighborhood thats not visiting? Send them a coupon for a free cheesy bread.

Ok, so how do I do it?

I'm not trying to sell you anything here - in fact, our typical projects are much larger than restaurant websites. I just want a better dining experience, so I'm offering you some technical advice:

Use 'Open Technology' standards

Make sure your website firm designs with html/css/javascript. Anything that requires a browser plugin to use (flash, Java, and most likely pdf), are non-starters for your marketing purposes.

Make sure your website looks good on small devices

I'll spare you most of the technical details, but with the kinds of tool we have today, a good website design scales down to work on phones, and scales up to work on big screens. On big screens, sure - show me your family in the kitchen. On my cell phone, echo the design with logos, fonts, and colors, but just give me the menu, hours, and location.

Search Engines are your best marketing tool

You don't need to hire an expensive SEO consultant - in fact, I think that most SEO consultants are the equivalent of Internet Snake Oil. Instead, just make sure your design firm eats and breathes the advice in Google's SEO starter guide. From your business' perspective, you should read a book like Search Engine Optimization (SEO): An Hour a Day or Internet Marketing: An Hour a Day to figure out how you can best market your restaurant.

Thats it! I hope you find this advice useful. Remember... I want to eat your food, I just need to be able to find you when you're just down the street.


Items:   1 to 5 of 20   Next »