unshorten 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/unshorten ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'unshorten'
4
+
5
+ if ARGV.empty?
6
+ STDERR << "USAGE: unshorten URL\n"
7
+ else
8
+ ARGV.each { |a| puts Unshorten[a] }
9
+ end
10
+
data/lib/unshorten.rb ADDED
@@ -0,0 +1,86 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ # Get original URLs from shortened ones.
5
+ class Unshorten
6
+
7
+ # Cache entities limit
8
+ CACHE_SIZE_LIMIT = 1024
9
+
10
+ # Default options for unshorten
11
+ DEFAULT_OPTIONS = {
12
+ :max_level => 10,
13
+ :timeout => 2,
14
+ :use_cache => true,
15
+ :add_missing_http => true
16
+ }
17
+
18
+ @@cache = { }
19
+
20
+ class << self
21
+
22
+ # Unshorten a URL
23
+ #
24
+ # @param url [String] A shortened URL
25
+ # @param options [Hash] A set of options
26
+ # @option options [Integer] :max_level Max redirect times
27
+ # @option options [Integer] :timeout Timeout in seconds, for every request
28
+ # @option options [Boolean] :use_cache Use cached result if available
29
+ # @option options [Boolean] :add_missing_http add 'http://' if missing
30
+ # @see DEFAULT_OPTIONS
31
+ #
32
+ # @return Original url, a url that does not redirect
33
+ def unshorten(url, options = {})
34
+ DEFAULT_OPTIONS.each { |k, v| (options[k] = v) unless options.has_key? k }
35
+
36
+ follow(url, options)
37
+ end
38
+
39
+ alias :'[]' :unshorten
40
+
41
+ private
42
+
43
+ def expire_cache #:nodoc:
44
+ @@cache = { }
45
+ end
46
+
47
+ def mix_options(old, *new) #:nodoc:
48
+ options = old.dup
49
+ new.each { |n| n.each { |k, v| options[k] = v } }
50
+ options
51
+ end
52
+
53
+ def add_missing_http(url) #:nodoc:
54
+ if url =~ /^https?:/i
55
+ url
56
+ else
57
+ "http://#{url}"
58
+ end
59
+ end
60
+
61
+ def follow(url, options = DEFAULT_OPTIONS, level = 0) #:nodoc:
62
+ return @@cache[url] if options[:use_cache] and @@cache[url]
63
+
64
+ url = add_missing_http(url) if options[:add_missing_http]
65
+ return url if level >= options[:max_level]
66
+
67
+ uri = URI.parse(url)
68
+ http = Net::HTTP.new(uri.host, uri.port)
69
+ http.read_timeout = options[:timeout]
70
+
71
+ response = http.request_head(uri.path.empty? ? '/' : uri.path) rescue nil
72
+
73
+ if response.is_a? Net::HTTPRedirection and response['location'] then
74
+ expire_cache if @@cache.size > CACHE_SIZE_LIMIT
75
+ @@cache[url] = follow(response['location'], options, level + 1)
76
+ else
77
+ url
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ # vim:et:ts=2 sw=2
86
+
@@ -0,0 +1,16 @@
1
+ require 'test/unit'
2
+ require 'unshorten'
3
+
4
+ class UnshortenTest < Test::Unit::TestCase
5
+ ORIGINAL_URL = 'http://dir.yahoo.com/Reference/Libraries/Library_and_Information_Science/Metadata/URIs___Universal_Resource_Identifiers/URLs___Uniform_Resource_Locators/URL_Shortening/'
6
+ SHORTENED_URL = 'http://tinyurl.com/j'
7
+
8
+ def test_unshorten_alias
9
+ assert_equal ORIGINAL_URL, Unshorten[SHORTENED_URL, :use_cache => false]
10
+ end
11
+
12
+ def test_option_max_level
13
+ assert_equal SHORTENED_URL, Unshorten.unshorten(SHORTENED_URL, :max_level => 0, :use_cache => false)
14
+ end
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unshorten
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Wu Jun
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-10 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Get original URLs from shortened ones
15
+ email: quark@lihdd.net
16
+ executables:
17
+ - unshorten
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/unshorten.rb
22
+ - test/test_unshorten.rb
23
+ - bin/unshorten
24
+ homepage: https://github.com/quark-zju/unshorten
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.11
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: Unshorten URLs
48
+ test_files:
49
+ - test/test_unshorten.rb
50
+ has_rdoc: