shorty 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +7 -0
  3. data/README.rdoc +76 -0
  4. data/Rakefile +68 -0
  5. data/VERSION +1 -0
  6. data/features/bitly.feature +4 -0
  7. data/features/step_definitions/api.rb +18 -0
  8. data/features/step_definitions/common_steps.rb +163 -0
  9. data/features/support/common.rb +29 -0
  10. data/features/support/env.rb +14 -0
  11. data/features/support/matchers.rb +11 -0
  12. data/features/trim.feature +8 -0
  13. data/lib/shorty/bitly.rb +101 -0
  14. data/lib/shorty/cligs.rb +56 -0
  15. data/lib/shorty/isgd.rb +14 -0
  16. data/lib/shorty/supr.rb +100 -0
  17. data/lib/shorty/tinyurl.rb +14 -0
  18. data/lib/shorty/trim.rb +110 -0
  19. data/lib/shorty/twurl.rb +32 -0
  20. data/lib/shorty.rb +17 -0
  21. data/shorty.gemspec +95 -0
  22. data/test/bitly_test.rb +32 -0
  23. data/test/cligs_test.rb +18 -0
  24. data/test/fixtures/bitly-expand-cnn.json +10 -0
  25. data/test/fixtures/bitly-shorten-cnn.json +1 -0
  26. data/test/fixtures/bitly-stats-cnn.json +1 -0
  27. data/test/fixtures/cligs-shorten-google.txt +1 -0
  28. data/test/fixtures/isgd-shorten-google.txt +1 -0
  29. data/test/fixtures/supr-expand-cnn-error.json +1 -0
  30. data/test/fixtures/supr-expand-cnn.json +1 -0
  31. data/test/fixtures/supr-shorten-cnn.json +1 -0
  32. data/test/fixtures/tinyurl-shorten-google.txt +1 -0
  33. data/test/fixtures/trim-trim-simple.txt +1 -0
  34. data/test/fixtures/trim-trim-url.xml +7 -0
  35. data/test/fixtures/twurl-shorten-google.txt +1 -0
  36. data/test/isgd_test.rb +18 -0
  37. data/test/shory_test.rb +7 -0
  38. data/test/supr_test.rb +69 -0
  39. data/test/test_helper.rb +9 -0
  40. data/test/tinyurl_test.rb +18 -0
  41. data/test/trim_test.rb +24 -0
  42. data/test/twurl_test.rb +18 -0
  43. metadata +124 -0
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ doc/
3
+ features/
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2009 Alex Coomans
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,76 @@
1
+ = Shorty
2
+
3
+ shorty makes interfacing with url shortening services easy, so far the following are supported:
4
+ - http://bit.ly
5
+ - http://tr.im - only URL API implemented, not media ones
6
+ - http://is.gd
7
+ - http://tinyurl.com
8
+ - http://cli.gs - only shorten implemented, expand not
9
+ - http://twurl.nl
10
+ - http://su.pr
11
+
12
+ == Install
13
+
14
+ sudo gem install drcapulet-shorty
15
+
16
+ == Usage
17
+
18
+ Yeah just read the rdocs. But to get started, make sure the gem is installed. Require:
19
+
20
+ require 'shorty'
21
+
22
+ or with Rails:
23
+
24
+ config.gem 'drcapulet-shorty', :lib => 'shorty'
25
+
26
+ == Possible Additions
27
+
28
+ - http://ow.ly - currently no API, says it is coming soon
29
+
30
+ == Other Possible Gems
31
+
32
+ - http://post.ly - Not really a shortener
33
+ - http://ping.fm - Not really a shortener
34
+ - http://ff.im - Not a shortener either
35
+ - http://yfrog.com - Not a shortener, maybe expand this gem or a media gem. API docs: http://code.google.com/p/imageshackapi
36
+ - http://twitpic.com - Same as yfrog. API docs: http://twitpic.com/api.do
37
+
38
+ == Other Ideas
39
+
40
+ * Possibly use OpenStruct to make data access easier
41
+ * Possibly set a user agent using
42
+
43
+ class Foo
44
+ include HTTParty
45
+ headers 'Accept' => 'text/html'
46
+ end
47
+
48
+ * Also possibly create a command line app
49
+ * Any other ideas create an issue and start the title with [feature]
50
+
51
+ == Contributing
52
+
53
+ I invite anyone who wants to help to fork and then when you've made your changes, send me a pull request. I'd love to keep everything central.
54
+
55
+ == License
56
+
57
+ Copyright (c) 2009 Alex Coomans
58
+
59
+ Permission is hereby granted, free of charge, to any person obtaining
60
+ a copy of this software and associated documentation files (the
61
+ "Software"), to deal in the Software without restriction, including
62
+ without limitation the rights to use, copy, modify, merge, publish,
63
+ distribute, sublicense, and/or sell copies of the Software, and to
64
+ permit persons to whom the Software is furnished to do so, subject to
65
+ the following conditions:
66
+
67
+ The above copyright notice and this permission notice shall be
68
+ included in all copies or substantial portions of the Software.
69
+
70
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
71
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
72
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
73
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
74
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
75
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
76
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+
2
+
3
+ # begin
4
+ # require 'cucumber/rake/task'
5
+ #
6
+ # Cucumber::Rake::Task.new(:features) do |t|
7
+ # t.fork = true
8
+ # t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
9
+ # end
10
+ # rescue LoadError
11
+ # desc 'Cucumber rake task not available'
12
+ # task :features do
13
+ # abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
14
+ # end
15
+ # end
16
+
17
+ begin
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |gemspec|
20
+ gemspec.name = "shorty"
21
+ gemspec.summary = "Gem that talks to APIs for shortening urls"
22
+ gemspec.description = "Makes it easy to shorten URLs"
23
+ gemspec.email = "alex@alexcoomans.com"
24
+ gemspec.homepage = "http://github.com/drcapulet/shorty"
25
+ gemspec.authors = ["Alex Coomans"]
26
+ gemspec.add_dependency('httparty', '>= 0.4.4')
27
+ gemspec.add_dependency('crack', '>= 0.1.4')
28
+ end
29
+ Jeweler::GemcutterTasks.new
30
+ rescue LoadError
31
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
32
+ end
33
+
34
+ require 'rake/testtask'
35
+ Rake::TestTask.new(:test) do |test|
36
+ test.libs << 'lib' << 'test'
37
+ test.pattern = 'test/**/*_test.rb'
38
+ test.verbose = true
39
+ end
40
+
41
+ begin
42
+ require 'rcov/rcovtask'
43
+ Rcov::RcovTask.new do |test|
44
+ test.libs << 'test'
45
+ test.pattern = 'test/**/*_test.rb'
46
+ test.verbose = true
47
+ end
48
+ rescue LoadError
49
+ task :rcov do
50
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
51
+ end
52
+ end
53
+
54
+ task :default => :test
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ if File.exist?('VERSION')
59
+ version = File.read('VERSION')
60
+ else
61
+ version = ""
62
+ end
63
+
64
+ rdoc.rdoc_dir = 'doc'
65
+ rdoc.title = "shorty #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,4 @@
1
+ Feature: Interface with the bit.ly API
2
+ As a user
3
+ I want to be able to interface with the bit.ly API
4
+ So that I can shorten URLs
@@ -0,0 +1,18 @@
1
+ Given /I have created a new (.*) instance/ do |n|
2
+ @instance = Shorty::Trim.new()
3
+ end
4
+
5
+ Given /I want to shorten (.*)/ do |n|
6
+ @url = @instance.shorten(n)
7
+ end
8
+
9
+ Then /^I should see "([^\"]*)"$/ do |text|
10
+ actual_output = File.read(@stdout)
11
+ actual_output.should contain(text)
12
+ end
13
+
14
+ Then /the URL should look like "([^\"]*)"$/ do |text|
15
+ @url.should contain(text)
16
+ end
17
+
18
+
@@ -0,0 +1,163 @@
1
+ # Given /^this project is active project folder/ do
2
+ # @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
3
+ # end
4
+ #
5
+ # Given /^env variable \$([\w_]+) set to "(.*)"/ do |env_var, value|
6
+ # ENV[env_var] = value
7
+ # end
8
+ #
9
+ # Given /"(.*)" folder is deleted/ do |folder|
10
+ # in_project_folder { FileUtils.rm_rf folder }
11
+ # end
12
+ #
13
+ # When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
14
+ # @stdout = StringIO.new
15
+ # in_project_folder do
16
+ # if Object.const_defined?("APP_ROOT")
17
+ # APP_ROOT.replace(FileUtils.pwd)
18
+ # else
19
+ # APP_ROOT = FileUtils.pwd
20
+ # end
21
+ # run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
22
+ # end
23
+ # File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
24
+ # @stdout.rewind
25
+ # f << @stdout.read
26
+ # end
27
+ # end
28
+ #
29
+ # When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
30
+ # @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
31
+ # in_project_folder do
32
+ # system "#{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
33
+ # end
34
+ # end
35
+ #
36
+ # When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
37
+ # @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
38
+ # in_project_folder do
39
+ # system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
40
+ # end
41
+ # end
42
+ #
43
+ # When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
44
+ # @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
45
+ # executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
46
+ # in_project_folder do
47
+ # system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
48
+ # end
49
+ # end
50
+ #
51
+ # When /^I invoke task "rake (.*)"/ do |task|
52
+ # @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
53
+ # in_project_folder do
54
+ # system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
55
+ # end
56
+ # end
57
+ #
58
+ # Then /^folder "(.*)" (is|is not) created/ do |folder, is|
59
+ # in_project_folder do
60
+ # File.exists?(folder).should(is == 'is' ? be_true : be_false)
61
+ # end
62
+ # end
63
+ #
64
+ # Then /^file "(.*)" (is|is not) created/ do |file, is|
65
+ # in_project_folder do
66
+ # File.exists?(file).should(is == 'is' ? be_true : be_false)
67
+ # end
68
+ # end
69
+ #
70
+ # Then /^file with name matching "(.*)" is created/ do |pattern|
71
+ # in_project_folder do
72
+ # Dir[pattern].should_not be_empty
73
+ # end
74
+ # end
75
+ #
76
+ # Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
77
+ # in_project_folder do
78
+ # actual_output = File.read(file)
79
+ # (does == 'does') ?
80
+ # actual_output.should(match(/#{regex}/)) :
81
+ # actual_output.should_not(match(/#{regex}/))
82
+ # end
83
+ # end
84
+ #
85
+ # Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
86
+ # File.exists?(gem_file).should be_true
87
+ # File.exists?(project_file).should be_true
88
+ # gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
89
+ # project_file_contents = File.read(File.join(@active_project_folder, project_file))
90
+ # project_file_contents.should == gem_file_contents
91
+ # end
92
+ #
93
+ # Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
94
+ # actual_output = File.read(@stdout)
95
+ # does_invoke == "does" ?
96
+ # actual_output.should(match(/dependency\s+#{generator}/)) :
97
+ # actual_output.should_not(match(/dependency\s+#{generator}/))
98
+ # end
99
+ #
100
+ # Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
101
+ # actual_output = File.read(@stdout)
102
+ # actual_output.should match(/#{opt1}/)
103
+ # actual_output.should match(/#{opt2}/)
104
+ # end
105
+ #
106
+ # Then /^I should see$/ do |text|
107
+ # actual_output = File.read(@stdout)
108
+ # actual_output.should contain(text)
109
+ # end
110
+ #
111
+ # Then /^I should not see$/ do |text|
112
+ # actual_output = File.read(@stdout)
113
+ # actual_output.should_not contain(text)
114
+ # end
115
+ #
116
+ # Then /^I should see exactly$/ do |text|
117
+ # actual_output = File.read(@stdout)
118
+ # actual_output.should == text
119
+ # end
120
+ #
121
+ # Then /^I should see all (\d+) tests pass/ do |expected_test_count|
122
+ # expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
123
+ # actual_output = File.read(@stdout)
124
+ # actual_output.should match(expected)
125
+ # end
126
+ #
127
+ # Then /^I should see all (\d+) examples pass/ do |expected_test_count|
128
+ # expected = %r{^#{expected_test_count} examples?, 0 failures}
129
+ # actual_output = File.read(@stdout)
130
+ # actual_output.should match(expected)
131
+ # end
132
+ #
133
+ # Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
134
+ # in_project_folder do
135
+ # yaml = eval yaml
136
+ # YAML.load(File.read(file)).should == yaml
137
+ # end
138
+ # end
139
+ #
140
+ # Then /^Rakefile can display tasks successfully/ do
141
+ # @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
142
+ # in_project_folder do
143
+ # system "rake -T > #{@stdout} 2> #{@stdout}"
144
+ # end
145
+ # actual_output = File.read(@stdout)
146
+ # actual_output.should match(/^rake\s+\w+\s+#\s.*/)
147
+ # end
148
+ #
149
+ # Then /^task "rake (.*)" is executed successfully/ do |task|
150
+ # @stdout.should_not be_nil
151
+ # actual_output = File.read(@stdout)
152
+ # actual_output.should_not match(/^Don't know how to build task '#{task}'/)
153
+ # actual_output.should_not match(/Error/i)
154
+ # end
155
+ #
156
+ # Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
157
+ # in_project_folder do
158
+ # gem_file = Dir["pkg/*.gem"].first
159
+ # gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
160
+ # spec_value = gem_spec.send(key.to_sym)
161
+ # spec_value.to_s.should match(/#{regex}/)
162
+ # end
163
+ # end
@@ -0,0 +1,29 @@
1
+ module CommonHelpers
2
+ def in_tmp_folder(&block)
3
+ FileUtils.chdir(@tmp_root, &block)
4
+ end
5
+
6
+ def in_project_folder(&block)
7
+ project_folder = @active_project_folder || @tmp_root
8
+ FileUtils.chdir(project_folder, &block)
9
+ end
10
+
11
+ def in_home_folder(&block)
12
+ FileUtils.chdir(@home_path, &block)
13
+ end
14
+
15
+ def force_local_lib_override(project_name = @project_name)
16
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
17
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
18
+ f << "$:.unshift('#{@lib_path}')\n"
19
+ f << rakefile
20
+ end
21
+ end
22
+
23
+ def setup_active_project_folder project_name
24
+ @active_project_folder = File.join(@tmp_root, project_name)
25
+ @project_name = project_name
26
+ end
27
+ end
28
+
29
+ World(CommonHelpers)
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + "/../../lib/shorty"
2
+
3
+ gem 'cucumber'
4
+ require 'cucumber'
5
+ gem 'rspec'
6
+ require 'spec'
7
+
8
+ Before do
9
+ @tmp_root = File.dirname(__FILE__) + "/../../tmp"
10
+ @home_path = File.expand_path(File.join(@tmp_root, "home"))
11
+ FileUtils.rm_rf @tmp_root
12
+ FileUtils.mkdir_p @home_path
13
+ ENV['HOME'] = @home_path
14
+ end
@@ -0,0 +1,11 @@
1
+ module Matchers
2
+ def contain(expected)
3
+ simple_matcher("contain #{expected.inspect}") do |given, matcher|
4
+ matcher.failure_message = "expected #{given.inspect} to contain #{expected.inspect}"
5
+ matcher.negative_failure_message = "expected #{given.inspect} not to contain #{expected.inspect}"
6
+ given.index expected
7
+ end
8
+ end
9
+ end
10
+
11
+ World(Matchers)
@@ -0,0 +1,8 @@
1
+ Feature: Interface with the tr.im API
2
+ As a user
3
+ I want to be able to interface with the tr.im API
4
+ So that I can shorten URLs
5
+
6
+ Scenario: Shorten URL
7
+ Given I want to shorten "http://google.com"
8
+ Then the URL should look like "http://tr.im/szkO"
@@ -0,0 +1,101 @@
1
+ module Shorty
2
+ # The bit.ly API class. API documentation: http://code.google.com/p/bitly-api/wiki/ApiDocumentation
3
+ # For testing, use:
4
+ # require 'lib/shorty'
5
+ # bitly = Shorty::Bitly.new('bitlyapidemo', 'R_0da49e0a9118ff35f52f629d2d71bf07')
6
+ class Bitly
7
+ attr_reader :options
8
+ include HTTParty
9
+
10
+ # Standard Error Class
11
+ class Error < StandardError; end
12
+
13
+ API_URL = 'api.bit.ly'
14
+ API_VERSION = '2.0.1'
15
+ base_uri API_URL
16
+
17
+ # Options to pass:
18
+ #
19
+ # - login
20
+ # - apikey
21
+ def initialize(login, apikey)
22
+ @options = {
23
+ :login => login,
24
+ :apiKey => apikey,
25
+ :version => API_VERSION
26
+ }
27
+ end
28
+
29
+ # shorten, pass:
30
+ #
31
+ # - longurl: the URL to be shortened
32
+ def shorten( longurl )
33
+ query = {:longUrl => longurl}
34
+ query.merge!(@options)
35
+ short = self.class.get('/shorten', :query => query)
36
+ short = Crack::JSON.parse(short)
37
+ short["errorCode"].zero? ? short["results"][longurl]["shortUrl"] : raise_error(short["errorCode"], short["errorMessage"])
38
+ end
39
+
40
+ # expand- given a bit.ly url, returns long source url, takes:
41
+ #
42
+ # - shorturl: the bit.ly url, can either be the full url or missing http://bit.ly
43
+ def expand(shorturl)
44
+ shorturl = gsub_url(shorturl)
45
+ query = {:hash => shorturl}
46
+ query.merge!(@options)
47
+ expand = self.class.get('/expand', :query => query)
48
+ expand = Crack::JSON.parse(expand)
49
+ expand["errorCode"].zero? ? expand["results"][shorturl]["longUrl"] : raise_error(expand["errorCode"], expand["errorMessage"])
50
+ end
51
+
52
+ # info - Given a bit.ly url or hash, return information about that page, such as the long source url, ...
53
+ def info(urlorhash, keys = [])
54
+ urlhash = gsub_url(urlorhash)
55
+ if keys != []
56
+ query = {:hash => urlhash, :keys => keys.join(',')}
57
+ else
58
+ query = {:hash => urlhash}
59
+ end
60
+ query.merge!(@options)
61
+ stats = self.class.get('/info', :query => query)
62
+ stats = Crack::JSON.parse(stats)
63
+ stats["errorCode"].zero? ? stats["results"][urlhash] : raise_error(stats["errorCode"], stats["errorMessage"])
64
+ end
65
+
66
+ # stats - get stats on clicks and reffers, pass either:
67
+ #
68
+ # - shortURL: A single bitly url, eg: http://bit.ly/1RmnUT
69
+ # - hash: A single hash, eg: 1RmnUT
70
+ #
71
+ # Example:
72
+ # bitly = Shorty::Bitly.new('login', 'apikey')
73
+ # bitly.expand('1RmnUT')
74
+ # Or:
75
+ # bitly = Shorty::Bitly.new('login', 'apikey')
76
+ # bitly.expand('http://bit.ly/1RmnUT')
77
+ def stats(urlorhash)
78
+ urlhash = gsub_url(urlorhash)
79
+ query = {:hash => urlhash}
80
+ query.merge!(@options)
81
+ stats = self.class.get('/stats', :query => query)
82
+ stats = Crack::JSON.parse(stats)
83
+ stats["errorCode"].zero? ? stats["results"] : raise_error(stats["errorCode"], stats["errorMessage"])
84
+ end
85
+
86
+
87
+ protected
88
+
89
+ def gsub_url(shorturl)
90
+ shorturl.split('/').last
91
+ # shorturl = shorturl.gsub(/http:\/\//, '') if shorturl.include?('http://')
92
+ # shorturl = shorturl.gsub(/bit.ly\//, '') if shorturl.include?('bit.ly/')
93
+ end
94
+
95
+ def raise_error(code, message = '(no error message)')
96
+ error = message + " (error code: #{code})"
97
+ raise Shorty::Bitly::Error, error
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,56 @@
1
+ module Shorty
2
+ # The cli.gs API class. API documentation: http://blog.cli.gs/api
3
+ # For testing, use:
4
+ # require 'lib/shorty'
5
+ # cligs = Shorty::Cligs.new
6
+ class Cligs
7
+ attr_reader :options
8
+ include HTTParty
9
+
10
+ # Standard Error Class
11
+ class Error < StandardError; end
12
+
13
+ API_URL = 'http://cli.gs/api/v1/cligs'
14
+ API_VERSION = '1'
15
+ base_uri API_URL
16
+
17
+ # Options to pass:
18
+ #
19
+ # - API key: f given it associates the new clig with a user account so that they can view the traffic statistics. If not given, then a Public clig is created.
20
+ # - AppId: a simple string, HTML allowed, that identifies your App when the API usage is listed in the user’s control panel. Keep it short and simple please.
21
+ #
22
+ # cligs = Shorty::Cligs.new(:apikey => 'apikey', :appid => 'appid')
23
+ def initialize(options = {})
24
+ @options = {}
25
+ @options[:key] = options[:apikey] if options[:apikey]
26
+ @options[:appid] = options[:appid] if options[:appid]
27
+ end
28
+
29
+ # shorten. pass:
30
+ #
31
+ # - url: the url to shorten
32
+ def shorten(url)
33
+ query = {:url => url}
34
+ query.merge!(@options)
35
+ self.class.get('/create', :query => query)
36
+ end
37
+
38
+ # expand. pass either:
39
+ #
40
+ # - A valid clig ID, like Ts8p6Y
41
+ # - A clig URL, like http://cli.gs/Ts8p6Y
42
+ #
43
+ # Currently not implemented due to the fact this method wont work for demo.
44
+ def expand(urlorhash)
45
+ raise StandardError, 'Method not implemented'
46
+ end
47
+
48
+ protected
49
+
50
+ def raise_error(code, message = '(no error message)')
51
+ error = message + " (error code: #{code})"
52
+ raise Shorty::Bitly::Error, error
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ module Shorty
2
+ # is.gd API as defined http://is.gd/api_info.php
3
+ class Isgd
4
+ include HTTParty
5
+
6
+ def shorten(url)
7
+ self.class.get('http://is.gd/api.php', :query => {:longurl => url})
8
+ end
9
+
10
+ def self.shorten(url)
11
+ get('http://is.gd/api.php', :query => {:longurl => url})
12
+ end
13
+ end
14
+ end