url_expander 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.document +5 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +28 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +131 -0
  6. data/Rakefile +70 -0
  7. data/VERSION +1 -0
  8. data/lib/url_expander/expanders/api/4sq.rb +12 -0
  9. data/lib/url_expander/expanders/api/bitly.rb +61 -0
  10. data/lib/url_expander/expanders/api/budurl.rb +41 -0
  11. data/lib/url_expander/expanders/api/cligs.rb +42 -0
  12. data/lib/url_expander/expanders/api/decenturl.rb +42 -0
  13. data/lib/url_expander/expanders/api/fxnws.rb +12 -0
  14. data/lib/url_expander/expanders/api/googl.rb +43 -0
  15. data/lib/url_expander/expanders/api/isgd.rb +41 -0
  16. data/lib/url_expander/expanders/api/nytims.rb +12 -0
  17. data/lib/url_expander/expanders/api/tcrnch.rb +12 -0
  18. data/lib/url_expander/expanders/api/xrlus.rb +40 -0
  19. data/lib/url_expander/expanders/api.rb +21 -0
  20. data/lib/url_expander/expanders/basic/adjix.rb +29 -0
  21. data/lib/url_expander/expanders/basic/digbig.rb +30 -0
  22. data/lib/url_expander/expanders/basic/doiop.rb +30 -0
  23. data/lib/url_expander/expanders/basic/easyurljp.rb +23 -0
  24. data/lib/url_expander/expanders/basic/justas.rb +23 -0
  25. data/lib/url_expander/expanders/basic/moourl.rb +29 -0
  26. data/lib/url_expander/expanders/basic/notlong.rb +29 -0
  27. data/lib/url_expander/expanders/basic/nutshellurl.rb +30 -0
  28. data/lib/url_expander/expanders/basic/owly.rb +23 -0
  29. data/lib/url_expander/expanders/basic/shrtst.rb +23 -0
  30. data/lib/url_expander/expanders/basic/snipurl.rb +26 -0
  31. data/lib/url_expander/expanders/basic/tco.rb +23 -0
  32. data/lib/url_expander/expanders/basic/tighturl.rb +23 -0
  33. data/lib/url_expander/expanders/basic/tinycc.rb +29 -0
  34. data/lib/url_expander/expanders/basic/tinyurl.rb +25 -0
  35. data/lib/url_expander/expanders/basic/twurlnl.rb +34 -0
  36. data/lib/url_expander/expanders/basic/urlie.rb +23 -0
  37. data/lib/url_expander/expanders/basic/youtube.rb +24 -0
  38. data/lib/url_expander/expanders/basic.rb +62 -0
  39. data/lib/url_expander/expanders/expanders.rb +49 -0
  40. data/lib/url_expander/expanders/scrape/qsrli.rb +30 -0
  41. data/lib/url_expander/expanders/scrape/shorl.rb +30 -0
  42. data/lib/url_expander/expanders/scrape/simurl.rb +34 -0
  43. data/lib/url_expander/expanders/scrape.rb +71 -0
  44. data/lib/url_expander.rb +62 -0
  45. data/test/helper.rb +18 -0
  46. data/test/test_url_expander.rb +7 -0
  47. metadata +216 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "httparty", ">= 0.6.1"
7
+ gem "json"
8
+ gem "hpricot"
9
+
10
+ # Add dependencies to develop your gem here.
11
+ # Include everything needed to run rake, tests, features, etc.
12
+ group :development do
13
+ gem "shoulda", ">= 0"
14
+ gem "bundler", "~> 1.0.0"
15
+ gem "jeweler", "~> 1.6.4"
16
+ gem "rcov", ">= 0"
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ crack (0.1.8)
5
+ git (1.2.5)
6
+ hpricot (0.8.4)
7
+ httparty (0.7.8)
8
+ crack (= 0.1.8)
9
+ jeweler (1.6.4)
10
+ bundler (~> 1.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ json (1.5.3)
14
+ rake (0.9.2)
15
+ rcov (0.9.9)
16
+ shoulda (2.11.3)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ bundler (~> 1.0.0)
23
+ hpricot
24
+ httparty (>= 0.6.1)
25
+ jeweler (~> 1.6.4)
26
+ json
27
+ rcov
28
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Moski
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,131 @@
1
+ = url_expander
2
+
3
+ The idea is simple, One expander to expand them all. I've been working on an analytical tool for twitter.com and i wanted a way to expand all the shortened urls. Url_expander is a good start, it covers 34 services. I tried to make it as simple as possible to extend & add new services.
4
+
5
+ == Install
6
+
7
+ gem install url_expander
8
+
9
+ == How to use
10
+
11
+ Download the config used to authenticate with some of the shortening services
12
+
13
+ curl -s https://raw.github.com/gist/1086114/c5c401e811effc3e99ed37ae9503f267877d8e68/url_expander_credentials.yml -o ~/url_expander_credentials.yml
14
+
15
+ Require and Use
16
+ require 'rubygems' # if ruby < 1.9
17
+ require 'url_expander'
18
+ UrlExpander::Client.expand('http://tinyurl.com/66sekq5')
19
+
20
+ === Options
21
+
22
+ * :nested_shortening -- Nested shortening is turned on by default (:nested_shortening => true)
23
+ UrlExpander::Client.expand("http://t.co/ZGEGdas") => "http://www.blink182.com/upallnight/"
24
+ UrlExpander::Client.expand("http://t.co/ZGEGdas", :nested_shortening => false) => "http://bit.ly/oi029o"
25
+
26
+ * :limit -- If the nested_shortening is turned on, then :limit controls the max number of redirection allowed. Default value is 10
27
+ UrlExpander::Client.expand('http://tinyurl.com/66sekq5', :limit => 4)
28
+
29
+ * :config_file -- Some services Require credentials to access the api (such as bitly). You need to provide YAML file with the access credentials. Default is "~/url_expander_credentials.yml".
30
+ UrlExpander::Client.expand('http://bit.ly/qpshuI', :config_file => '/Users/moski/url_expander_credentials.yml')
31
+
32
+
33
+ == Supported Services:
34
+
35
+ * 4sq.com
36
+ UrlExpander::Client.expand("http://4sq.com/pQkuZk")
37
+ * bit.ly
38
+ UrlExpander::Client.expand("http://bit.ly/qpshuI")
39
+ * j.mp
40
+ UrlExpander::Client.expand("http://j.mp/qpshuI")
41
+ * budurl.com
42
+ UrlExpander::Client.expand("http://budurl.com/EYOS2")
43
+ * cli.gs
44
+ UrlExpander::Client.expand("http://cli.gs/2BAzKa")
45
+ * decenturl.com
46
+ UrlExpander::Client.expand("http://decenturl.com/youtube/medieval")
47
+ UrlExpander::Client.expand("http://youtube.decenturl.com/medieval")
48
+ * fxn.ws
49
+ UrlExpander::Client.expand("http://fxn.ws/pBewvL")
50
+ * goo.gl
51
+ UrlExpander::Client.expand("http://goo.gl/DRppM")
52
+ * is.gd
53
+ UrlExpander::Client.expand("http://is.gd/wsJRhR")
54
+ * nyti.ms
55
+ UrlExpander::Client.expand("http://nyti.ms/dzy2b7")
56
+ * tcrn.ch
57
+ UrlExpander::Client.expand("http://tcrn.ch/oe50JN")
58
+ * xrl.us
59
+ UrlExpander::Client.expand("http://xrl.us/bkz5iy")
60
+ * adjix.com
61
+ UrlExpander::Client.expand("http://adjix.com/cm4m")
62
+ * digbig.com
63
+ UrlExpander::Client.expand("http://digbig.com/3bbd")
64
+ * doiop.com
65
+ UrlExpander::Client.expand("http://doiop.com/dz8896")
66
+ * easyurl.jp
67
+ UrlExpander::Client.expand("http://easyurl.jp/1qdv")
68
+ * just.as
69
+ UrlExpander::Client.expand("http://just.as/amMF3i")
70
+ * moourl.com
71
+ UrlExpander::Client.expand("http://moourl.com/flsho")
72
+ * notlong.com
73
+ UrlExpander::Client.expand("http://moski.notlong.com")
74
+ * nutshellurl.com
75
+ UrlExpander::Client.expand("http://nutshellurl.com/1v38")
76
+ * ow.ly
77
+ UrlExpander::Client.expand("http://ow.ly/5EVkL")
78
+ * shrt.st
79
+ UrlExpander::Client.expand("http://shrt.st/148u")
80
+ * snipurl.com, sn.im, cl.lk, snipr.com, snurl.com
81
+ UrlExpander::Client.expand("http://snipurl.com/209hem")
82
+ UrlExpander::Client.expand("http://sn.im/209hem")
83
+ UrlExpander::Client.expand("http://cl.lk/209hem")
84
+ UrlExpander::Client.expand("http://snipr.com/209hem")
85
+ UrlExpander::Client.expand("http://snurl.com/209hem")
86
+ * t.co
87
+ UrlExpander::Client.expand("http://t.co/ZGEGdas")
88
+ * tighturl.com
89
+ UrlExpander::Client.expand("http://tighturl.com/3eoz")
90
+ * tiny.cc
91
+ UrlExpander::Client.expand("http://tiny.cc/pabx5")
92
+ * tinyurl.com
93
+ UrlExpander::Client.expand("http://tinyurl.com/66sekq5")
94
+ * twurl.nl
95
+ UrlExpander::Client.expand("http://twurl.nl/e6mglc")
96
+ * url.ie
97
+ UrlExpander::Client.expand("http://url.ie/cert")
98
+ * youtu.be
99
+ UrlExpander::Client.expand("http://youtu.be/bINUfbLV_0M")
100
+ * y2u.be
101
+ UrlExpander::Client.expand("http://y2u.be/bINUfbLV_0M")
102
+ * qsr.li
103
+ UrlExpander::Client.expand("http://qsr.li/5Zg9")
104
+ * shorl.com
105
+ UrlExpander::Client.expand("http://shorl.com/nigekohalenu")
106
+ * simurl.com
107
+ UrlExpander::Client.expand("http://simurl.com/fendaz")
108
+
109
+
110
+
111
+ Services are divided into 3 categories:
112
+
113
+ * Provide an API for expanding
114
+ * Support 301 redirection
115
+ * Manual Scraping
116
+
117
+
118
+ == Contributing to url_expander
119
+
120
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
121
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
122
+ * Fork the project
123
+ * Start a feature/bugfix branch
124
+ * Commit and push until you are happy with your contribution
125
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
126
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
127
+
128
+ == Copyright
129
+
130
+ Copyright (c) 2011 Moski. See LICENSE.txt for
131
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "url_expander"
18
+ gem.homepage = "http://github.com/moski/url_expander"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Expand short url from different services}
21
+ gem.description = %Q{Expand short urls from shortning services shuch as bitly and tinyurl}
22
+ gem.email = "abushaikh@gmail.com"
23
+ gem.authors = ["Moski"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "url_expander #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
54
+
55
+
56
+ namespace :url_expander do
57
+ desc "Generate config file"
58
+ task(:generate_config) do
59
+ credentials = {
60
+ :bitly => {
61
+ :login => 'BITLY LOGIN',
62
+ :api_key => 'BITLY API KEY'
63
+ }
64
+ }
65
+ File.open('url_expander_credentials.yml', 'w') { |file| YAML.dump(credentials, file) }
66
+ end
67
+ end
68
+
69
+
70
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,12 @@
1
+ module UrlExpander
2
+ module Expanders
3
+ #
4
+ # Expand 4sqr shortner
5
+ # Usage:
6
+ # UrlExpander::Client.expand("http://4sq.com/pQkuZk")
7
+ #
8
+ class Foursq < UrlExpander::Expanders::Bitly
9
+ PATTERN = %r'(http://4sq\.com/([\w/]+))'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,61 @@
1
+ module UrlExpander
2
+ module Expanders
3
+ #
4
+ # Expand Bitly URLS
5
+ # Usage:
6
+ # UrlExpander::Client.expand("http://bit.ly/qpshuI")
7
+ # UrlExpander::Client.expand("http://j.mp/qpshuI")
8
+ # UrlExpander::Client.expand("http://nyti.ms/dzy2b7")
9
+ # UrlExpander::Client.expand("http://tcrn.ch/oe50JN")
10
+ # UrlExpander::Client.expand("http://fxn.ws/pBewvL")
11
+ #
12
+ class Bitly < UrlExpander::Expanders::API
13
+ # NOTICE: We ignored the / before the key
14
+ # http://bit.ly/qpshuI => 'qpshuI' without /
15
+ PATTERN = %r'(http://(?:bit\.ly|j\.mp)/([\w/]+))'
16
+
17
+ attr_reader :parent_klass
18
+ attr_accessor :login, :api_key
19
+
20
+ def initialize(short_url, options={})
21
+ @parent_klass = self
22
+ load_credentials(options[:config_file])
23
+
24
+ if @login.nil? || @api_key.nil?
25
+ raise ArgumentError.new('Bitly Expander require login, api_key. Run "rake url_expander:generate_config"')
26
+ end
27
+
28
+ super(short_url,options)
29
+ fetch_url
30
+ end
31
+
32
+ class Request
33
+ include HTTParty
34
+ base_uri 'api.bit.ly'
35
+ format :json
36
+ end
37
+
38
+ private
39
+
40
+ def fetch_url
41
+ data = JSON.parse Request.get("/v3/expand?hash=#{@shortner_key}&login=#{@login}&apiKey=#{@api_key}").response.body
42
+ expand = data['data']['expand'].first
43
+ if(data['status_code'] == 200 && !expand.has_key?('error'))
44
+ @long_url = expand["long_url"]
45
+ else
46
+ raise UrlExpander::Error.new(expand['error'],data['status_code'])
47
+ end
48
+ end
49
+
50
+ def load_credentials(file_path)
51
+ unless File.exists?(file_path)
52
+ raise ArgumentError.new('Bitly Expander require login, api_key. Run "rake url_expander:generate_config"')
53
+ else
54
+ credentials = YAML.load_file(file_path)[:bitly]
55
+ @login = credentials[:login]
56
+ @api_key = credentials[:api_key]
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,41 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Budurl URLS
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://budurl.com/EYOS2")
8
+ #
9
+ class Budurl < UrlExpander::Expanders::API
10
+ # NOTICE: We ignored the / before the key
11
+ # http://budurl.com/EYOS2 => 'EYOS2' without /
12
+ PATTERN = %r'(http://budurl\.com/([\w/]+))'
13
+
14
+ attr_reader :parent_klass
15
+
16
+ def initialize(short_url, options={})
17
+ @parent_klass = self
18
+ super(short_url,options)
19
+ fetch_url
20
+ end
21
+
22
+ class Request
23
+ include HTTParty
24
+ base_uri 'budurl.com'
25
+ format :json
26
+ end
27
+
28
+
29
+ private
30
+
31
+ def fetch_url
32
+ data = JSON.parse Request.get("/api/v1/budurls/expand?budurl=#{@shortner_key}").response.body
33
+ if(data["success"] == 1)
34
+ @long_url = data["long_url"]
35
+ else
36
+ raise UrlExpander::Error.new(data['error_message'],data['error_code'])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Cligs URLS
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://cli.gs/2BAzKa")
8
+ #
9
+ class Cligs < UrlExpander::Expanders::API
10
+ # NOTICE: We ignored the / before the key
11
+ # http://cli.gs/2BAzKa => '2BAzKa' without /
12
+ PATTERN = %r'(http://cli\.gs/([\w/]+))'
13
+
14
+ attr_reader :parent_klass
15
+
16
+ def initialize(short_url, options={})
17
+ @parent_klass = self
18
+ super(short_url,options)
19
+ fetch_url
20
+ end
21
+
22
+ class Request
23
+ include HTTParty
24
+ base_uri 'cli.gs'
25
+ end
26
+
27
+
28
+ private
29
+
30
+ def fetch_url
31
+ response = Request.get("/api/v1/cligs/expand?clig=#{@shortner_key}").response
32
+
33
+ case response.response
34
+ when Net::HTTPOK
35
+ @long_url = response.body
36
+ else
37
+ raise UrlExpander::Error.new(response.body,response.code)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Budurl URLS
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://decenturl.com/youtube/medieval")
8
+ # UrlExpander::Client.expand("http://youtube.decenturl.com/medieval")
9
+ #
10
+ class Decenturl < UrlExpander::Expanders::API
11
+ # NOTICE: We ignored the / before the key
12
+ # http://decenturl.com/youtube/medieval => 'youtube/medieval' without /
13
+ PATTERN = %r'(http://(?:(?>[a-z0-9-]*\.)+?|)decenturl\.com/([\w/]+))'
14
+
15
+ attr_reader :parent_klass, :short_url
16
+
17
+ def initialize(short_url, options={})
18
+ @parent_klass = self
19
+ @short_url = short_url
20
+ fetch_url
21
+ end
22
+
23
+ class Request
24
+ include HTTParty
25
+ base_uri 'decenturl.com'
26
+ format :json
27
+ end
28
+
29
+
30
+ private
31
+
32
+ def fetch_url
33
+ data = JSON.parse Request.get("/api-resolve?d=#{@short_url}").response.body
34
+ if(data.include?("ok"))
35
+ @long_url = data[1]
36
+ else
37
+ raise UrlExpander::Error.new(data.join(","),404)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+ module UrlExpander
2
+ module Expanders
3
+ #
4
+ # Expand Foxnews
5
+ # Usage:
6
+ # UrlExpander::Client.expand("http://fxn.ws/pBewvL")
7
+ #
8
+ class Fxnws < UrlExpander::Expanders::Bitly
9
+ PATTERN = %r'(http://fxn\.ws/([\w/]+))'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Google URLS
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://goo.gl/DRppM")
8
+ #
9
+ class Googl < UrlExpander::Expanders::API
10
+ # NOTICE: We ignored the / before the key
11
+ # http://goo.gl/DRppM => 'DRppM' without /
12
+ PATTERN = %r'(http://goo\.gl/([\w/]+))'
13
+
14
+ attr_reader :parent_klass
15
+
16
+ def initialize(short_url, options={})
17
+ @parent_klass = self
18
+ super(short_url,options)
19
+ fetch_url
20
+ end
21
+
22
+ class Request
23
+ include HTTParty
24
+ base_uri 'https://www.googleapis.com'
25
+ headers 'Content-Type' => 'application/json'
26
+ headers "Content-length" => "0"
27
+ end
28
+
29
+
30
+ private
31
+
32
+ def fetch_url
33
+ response = Request.get("/urlshortener/v1/url?shortUrl=http://goo.gl/#{@shortner_key}")
34
+ if response.code == 200
35
+ @long_url = response['longUrl']
36
+ else
37
+ error = (JSON.parse response.body)['error']
38
+ raise UrlExpander::Error.new(error['message'],response.code)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Isgd URLS
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://is.gd/wsJRhR")
8
+ #
9
+ class Isgd < UrlExpander::Expanders::API
10
+ # NOTICE: We ignored the / before the key
11
+ # http://is.gd/wsJRhR => 'wsJRhR' without /
12
+ PATTERN = %r'(http://is\.gd/([\w/]+))'
13
+
14
+ attr_reader :parent_klass
15
+
16
+ def initialize(short_url, options={})
17
+ @parent_klass = self
18
+ super(short_url,options)
19
+ fetch_url
20
+ end
21
+
22
+ class Request
23
+ include HTTParty
24
+ base_uri 'is.gd'
25
+ format :json
26
+ end
27
+
28
+
29
+ private
30
+
31
+ def fetch_url
32
+ data = JSON.parse Request.get("/forward.php?format=json&shorturl=http://is.gd/#{@shortner_key}").response.body
33
+ unless(data["errorcode"])
34
+ @long_url = data["url"]
35
+ else
36
+ raise UrlExpander::Error.new(data['errormessage'],data['errorcode'])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ module UrlExpander
2
+ module Expanders
3
+ #
4
+ # Expand Newyork times
5
+ # Usage:
6
+ # UrlExpander::Client.expand("http://nyti.ms/dzy2b7")
7
+ #
8
+ class Nytims < UrlExpander::Expanders::Bitly
9
+ PATTERN = %r'(http://nyti\.ms/([\w/]+))'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module UrlExpander
2
+ module Expanders
3
+ #
4
+ # Expand techcruch
5
+ # Usage:
6
+ # UrlExpander::Client.expand("http://tcrn.ch/oe50JN")
7
+ #
8
+ class Tcrnch < UrlExpander::Expanders::Bitly
9
+ PATTERN = %r'(http://tcrn\.ch/([\w/]+))'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ module UrlExpander
2
+ module Expanders
3
+
4
+ #
5
+ # Expand Xrl.us URLS -- http://metamark.net/
6
+ # Usage:
7
+ # UrlExpander::Client.expand("http://xrl.us/bkz5iy")
8
+ #
9
+ class Xrlus < UrlExpander::Expanders::API
10
+ # NOTICE: We ignored the / before the key
11
+ # http://xrl.us/bkz5iy => 'bkz5iy' without /
12
+ PATTERN = %r'(http://xrl\.us/([\w/]+))'
13
+
14
+ attr_reader :parent_klass, :short_url
15
+
16
+ def initialize(short_url, options={})
17
+ @parent_klass = self
18
+ @short_url = short_url
19
+ fetch_url
20
+ end
21
+
22
+ class Request
23
+ include HTTParty
24
+ base_uri 'metamark.net'
25
+ end
26
+
27
+
28
+ private
29
+
30
+ def fetch_url
31
+ data = Request.get("/api/rest/simple?short_url=#{@short_url}").response.body
32
+ unless(data[0..5] == 'ERROR:')
33
+ @long_url = data
34
+ else
35
+ raise UrlExpander::Error.new(data,404)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ require 'json'
2
+
3
+ module UrlExpander
4
+ module Expanders
5
+ class API
6
+ attr_accessor :long_url
7
+ attr_reader :parttern, :parent_klass, :shortner_key
8
+
9
+ # Called from the Subclasses, its only job to set the @shortner_key
10
+ # For example, if the short_url = 'http://bit.ly/k3irb0+'
11
+ # then @shortner_key = 'k3irb0+'
12
+ def initialize(short_url="", options={})
13
+ if short_url.match(parent_klass.class::PATTERN)
14
+ @shortner_key = $2
15
+ else
16
+ raise 'invalid pattern'
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end