Tuesday, April 9, 2013

Full Stack Developer Retires MacBookPro for Ubuntu Laptop

Since I began developing with open source technologies in 2007, my computer of choice was the MacBookPro (MBP).

The MBP continues to be a great system for developing open source software, but at this time, when I started looking for my next development workstation, speed, service and value were the leading factors, and it made more sense to stop working with the MBP and start working on a laptop that doesn't glow Apple.

I will miss the MBP's glowing keyboard, and I will miss the magnetic click of the power adapter. However, I will not miss needing to drop $80 for a new adapter after my daughter decides to suck on it like a chew toy.

AppleCare is a fantastic service plan that I have utilized to keep the MBP in tip-tip shape in the USA and Costa Rica. Now, I'm living too far away from an Apple Store to get a F'ed system in the hands of a "Genius." My town has a sharp computing community and would not have a hard time serving any issues on a generic system.

The features I wanted in my new system were a Solid State Hard Drive for fast disk read/writes, and a monster dose of RAM (16 Gig). The MBP with retina display offered these features, for a hefty price. Adding the AppleCare support plan gave me pretty expensive system that I would need to dump in three years when the warranty expired.

I've learned the lessons on servicing computers in Costa Rica and know the risk of carrying around a $2K system. It's time for something new.

I'm empowering myself to continue the journey in open source software and Linux operating systems. The seven years that I have been working with Linux hosting environments has given me the chance to learn how to be productive in the Linux environment. I am excited to add to that knowledge and offer clients more "full-stack" skills. Developing on a Mac and managing production environments are two different animals. Bringing the practices of maintaining secure production systems back to the workstation is clearly the new win-win to work towards.

Sunday, January 13, 2013

Dreamhost Server Blocking Emails From Getting Sent

For anyone who has a rails project hosted on Dreamhost that sends emails this might affect you. Some time recently Dreamhost updated their security setting for sending mail through their SMTP servers and now require plain authentication to send mail through your localhost.

If your error log looks like this, you definitely need to make sure you are getting authenticated to send email.

Dec 28 17:51:16 servernuts postfix/smtpd[57430]: NOQUEUE: reject: RCPT from localhost[127.0.0.1]: 554 5.7.1 : Recipient address rejected: Access denied;
In your rails app environment files you can enable authentication:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "localhost",
:port => 587,
:domain => 'foobar.com',
:user_name => '',
:password => '',
:authentication => 'plain',
:enable_starttls_auto => true }

I am not a fan of this update since one would have to put their shell account credentials in a codebase. This is a good reason to check out something like postmarkapp or sendgrid.

Saturday, January 12, 2013

Problem Solving: Thread a 1/2 in. tube

Problem solving is an art. Here's a problem I recently faced outside of the software engineering space, but I felt it was worth posting here.

The problem: Running copper wire through 90 meters of 1/2 tubing

Background: I decided it was time to extend my electricity line to a structure about 60 meters from the source. With 120 meters of copper wire in hand I set off on the challenge. To protect from weather, I wanted to make sure the wire is insulated in a plastic tube. It became apparent rather quickly that the cable wasn't going to walk itself through the tube.

The solution: +1 to my neighbor who happened to be walking by and gave the suggestion that ultimately did the trick.

Materials:
100 meters of fishing line
Small piece of foam that with a little squeezing will fit in the 1/2 in tube
100 meters of all purpose twine
Water source (hose will work)
Sharp piercing object that will pierce tube

  1. Start off by unraveling the tubing
  2. With your piercing object, make a small hole about 2 inches from the high end of the tube. My hole was small enough to pass the fishing line through, but small enough that a pencil wouldn't enter
  3. Put the tip of the fishing line through this hole and pull it out the closest end of the tube
  4. Tie off the sponge
  5. Push the sponge towards the low and end apply water source
  6. Watch the fishing line get pulled into the tube with the sponge fighting the force of the water
  7. Your sponge will eventually come our of the other end of the tube and you can tie off the fishing line the the all purpose twine and feed the twine through the tube by pulling on the fishing line that the water fed down the line. I had to run the twine because my fishing line was pretty light weight and probably would snap if the copper wires were tied off to the line
  8. With the twine capable of resisting more force, tie it off of the copper cables and pull the suckers through.

    ----------------------------
A     .                            B
    ----------------------------

Monday, January 7, 2013

Suppress RestClient gem Exceptions

This is a little rant on how the RestClient gem handles 400 'bad request' responses. I often use RestClient to handle calls to third-party APIs. I recently hit a use case that had me a little stumped.

