uncoil 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,4 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
- coverage/
5
+ coverage/
6
+ credentials.yml
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - rbx-19mode
7
+ - jruby-19mode
data/.yardoc/checksums ADDED
@@ -0,0 +1,3 @@
1
+ lib/uncoil.rb 0ab3336a87ae06d8a3aa55e15104552fcd7f6e9e
2
+ lib/uncoil/version.rb 2a25a2d46f761aa4d70eeee4a7f6adc42215db7a
3
+ lib/uncoil_submethods.rb 94e18e69c539be74e772316cc9cdc9cfaad296fd
Binary file
@@ -0,0 +1,2 @@
1
+ {I" Object:EF:
2
+ class
data/README.md CHANGED
@@ -1,21 +1,63 @@
1
- # uncoil
1
+ # uncoil - the link unshortening gem
2
+
3
+ [![Build Status](https://secure.travis-ci.org/stim371/uncoil.png)](http://travis-ci.org/stim371/uncoil)
2
4
 
3
5
  The uncoil gem is a one stop shop for un-shortening urls.
4
6
 
5
7
  The idea is based off of my site http://uncoil.me and I built this as part of my UWE-Ruby fall project.
6
8
 
7
9
  ## Why the heck does this exist?
8
- This gem is all about transparency and safety, and knowing where you are going on the internet.
10
+ This gem is all about transparency, safety and knowing where you are going on the internet.
11
+
12
+ The last straw was seeing TechCrunch articles with titles like "Don't click on this one specific goo.gl link! It's a virus!" (like [this](http://techcrunch.com/2010/12/07/twitter-virus/) one), which was flabbergasting. How is it that a tech blog and community's only response to these kind of threats is so reactionary and linear? **We can do better than that.**
9
13
 
10
14
  There are a few instances where it may come in handy:
11
15
 
12
16
  * You want to make sure you're not heading into an obviously sketchy site
13
17
  * You're at work and want to keep out the NSFW
14
18
 
15
- ## Example
16
- I have no idea where http://bit.ly/2EEjBl really goes.
19
+ ## Installation
20
+
21
+ Install the gem:
22
+
23
+ gem install uncoil
24
+
25
+ Add it to your file:
26
+
27
+ ```ruby
28
+ require 'uncoil'
29
+ ```
30
+
31
+ ## Usage
32
+ * If you have Bitly login credentials, use them to create a new instance:
17
33
 
18
- But by expanding it with uncoil, I can see that it goes to http://www.cnn.com
34
+ ```ruby
35
+ @a = Bitly.new(:bitlyuser => 'YOURAPIUSERNAME', :bitlykey => 'YOURAPIKEY')
36
+ # Or if you don't have any auth criteria
37
+ @a = Bitly.new
38
+ # in which case it will use a standard HTTP loop to find bitly destination urls
39
+ ```
40
+
41
+ * Use the `expand` method to see where the short link goes:
42
+
43
+ ```ruby
44
+ @a.expand('http://bit.ly/2EEjBl')
45
+ # or pass in an array of links
46
+ @a.expand(['http://bit.ly/2EEjBl','http://is.gd/gbKNRq'])
47
+ ```
48
+
49
+ For each link you pass in, you will get a separate `Uncoil::Response` object out with parameters for `long_url`, `short_url` and `error`
50
+
51
+ A full usage cycle may look like this:
52
+
53
+ ```ruby
54
+ @a = Bitly.new(:bitlyuser => 'YOURAPIUSERNAME', :bitlykey => 'YOURAPIKEY')
55
+ @b = @a.expand('http://bit.ly/2EEjBl') # => <Uncoil::Response:0x00000100a0d948 @long_url="http://www.cnn.com/" @short_url="http://bit.ly/2EEjBl" @error=nil>
56
+
57
+ @b.long_url # => "http://www.cnn.com/"
58
+ @b.short_url # => "http://bit.ly/2EEjBl"
59
+ @b.error # => nil
60
+ ```
19
61
 
20
62
  ## How the app works
21
63
 
@@ -23,9 +65,7 @@ But by expanding it with uncoil, I can see that it goes to http://www.cnn.com
23
65
  2. See if it matches with any of the supported APIs
24
66
  * If so, it calls the correct API method
25
67
  * If no matching method is found, it runs through an HTTP loop until it receives a 200 response
26
- 3. It then returns a hash containing, among other items, the full url
27
-
28
- ## Current Issues
68
+ 3. It then returns a Response object containing, among other items, the full url
29
69
 
30
70
  ## Future Enhancements
31
71
  Here are a few ideas I have for the future:
data/lib/uncoil.rb CHANGED
@@ -1,12 +1,21 @@
1
1
  require 'bitly'
2
- require 'open-uri'
3
- require 'net/http'
4
- require 'json'
2
+ require_relative 'uncoil_submethods'
5
3
 
4
+ # @author Joel Stimson
6
5
  class Uncoil
7
6
  ISGD_ROOT_URL = "http://is.gd/forward.php?format=json&shorturl="
8
7
  BITLY_DOM_ARRAY = %w[bit.ly, j.mp, bitlypro.com, cs.pn, nyti.ms]
9
8
 
9
+ # Creates a new Uncoil object and will log into Bit.ly if you provide credentials
10
+ #
11
+ # @option options [String] :bitlyuser A key for your Bit.ly API username
12
+ # @option options [String] :bitlykey A key for your Bit.ly API key
13
+ #
14
+ # @return [Class] the new instance of the Uncoil class
15
+ #
16
+ # @example Set up a new instance
17
+ # Uncoil.new(:bitlyuser => CREDENTIALS['bitlyuser'], :bitlykey => CREDENTIALS['bitlykey']) => "#<Uncoil:0x00000102560d30 @bitly_access=true>"
18
+ #
10
19
  def initialize options = {}
11
20
  Bitly.use_api_version_3
12
21
  @bitly_access = false
@@ -17,11 +26,28 @@ class Uncoil
17
26
  @bitly_access = true
18
27
  end
19
28
  end
29
+
30
+ # A class method version of the main expand method. This will not have access to the bit.ly API, but it's faster than having to create an instance and then use it for a one-off request.
31
+ #
32
+ # @param [String, Array] short_url The single url or array of urls you would like to expand
33
+ #
34
+ # @example Use the class method for a one-off request
35
+ # Uncoil.expand("http://tinyurl.com/736swvl") # => #<Uncoil::Response:0x00000101ed9250 @long_url="http://www.chinadaily.com.cn/usa/business/2011-11/08/content_14057648.htm", @short_url="http://tinyurl.com/736swvl", @error=nil>
36
+ #
37
+ def self.expand short_url
38
+ Uncoil.new.expand(short_url)
39
+ end
20
40
 
41
+ # The main method used for all requests. This method will delegate to submethods based on the domain of the link given.
42
+ #
43
+ # @param [String, Array] url_arr This can be a single url as a String or an array of Strings that the method will expand in order
44
+ #
45
+ # @return [Uncoil::Response] Returns a response object with getters for the long and short url
46
+ #
21
47
  def expand url_arr
22
48
  output_array = Array(url_arr).flatten.map do |short_url|
23
- short_url = clean_url(short_url)
24
- domain = identify_domain(short_url)
49
+ short_url = clean_url(short_url)
50
+ domain = identify_domain(short_url)
25
51
 
26
52
  begin
27
53
  long_url =
@@ -43,34 +69,29 @@ class Uncoil
43
69
  output_array.length == 1 ? output_array[0] : output_array
44
70
  end
45
71
 
72
+
73
+ # Contacts the bit.ly API to see if the domain is a bitlypro domain, which are custom domains purchased by 3rd parties but managed by bit.ly
74
+ #
75
+ # @param [String] url_domain The domain to check against the bit.ly API.
76
+ #
46
77
  def check_bitly_pro url_domain
47
78
  @bitly_instance.bitly_pro_domain(url_domain)
48
79
  end
49
-
50
- def uncoil_bitly short_url
51
- @bitly_instance.expand(short_url).long_url
52
- end
53
-
54
- def uncoil_isgd short_url
55
- JSON.parse(open(ISGD_ROOT_URL + "#{short_url}") { |file| file.read } )["url"]
56
- end
57
-
58
- def uncoil_other short_url, depth = 10
59
- url = URI.encode(short_url)
60
- response = Net::HTTP.get_response(URI.parse(url))
61
-
62
- case response
63
- when Net::HTTPSuccess then url
64
- when Net::HTTPRedirection then uncoil_other(response['location'], depth - 1)
65
- end
66
- end
67
80
 
68
- # helper methods to clean up the code above
69
81
 
82
+ # Extracts the domain from the link to help match it with the right sub-method to expand the url
83
+ #
84
+ # @param [String] short_url A single url to extract a domain from.
85
+ #
70
86
  def identify_domain short_url
71
87
  clean_url(short_url).split("/")[2].to_s
72
88
  end
89
+
73
90
 
91
+ # Standardizes the url by adding a protocol if there isn't one and removing trailing slashes
92
+ #
93
+ # @param [String] short_url A single url to be cleaned up.
94
+ #
74
95
  def clean_url short_url
75
96
  short_url = "http://" << short_url unless short_url =~ /^https?:\/\//
76
97
  short_url.chop! if short_url[-1] == "/"
@@ -79,9 +100,16 @@ class Uncoil
79
100
 
80
101
  end
81
102
 
103
+
82
104
  class Uncoil::Response
83
105
  attr_reader :long_url, :short_url, :error
84
106
 
107
+ # Creates a new Response object with attributes for the original and short url, as well as any errors that occured. It is called at the end of 'expand' method.
108
+ #
109
+ # @param [String] long_url The expanded url that we were looking for.
110
+ # @param [String] short_url The original, short url that we used to look up the long url.
111
+ # @param [String] error The error output if anything went wrong during the request. And I mean ANYTHING from a code error to an HTTP issue. It catches it all.
112
+ #
85
113
  def initialize(long_url, short_url, error)
86
114
  @long_url = long_url
87
115
  @short_url = short_url
@@ -1,3 +1,3 @@
1
1
  class Uncoil
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,38 @@
1
+ require 'open-uri'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ class Uncoil
6
+
7
+ # Expands any links that are bitly or bitlypro domains as long as you have logged into the bitly API.
8
+ #
9
+ # @param [String] short_url The short url you would like to expand.
10
+ #
11
+ def uncoil_bitly short_url
12
+ @bitly_instance.expand(short_url).long_url
13
+ end
14
+
15
+ # Expands any links that are isgd domains.
16
+ #
17
+ # @param [String] short_url The short url you would like to expand.
18
+ #
19
+ def uncoil_isgd short_url
20
+ JSON.parse(open(ISGD_ROOT_URL + "#{short_url}") { |file| file.read } )["url"]
21
+ end
22
+
23
+ # Expands any links that do not match the above domains.
24
+ #
25
+ # @param [String] short_url The short url you would like to expand.
26
+ # @param [Integer, 10] depth The number of redirects you would like this method to follow.
27
+ #
28
+ def uncoil_other short_url, depth = 10
29
+ url = URI.encode(short_url)
30
+ response = Net::HTTP.get_response(URI.parse(url))
31
+
32
+ case response
33
+ when Net::HTTPSuccess then url
34
+ when Net::HTTPRedirection then uncoil_other(response['location'], depth - 1)
35
+ end
36
+ end
37
+
38
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,4 @@
1
1
  require 'simplecov'
2
- SimpleCov.start
2
+ SimpleCov.start
3
+
4
+ CREDENTIALS = YAML.load_file("./credentials.yml")['bitly']
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'uncoil'
3
+
4
+ describe "the response object" do
5
+
6
+ subject { Uncoil.new(:bitlyuser => CREDENTIALS['bitlyuser'], :bitlykey => CREDENTIALS['bitlykey'])}
7
+
8
+ before(:all) {
9
+ @subject = subject.expand("http://is.gd/gbKNRq")
10
+ }
11
+
12
+ it "should return a response object" do
13
+ @subject.class.should eq Uncoil::Response
14
+ end
15
+
16
+ it "should respond to getter methods" do
17
+ @subject.long_url.should_not eq nil
18
+ @subject.short_url.should_not eq nil
19
+ end
20
+
21
+ end
data/spec/uncoil_spec.rb CHANGED
@@ -3,21 +3,26 @@ require 'uncoil'
3
3
 
4
4
  describe Uncoil do
5
5
 
6
- subject { Uncoil.new(:bitlyuser => "stim371", :bitlykey => "R_7a6f6d845668a8a7bb3e0c80ee3c28d6")}
6
+ subject { Uncoil.new(:bitlyuser => CREDENTIALS['bitlyuser'], :bitlykey => CREDENTIALS['bitlykey'])}
7
7
 
8
- describe "when using the submethods" do
8
+ describe "#expand class method" do
9
+ it "should successfully return a response object" do
10
+ Uncoil.expand("http://tinyurl.com/736swvl").class.should eq Uncoil::Response
11
+ end
9
12
 
10
- context "when trying to undo a bit.ly link" do
11
- it "should bring back the correct long link" do
12
- expected_result = "http://www.cnn.com/"
13
- subject.uncoil_bitly("http://bit.ly/2EEjBl").should eq expected_result
14
- end
13
+ it "should bring back the correct link" do
14
+ response = Uncoil.expand("http://tinyurl.com/736swvl")
15
+ response.long_url.should eq "http://www.chinadaily.com.cn/usa/business/2011-11/08/content_14057648.htm"
15
16
  end
17
+ end
16
18
 
17
- context "when trying to undo a bit.ly pro link" do
19
+ describe "when using the submethods" do
20
+
21
+ context "when trying to undo a bit.ly and bit.ly pro link" do
18
22
  it "should bring back the correct long link" do
19
- expected_result = "http://www.c-spanvideo.org/program/CainNew"
20
- subject.uncoil_bitly("http://cs.pn/vsZpra").should eq expected_result
23
+ {"http://bit.ly/2EEjBl" => "http://www.cnn.com/", "http://cs.pn/vsZpra" => "http://www.c-spanvideo.org/program/CainNew" }.each { |short_url, long_url|
24
+ subject.uncoil_bitly(short_url).should eq long_url
25
+ }
21
26
  end
22
27
  end
23
28
 
@@ -36,15 +41,11 @@ describe Uncoil do
36
41
 
37
42
  describe "the main expand method" do
38
43
 
39
- it "should return a response object" do
40
- subject.expand("http://is.gd/gbKNRq").class.should eq Uncoil::Response
41
- end
42
-
43
44
  it "should raise an error for non-urls" do
44
45
  subject.expand("a").error.should_not be_nil
45
46
  end
46
47
 
47
- context "and when expanding a link" do
48
+ context "when expanding a link" do
48
49
 
49
50
  def check_response response, expected_result
50
51
  response.long_url.should eq expected_result[:long_url]
data/uncoil.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "rspec"
23
23
  s.add_development_dependency "guard-rspec"
24
24
  s.add_development_dependency "simplecov"
25
+ s.add_development_dependency "rake"
25
26
 
26
27
  s.add_runtime_dependency "bitly"
27
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uncoil
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-21 00:00:00.000000000 Z
12
+ date: 2012-03-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2157463580 !ruby/object:Gem::Requirement
16
+ requirement: &2152984160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2157463580
24
+ version_requirements: *2152984160
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: guard-rspec
27
- requirement: &2157463160 !ruby/object:Gem::Requirement
27
+ requirement: &2152983000 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2157463160
35
+ version_requirements: *2152983000
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: simplecov
38
- requirement: &2157462740 !ruby/object:Gem::Requirement
38
+ requirement: &2152981500 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,21 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2157462740
46
+ version_requirements: *2152981500
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &2152980660 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2152980660
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: bitly
49
- requirement: &2157462320 !ruby/object:Gem::Requirement
60
+ requirement: &2152979620 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,7 +65,7 @@ dependencies:
54
65
  version: '0'
55
66
  type: :runtime
56
67
  prerelease: false
57
- version_requirements: *2157462320
68
+ version_requirements: *2152979620
58
69
  description: Uncoil is a gem to unshorten urls so you know where obscured links really
59
70
  go. If you have bitly login credentials, initialize an instance of Uncoil to use
60
71
  the bitly API.
@@ -65,6 +76,10 @@ extensions: []
65
76
  extra_rdoc_files: []
66
77
  files:
67
78
  - .gitignore
79
+ - .travis.yml
80
+ - .yardoc/checksums
81
+ - .yardoc/objects/root.dat
82
+ - .yardoc/proxy_types
68
83
  - Gemfile
69
84
  - Guardfile
70
85
  - Manifest
@@ -72,8 +87,10 @@ files:
72
87
  - Rakefile
73
88
  - lib/uncoil.rb
74
89
  - lib/uncoil/version.rb
90
+ - lib/uncoil_submethods.rb
75
91
  - spec/helper_method_spec.rb
76
92
  - spec/spec_helper.rb
93
+ - spec/uncoil_response_spec.rb
77
94
  - spec/uncoil_spec.rb
78
95
  - uncoil.gemspec
79
96
  homepage: https://github.com/stim371/uncoil
@@ -104,4 +121,6 @@ summary: Uncoil is a gem to unshorten urls so you know where obscured links real
104
121
  test_files:
105
122
  - spec/helper_method_spec.rb
106
123
  - spec/spec_helper.rb
124
+ - spec/uncoil_response_spec.rb
107
125
  - spec/uncoil_spec.rb
126
+ has_rdoc: