Archive for Uncategorized

Delta nightmare

I normally post only technical stuff on the blog but I had to rant about this nightmare on Delta that I had last night.

I was flying DL1152 from Honolulu(boarded on Oct 15th) to San Francisco with my wife and I had my worst flight experience ever right from getting my boarding pass to checking in to the flight. I had booked this flight at least 3 months in advance and our seats were not together. While getting my boarding passes at the gate, I checked with the ticket agent if she could put us together. She said that she has put my request down and will be calling my name soon. She never called our name, and every 20 minutes or so, when I would go to the counter and ask about the seats, she would reply: "I am working on it and I will call your name". In the meanwhile she kept on allotting seats to standbys and upgrading people. Then came the final announcement to board the flight. I rush to the ticket counter and ask the ticket agent, if she managed to get us a seat together and she replies, "Sorry sir, the flight is full and we cannot put you together". We were the last person to board the flight. I would have appreciated if she could have called my name and let me know that she won't be able to accommodate my request rather than me asking her all the time. Moreover, I don't know what Delta's policy is but I did see the agent accommodating requests from other people who were either standby's or checked in at the counter much later than I did.

Well, this was just the start of my nightmare. What ensued later, was the worst display of customer experience that I have ever heard of. I had two conversations with  two of  Delta's air hostesses.

1st conversation

I was walking down the aisle to my seat with my carry on baggage and was stopped midway by this hostess.

Hostess: I wonder how did the guys upfront allow you to bring your bag till here. The flight is full and there is no space in the overhead baggage cabin. You will have to check-in your bag.

Me: I have some fragile glass stuff in my bag. I am sorry I cannot check it in. Can you please help me find some space?

Hostess [continues to smile as if she did not hear/care what I said]: Sir, there is no space. You will have to check it in.

Me: Its not my fault that there is no space. I was held up by Delta's ticket agent for no reason and thats why I am the last one to board.

Hostess[keeps smiling and repeats] : Sir, you will have to check it in.

Me:  Ok, I will check it in but if something breaks, will you or Delta pay for it ?

Hostess[ keeps smiling ] : Sir in that case, I will have to put you in a different flight.

Me: I have booked my seat on this flight 3 months ago and I don't understand why you would suggest me to get a different flight when you overbooked the flight. I have two tickets and I don't get a single spot to put my bag in overhead cabin. If you cannot help me, let me walk down to my seat and see if I can figure out something.

2nd conversation

Now I walk down to my seat and put my bag under my seat. There was a very helpful couple sitting right next to me. They said that they have a bag that they could check in and that would allow me to put my bag in the carry on baggage. This is the conversation that me, the helpful co-traveller and the hostess had.

Co-traveller [ to the hostess ] : I have a bag that I can check in. Can you please check my bag in ?

Hostess[to the co-traveller]: Sorry no more check in bags. Also you don't have to worry, its not your problem.

Co-traveller [ to the hostess ] : Let me see if I can put my bag below the seat in front me. Then he can put his bag in the overhead cabin and sit a little comfortably.facebook

[ The co-traveller stands up, opens the cabin and tries to move her stuff. Hostess stops her ]

Hostess [ to the co-traveller]: You don't have to worry. Its his problem, let him figure out.

Hostess [ to me ]: There is a little space in the cabin, do you think you can fit your bag in there .

Me [ completely startled at this behavior ] : I am sorry but there is literally no space there for my bag to fit. Even you can see that.

[ In the meantime, my co-traveller just stands up and moves her bag to the seat in front of me. And then I put my bag in ]

All through the two conversations that I had with two different air hostesses, they cared the least about my comfort or the safety of my stuff. It totally pissed me off to see that even when my co-traveller was ready to help me, she was trying hard to make sure that it did not happen and I checked in my bag.

I always thought that Delta has one of the better customer experiences but yesterday's horror has disappointed me to such an extent that I dont think I will be flying Delta again.

Leave a Comment

Browser and NodeJS

I am writing a new javascript library and I wanted the library to work server side ( nodejs ) and in the browser. The main question that I had was how to design my code so that I can use the same files both with node and in the browser. I had a file called base.js which needed some utility functions from util.js .And I wanted my code to work in both the browser and with node.

Here is what my base.js looked like:


(function(global) {
var $b = global;
var $u = ( typeof exports !== "undefined" ) ? require('./utils.js').Utils : global.Utils;

......

})(typeof exports !== "undefined" ? exports : window );

This compiles fine in node. and then in the html I include utils.js above base.js and things work fine there too :)

Leave a Comment

Greasemonkey and avoiding the sandbox

Recently, I was trying to write a greasemonkey script to override the HTMLHeadElement.appendChild function in the browser DOM. Well, the reason I was trying to do that was to redirect a json-p call to my servers instead of the once mentioned in the webpage. Json-p works by dynamically adding a script tag to get around the cross-domain restriction policy of browsers. So, in most cases the script tag is added to the "" element. What I was trying to do was :


HTMLHeadElement.prototype._appendChild = HTMLHeadElement.prototype.appendChild;

HTMLHeadElement.prototype.appendChild = function(node) {
if(node.nodeName == "SCRIPT") {
var new_src = "http://foo.com/?...";
node.setAttribute("src", new_src);
}
HTMLHeadElement.prototype._appendChild.apply(this,arguments);
}

Well, this script worked on the Firefox console. But, it turns out it does not work as a Greasemonkey script. The reason being the greasemonkey scripts are run as part of a sandbox, and so do not have access to all the window elements. ( I wonder why ? ) . I even tried using "unsafewindow" , but even that does not work. You get access to HTMLHeadElement, but HTMLHeadElement.prototype is undefined. So, what now ?

Well, there is a simple workaround. Just modify your greasemonkey script to run the above code as part of the script in page. Basically, create a script tag, and add the abpve script as part of the script. Now since, this code will run in the context of the page and not in the context of the greasemonkey script, you will not have to worry about any restrictions imposed by the greaemonkey script. I basically put all my code in a separate js file and then loaded that into the script tag using greasemonkey:

var scriptElement = document.createElement("script");

scriptElement.setAttribute("src", "new_js.js");
scriptElement.setAttribute("type", "text/javascript");

document.body.appendChild(scriptElement);

And, there is another advantage to writing greasemonkey scripts this way, you separate out the main javascript from the greasemonkey script. And now you can keep updating your javascript and the users can keep getting the updated functionality without them re-installing the greasemonkey script again. Sweet!

Leave a Comment

install_name_tool to the rescue

I upgraded to Rails 3 and the mysql2 gem. And then:

balpreet-pankajs-macbook:youmash balpreetpankaj$ rake db:create
rake aborted!
dlopen(/opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.18.dylib
Referenced from: /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle
Reason: image not found - /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle

(See full trace by running task with --trace)

This is when install_name_tool came to the rescue. Apparently mysql2 gem is not using the full path to the library. And install_name_tool allows us to change dynamic shared lib names.

So, I did this:

balpreet-pankajs-macbook:youmash balpreetpankaj$ sudo install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle

And things worked :)

Leave a Comment

Skip Validations

How many times have you felt like skipping validations on a particular model while writing rspec tests ? Last night, I was trying to write rspec tests for one of my models which tested transactions of money between two users. My user model has tens of validations and I totally wanted to skip them all. I just wanted to test the functionality that the money was transacted between the two users correctly. Thats when I used some of Ruby's metaprogramming capabilities to skip validations. Once I was done writing my tests (phew !!) , I decided to turn this into a Rails Plugin, enter SkipValidations ( http://github.com/balpreetspankaj/SkipValidations/tree/master).

This is a very simple plugin. Just install the plugin and then use the skip_validations on any ActiveRecord::Base class and give it the list of models fr which you want no validations. Simple ! for example,

User.skip_validations(:user, :person) {SellRequest.match_requests }

will skip validations for both User and Person model while running the SellRequest.match_requests function. This plugin made my testing a lot more smoother. Hopefully this is useful for you guys too.

Leave a Comment

Facebooker: Creating an Iframe Application (Incorrect Signature)

I started developing a Facebook app for one of my existing websites.  Since, I already had a working website and I prefer normal html and js over fbml and JS over FBML and FBJS, I decided to take the IFrame route. While working with my app, I ran into this bizarre problem where clicking on any link after loading the facebook app, gave me an invalid Signature exception. After digging my way through the Facebooker (Rails plugin for Facebook app dev) code, I find that the expected signature is nil inside the "verify_signature function". Turns out you need to append all your links in a Facebook iframe app with the fb_sig params. So, I created a function in Application.rb and set it as a before_filter

before_filter :set_facebook_params
ensure_application_is_installed_by_facebook_user
 
protected
def set_facebook_params
@fb_params = params.inject({}) do |collection, pair|
collection[pair.first] = pair.second if pair.first =~ /^fb_sig/
collection
end
end

The above code will extract out all the fb_sig params from the url and store it in @fb_params. Now add this hash to every url that you create inside you Iframe. This was the fix that I came in the middle of the might, and I am sure this may not be the best fix. But this works. Let me know if there is another workaround.

Leave a Comment