I was working on a task that required me to hit a few endpoints on the plivo.com API. No biggie. I set up a RestClient post like normal and expected to get a response back.

ruby-1.9.3-p194 :023 > cp = {"to"=>"121212121212", "from"=>"12121212121212", "answer_url"=>"http://example.com/AnswerUrl", "answer_method"=>"GET", "hangup_url"=>"http://example.com/HanguUrl", "time_limit"=>10}
 => {"to"=>"121212121212", "from"=>"12121212121212", "answer_url"=>"http://example.com/AnswerUrl", "answer_method"=>"GET", "hangup_url"=>"http://example.com/HanguUrl", "time_limit"=>10} 
ruby-1.9.3-p194 :024 > call = RestClient::Resource.new("https://api.plivo.com/v1/Account/XXXXXXXXXX", "XXXXXXXXX", "XXXXXXXXXXXX")
 => https://api.plivo.com/v1/Account/XXXXXXXXXXX
ruby-1.9.3-p194 :025 > r = call["/Call/"].post cp.to_json, :content_type => 'application/json'

RestClient::BadRequest: 400 Bad Request
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/abstract_response.rb:48:in `return!'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/request.rb:231:in `process_result'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/request.rb:178:in `block in transmit'
        from /Users/user/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/net/http.rb:745:in `start'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/request.rb:172:in `transmit'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/request.rb:64:in `execute'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/request.rb:33:in `execute'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/rest-client-1.6.7/lib/restclient/resource.rb:67:in `post'
        from (irb):25
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
        from /Users/user/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start' 

The problem was that instead of giving me a readable response, it gave me a RestClient exception. Shouldn't a REST-Client return a verbose response regardless of that the http status sent? It should be noted that in the case I was working with, the 400 bad request response also returned a message that would help users get a grasp of the problem, but in this case, RestClient just chokes and never passes the returned response message on. I added a 'puts' on the response instance in the request.rb to check out the body of the response and sure enough I saw the message that I was looking for.

{ 
  "api_id": "0f00e214-62d1-11e2-a3f8-22000abc1360",
  "error": "insufficient balance"
}

From the RestClient request.rb source:

# Return the default behavior corresponding to the response code: 
# the response itself for code in 200..206, redirection for 301, 302 and 307 in get and head cases, redirection for 303 and an exception in other cases

Don't get too hung up on not seeing your 400 responses with RestClient. I did a little digging around and it turns out that you actually can disable the exceptions by passing a block with the request.

call["/Call/"].post(cp.to_json, :content_type => 'application/json'){|response| response }
 => "{\n  \"api_id\": \"7def1e60-62d7-11e2-a3f8-22000abc1360\",\n  \"error\": \"insufficient balance\"\n}" 

This is why we read the code :)

Tuesday, January 1, 2013

Mountable Deals API for Rails 3 Apps

Well written targeted deals online lead to sales. It's that simple.

Now it's really simple to add a powerful deals engine to any Rails 3 site. Check out the "deals" gem that I just authored here.

The deals gem will add an API to your app so you can publish your deals to your partner sites. The deals webservice can also serve as the back end to a rich client app since RESTful requests serve JSON responses.

The deals gem is built with the RailsAdmin UI so you can easily edit the deals and place them in categories and location. This gives you a deep and wide approach to dominate the deals in your niche.

The code for the gem is available on github.

Wednesday, December 19, 2012

Bundle Discount Extension for Piggybak e-commerce framework

I recently authored an extension for the piggybak e-commerce framework: The extension can be found here.

Piggybak is a rails e-commerce maintained by End Point.

There was no go-to guide on writing an extension for piggybak so I went wrote one. It is was recently posted on End Point's blog here.

Sunday, December 2, 2012

Configuring CouchDB for Travis CI

Today I made a new release on the DPLA platform that updated requests for single records. I added some new cucumber integration steps that passed locally but broke the Travis CI build.

The new record "Fetch" mechanism is performing a fetch on CouchDB after doing a simple "transformation" on the requested record ID. The id for the CouchDB is pulled from an ID assigned at the time of ingestion and indexed in ElasticSearch.

The new method and integration tests require hitting CouchDB, so fixing the build entailed enabling CouchDB in Travis. Check out the commit with the new Travis configuration here.

Instructions for setting up the CouchDB service in Travis can be found here. To get the DPLA platform configuration set up correctly for the test suite, I needed to ensure we had an Admin user set up in CouchDB, which was different from the vanilla CouchDB setup with Travis. The final solution entailed a small change to the config files so the search endpoint can be defined independent of the test environment.