shorturl 0.8.8 → 1.0.0

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.
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