em-shorturl 0.0.1 → 0.1.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ require 'em-http-request'
2
+ require 'uri'
3
+
4
+ module EventMachine
5
+ module ShortURL
6
+
7
+ ##
8
+ # Driver for bitly.com URL Shortening service.
9
+
10
+ class Bitly
11
+ include EventMachine::Deferrable
12
+ API_OAUTH_URL = 'https://api-ssl.bitly.com/oauth/access_token'
13
+ API_SHORTEN_URL = 'https://api-ssl.bitly.com/v3/shorten'
14
+
15
+ def initialize(account={})
16
+ @client_id = account[:client_id]
17
+ @client_secret = account[:client_secret]
18
+ @username = account[:username]
19
+ @password = account[:password]
20
+ @access_token = account[:token]
21
+ @deferrable_args = [self]
22
+ end
23
+
24
+ def shorten(url)
25
+ if @access_token.nil?
26
+ login { shorten(url) }
27
+ return self
28
+ end
29
+
30
+ params = get_request_parameters(url)
31
+ request = EM::HttpRequest.new(API_SHORTEN_URL).get(params)
32
+ request.callback(&method(:on_success))
33
+ request.errback(&method(:on_error))
34
+ self
35
+ end
36
+
37
+ def login
38
+ params = {
39
+ :head => { 'authorization' => [@username, @password] },
40
+ :body => {}
41
+ }
42
+ params[:body]['client_id'] = @client_id if @client_id
43
+ params[:body]['client_secret'] = @client_secret if @client_secret
44
+ http = EM::HttpRequest.new(API_OAUTH_URL).post(params)
45
+
46
+ http.errback do |http|
47
+ fail(http.error, *@deferrable_args)
48
+ end
49
+
50
+ http.callback do |http|
51
+ if http.response_header.status != 200
52
+ fail(http.response, *@deferrable_args)
53
+ next
54
+ end
55
+
56
+ @access_token = http.response
57
+ if @access_token.nil?
58
+ fail('OAuth request did not return an access token', *@deferrable_args)
59
+ next
60
+ else
61
+ yield if block_given?
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def get_request_parameters(url)
69
+ url = URI(url)
70
+ url.path = '/' if url.path.empty?
71
+
72
+ return {
73
+ :query => {
74
+ 'access_token' => @access_token,
75
+ 'longUrl' => url.to_s,
76
+ 'format' => 'txt'
77
+ }
78
+ }
79
+ end
80
+
81
+ def on_success(http)
82
+ if http.response_header.status != 200
83
+ fail(http.response, *@deferrable_args)
84
+ return
85
+ end
86
+
87
+ succeed(http.response, *@deferrable_args)
88
+ end
89
+
90
+ def on_error(http)
91
+ fail(http.response, *@deferrable_args)
92
+ end
93
+ end
94
+ end
95
+ end
@@ -7,6 +7,11 @@ module EventMachine
7
7
  ##
8
8
  # The Google class is the driver for URLShortener to use Google's API
9
9
  # for URL shortening.
10
+ #
11
+ # As a deferrable, instances accept callback procs in calls to
12
+ # callback() and errback(). Callbacks are provided arguments
13
+ # +shorturl+ and +self+, while errbacks are provided +err_string+
14
+ # and +self+.
10
15
 
11
16
  class Google
12
17
  include EventMachine::Deferrable
@@ -16,8 +21,9 @@ module EventMachine
16
21
 
17
22
 
18
23
  ##
19
- # Takes the URL to shorten and optionally two callbacks for success
20
- # and error. Does not immediately shorten the URL.
24
+ # Initializes the driver instance, optionally with account information
25
+ # for making requests on behalf of an account. Benefits of using an api key
26
+ # include higher request limits and stat tracking.
21
27
  #
22
28
  # The +account+ argument may take the following options:
23
29
  # :apikey Defines an apikey to use for the request
@@ -27,9 +33,14 @@ module EventMachine
27
33
  @account_apikey = account[:apikey]
28
34
  end
29
35
 
30
-
36
+
31
37
  ##
32
- # Performs the request of shortening a URL asynchronously.
38
+ # Performs the request of shortening a URL asynchronously. Returns self,
39
+ # which is a deferrable. This allows a usage like the following:
40
+ #
41
+ # EM::ShortURL::Google.new.shorten('http://google.com').callback do |u,d|
42
+ # puts "Shorturl: #{u}"
43
+ # end
33
44
 
34
45
  def shorten(url)
35
46
  params = get_request_parameters(url)
@@ -45,7 +56,7 @@ module EventMachine
45
56
 
46
57
  ##
47
58
  # Creates the parameter hash for the HTTP Request to Google
48
-
59
+
49
60
  def get_request_parameters(url)
