Report abuse

require 'net/http'

module BarkingIguana
  # Expand URLs that have been shortened using services like TinyURL or 
  # Bit.ly.
  #
  # Include it something like this:
  #
  #     class String
  #       include BarkingIguana::ExpandUrl
  #     end
  #
  # Then use it like this:
  #
  #     s = "http://tinyurl.com/asdf"
  #     s.expand_urls!
  #     puts s.inspect
  #     # => "http://support.microsoft.com/default.aspx?scid=kb;EN-US;158122"
  #
  # I'd love more services. Let me know about them!
  #
  # The implementation was largely stolen from here: http://tinyurl.com/csokml
  #
  # Copyright (C) 2008-2009 The Termtter Development Team
  # Copyright (C) 2009 Craig R Webster <http://barkingiguana.com/~craig>
  #
  # Permission is hereby granted, free of charge, to any person obtaining a 
  # copy of this software and associated documentation files (the ‘Software’), 
  # to deal in the Software without restriction, including without limitation 
  # the rights to use, copy, modify, merge, publish, distribute, sublicense, 
  # and/or sell copies of the Software, and to permit persons to whom the 
  # Software is furnished to do so, subject to the following conditions:
  #
  # The above copyright notice and this permission notice shall be included in 
  # all copies or substantial portions of the Software.
  #
  # THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
  # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
  # DEALINGS IN THE SOFTWARE.
  #
  module ExpandUrl
    def expand_urls!
      ExpandUrl.services.each do |service|
        gsub!(service[:pattern]) { |match|
          ExpandUrl.expand($2, service[:host]) || $1
        }
      end
    end

    def expand_urls
      s = dup
      s.expand_urls!
      s
    end

    def ExpandUrl.services
      [
        { :host => "tinyurl.com", :pattern => %r'(http://tinyurl\.com(/[\w/]+))' },
        { :host => "is.gd", :pattern => %r'(http://is\.gd(/[\w/]+))' },
        { :host => "bit.ly", :pattern => %r'(http://bit\.ly(/[\w/]+))' },
        { :host => "ff.im", :pattern => %r'(http://ff\.im(/[\w/]+))'},
      ]
    end

    def ExpandUrl.expand(path, host)
      result = ::Net::HTTP.new(host).head(path)
      case result
      when ::Net::HTTPRedirection
        result['Location']
      end
    end
  end
end