eddorre

FedEx and the Magic Package

January 17, 2008 — 0 Comments

I recently purchased Office 2008 Home from Apple. When I went to check the delivery status, I found something strange. The package seems to have magical teleporting powers as it teleports between Oakland and California multiple times:

FedEx Magical Package

Version 4

February 26, 2008 — 0 Comments
  • Tagged with:

I’m on the cusp of releasing version 4 of my custom blogging engine. Version 2, 2.1, and 2.5 were all based on C#/ASP.NET code and then I did something which slowed me down significantly; I ported everything to Ruby on Rails for version 3. Honestly, the learning curve was steeper than I anticipated.

It’s not that Ruby and Rails are more complicated than C# and ASP.NET, it’s the fact that during that time, I did a complete platform change as well. All of my computers back then (including email servers, web servers and workstation) were all Microsoft-based.

I was using Windows XP with Visual Studio to write my applications, using Exchange Server for my email, and using Windows 2000 with IIS to host my web applications. You get the idea.

Then it all changed. Not sure what it was exactly, I think it was a number of factors, but I decided that I was going to develop Ruby on Rails applications and if I was going to do it, then gosh darn it, I was going to do it right! When I say right, I really mean developing on a Mac and using Linux based servers.

I basically threw away years of foundation and knowledge and started from scratch. It was tough but rewarding. In time, I hobbled together version 3 of eddorre.com with the earliest of the earliest Ruby and Rails code that I knew.

Even as I was writing version 3, I knew that I would eventually re-write it again and probably even from scratch. That’s exactly what happened. A number of reasons can be attributed to this. Version 3 is based off of Rails 1.1.6 which is horribly outdated. So much in the Rails world has changed including the milestone release of Rails 2.0 (and the paradigm of RESTful development).

In addition, my knowledge of Ruby, Rails, CSS, and Javascript have grown tremendously since I released the last version.

So I threw my old code (version 3) and started anew (again). Luckily, this time, I wasn’t changing platforms. There are more features that I want to import into the project, but for now, it’s almost done and close to release (probably sometime this week). And it’s a good thing too, now that I’m fairly comfortable with Ruby on Rails, there are some other projects that I’ve been wanting to work on. So, hopefully, I can shed the self-imposed mantle of “one trick pony.”

And now for the obligatory teaser image:

version4

How to Hose Your Vista Machine in Two Clicks

February 26, 2008 — 0 Comments

I just came across a huge, terrible nasty, bug feature in Windows Vista. I was attempting to download a program (.exe) file from an FTP link in my email.

Instead of just downloading the item, Windows requests to choose a program with which to open the .exe file with. It my case, it chooses to use Firefox to open it. Unfortunately, you cannot uncheck the setting “Always use the selected program to open this kind of file.”

Windows FOOBAR
If you click on the OK button, Firefox now becomes the application launcher on your system which means that your system is now borked.

The only fix that I found (actually a friend of mine found it for me) was a reg hack that puts everything back in place.

This kind of bug feature is completely egregious. Why oh why is this ever ok?

Solar Energy Meeting

February 26, 2008 — 0 Comments

I’ve always been interested in solar energy but I’ve never dug deep enough to understand the mechanics or the economics of it. Tonight, Dear GF and I are attending a free workshop that might be interesting; Basics of Going Solar at the Ecotrust building in downtown Portland. The summary of the workshop reads that at the end “…you’ll come away with basic knowledge about solar energy systems…”

Hopefully, the workshop will be illuminating (no pun intended) instead of being a sales pitch.

Update No sales pitch at all. It was actually very informative. Might do a write later about it. If you’re in the Portland area and want to know about solar energy, go the website above and take a look. Best of all it’s free.

Version 4 Released

February 27, 2008 — 0 Comments

I’ve come up for air after doing the upgrade. Remind me not to drastically change my database schema next time.

There are a few bugs that I see here and there will be addressed at a later date. For now, I’m going to bed.

A Good Intro to SQLite

March 07, 2008 — 0 Comments

While watching the iPhone SDK announcement yesterday, I noticed that SQLite has been bundled with the iPhone in what Apple calls Core Services. Most likely, the iPhone uses SQLite to store all of the user data such as contacts, phone calls, Mobile Safari Bookmarks, etc.

In addition to the iPhone, SQLite has been embedded with several applications and services that I’ve been using directly or high profile projects that I’ve come across. Some of those include Mac OS X software NetNewsWire (my RSS feed reader), SpamSieve (a client side anti-spam solution for OS X), Ruby on Rails, and Google Gears.

So, while SQLite has been on my radar screen for a while, I haven’t actually sat down for a primer on the program. That is until I came across the Google Video Introduction to SQLite a recorded talk with the author of SQLite, Richard Hipp.

It’s definitely one of the best intros to SQLite that I’ve come across.

I Still Love DST

March 08, 2008 — 0 Comments

This weekend is the start of Daylight Saving Time across most of America. Historically, modern Daylight Saving Time (DST) was introduced to allow for more leisure time during the summer months (as introduced by William Willet).

In the last 30-40 years, DST has been trumpeted as reducing energy costs by cutting the amount of electricity use in the afternoon hours. So prevalent was this opinion that the length of DST was increased by one month starting in 2007 by the Energy Policy Act of 2005.

A recent study purports that DST doesn’t actually reduce energy costs, but it actually does the opposite; it increases energy costs by as much as 4%. Any electricity costs that are recouped by less incandescent lighting are spent (and then some) by air conditioning cooling costs.

The news isn’t all bad for DST as it also concludes that advancing the clocks an hour increase leisure activities, reduces traffic collisions, reduces crime and helps with SAD.

Regardless of statistics, polls, and studies I know that I love DST and I’m overjoyed that it’s starting earlier (and ending later). I can remember, not too long ago, leaving work in the dead of night (5 PM) and being completely demoralized for the rest of the day. Traffic was horrible and forget about being active for the rest of the day. Of course, I’m a sun follower and always will be so I’m a little predisposed to DST.

With all of that in mind, I wanted to link to two comics (from We the Robots) by the brilliant Chris Harding (his About section is pure comedic genius especially the Biology portion) that recently made me bust up laughing. I promise, this has something to do with DST (or at least SAD).

SAD
Practical by Chris Harding

Practical
SAD by Chris Harding

Body in Motion

March 08, 2008 — 2 Comments

Last week, during my code sprint to release version 4 of my home grown blogging engine, I seem to have upset my upper back. Most likely this pain can be attributed to poor posture while sitting in front of the computer (which I was doing for 10 hours+ at the time). You know the pose; lower back out, shoulders up and rolled forward and head down.

The result of neglecting my body is sharp shooting pains whenever I look down. I’ve felt this pain before, usually from “sleeping wrong” or something like that. Historically, pain in my upper back or neck tends to alleviate itself in about 2-3 days.

Unfortunately, this time it seems as if I’ve aggravated my back more than usual. So much so that I went to the doctor just to make sure that there wasn’t another underlying cause other than poor posture. After a standard exam testing my range of motion, the doc sent me on my way with a new prescription in hand; Cyclobenzaprine.

Now I’ve never taken muscle relaxers before and when I first looked at the dosage I was a little disappointed. At 10mg, I thought this isn’t going to do much. Boy was I ever wrong. He might as well have given me voodoo zombie stuff because that’s what I turned into for two days; a walking zombie. Naturally, pain relievers and the like only target the symptom and not the cause.

With that in mind, I’ve started becoming more aware of my posture both at home and at work and correcting it when I notice myself regressing to my old habits. I’ve also been stretching more so that my range of motion isn’t as limited throughout the day.

A few years back, I was taking a Tae Kwon Do class and I enjoyed the warm up before the actual class started. Taking my previous experience with me I’ve turned to Sang H. Kim’s DVD Ultimate Flexibility: Stretching for Martial Arts which I try to do for daily stretching.

The workouts are separated into Easy, Moderate, and Intense with each one lasting approximately 20 minutes. I’ve done both the Easy and Moderate workouts and I’ve been extremely happy with the routines in each.

Dear GF, who has done the Easy workout with me, remarked that some of the techniques used in the DVD borrow heavily from yoga. I’ve been interested in yoga for a long time, especially after reading Mark Verstegen’s Core Performance_2?ie=UTF8&s=books&qid=1205026282&sr=8-2 books which borrow extensively from yoga (in fact, I’d say that a lot of it is yoga).

To get basic comprehension on the subject, I picked up Sage Rountree’s the Athlete’s Guide to Yoga_1?ie=UTF8&s=books&qid=1205026577&sr=8-1 (which now has a companion DVD) and I’ve been reading it from time to time. From what I’ve read, I’m been really pleased with the format and text of the book.

Hopefully with a pairing of martial arts stretching and yoga, I can avoid injuring myself even when it’s just sitting at the computer.

Traffic Shockwave

March 12, 2008 — 3 Comments

It’s official. Humans are terrible at driving in traffic. A recent study by researchers from several Japanese universities observed a phenomenon referred to as a “traffic shockwave” in a live traffic simulation. They setup a 230 meter circular track and had 22 vehicles drive around in a circle at 30 km/h (around 19 mph). At first, everything is free flowing and then, out of nowhere, “pockets” of congestion begin to appear. It’s amazing to watch (see Youtube video below).

The recent study lends credence to Dear GF’s theory that cars should be computer controlled. This would effectively remove the human element and lapses in judgment that cause “traffic shockwaves.” However, I think it’s unrealistic to think that humans would give up their control of driving altogether, but I do think that a hybrid system would eventually work.

The system would work very similarly to how driving works in the 2004 movie I, Robot. When you leave your house, the vehicle would be manually controlled. When approaching large metropolitan freeways (interstates and highways, etc.) an autopilot would activate and take you to your destination exit. Once reached, you would once again regain manual control of your vehicle and travel to your final destination.

For those that wish to rebel, there would still be the option of manually driving on the freeways…for a charge and it would be restricted to one or two lanes (I can’t imagine that anyone would want to drive manually on the freeways).

You can imagine the benefits of this type of system. Pollution and fuel reduction (the vehicle could be magnetically propelled) come to mind and of course there are the time savings by reducing traffic congestion. A 30 minute trip to work wouldn’t be so bad if you could watch a show, read a book, or play a game while the vehicle drove itself to your designated exit. It could be the perfect marriage between public transportation and driving. Combining the best of both worlds.

But let’s be honest, at this point that’s just wishful thinking and fantasy, but I’m sure that there are ways to increase the efficiency of our automotive transportation system.

Most of my commute to and from work takes me through the worst traffic in the Portland metro area, so I’ve recently become fascinated with traffic analysis; the hows and whys of how traffic congestion occurs and how it can be solved. So much so that I’ve added a set of books The Road More Traveled: Why the Congestion Crisis Matters More Than You THink, and What We Can Do About It, Stuck in Traffic: Coping with Peak-Hour Traffic Congestion, and 21st Century Highways: Innovative Solutions to America’s Transportation Needs to my Amazon wishlist to eventually read.

Coming from an IT world, where static values are usually frowned upon, I’m frustrated by the fact that freeways, bridges, etc. are still built with this mentality without giving a thought to the dynamic nature of traffic.

For example, Interstate 5 (I5) in North Portland has three lanes going north and three (sometimes it cuts down to two) going south. As people commute to downtown Portland in the morning, I5 south is a complete mess and in the afternoon, I5 north (as people commute home to Southwest Washington) is a complete mess.

One can easily imagine a dynamic system of traffic distribution that “takes away” lanes from an unused part of the highway and “gives them” to the part that needs it. Now, I understand that comparing packets and routers to vehicles and physical infrastructure is like comparing apples to oranges, but let me explain where I got this idea from.

Last summer, my family and I went to Vancouver BC where we did the normal tourist things. While coming back from Stanley Park, I drove us over the Lions’ Gate Bridge and I noticed that traffic on the bridge can be dynamically adjusted by a series of lights (red, green, and yellow). In fact, this actually happened while I was going across the bridge. When the lane that I was driving in started flashing yellow, I had to do a double-take. After a few seconds of confusion, it made total sense. My lane was being repurposed to allow cars to come the other way.

It would be interesting if something like this is being considered for the replacement of the I5 Interstate Bridge (the total cost is in the billions of dollars) that is scheduled to take place in 2010. Until then, I’ll just have to keep my sanity by listening to podcasts and music while going to and fro.

Lions Gate Bridge from Wikipedia

Mass Effect – Bring Down the Sky

March 13, 2008 — 0 Comments

I’m not sure how I missed this news when it first came out a month or so ago. Mass Effect, one of my favorite Xbox 360 games of all time now had a downloadable expansion pack called Bring Down the Sky. I just found out about it today as I was reading Penny Arcade. It includes about 90 minutes of gameplay and introduces a new race to the Mass Effect universe; the Batarians. All of this for 400 points (or 5 dollars).

According to the Mass Effect website, the plot for this expansion is as follows: “A batarian extremist group has hijacked a mobile asteroid station and set it on a collision course with Terra Nova. Only you can save millions of civilians before the asteroid completes its deadly descent.”

Now there is a catch, as Tycho from Penny Arcade writes: “The trouble with this content is that it can’t really be enjoyed by people who have beaten the game. I could go back, certainly, to some previous save, but unless I wanted to move on from there and beat the game again I’d lose anything I had earned in it.”

That seems a little short-sighted on the part of BioWare, but I’ve been itching to play the game again (and pick the baddest, biggest jerk in the universe this time) and this gives me an excuse to do just that.

Upper Back Stretching

March 26, 2008 — 0 Comments

Almost 3 weeks after I posted Body in Motion, I’m still experiencing upper back pain. The pain seems to be centered on the muscles and tendons most commonly referred to as the Erector Spinae and it’s significantly worse in the early morning.

Although the pain is still there, it’s not as severe as it was before. A combination of attention to posture and upper back stretching have seemed to lessen the pain.

I’ve found one technique on Howcast.com site that I’m really enjoying.

Although you can use a rolled up towel to do the exercise, I’ve found that using a foam roller (shown in the video) is more solid and can help to massage the back by gently rolling back and forth on it.

I’ve also ordered a Viniyoga DVD specifically targeted for the upper back, neck and shoulders. This is my first foray into any kind of yoga. Last night, I popped in the DVD and decided to give it a go.

Before you get to any techniques, there is an anatomy primer and Viniyoga primer that are interesting to watch (although you can skip them). After the primer, there is a tutorial section that goes through each technique and form in detail and finally there is the portion of the DVD that you follow along with.

Before I get to anything else, for some reason the DVD is not in widescreen format so on a TV like mine (Sharp Aquos) you’ll have bars on each side of the screen unless you adjust the aspect ratio. This is a minor niggle, so I’ll leave it at that.

The techniques appear solid and do quite a bit to target my specific pain points but as a beginner it seemed quite daunting and difficult to get down. It almost seemed mechanical at times and reminded me of the mental gymnastics that I perform while attempting to play golf; Put head down, bend your knees slightly, swing back and twist keeping you left arm as straight as possible – you get the idea.

In fact, I felt so awkward that I enrolled the help of Dear GF (a frequent practitioner of some form of yoga) to coach me through it.

The DVD isn’t bad, but it’s a bit more complicated than I thought. I’m sure that I’ll eventually get the techniques down and when I do that, it’ll help a great deal.

Using SSH Keys for Remote Logins

March 27, 2008 — 0 Comments

When I had Windows servers at home, I would use the Remote Desktop tool to remotely login and manage everything from my Windows workstation.

Now that all of my servers have been converted over to Linux, I use the time honored tradition of using SSH to login and manage everything from my Macs (iMac and MacBook). Although with 5 Linux servers, it gets quite tiring typing in your password to authenticate each and every time I want to connect. Above and beyond that, password-less SSH logins come in handy when you have backup scripts running or when you’re deploying applications using Capistrano.

You can avoid pitfall by using SSH keys that are generated on your workstation and then stored on your servers.

I should note that this method doesn’t make your systems more secure, in fact it makes security weaker. If someone were to get a hold of your private keys, they could automatically login to any servers that use this method! Use at your own risk.

As I’ve said, I’m using my Mac as a client (specifically OS X Leopard) so these instructions are written with that client in mind. With that being said, I’m sure that the instructions can easily be ported to Linux or *BSD with minimal effort.

Open up a terminal window and type in “ssh-keygen -t [rsa|dsa]”. You can choose either RSA encryption or DSA encryption. As to which one is better, that’s open for debate. For my application, either one is equally suitable. One thing seems to be certain in my cursory research; RSA key generation is slower that DSA, but RSA is faster when verifying. For the rest of the example, I’ll be using an RSA key pair.

Once you run the ssh-keygen command, it will start generating a public and private key pair. You’ll be prompted to save the private key, I would choose the default which would normally be something like this: /Users/[username]/.ssh/id_rsa.

After choosing the directory where the private key is stored, you’ll be prompted for a passphrase. This is the passphrase for the private key and as such you’ll want to choose a strong passphrase. Something like, “I wouldn’t vote for Hillary for all of the tea in China!” Again, make this as strong as possible and DO NOT FORGET IT!

Once that has been completed, you should have two files in the directory that you chose earlier; a public key (id_rsa.pub) and a private key (id_rsa).

This public key now has to be copied to the server. You can do this with one command: "cat .ssh/id_rsa.pub | ssh [username]@[servername] “cat >> .ssh/authorized_keys”. Since the public key hasn’t been copied, you’ll have to enter in your password for the remote server. This should be the last time that you’ll need to do that if everything has gone well.

One last thing, if you want a deeper understanding of encryption, decryption and public key cryptography the book, Cryptography Decrypted, is an excellent resource.

Presidential Salary

March 31, 2008 — 0 Comments

Politicians rarely surprise my be doing something inspiring. So, I was shocked to read that Lee Myung-Bak, the new president of South Korea, has promised to donate his salary to the poor during his entire five year term (his salary remains unknown).

That’s truly inspiring. The gesture reminds me of Steve Jobs, Eric Schmidt, Larry Page, and Sergey Brin only getting $1 for an annual salary.

An American president makes $400,000 annually for serving their country. In my lifetime, I’ve never known an American president that wasn’t already wealthy by the time that they went to the White House and I suspect that it isn’t likely to change in the future. Given that, I think American presidents (and perhaps some wealthy Senators and House members) should step up to the plate and follow Myung-Bak’s example.

Calorie Counter Application

April 03, 2008 — 7 Comments

Calorie Counter ApplicationDear GF and I have iPhones and she’s become increasingly addicted to the fact that she can access web applications online at any time (as long as she has at least EDGE access).

A couple of weeks ago, she was looking online for a calorie counting web application and she was frustrated by the fact that she couldn’t find something she liked. Since I have mad Google-Fu skills, she asked me to try to find something. Instead, I asked her what her requirements were and since they were simple enough, I offered to write an iPhone specific application for her in Ruby on Rails.

Even though the application is dead simple, I learned a lot this time around since I tried to follow the recommended practices defined by the Rails community from coding to deployment. I’ve still got some more to learn (does one ever stop learning? Maybe when you’re dead), but I’m becoming more and more confident in my Rails skills.

She’s been testing the application on my staging server for the last week and we’ve discovered some bugs that were pretty egregious. Now that I have those worked out, I’ve deployed the beta application at caloriecounter.eddorre.com.

Although the application was written specifically to be displayed on the iPhone, I’ve tested it using desktop browsers such as Firefox, Safari, and Internet Explorer 7 (IE 6 is dead to me – I won’t even test against it). With the exception of a CSS styling bug in IE 7, it’ll work just fine on your desktop.

In addition to to all of this, I’ve actually allowed open registration to the application so that anyone can use it. I’m actually quite nervous about this as no one has ever used my web software besides me. Apparently, it might get more use than I expected since Dear GF’s work is having some sort of Biggest Loser-esque challenge at work and several of her co-workers have expressed interest in using it.

One more thing, at this time, I’m hosting the application on my home server. If you decide to take it for a spin, please be patient with the poor box.

Spring Thunderstorm

May 25, 2008 — 0 Comments

In the Pacific Northwest, rain is almost a daily occurrence but this rarely comes in the form of thunderstorms. Growing up in the desert Southwest, I miss the power and emotion that a thunderstorm can bring. I miss the otherworldly yellowing of the sky as the sunset bounces off of thunderheads high up in the sky.

Last night, that familiar scene played itself out here in Oregon and Southwest Washington. I couldn’t let the beauty of the storm pass overhead without taking some photos of the clouds.

My favorite photo out of the series appears below. It’s actually a photo that was taken vertically instead of horizontally (the position of the camera), but I like the way it turned out when it’s rotated.

To see the entire set, go to my flickr stream.

thunderhead

Say It Isn’t So

June 11, 2008 — 2 Comments

Like many, when I first heard of the concept of Twitter, I was skeptical about the merits of the service. Ok, ok it’s more on the side of violently opposed than skeptical. I mean, we could already read the details of people’s lives on blogs, did we need more intimate up-to-the-minute updates in between blog posts? Is our attention span so diminished that we can only take the time to read information in 140 character chunks?

I could just imagine the monotonous minutiae that people would be “tweeting” about. I could literally imagine someone becoming a Twitter Shitter.

Then something happened that would change my mind completely. I started attending geek/tech social events in and around Portland and I met a ton of cool people most of which use Twitter in some fashion or another. After a while I observed that the community and the conversation that was held in person would continue and/or morph into a conversation in the Twitter-verse. So I created an account and started following people that I was getting to know at these meet-ups.

Ever since then Twitter has become increasingly useful. I think that I found it most useful at the wonderful WebVisions conference in Portland. Beyond the usefulness at conferences (where it first gained an absurd amount of popularity), I’ve discovered new TV shows via Twitter, learned about new local events, and I’ve even reduced my digg reading by a measurable amount. No reason to drink from the fire hose of news when your friends tweet about the stuff that you care about. It’s like a built in news filter.

It’s easy to get carried away with Twitter and follow thousands of people that you’ll never meet and you’ll never have a connection with (not that there is anything wrong with that). Honestly I’m not sure how one would keep up with all of the updates if that’s the route that you chose. For me, I’m starting small. Just following a select number of people here and there and increase when I feel like I have an attention surplus.

For those of you that are so inclined you can read my updates and follow me at http://twitter.com/eddorre.

XMPP and Ruby

July 11, 2008 — 2 Comments

Although I didn’t make it to Ezra’s RailsConf 2008 presentation on scaling Rails, I was highly interested in the topic and downloaded the slides immediately after they were available.

The big news from his presentation was the reveal of Vertebra which is billed as a Next Generation Cloud Computing/Automation Framework. One slide stood out and immediately got me thinking with the question XMPP is a realtime messaging protocol built fro IM/chat, great for communication between thousands of people, why not machines?

After a dealing with a couple of server failures at work where notification was less than satisfactory, I started mulling around the thought of using Ezra’s idea for a small scale XMPP agent that was used for server monitoring and command processing.

The result is just a small proof of concept that I put together for a recent lunch and learn demonstration. This simple XMPP agent logs into my XMPP server (I’m using Jive Software’s OpenFire) and sets its presence to available. It also immediately sends me a message saying that it’s reporting for duty.

I’ve implemented message handling in a FIFO manner with an array that acts like a queue. If you send the agent a message (using a standard XMPP client like Spark or Adium) it will reply with “Thank you for sending me the message {yourmessagehere}”. If you preface your message with command: then it will attempt to execute that command (provided that it’s in the allowed list of commands). The output of the command is then sent to the sender as an IM message.

Please remember that this is only a proof of concept and it’s not my intent to put this iteration into production.

So without further ado, the code.


require 'rubygems'
require 'xmpp4r'
include Jabber

class Agent
  
  def initialize
    user = JID.new('yourusernamehere/XMPPAgent')
    @password = 'yourpasswordhere'
    @client = Client.new(user)
  end

  def connect(server_name, port)
    #Connect to server sending username and password
    @client.connect(server_name, port)
    @client.auth(@password)
    
    post_connect if @client
  end
  
  def post_connect
    #Set default presence to available
    status = Presence.new.set_type(:available)
    @client.send(status)
    #Start a new queue array
    @queue = []
    register_callbacks
  end
  
  def disconnect
    @client.close
  end
  
  def register_callbacks
    @client.add_message_callback do |message|
      @queue << message unless message.body.nil?
    end
  end
  
  def send_message(recipient, text, reply=false)
    message = Message.new(recipient)
    message.type = :chat
      if reply
        message.body = "Thank you for sending me the message: " << text
      else
        message.body = text
      end
      @client.send(message)
  end

  def start_worker_thread
    worker_thread = Thread.new do
      puts "Started new worker thread"
      #Start a loop to listen for incoming messages
      loop do
        if !@queue.empty?
          @queue.each do |item|
            puts item
            #Remove the resource from the user, e.g., carlos@xmppserver/exodus = carlos@xmppserver
            sender = item.from.to_s.sub(/\/.+$/, '')
            
            #If the message included the line command: create a new command object and attempt to run it
            if item.body.include? "command: "
              send_message(sender, "I'll try to run " << item.body.to_s, false)
              input_command = Command.new
              command_result = input_command.run_command(item.body.to_s)
              send_message(sender, command_result, false)
            else
              send_message(sender, item.body.to_s, true)            
            end
            @queue.shift
            puts "Queue is now empty" if @queue.empty?
          end
        end
      end
      sleep 1
    end
    worker_thread.join
  end
end

class Command
  @@allowable_commands = %w{ ipconfig ifconfig iisreset ping dig }
  
  def run_command(command)
    #Strip the command part out of the string - we don't need it any more.
    command.slice!("command: ")
        
    #Create an array for the arguments
    arguments = command.split(" ")
    arguments.delete_at(0) # Delete the first index, this is the command itself without arguments
    arguments.each {|x| puts "Argument: #{x}"}
    
    #Loop through the arguments and delete them from the command string
    arguments.each {|x| command.slice!(x)}
    
    puts "This is the command after munging #{command.strip!}"
    
    if @@allowable_commands.include? command
      puts "#{command} is an allowed command"
      result = `#{command} #{arguments.join(" ")}` #Backticks are a shortcut for system("commandhere"). Join the arguments back in.
    else
      result = "#{command} cannot be run"
    end
    puts result
    return result
  end
end

bot = Agent.new
bot.connect("xmppserver", "5222")
bot.send_message("carlos@xmppserver", "Bot reporting for duty at #{Time.now}", false)
bot.start_worker_thread

Viewing BIND9’s Cache

July 14, 2008 — 0 Comments

I’m posting this mostly for my own benefit so that I don’t forget but I have a feeling that it might help some wayward folks. Ever time my DNS server does some weird negative caching, I want to view the cache but I can never remember the command to do so.

In order dump the cache out to disk, use the command rndc dumpdb (BIND 9) and ndc dumpdb (BIND 8). This will output a file to /var/cache/bind/named_dump.db (On Debian Etch that is).

Extending XMPP and Ruby

August 26, 2008 — 3 Comments

After writing up my XMPP Agent written in Ruby, my friend Billy wrote a comment about a similar system written by Michael Still the author of Practical MythTV. His system for controlling MythTV over XMPP is the gtalkbot.

Curious as to how he worked around some issues, I downloaded the Python source code and stumbled my way through it. I was struck by the fact that he used a plugin architecture that would allow other authors to extend the functionality of his original program.

After seeing that, I decided that I would try something similar.

Without worrying about the XMPP Agent, I set out to code a plugin architecture. In a directory I have the following files:

  • init.rb (should probably be called plugin_loader.rb or something more descriptive)
  • test.rb
  • /plugins (this is a directory)
    • network.rb (inside the plugins directory)
    • system.rb (inside the plugins directory)

The code inside the test.rb file is simple enough:


require 'init'

puts “This is the allowed command set”

puts ALLOWED_COMMANDS

The first line of the code, loads the init.rb file which does the heavy lifting. The init.rb file has a plugin class defined. Other plugins will inherit from this class.

The plugin class is defined as:


require 'find'

class Plugin
  
  attr_reader :allowed_commands
  
  def initialize
    @allowed_commands = %w{ iisreset }
  end
  
  def load_plugins(dir, name="/^[a-z]+.rb/")
    plugins = []
    Find.find(dir) do |path|
        Find.prune if [".",".."].include? path
        plugins << path if File.basename(path).include? ".rb"
    end
    
    plugins.each do |item|
      puts "Loading plugin => #{item}"
      #Load the file
      require File.join(File.dirname(__FILE__), item)
      
      #Extract the file name from the directory name (without .rb extension)
      file_name = File.basename(item, ".rb")
      
      #Create a new object and instantiate it and find the allowed_methods attribute
      c = Object.const_get(file_name.capitalize).new
      puts "Loading command set for plugin #{file_name.capitalize} "
      puts c.allowed_commands
      
      #Add it to the array for allowed_commands
      @allowed_commands << c.allowed_commands
    end
  end
  
  def run_command(command)
    #Strip the command part out of the string - we don't need it anymore
    command.slice!("command: ")
    
    #Create an array for the arguments
    arguments = command.split(" ")
    arguments.delete_at(0) #Delete the first index, this is the command itself without arguments
    
    #Loop through the arguments and then delete them from the command string
    arguments.each { |item| command.slice!(item) }
        
    if @allowed_commands.include? command
      puts "#{command} is an allowed command"
      result = `#{command} #{arguments.join(" ")}` #Backticks are a shortcut for system(yourcommand).
    else
      result = "#{command} cannot be run"
    end
    return result
  end
end

At the end of the init.rb file is the code that actually starts loading the plugins:


app_plugins = Plugin.new app_plugins.load_plugins("./plugins") ALLOWED_COMMANDS = app_plugins.allowed_commands

Now it’s easy to extend the test.rb script by instantiating a new System object (one of our plugins) just by this simple code in the test.rb file:

tester = System.new

I can then call methods defined in the System.rb file (shown below):


tester.test

System.rb file:


class System < Plugin
  
  attr_reader :allowed_commands
  
  def initialize
    @allowed_commands = %w{ set shutdown }  
  end
  
  def test
    "This is a test"
  end
end

Now all of this was just really another proof of concept to find out if it could be done. I’m happy with the results even though I’m sure that there is a better way of doing it.

Site Updates

August 28, 2008 — 0 Comments

Over the past few days, I fell in love with updating my blog engine again. I go through these cycles where after an update, I won’t touch it for a while. Then something comes along that I need to fix and I’ll update a whole bunch of stuff all at once.

This time I went in and added some new features, updates old pages, and fixed some bugs. One of the pages that had been published, but was not publicly accessible, is the changelog. A changelog is a simple log of changes that have occurred during a project that includes new features and bug fixes. This is the first time that it’s been publicly linked. I’ll keep updating this as I add features and continue doing bug fixes.

You can access the changelog from the updated About page which contains updated information about the blog URL name (eddorre) as well as information about the tools that I use. Someday there will be information about me but I haven’t figured out if I’m going to write (hard to write about yourself) or have someone that I know do it.

As my changelog mentions, I’ve added Twitter updates. This just simply lists out the last 5 updates that I’ve made in Twitter via a JSON call. If you’re curious there are full updates available.

I’ve also fixed a nasty bug (that I thought that I had fixed before) where the order of the comments were listed in the wrong order (latest comment first in the list instead of last).

All of those changes are visible to everyone but there are changes that aren’t available for everyone to see. The mostly involve the back end publishing part of the site. Those updates include shoring my Models by using Rails’ new named_scope options as well as including several helper methods here and there.

I’m proud of what I’ve accomplished considering that I work on this in my spare time.

Loading Twitter Badge

August 30, 2008 — 0 Comments

I’ve recently become a Twitter user and I’m starting to use the service on a more regular basis. Considering how much I’m using the service now, I wanted to integrate some of the messages posted there onto my blog.

The folks at Twitter have 3 badges for use with custom made blogging engines. The first two are Flash based and I ruled those out quickly. The third was based on HTML and Javascript. This option gives me the most flexibility as far as configuration was concerned so I chose to go that route.

The process of getting the Twitter badge/updates to render on my site is fairly simple. Include some HTML and the following Javascript files:


<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" 
src="http://twitter.com/statuses/user_timeline/eddorre.json?callback=twitterCallback2&amp;count=5">
</script>

Usually Javascript files are loaded from the HEAD section of an HTML file, but the Twitter page specifically suggests to move the Javascript lines to the bottom of the page. The rationale behind this is simple; if Twitter is down and the their Javascript files are in the HEAD section then your page won’t load! In theory, by moving the Javascript lines to the bottom of the page they will be activated last after your page has already loaded.

Unfortunately, different browsers render Javascript and the DOM differently and there is no guarantee that a failure of the Twitter service will result in your page loading. The solution is to wait until the DOM is fully loaded before including or calling those Javascript files.

With any modern Javascript library such as Prototype (it’s what I use), jQuery, YUI, etc., it’s simple to interrogate the DOM to find out if it’s been loaded or not. The solution that I wanted was to display a “loading” graphic while the Twitter updates were loading and once they were finished, then the “loading” graphic would disappear; a standard ajax-y interface.

My solution was to render the “loading” graphic, wait until the DOM was loaded and then append the Javascript to the end of the BODY element.

Here is my implementation:


//Wait for DOM to fully load
Event.observe(window, 'load', function () {
	loadTwitterJSFiles("http://twitter.com/javascripts/blogger.js");
        	loadTwitterJSFiles("http://twitter.com/statuses/user_timeline/eddorre.json?callback=twitterCallback2&count=5");

//Hide twitter_spinner div
$('twitter_spinner').hide();
});

function loadTwitterJSFiles(url) {
      var urlRef = document.createElement('script');
      urlRef.type = "text/javascript";
      urlRef.src = url;

      if (typeof urlRef != "undefined")
          document.body.appendChild(urlRef);
};

There were a couple of adjustments that I had to make in order for it to work right. First off, notice the second Javascript line that Twitter gives you. In it, it refers to & where my code just has the & symbol. I had to make this change because I noticed when using the appendChild method it would insert a double & and therefore breaking the URL.

The second thing that I had to modify was the original DOM checking mechanism. In the Prototype documentation it says that you can observe the DOM loading by the following:


document.observe("dom:loaded", function () {
Your code here
});

This never worked out for me as it would never display the “loading” graphic even while getting the updates from Twitter was slow. I’m not sure if it hid it immediately or not, but I changed it to the code above that waits for the “window” to load and it’s worked out for me.

So that’s it. This works in IE7, Safari 3, and Firefox 3.

Rolled Out Gravatars

September 03, 2008 — 1 Comment

One of the things that I’ve had in mind when I started coding this blog in Rails was to eventually support Gravatars otherwise known as Globally Recognized Avatars.

Before rolling out this feature, comments had a little astronaut next to the speech bubble for each and every individual comment. If you have registered your email and uploaded a photo with the Gravatar service, it will no longer display the astronaut icon and it will load the registered image. If you haven’t registered, your comment gets a default kanji image.

Making this change in Rails was actually pretty trivial especially since Michael Mayo posted a very nice tutorial not long ago on his blog.

I did make some modifications from the code that he posted.

One of the more prominent changes that I made was to split out the image creation from the just generating the URL.

For example, I have this first method in my application_helper.rb file:


def gravatar_url_for(email, options = {})
      url_for({ :gravatar_id => Digest.MD5.hexdigest(email.downcase), :host => 'www.gravatar.com',
                   :protocol => 'http://', :only_path => false, :controller => 'avatar.php',
                   :default => 'http://eddorre.com/images/visitor.png',
                   :rating => 'G'}.merge(options))
end