50
61
  options = {
51
62
  :head => { "Content-Type" => "application/json" },
@@ -58,7 +69,8 @@ module EventMachine
58
69
 
59
70
  options
60
71
  end
61
-
72
+
73
+
62
74
  ##
63
75
  # Callback for HttpRequest object upon success. Parses the response
64
76
  # as JSON, checks for a Google API error, and finally saves the
@@ -0,0 +1,52 @@
1
+ require 'em-http-request'
2
+
3
+ module EventMachine
4
+ module ShortURL
5
+ class TinyURL
6
+ include EventMachine::Deferrable
7
+
8
+ # TinyURL API
9
+ API_URL = 'http://tinyurl.com/api-create.php'
10
+
11
+
12
+ ##
13
+ # TinyURL has no accounts or users, so while the class accepts an
14
+ # +account+ parameter, it is unused.
15
+
16
+ def initialize(account={})
17
+ @deferrable_args = [self]
18
+ end
19
+
20
+
21
+ def shorten(url)
22
+ params = { :query => { :url => url } }
23
+ request = EM::HttpRequest.new(API_URL).post(params)
24
+ request.callback(&method(:on_success))
25
+ request.errback(&method(:on_error))
26
+ self
27
+ end
28
+ private
29
+
30
+
31
+ ##
32
+ # Callback for HttpRequest object upon success. The response should
33
+ # just be the plaintest link.
34
+
35
+ def on_success(http)
36
+ short_url = http.response
37
+ succeed(short_url, *@deferrable_args)
38
+ end
39
+
40
+
41
+ ##
42
+ # Callback for an error from HttpRequest (caused by a server
43
+ # outage of lack of connectivity). Simply forwards the error
44
+ # value and sets the deferrable status to fail.
45
+
46
+ def on_error(http)
47
+ error = http.error
48
+ fail(error, *@deferrable_args)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module ShortURL
3
- VERSION = '0.0.1'
3
+ VERSION = '0.1.0.pre'
4
4
  end
5
5
  end
data/lib/em-shorturl.rb CHANGED
@@ -1,14 +1,34 @@
1
1
  require 'eventmachine'
2
2
  require 'em-shorturl/version'
3
3
  require 'em-shorturl/google'
4
+ require 'em-shorturl/tinyurl'
5
+ require 'em-shorturl/bitly'
4
6
 
5
7
  module EventMachine
8
+
9
+ ##
10
+ # The ShortURL module for EventMachine adds an asynchronous interface to
11
+ # shortening urls using several publically available URL shortening
12
+ # services. Several drivers may be provided, and the top level module
13
+ # provides a uniform and easy interface to using any of these services.
14
+
6
15
  module ShortURL
7
16
  DEFAULT_DRIVER = :google
8
17
  DRIVERS = {
9
- :google => ShortURL::Google
18
+ :google => ShortURL::Google,
19
+ :tinyurl => ShortURL::TinyURL,
20
+ :bitly => ShortURL::Bitly
10
21
  }
11
22
 
23
+
24
+ ##
25
+ # Takes a URL and returns the driver instance, which should then have
26
+ # its callback and errback attributes set. Optionally accepts +driver+
27
+ # and +account+. +driver+ is a symbol which maps to a driver class and
28
+ # +account+ is a driver-specific hash of account information.
29
+ #
30
+ # Raises +KeyError+ if the driver is not mapped.
31
+
12
32
  def self.shorten(url, driver=DEFAULT_DRIVER, account={})
13
33
  raise KeyError, "Driver does not exist" unless DRIVERS[driver]
14
34
 
@@ -0,0 +1,49 @@
1
+ require "test/unit"
2
+ require "em-shorturl/bitly"
3
+
4
+ class TestBitly < Test::Unit::TestCase
5
+ TEST_URL = 'http://google.com'
6
+ SHORT_REGEX = /^http:\/\/bit.ly\/\S+$/
7
+ USER_ENV_VAR = 'bitly_user'
8
+ PASS_ENV_VAR = 'bitly_pass'
9
+ TOKEN_ENV_VAR = 'bitly_token'
10
+
11
+ def test_no_auth
12
+ EM.run do
13
+ bitly = EM::ShortURL::Bitly.new
14
+ bitly.errback { |e| assert(true, e); EM.stop }
15
+ bitly.callback { |s| assert(false, s); EM.stop }
16
+ bitly.shorten(TEST_URL)
17
+ end
18
+ end
19
+
20
+ if ENV[USER_ENV_VAR] and ENV[PASS_ENV_VAR]
21
+ def test_with_oauth_basic
22
+ EM.run do
23
+ bitly = EM::ShortURL::Bitly.new(:username => ENV[USER_ENV_VAR], :password => ENV[PASS_ENV_VAR])
24
+ set_asserts(bitly)
25
+ bitly.shorten(TEST_URL)
26
+ end
27
+ end
28
+ else
29
+ warn "Skipping test_with_oauth_basic: '#{USER_ENV_VAR}' and '#{PASS_ENV_VAR}' environment variable must be set"
30
+ end
31
+
32
+ if ENV[TOKEN_ENV_VAR]
33
+ def test_with_oauth_token
34
+ EM.run do
35
+ bitly = EM::ShortURL::Bitly.new(:token => ENV[TOKEN_ENV_VAR])
36
+ set_asserts(bitly)
37
+ bitly.shorten(TEST_URL)
38
+ end
39
+ end
40
+ else
41
+ warn "Skipping test_with_oauth_token: '#{TOKEN_ENV_VAR}' environment variable must be set"
42
+ end
43
+
44
+ private
45
+ def set_asserts(deferrable)
46
+ deferrable.callback { |s| assert_match(SHORT_REGEX, s); EM.stop }
47
+ deferrable.errback { |e| assert(false, e); EM.stop}
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ require "test/unit"
2
+ require "em-shorturl/tinyurl"
3
+
4
+ class TestTinyURL < Test::Unit::TestCase
5
+ TEST_URL = 'http://google.com'
6
+ SHORT_REGEX = /^http:\/\/tinyurl\.com\/\S+$/
7
+
8
+ def test_tinyurl
9
+ EM.run do
10
+ tinyurl = EM::ShortURL::TinyURL.new
11
+ set_asserts(tinyurl)
12
+ tinyurl.shorten(TEST_URL)
13
+ end
14
+ end
15
+
16
+ private
17
+ def set_asserts(deferrable)
18
+ deferrable.callback { |s| assert_match(SHORT_REGEX, s); EM.stop }
19
+ deferrable.errback { |e| assert(false, e); EM.stop}
20
+ end
21
+ end
metadata CHANGED
@@ -1,29 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-shorturl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0.pre
5
+ prerelease: 6
5
6
  platform: ruby
6
7
  authors:
7
8
  - Nik Johnson
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-05-24 00:00:00.000000000 Z
12
+ date: 2013-05-29 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: em-http-request
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ~>
18
20
  - !ruby/object:Gem::Version
19
- version: '0'
21
+ version: '1.0'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '1.0'
27
30
  description: An EventMachine module for shortening urls
28
31
  email:
29
32
  - nikjohnson08@gmail.com
@@ -31,35 +34,42 @@ executables: []
31
34
  extensions: []
32
35
  extra_rdoc_files: []
33
36
  files:
34
- - lib/em-shorturl/version.rb
35
- - lib/em-shorturl/google.rb
36
37
  - lib/em-shorturl.rb
38
+ - lib/em-shorturl/tinyurl.rb
39
+ - lib/em-shorturl/google.rb
40
+ - lib/em-shorturl/bitly.rb
41
+ - lib/em-shorturl/version.rb
37
42
  - test/test_google.rb
38
43
  - test/test_shorturl.rb
44
+ - test/test_bitly.rb
45
+ - test/test_tinyurl.rb
39
46
  homepage: https://github.com/jumpandspintowin/em-shorturl
40
47
  licenses:
41
48
  - Simplified BSD
42
- metadata: {}
43
49
  post_install_message:
44
50
  rdoc_options: []
45
51
  require_paths:
46
52
  - lib
47
53
  required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
48
55
  requirements:
49
- - - '>='
56
+ - - ! '>='
50
57
  - !ruby/object:Gem::Version
51
58
  version: '0'
52
59
  required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
53
61
  requirements:
54
- - - '>='
62
+ - - ! '>'
55
63
  - !ruby/object:Gem::Version
56
- version: '0'
64
+ version: 1.3.1
57
65
  requirements: []
58
66
  rubyforge_project:
59
- rubygems_version: 2.0.3
67
+ rubygems_version: 1.8.24
60
68
  signing_key:
61
- specification_version: 4
69
+ specification_version: 3
62
70
  summary: An EventMachine module for shortening urls
63
71
  test_files:
64
72
  - test/test_google.rb
65
73
  - test/test_shorturl.rb
74
+ - test/test_bitly.rb
75
+ - test/test_tinyurl.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 67a5cd1bf46ff96a3c6a00d651b954229f11e7b2
4
- data.tar.gz: 778cb1c98b3a1aad091abc7a5eae7db018c6c387
5
- SHA512:
6
- metadata.gz: 86bc8edf6aa87d139397e3c0f1369d44590e63f958a525f147f59afde00e858cedb2eda16e59e8b3eb492156a16fed2046c47c6d93e53139288ee922785a1856
7
- data.tar.gz: 4a9d75b5909ae617b607afdadc5390c9ccc2765777f4ed3c91315be05431aabf5cff944e2ebac6c85abc45497ff7d179ff11ca3ca93abc24383b59f4ca5a3c3b