shorturl 0.8.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +1 -0
  2. data/{ChangeLog → ChangeLog.txt} +0 -0
  3. data/{MIT-LICENSE → LICENSE.txt} +0 -0
  4. data/{README → README.rdoc} +28 -1
  5. data/Rakefile +42 -0
  6. data/{TODO → TODO.rdoc} +0 -0
  7. data/examples/shorten.rb +3 -3
  8. data/lib/shorturl.rb +35 -142
  9. data/lib/shorturl/exceptions.rb +7 -0
  10. data/lib/shorturl/service.rb +62 -0
  11. data/lib/shorturl/services.rb +12 -0
  12. data/lib/shorturl/services/bitly.rb +28 -0
  13. data/lib/shorturl/services/lns.rb +18 -0
  14. data/lib/shorturl/services/metamark.rb +20 -0
  15. data/lib/shorturl/services/minilink.rb +17 -0
  16. data/lib/shorturl/services/moourl.rb +22 -0
  17. data/lib/shorturl/services/shiturl.rb +20 -0
  18. data/lib/shorturl/services/shorl.rb +19 -0
  19. data/lib/shorturl/services/shortify.rb +20 -0
  20. data/lib/shorturl/services/snipurl.rb +22 -0
  21. data/lib/shorturl/services/tinyurl.rb +20 -0
  22. data/lib/shorturl/services/url.rb +21 -0
  23. data/lib/shorturl/services/vurl.rb +17 -0
  24. data/lib/shorturl/version.rb +3 -0
  25. data/shorturl.gemspec +27 -0
  26. data/test/helper.rb +11 -0
  27. data/test/tc_service.rb +6 -10
  28. data/test/tc_shorturl.rb +3 -12
  29. data/test/ts_all.rb +0 -5
  30. metadata +80 -63
  31. data/doc/classes/InvalidService.html +0 -111
  32. data/doc/classes/Service.html +0 -202
  33. data/doc/classes/Service.src/M000003.html +0 -28
  34. data/doc/classes/Service.src/M000004.html +0 -26
  35. data/doc/classes/ShortURL.html +0 -227
  36. data/doc/classes/ShortURL.src/M000001.html +0 -18
  37. data/doc/classes/ShortURL.src/M000002.html +0 -22
  38. data/doc/created.rid +0 -1
  39. data/doc/files/ChangeLog.html +0 -190
  40. data/doc/files/MIT-LICENSE.html +0 -129
  41. data/doc/files/README.html +0 -289
  42. data/doc/files/TODO.html +0 -113
  43. data/doc/files/lib/shorturl_rb.html +0 -119
  44. data/doc/fr_class_index.html +0 -29
  45. data/doc/fr_file_index.html +0 -31
  46. data/doc/fr_method_index.html +0 -30
  47. data/doc/index.html +0 -24
  48. data/doc/rdoc-style.css +0 -208
@@ -0,0 +1 @@
1
+ doc/
File without changes
File without changes
@@ -13,7 +13,6 @@ http://rubyforge.org/frs/?group_id=732 if you do not want to use the gem.
13
13
 
14
14
  == Supported services
15
15
  Here is the list of the services supported by ShortURL:
16
- * http://rubyurl.com
17
16
  * http://tinyurl.com
18
17
  * http://shorl.com
19
18
  * http://snipurl.com
@@ -34,6 +33,7 @@ Here is the list of the services supported by ShortURL:
34
33
  * http://moourl.com
35
34
  * http://urltea.com
36
35
  * http://vurl.me
36
+ * http://bit.ly
37
37
 
38
38
  == Usage:
39
39
  call-seq:
@@ -63,12 +63,39 @@ The second parameter represents the service you want to use. These are:
63
63
  * <tt>:moourl</tt>
64
64
  * <tt>:urltea</tt>
65
65
  * <tt>:vurl</tt>
66
+ * <tt>:bitly</tt>**
66
67
 
67
68
 
68
69
  You can use <tt>ShortURL.valid_services</tt> to obtain a
69
70
  list of the valid services (in case I forget to update the
70
71
  documentation)
71
72
 
73
+ Bitly**
74
+ -------
75
+
76
+ Their API changed to require an API key.
77
+
78
+ Two painfree steps to fix this.
79
+
80
+ 1) Get yours easily right now from:
81
+
82
+ http://bitly.com/a/your_api_key
83
+
84
+
85
+ 2) Save it in ~/.shorturl similar to this YAML template:
86
+
87
+ --- Start of file ~/.shorturl ---
88
+
89
+ ---
90
+ bitly:
91
+ username: O_adsfasdfasfasfd
92
+ key: R_afasdfasdfasdf
93
+
94
+ --- END of file ~/.shorturl ---
95
+
96
+
97
+ You're done! Have a martini. Cheers.
98
+
72
99
  == Thanks