I convert the email address to lowercase letters with the downcase method because an MD5 of noemail@eddorre.com and NOEMAIL@eddorre.com are actually two different things. This way, there can be no error. One of the other settings that I’m passing in is a “default” flag. If you haven’t registered with the Gravatar service, I’ll just use the astronaut image that I have and finally I don’t want goatse photos or worse showing up on my blog so I make the rating a mandatory “G”.

Notice that the above method doesn’t actually generate an image tag, it will only generate a URL.

For that, I have a second helper method defined simply as:


def gravatar_image(email, options = {})
      image_tag(gravatar_url_for(email, options), :alt => "Author Image")
end

This is the code that actually creates the Gravatar image.

Now in my view code, I can do the following (where @comment.email represents a variable with the user’s email address):


<%= gravatar_image(@comment.email, { :size => 40 }) %>

And it will display the image correctly. I should note that Michael’s example lists a size in height and width and you’ll notice that I’m passing the size as just an integer. I believe that the height and width options have been deprecated in favor of the more succinct size option.

Did I Really Just See a Positive HFCS Ad?

September 07, 2008 — 4 Comments

In the past week or so Dear GF and I have seen two TV commercials that are pro HCFS; more commonly known as High Fructose Corn Syrup. You can watch the first one and the second.

In both ads there is a product (the first one uses some generic fruit punch and the second one a popsicle) that is being discussed between two individuals. They go something like this:

  • Person 1: You know that [product] has high fructose corn syrup in it.
  • Person 2: Yeah, and?
  • Person 1: Well, you know what they say about it.
  • Person 2: No, what do they say about it?
  • Person 1: Um….ah…um…
  • Person 2: Maybe that it’s made from corn and is perfectly fine in moderation?

Before fading to black there is an overlay that reads Corn Refiners Association followed by a prompt to “get the facts” by going to their website.

Anyone with half a brain that hasn’t been completely programmed and brainwashed by corporations can tell that this ad is horse shit.

First of all, the “in moderation” line is deceptive considering the increasing number of products (including breads, cereals, sodas, condiments and others) that include it. It’s hard to consume something in moderation when it’s practically in everything that you pick up. In order to get away from consuming it you’ll have to move to pricier “natural” brands which is out of the grasp of many American families (especially in these economic times).

Second, and most importantly, both ads use “Person 1’s” lack of in depth knowledge of HFCS as crutch. So let me get this straight. If I can’t explain why something is bad for me then it’s good? This is a play right out of the tobacco lobbyists playbook. They denied and probably still do deny that their products are harmful. Many people can’t explain why diabetes is bad and we all know that we don’t want it. Heck, many people can’t explain off the top of our heads why ingesting Liquid Drano is bad for you (other than knowing that it’s poison) but we know better than taking a swig of it.

It’s not a surprise that Corn Refiners Association would produce these ads. Word of mouth advertising is against them and so is popular opinion (even if the average person can’t explain why). They must protect their brand even if it isn’t good for people.

I just hope that people see these ads for what they are.

Extending XMPP and Ruby Part II

September 21, 2008 — 0 Comments

Last month I wrote the a post titled Extending XMPP and Ruby. The post dealt with incorporating a plugin system to be used with my XMPP script that I wrote about in the post XMPP and Ruby.

To summarize the goal of the XMPP Ruby script; it’s a lightweight XMPP (Jabber/Instant Message) agent that resides on servers. Using this agent, I can immediately tell if a server is up and running as well as pass it commands through my IM client and have it reply back to me with the output. To enforce security, the script had a set number of commands that it could execute.

This had the problem of not really being scalable or extensible. For example, in order to add allowed commands one would have to modify the actual XMPP script itself. Not good.

In order to rectify that, I authored the plugin system that dynamically loaded classes at start time. This made it possible for me to be able to instantiate any object from those classes and run the methods of those classes.

In the test script it worked fine, but when incorporated with the actual XMPP agent script it was still hobbled by the fact that if you wanted to instantiate a new object you’d have to modify the original script. Again, not scalable or extensible.

With this latest iteration, I have added the ability to dynamically instantiate objects based on plugins as well as the ability to call the methods of the object all from the IM interface.

figure1

Before we explore the code, let’s take a look at our file structure (pictured in Figure 1). Everything is contained in a top level directory titled xmpp_agent. There is an init.rb file which loads all of the plugins in the plugins directory which are: command.rb, iis.rb, network.rb, system.rb. Below the plugins, are the files test.rb and xmpp_agent.rb.

The test.rb file is a “scratchpad” file that I use to test functionality. It is not a unit test file. As the figure mentions, the command.rb plugin file is new to this iteration. This file is responsible for creating objects dynamically at runtime as well as dynamically executing methods from those objects.

Since running commands have been abstracted out to its own class, there is no need to have that resident in the xmpp_agent.rb file. That code has been removed from the previous incarnation (see XMPP and Ruby). Everything else remains the same in the xmpp_agent.rb file with the exception of a new require declaration at the top of the script; require ‘init’ – as this loads our plugins (see Extending XMPP and Ruby).

When you send the agent a message that is phrased like this (items in brackets are variables):

command: [plugin] [method name] [arguments]

It will create a new Command object and calls the run_command method.

The first thing that the run_command method does is it calls a command parser method shown below:


  def parse_command(command)
    #Strip the command part out of the string - we don't need it any more.
    command.slice!("command: ")
        
    #Create an array for the arguments
    arguments = command.split(" ")
    return arguments
  end

This removes the extraneous “command:” part of the IM message and returns the rest of the string to the run_command method which is defined below:


  def run_command(command)
    vars = self.parse_command(command)
    
    #Convert the first item in the array to a class
    begin
      class_name = Object.const_get(vars[0].capitalize)
    rescue Exception => e
      return "ERROR: " << e.message << ". Are you sure that the #{vars[0]} plugin is installed?"
    end
    
    #Remove the first item (class name) since it's not needed anymore
    vars.delete_at(0)
    
    #Get the method name and remove it from the array
    if vars[0]
      method_name = vars.delete_at(0)
    else
      return "ERROR: Are you missing the method name?"
    end
    
    #If there are more arguments left call remote method passing in args, else just call the remote method
    if vars[0]
      run_remote_method(class_name, method_name, vars.each {|x| "#{x}" })
    else
      run_remote_method(class_name, method_name)
    end
  end

Now that we have everything parsed like we need it, we call run_remote_method.


  def run_remote_method(class_name, method_name, *args)
    begin
      o = class_name.new
    rescue Exception => e
      return "ERROR: " << e.message << ". Can't create the object, is it in the plugin folder?"
    end
    
    begin
      o.send(method_name, *args)
    rescue Exception => e
      return "ERROR: " << e.message << ". Did you include this method in the plugin file?"
    end
  end

As you can see, we dynamically instantiate a new object based on the class name that we’re passing in. After the exception handling, we call the method of the new object followed by any arguments.

For example: Let’s say that I want my server to ping an address. Instead of logging into the server and running the ping command, I could use the IM client to tell the server to ping the address and give me the results. All I have to type into the IM chat window is the following: command: network ping -c2 eddorre.com. This will ping eddorre.com twice on *nix machines.

The script will dynamically instantiate a Network object (provided it’s in the plugins directory) and try to run the method ping followed by any arguments.

In order for this to work, the network plugin/class has to have a method for ping in it. Let’s take a look at the code for that:


  def ping(*args)
    command = 'ping ' << args.join(" ")
    #Execute the command and return the result
    `#{command}`
  end

From the code above, I have defined a method called ping which takes the arguments at the command line, appends them to “ping”, and then executes the command (the backtick symbols mean execute the command and return the result).

Now, I’ll admit, using IM as an interactive shell is sort of limiting, but it can be much more powerful. For example, let’s take a look at the IIS class. This class, would in theory, handle everything related to Microsoft’s IIS web server. Let’s say that we want to find out how many current anonymous users are on a specific web site on our web server. We can define a method to return that information via the IM interface.

For example, let’s say I call this from the IM interface: command: iis current_anon_users [website]

The code for the current_anon_users method is below:


require 'win32ole'

class Iis < Plugin
  def current_anon_users(site)
    wmi = WIN32OLE.connect("winmgmts:root\\cimv2:Win32_PerfRawData_W3SVC_WebService.Name='_#{site}'")
    wmi.CurrentAnonymousUsers
  end
end

The code is simple, use a WMI object to return the data using the built in performance monitor on the server.

Using this new extensibility, you would be able to send a message to an agent such as “record this show” or “turn on the lights” depending on what you wanted it to do. All you have to do is build the plugin for it.

Canadian Adventures – Part I – The Capilano Bridge

September 21, 2008 — 11 Comments

I’ve been meaning to post about this but I never seem to get around to it. In perusing my Flickr Photostream, I rediscovered my old photos from a recent trip to Canada.

This is the first part of that post.

Last year, my mom, sister, and niece came to visit our new home Vancouver, WA. After a couple of days chilling at home we drove up to the other, more well known Vancouver.

My sister, the architect of the trip, wanted to hit a couple of spots that included Stanley Park, The Capilano Suspension Bridge, and Grouse Mountain. Now, for those that don’t know me personally, I’ll get this right out; I’m terrified of heights. Well, that’s a misnomer really. I’m terrified of what happens when you fall from a great height. If I could fly under my own power then heights probably wouldn’t be as scary.

The Capilano Bridge was up first. We drove up to the parking area and headed toward the bridge area. As we walked up to the entrance, I started getting nervous. They made it seem so official and so final. As if “if you get past this point you have to cross the bridge”.

Capilano Bridge Entrance

I asked the gal that was herding lines of people, “Has anyone ever gotten halfway and then couldn’t make it the rest of the way?” I just imagined myself getting halfway out there, suddenly being paralyzed with fear, collapsing into a fetal position where I would wet myself, suck my thumb and whine incoherently until being rescued by park rangers. She looked at me incredulously as if the thought was inconceivable and simply answered, “No.”

Goaded by my family, we all paid and entered the park area. It seems that my paranoia about entering the park was largely unfounded. You could pay the money to enter and actually not go across the bridge at all. I was somewhat relieved. This could be my spot to chicken out and not cross the bridge. Before I made that decision though, I wanted to take a look at the beast. The first time I viewed it, it didn’t look that bad.

Capilano Bridge View 1

In reality, this is an optical illusion. The bridge actually looks like something out of Indiana Jones and the Temple of Doom. Witness a far away shot of the bridge!

Capilano Bridge View 2

Feeling somewhat encouraged by the first view of the bridge, I decided to cross and confront my fears. Upon setting foot on the bridge, the first thing that I noticed was that it swayed, a lot. Of course as a suspension bridge, this is a good thing. If the bridge was rigid, it would certainly snap in the face of mother nature but that didn’t help to allay my fears.

I steeled myself and continued. As I made my way forward the enormity of the situation (the bridge is 230 ft/80 m above the Capilano Canyon floor and has a 450 ft/150 m span) started taking hold and fear started to rush in. I could feel the blood rushing away from my face as I stood paralyzed on the span grasping both of the hand rails. I felt the bridge sway underneath my feet and imagined kids horse playing behind me and accidentally knocking me off to my death.

I considered my options. Turn around and head back leaving my family to wonder where I had gone, collapse in a pool of my own fear and urine, or keep going. I closed my eyes, took a deep breath, refocused and miraculously continued forward.

I made my way slowly all the while holding both hand rails with an eagle like grip until someone wanted to pass me in which case I gripped the right hand railing with both hands and stopped moving until they passed. Although it felt like a lifetime of anguish while crossing the bridge, I reality it probably took 60 seconds to move across the entire span.

Once I was over, I felt like kissing the ground but I was exhilarated by the fact that I had faced my fear, set it aside and accomplished the task at hand. It was definitely worth it for the resulting “treetop adventure” on the other side as well as a personal sense of satisfaction.

Moving from Subversion to Git & GitHub

December 08, 2008 — 0 Comments

Although Git has been making the rounds in social media for a while, it really caught my attention this year at RailsConf with Scott Chacon’s presentation; Getting Git.

After RailsConf and throughout the summer, I was determined to learn more about the fledgling revision control system but something always came up to squash that effort.

Luckily, Planet Argon uses Git exclusively for their version control system and it’s allowed me to learn some of the basics via my favorite learning technique; trial by fire.

In the few weeks that I have been working with Git I’ve been very impressed with how easy it is to get up and running. I’ve been so impressed that I decided to migrate away from Subversion and move to using Git and GitHub for all of my big projects (including this blogging engine).

WARNING: By following these instructions you are taking responsibility for what happens on your system. As with anything, your mileage may vary and I suggest you do a complete backup of your client machine and server machines.

First this is first; install Git. If you’re on a Debian Linux based machine you can install the Git package by running the following commands:

sudo aptitude install git-core git-svn

If you’re on a Mac, I suggest using MacPorts to install the software by running the following commands (after MacPorts has been installed)

sudo port install git-core git-svn

If you’re using a different OS, consult the Git install documentation.

Before I continue further, it’s important to understand my goal. I want to migrate everything from Subversion to Git and then dump Subversion. I do not want to keep Subversion at the end of this process. There are ways to bridge Git to Subversion just in case you can’t completely remove Subversion from your infrastructure but that’s not my intent.

With that in mind, if you have any uncommitted files from your Subversion repository, I suggest finishing up your work and getting all files committed before proceeding otherwise they won’t be available for Git.

First thing you’ll want to do is to identify yourself to Git so that when you make commits, it’ll know who you are. This is done by the following command (this can also be done on a per project basis but I’m doing it globally):

git config --global user.email your_email_here.com

Once that is finished, we’ll use git-svn to “clone” our Subversion repository. Basically, this checks out your entire project into a branch titled git-svn and then creates a new branch called master. Finally it merges git-svn to your master branch.

The command to run this “cloning” process is:

git svn clone path_to_your_subversion_respository_here

You may need to include “/trunk” to the end of your Subversion repository. Also, depending on the size of your project, the cloning process could take a while.

I’m paranoid, so I like to confirm that both the git-svn and the master branches are merged together at the end of the “cloning” process. First, make sure that you are in the master branch by running the following command:

git checkout master

Then merge git-svn into it by running:

git merge git-svn

You should be greeted with a message that reads “Already up to date.” Everything should now be in Git and you could theoretically be able to dump Subversion now. Obviously, a pragmatic approach would be to archive your Subversion repository on a backup device just in case anything bad happens.

I should note that Git is now running on your local machine and you can make commits to your local repository. This is obviously different from the Subversion client-server model and if this makes you uncomfortable you can certainly setup an origin server to push and pull content from. I chose GitHub primarily because it’s easy to use and setup. Once you are signed up with GitHub, create a repository and run the following commands:

cd existing_git_repository
git remote add origin github_repository_address
git push origin master

I should make a footnote here. Since my Subversion repository isn’t available on the Internet, I wasn’t able to use GitHub’s Subversion import feature. Feel free to use that feature if your Subversion repository is available on the Internet. That way you can skip the whole git-svn thing.

At this point, feel free to delete the git-svn branch as it won’t be needed anymore. You can do this by running the following command:

git branch -d branch_name

Now that you have installed Git, what now?

I would suggest reading the article Git for Designers

More resources:

GitCasts
git-scm.com

Blasting off on a Rocket Ship

December 07, 2008 — 2 Comments

It’s often said (and I wish that I could remember the exact quote) that in order to climb a mountain, you have to take 1000 individual steps. Over the past few years, I’ve been trying to climb over a mountain of my own; my attempted transition from working as a sysadmin to working with code as a web developer.

It’s been a long, arduous path with many days and nights sitting in front of my Mac trying to learn the ins and outs of a very fast moving target. There were times that I didn’t think that I would ever achieve my goals but there is a light at the end of every tunnel.

6 weeks ago, my hard work and determination finally paid off when I accepted a full time developer position at Planet Argon in the heart of Portland, Oregon.

I still can’t believe that I get to work on a Mac with my preferred web framework and programming language. Of course, these are just tools and even in the wrong environment the best tools won’t help you or make you happy. Luckily for me, the environment couldn’t be better. I work alongside a group of talented and funny individuals that make work seem…well not so much like work. I know, it’s cliche, but it’s true.

iPhone Texting Question

December 07, 2008 — 3 Comments

As of this writing, iPhone users have 4 different texting plans to choose from with AT&T. The first and probably the most nefarious is the “Pay Per Use” plan which will cost you $0.20 per text message. The second is the “200 Text Messages” plan that affords 200 text messages a month for $5. From there you can choose the “1500 Text Messages” plan that will cost you $15 a month and the “Unlimited Text Messages” plan that will cost $20 ($30 for a family talk plan) a month. These costs are in addition to any voice and data plans that have already been chosen.

Now that texting is more popular among US mobile users that phone calls (I’m certain that it’s been more popular in other countries for a while) it’s easy to see that this is a lucrative market for AT&T (and other carriers) to be in. It’s so lucrative that it’s netted carriers a total of 100 billion dollars globally.

Before we answer the question, “Why is texting so expensive?” we have to understand what a text message is. A text message, referred to in tech circles as an SMS message, is a text message that is either 160 7-bit characters, 140 8-bit characters (used for binary messages only) or 70 16-bit characters.

What does all of that mean?

A single text message is tiny, microscopic even, in the day and age of high speed data connections. On a 350GB drive (the standard size of a hard drive on a MacBook Pro), you could store approximately 2,348,810,240 text messages. Here is another example; a Lacuna Coil song (8 MB) is the equivalent of 57,344 text messages. If I were to use SMS to download a song (without a plan) it would cost me $11,469!

If you want a more detailed analysis of text messages costs, I would suggest reading the article The True Price of SMS Messages.

Once it’s broken down it’s easy to understand why users and Congress are asking the same question, “Why the hell is texting so expensive?”

One answer, put simply by the article The Rising Cost of Texting, is because it can be.

Enter the iPhone. With its custom applications and rich UI, many developers are surely thinking of making a replacement for the built in text messaging application; one that bypasses AT&T’s draconian text messaging fees. There is one problem. Right now, official iPhone applications that are created by developers cannot run in the background. Unfortunately, this stipulation cripples a text messaging replacement because unless the app is running, you won’t get notified that you have a message.

During WWDC, Apple created a resolution to this by allowing developers to a unified push notification service. This service will notify users when fresh data is available from an application that is not actively being used. These notifications will come in the form of counter badges, audio cues, and pop-up messages that look similar to text alerts.

With a background processing application, it’s easy to recreate the built in texting application while obviating the text messaging costs.

In October, Apple missed its self-imposed deadline for releasing this update to the iPhone but the update is surely coming and you can bet that developers will attempt to release a text messaging replacement and it would be a killer. Taking a look at the top paid applications on the App Store, most aren’t over $2.99. I could easily see a company releasing a text messaging replacement for $20. This may seem steep compared to the apps that are out there right now, but if you compare costs a $20 one-time fee is easily more affordable than $20 a month forever.

Of course the obvious questions are:

  • Will Apple even allow a text messaging replacement app to be allowed into the App Store?
  • If Apple allows an app, will Apple’s servers start crashing under the load of people moving away from the traditional text messaging applications?

Navigating the Command Line in Terminal.app

December 21, 2008 — 0 Comments

I recently switched back to using Apple’s built in Terminal.app (I was using iTerm previously) program for all of my command line needs. There are tons of keyboard shortcuts when you’re using bash but there are a few that are especially handy to have memorized.

  • CTRL-A: Goes to the beginning of the line
  • CTRL-E: Goes to the end of the line

Sometimes you want to get to the middle of the line instead of heading to the beginning or to the end. These will help:

  • OPTION/ALT-B: Jumps cursor back
  • OPTION/ALT-F: Jumps cursor forward

There is one caveat though. The first time I tried the OPTION key trick, the Terminal would just type in strange characters. In order to get Terminal to recognize the OPTION/ALT key as a command key you have to check the option for “Use option as meta key” in the preferences pane of the Terminal app. Once that is done, the Option key shortcuts will work.

Terminal Preferences

Thanks to Alex (aka @demonbane) for showing me this trick.

There are ton of shortcuts for the bash shell but these are among my favorites/most used.

Displaying Git Branch Name with Bash at Command Line

December 21, 2008 — 1 Comment

When you’re first introduced to Git, you’ll probably just be working in your master branch, but eventually you’ll want to test some experimental feature in your code base without disturbing the master branch. Git makes this a snap to do with the command “git checkout -b branchname”.

If you’re working on a few experimental features at a time, each with their own branch name, it gets a little confusing as to which branch you’re currently working in. Of course, you could just type in the commands “git branch” or “git status” but there is an easier way to keep track of what branch you’re actively working in.

Robby posted an excellent article titled Lighthouse tickets and Git branching that helps him and others at Planet Argon with their workflow during the day. By appending the Git branch name to the end of the command line prompt, he’s able to instantly recognize which branch he’s currently working in.

Unfortunately, he doesn’t tell you how he achieved that feat. After Googling for a bit, I came up with a solution that worked for me. NOTE: Robby is using the z shell (zsh) and I’m using the built in shell with OS X; bash. My solution works with bash and not zsh.

First, I created a .bash_profile file by running the following command from my home directory: “touch .bash_profile”.

Then I modified the contents of the file to include the following:


function parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
PS1="\h:\w \u\$(parse_git_branch)$ "

When I’m in a directory that isn’t source controlled via Git, the command line will appear normal:

skyrocket:~ carlos$

Otherwise, it will display the following:

skyrocket:~/work/eddorreblog carlos(master)$

Although I’m using the notation “hostname:working_directory username” you can modify it to your liking using the Bash Prompt HOWTO.