73
100
  - Marcel Molina Jr., Devin Mullins for some ideas
74
101
  - imperator from #ruby-lang (I don't know your real name, sorry) for
@@ -0,0 +1,42 @@
1
+ require "rake"
2
+ require "rake/testtask"
3
+ require "rdoc/task"
4
+
5
+ task :default => [ :test, :doc ]
6
+
7
+ desc "Run the tests"
8
+ Rake::TestTask.new("test") { |t|
9
+ t.libs << 'test'
10
+ t.pattern = "test/**/ts_*.rb"
11
+ t.verbose = true
12
+ }
13
+
14
+ desc "Write the documentation"
15
+ RDoc::Task.new("doc") { |rdoc|
16
+ rdoc.rdoc_dir = "doc"
17
+ rdoc.title = "ShortURL Documentation"
18
+ # rdoc.options << "--line-numbers --inline-source"
19
+ rdoc.rdoc_files.include("README.rdoc")
20
+ rdoc.rdoc_files.include("TODO.rdoc")
21
+ rdoc.rdoc_files.include("LICENSE.txt")
22
+ rdoc.rdoc_files.include("ChangeLog.txt")
23
+ rdoc.rdoc_files.include("lib/*.rb")
24
+ rdoc.rdoc_files.exclude("test/*")
25
+ }
26
+
27
+ desc "Upload documentation to RubyForge"
28
+ task :upload_doc do
29
+ sh "scp -r doc/* robbyrussell@rubyforge.org:/var/www/gforge-projects/shorturl"
30
+ end
31
+
32
+
33
+ desc "Statistics for the code"
34
+ task :stats do
35
+ begin
36
+ require "code_statistics"
37
+ CodeStatistics.new(["Code", "lib"],
38
+ ["Units", "test"]).to_s
39
+ rescue LoadError
40
+ puts "Couldn't load code_statistics (install rails)"
41
+ end
42
+ end
File without changes
@@ -11,9 +11,9 @@ end
11
11
  def main
12
12
  begin
13
13
  case ARGV.length
14
- when 0: usage
15
- when 1: puts ShortURL.shorten(ARGV[0])
16
- else puts ShortURL.shorten(ARGV[0], ARGV[1].to_sym)
14
+ when 0 then usage
15
+ when 1 then puts ShortURL.shorten(ARGV[0])
16
+ else puts ShortURL.shorten(ARGV[0], ARGV[1].to_sym)
17
17
  end
18
18
  rescue InvalidService
19
19
  puts "Invalid service"
@@ -3,148 +3,45 @@
3
3
  # Created by Vincent Foley on 2005-06-02
4
4
  #
5
5
 
6
- require "net/http"
7
- require "cgi"
6
+ require "shorturl/services"
8
7
  require "uri"
9
-
10
- class ServiceNotAvailable < Exception
11
- end
12
-
13
- class InvalidService < Exception
14
- end
15
-
16
- class Service
17
- attr_accessor :port, :code, :method, :action, :field, :block, :response_block
18
-
19
- # Intialize the service with a hostname (required parameter) and you
20
- # can override the default values for the HTTP port, expected HTTP
21
- # return code, the form method to use, the form action, the form
22
- # field which contains the long URL, and the block of what to do
23
- # with the HTML code you get.
24
- def initialize(hostname) # :yield: service
25
- @hostname = hostname
26
- @port = 80
27
- @code = 200
28
- @method = :post
29
- @action = "/"
30
- @field = "url"
31
-
32
- if block_given?
33
- yield self
34
- end
8
+ require "yaml"
9
+
10
+ module ShortURL
11
+ CREDENTIALS_PATH = File.join(Gem.user_home,'.shorturl')
12
+
13
+ def self.credentials
14
+ @credentials ||= begin
15
+ if File.file?(CREDENTIALS_PATH)
16
+ YAML.load_file(CREDENTIALS_PATH)
17
+ else
18
+ {}
19
+ end
20
+ end
35
21
  end
36
22
 
37
- # Now that our service is set up, call it with all the parameters to
38
- # (hopefully) return only the shortened URL.
39
- def call(url)
40
- Net::HTTP.start(@hostname, @port) { |http|
41
- response = case @method
42
- when :post: http.post(@action, "#{@field}=#{CGI.escape(url)}")
43
- when :get: http.get("#{@action}?#{@field}=#{CGI.escape(url)}")
44
- end
45
- if response.code == @code.to_s
46
- @response_block ? @response_block.call(response) : @block.call(response.read_body)
47
- end
48
- }
49
- rescue Errno::ECONNRESET => e
50
- raise ServiceNotAvailable, e.to_s, e.backtrace
23
+ def self.credentials_for(service)
24
+ credentials.fetch(service,{})
51
25
  end
52
- end
53
26
 
54
- class ShortURL
55
27
  # Hash table of all the supported services. The key is a symbol
56
28
  # representing the service (usually the hostname minus the .com,
57
29
  # .net, etc.) The value is an instance of Service with all the
58
30
  # parameters set so that when +instance+.call is invoked, the
59
31
  # shortened URL is returned.
60
- @@services = {
61
- :rubyurl => Service.new("rubyurl.com") { |s|
62
- s.action = "/rubyurl/remote"
63
- s.field = "website_url"
64
- s.block = lambda { |body| URI.extract(body).grep(/rubyurl/)[0] }
65
- },
66
-
67
- :tinyurl => Service.new("tinyurl.com") { |s|
68
- s.action = "/api-create.php"
69
- s.method = :get
70
- s.block = lambda { |body| URI.extract(body).grep(/tinyurl/)[0] }
71
- },
72
-
73
- :shorl => Service.new("shorl.com") { |s|
74
- s.action = "/create.php"
75
- s.block = lambda { |body| URI.extract(body)[2] }
76
- },
77
-
78
- # SnipURL offers a restful HTTP API but it cannot be used without
79
- # registration.
80
- :snipurl => Service.new("snipurl.com") { |s|
81
- s.action = "/site/index"
82
- s.field = "url"
83
-
84
- # As with other services, this is far from elegant and might break
85
- # any time. Might just be better to do some HTML parsing instead.
86
- s.block = lambda { |body| URI.extract(body).grep(/http:\/\/snipurl.com/)[0] }
87
- },
88
-
89
- :metamark => Service.new("metamark.net") { |s|
90
- s.action = "/add"
91
- s.field = "long_url"
92
- s.block = lambda { |body| URI.extract(body).grep(/xrl.us/)[0] }
93
- },
94
-
95
- :minilink => Service.new("minilink.org") { |s|
96
- s.method = :get
97
- s.block = lambda { |body| URI.extract(body)[-1] }
98
- },
99
-
100
- :lns => Service.new("ln-s.net") { |s|
101
- s.method = :get
102
- s.action = "/home/api.jsp"
103
- s.block = lambda { |body| URI.extract(body)[0] }
104
- },
105
-
106
- :shiturl => Service.new("shiturl.com") { |s|
107
- s.method = :get
108
- s.action = "/make.php"
109
- s.block = lambda { |body| URI.extract(body).grep(/shiturl/)[0] }
110
- },
111
-
112
- :shortify => Service.new("shortify.wikinote.com") { |s|
113
- s.method = :get
114
- s.action = "/shorten.php"
115
- s.block = lambda { |body| URI.extract(body).grep(/shortify/)[-1] }
116
- },
117
-
118
- :moourl => Service.new("moourl.com") { |s|
119
- s.code = 302
120
- s.action = "/create/"
121
- s.method = :get
122
- s.field = "source"
123
- s.response_block = lambda { |res| "http://moourl.com/" + res["location"].match(/\?moo=/).post_match }
124
- },
125
-
126
- :bitly => Service.new("bit.ly") { |s|
127
- s.method = :get
128
- s.action = "/index.php"
129
- s.field = "url"
130
- s.block = lambda { |body|
131
- body.match(%r{<input id="shortened-url" value="(.*)" />}).captures[0]
132
- }
133
- },
134
-
135
- :ur1 => Service.new("ur1.ca") { |s|
136
- s.method = :post
137
- s.action = "/"
138
- s.field = "longurl"
139
- s.block = lambda { |body| URI.extract(body).grep(/ur1/)[0] }
140
- },
141
-
142
- :vurl => Service.new("vurl.me") { |s|
143
- s.method = :get
144
- s.action = "/shorten"
145
- s.field = "url"
146
- s.block = lambda { |body| body }
147
- }
32
+ SERVICES = {
33
+ :tinyurl => Services::TinyURL.new,
34
+ :shorl => Services::Shorl.new,
35
+ :snipurl => Services::SnipURL.new,
36
+ :metamark => Services::Metamark.new,
37
+ :minilink => Services::Minilink.new,
38
+ :lns => Services::Lns.new,
39
+ :shiturl => Services::ShitURL.new,
40
+ :shortify => Services::Shortify.new,
41
+ :moourl => Services::MooURL.new,
42
+ :bitly => Services::Bitly.new,
43
+ :ur1 => Services::Url.new,
44
+ :vurl => Services::Vurl.new,
148
45
 
149
46
  # :skinnylink => Service.new("skinnylink.com") { |s|
150
47
  # s.block = lambda { |body| URI.extract(body).grep(/skinnylink/)[0] }
@@ -195,11 +92,8 @@ class ShortURL
195
92
 
196
93
  # Array containing symbols representing all the implemented URL
197
94
  # shortening services
198
- @@valid_services = @@services.keys
199
-
200
- # Returns @@valid_services
201
95
  def self.valid_services
202
- @@valid_services
96
+ SERVICES.keys
203
97
  end
204
98
 
205
99
  # Main method of ShortURL, its usage is quite simple, just give an
@@ -209,7 +103,6 @@ class ShortURL
209
103
  #
210
104
  # Valid +service+ values:
211
105
  #
212
- # * <tt>:rubyurl</tt>
213
106
  # * <tt>:tinyurl</tt>
214
107
  # * <tt>:shorl</tt>
215
108
  # * <tt>:snipurl</tt>
@@ -229,11 +122,11 @@ class ShortURL
229
122
  # * <tt>:orz</tt>
230
123
  #
231
124
  # call-seq:
232
- # ShortURL.shorten("http://mypage.com") => Uses RubyURL
233
- # ShortURL.shorten("http://mypage.com", :tinyurl)
234
- def self.shorten(url, service = :rubyurl)
235
- if valid_services.include? service
236
- @@services[service].call(url)
125
+ # ShortURL.shorten("http://mypage.com") => Uses TinyURL
126
+ # ShortURL.shorten("http://mypage.com", :bitly)
127
+ def self.shorten(url, service = :tinyurl)
128
+ if SERVICES.has_key?(service)
129
+ SERVICES[service].call(url)
237
130
  else
238
131
  raise InvalidService
239
132
  end
@@ -0,0 +1,7 @@
1
+ module ShortURL
2
+ class ServiceNotAvailable < Exception
3
+ end
4
+
5
+ class InvalidService < Exception
6
+ end
7
+ end
@@ -0,0 +1,62 @@
1
+ require "shorturl/exceptions"
2
+ require "net/http"
3
+ require "net/https"
4
+ require "cgi"
5
+
6
+ module ShortURL
7
+ class Service
8
+ attr_accessor :port, :code, :method, :action, :field, :block, :response_block, :ssl
9
+
10
+ # Intialize the service with a hostname (required parameter) and you
11
+ # can override the default values for the HTTP port, expected HTTP
12
+ # return code, the form method to use, the form action, the form
13
+ # field which contains the long URL, and the block of what to do
14
+ # with the HTML code you get.
15
+ def initialize(hostname) # :yield: service
16
+ @hostname = hostname
17
+ @port = 80
18
+ @code = 200
19
+ @method = :post
20
+ @action = "/"
21
+ @field = "url"
22
+ @ssl = false
23
+
24
+ if block_given?
25
+ yield self
26
+ end
27
+ end
28
+
29
+ # Now that our service is set up, call it with all the parameters to
30
+ # (hopefully) return only the shortened URL.
31
+ def call(url)
32
+ http = Net::HTTP.new(@hostname, @port)
33
+ http.use_ssl = @ssl
34
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
35
+
36
+ http.start do
37
+ response = case @method
38
+ when :post
39
+ http.post(@action, "#{@field}=#{CGI.escape(url)}")
40
+ when :get
41
+ http.get("#{@action}?#{@field}=#{CGI.escape(url)}")
42
+ end
43
+
44
+ if response.code == @code.to_s
45
+ on_response(response)
46
+ end
47
+ end
48
+ rescue Errno::ECONNRESET => e
49
+ raise ServiceNotAvailable, e.to_s, e.backtrace
50
+ end
51
+
52
+ # Extracts the shortened URL from a response body.
53
+ def on_body(body)
54
+ body
55
+ end
56
+
57
+ # Extracts the shortened URL from the response.
58
+ def on_response(response)
59
+ on_body(response.read_body)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ require "shorturl/services/tinyurl"
2
+ require "shorturl/services/shorl"
3
+ require "shorturl/services/snipurl"
4
+ require "shorturl/services/metamark"
5
+ require "shorturl/services/minilink"
6
+ require "shorturl/services/lns"
7
+ require "shorturl/services/shiturl"
8
+ require "shorturl/services/shortify"
9
+ require "shorturl/services/moourl"
10
+ require "shorturl/services/bitly"
11
+ require "shorturl/services/url"
12
+ require "shorturl/services/vurl"
@@ -0,0 +1,28 @@
1
+ require "shorturl/service"
2
+
3
+ module ShortURL
4
+ module Services
5
+ class Bitly < Service
6
+
7
+ def initialize
8
+ super("api-ssl.bitly.com")
9
+
10
+ @method = :get
11
+ @port = 443
12
+ @ssl = true
13
+ @action = "/v3/shorten/"
14
+
15
+ creds = ShortURL.credentials_for('bitly')
16
+ username = creds['username']
17
+ key = creds['key']
18
+
19
+ @field = "format=txt&login=#{username}&apiKey=#{key}&longUrl"
20
+ end
21
+
22
+ def on_body(body)
23
+ body
24
+ end
25
+
26
+ end
27
+ end
28
+ end